在react中,后端接口(异步函数)中传过来的经纬度不能在第一时间(接口调用时)马上渲染到openlayers地图上怎么办,地图feature不能在第一时间获取渲染怎么办?

一般在前端接口调用如下拿到经纬度:

//按钮点击事件,调用接口取出经纬度并马上绘制到地图上
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]);

猜你喜欢

转载自blog.csdn.net/qq_37967853/article/details/129119505