一般在前端接口调用如下拿到经纬度:
//按钮点击事件,调用接口取出经纬度并马上绘制到地图上
const pointdrawClick = async (record: any) => {
//接口
let res=await viewDeviceInfo({
...record })
//马上绘制点
//创建一个空的Vector面图层
const mapLayer = new VectorLayer({
source: new VectorSource({
features: []
})
});
mapLayer.set('maplayer', mapLayer);
map.addLayer(mapLayer);
//创建点geometry
let point = new Point(
transform(
[Number(res,longitude), Number(res,latitude )],
'EPSG:4326',
'EPSG:3857'
)
);
// 创建feature要素,一个feature就是一个点
let pointFeature = new Feature(point);
// 设置要素的图标
pointFeature.setStyle(pointStyle);
pointFeature.setId('pointFeature');
layerarr[2].getSource().addFeatures([pointFeature]);
map
.getView()
.setCenter(
transform(
[Number(res,longitude), Number(res,latitude)],
'EPSG:4326',
'EPSG:3857'
)
);
map.getView().setZoom(17.5);
}
此时我们会发现,在第一次点击时地图没有反应,只有再进行第二次操作时才会绘制点。
后端返回的值并不能马上拿到。
场景:1)后端返回的经纬度不能马上渲染到地图上
解决:a.设状态值,监听经纬度。
2)地图要素不能在页面第一次打开时就迅速获取到,比如根据坐标获取其相交的要素,也是在第二次操作才获取到。
解决:a.定时器中设置调用获取要素的方法(不推荐)
b.在设置状态值时用nextTick,在nextTick中调用获取要素的方法,通过让坐标“延时”到达来等地图要素初始化成功。
nextTick(() => {
setlongitude(res.longitude);
setlatitude(res.latitude);
})
useEffect(() => {
if (latitude != undefined && longitude != undefined) {
nextTick(()=>{
creatpoint();
} )
}
}, [longitude, latitude]);
//输入的坐标,判断其所属田块并让其高亮
const coorinField=(coordinate:any)=>{
//根据坐标获取其相交的要素
.......
}
//创建点要素
const creatpoint = () => {
if (rtkobj.latitude) {
let devicepoint = transform(
[Number(rtkobj.longitude), Number(rtkobj.latitude)],
'EPSG:4326',
'EPSG:3857'
);
nextTick(()=>{
coorinField(devicepoint);
})
}
}
c.在一个异步请求中(比如相关的后端接口中)刚好使用了调用获取要素的方法,顺理成章完成。
nextTick不需要了
const coorinField=(coordinate:any)=>{
let layerarr = hxMap.mapInstance.getLayers().getArray();
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{
}');
const {
code } = userInfo.ffarmRespVO;
//异步请求中
getCountByFarmCode({
farmCode:code}).then((res)=>{
let features_=layerarr[1].getSource().getFeatures()
if(features_.length=res.dcount){
let features=layerarr[1].getSource().getFeaturesAtCoordinate(coordinate)
if(features.length>0){
//删除上一个田块样式
clearselectstyle()
//重新设置样式
features[0].setStyle(selectFieldStyle(features[0]));
features[0].setId('readfeature');
formRef.setFieldsValue({
landCode: features[0].code });
}else{
message.error("坐标不位于田块内!")
}
}
})
}
对于场景1,在这里,我们可以借用react中的useState和useEffect来实现第一时间渲染,将接口拿到的经纬度设为状态值,用useEffect监听此状态值完成绘制。
具体代码如下:
const [latitude,setlatitude]=useState<any>()
const pointdrawClick = async (record: any) => {
//接口
let res=await viewDeviceInfo({
...record })
setlongitude(res.longitude)
setlatitude(res.latitude)
}
//监听
useEffect(() => {
let layerarr = hxMap.mapInstance.getLayers().getArray();
//删除多余layer
if (layerarr.length > 2) {
for (let i = 2; i < layerarr.length; i++) {
map.removeLayer(layerarr[i]);
}}
//创建一个空的Vector面图层
const mapLayer = new VectorLayer({
source: new VectorSource({
features: []
})
});
mapLayer.set('maplayer', mapLayer);
map.addLayer(mapLayer);
//创建点geometry
let point = new Point(
transform(
[Number(longitude), Number(latitude )],
'EPSG:4326',
'EPSG:3857'
)
);
// 创建feature要素,一个feature就是一个点
let pointFeature = new Feature(point);
// 设置要素的图标
pointFeature.setStyle(pointStyle);
pointFeature.setId('pointFeature');
layerarr[2].getSource().addFeatures([pointFeature]);
map
.getView()
.setCenter(
transform(
[Number(longitude), Number(latitude)],
'EPSG:4326',
'EPSG:3857'
)
);
map.getView().setZoom(17.5);
}, [longitude,latitude]);