1

我正在使用 openlayers 5 来实现一个简单的地理定位功能:

当检查地理位置复选框时,地理位置启动,通过动画过渡将放大到位置,并自动跟踪位置。它在矢量图层中添加了一个特征。

当取消选中地理定位复选框时,地理定位以及跟踪将被关闭,并且该矢量图层被清除。

我的问题是我不知道如何等到 geolocation 具有 value,所以我可以正确地继续放大该位置。我认为地理定位需要一点时间才能产生价值是正常的,但我不知道如何等到那时。我的代码只是放大了它的当前位置,过了一会儿,地理位置点就呈现在了正确的位置。

我的代码(openlayers 5 + angular 6)

ngOnInit(){ //while initializing everything else

    this.vectorlayer = new VectorLayer({
      source: this.vectorsource,
      style: styleFunction,
      title:'features'
    });

    this.geolocation = new Geolocation({      
      trackingOptions: {
        enableHighAccuracy: true
      },
      projection: 'EPSG:3857'
    });

    this.geolocation.on('error', (error) => {
      this.geolocationerror=true;
      this.geolocationmsg = error;
    });

    this.accuracyFeature = new Feature(); 
    this.geolocation.on('change:accuracyGeometry', ()=> {
      this.accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
    });

    this.positionFeature = new Feature();
    this.positionFeature.setStyle(new Style({
      image: new CircleStyle({
        radius: 6,
        fill: new Fill({
          color: '#3399CC'
        }),
        stroke: new Stroke({
          color: '#fff',
          width: 2
        })
      })
    }));

    this.geolocation.on('change:position', ()=> {
      let coordinates = this.geolocation.getPosition();
      this.positionFeature.setGeometry(coordinates ?
        new Point(coordinates) : null);
    });

    if(window.innerWidth < 600){
      this.isChecked = true;
    }    

    this.geolocsource = new VectorSource({});

    this.geoloclayer = new VectorLayer({
      source: this.geolocsource,
      title:'location'
    });

    this.view = new View({ ....
    this.olmap = new Map({....

   //turn on in smaller screenc, <600
   this.toggleGeolocation(this.isChecked);

}//ngOnInit

ngOnInit

  toggleGeolocation(checked){    
    this.geolocationmsg='';
    this.geolocationerror=false;
    if(checked){   //turned on                                    
      this.geolocation.setTracking(checked);
      this.geolocsource.addFeatures([this.accuracyFeature, this.positionFeature]);             
      this.geolocOn = true;   
      this.geolocLiveCoords = this.geolocation.getPosition();
      let center = this.geolocation.getPosition();      
      this.olmap.getView().animate({
        center: center,
        duration: 2000,
        zoom:10
      });   
    }
    else{   //turned off
      this.geolocation.setTracking(checked);      
      this.geolocOn = false;
      this.geolocsource.clear();
      this.geolocLiveCoords='';
    }    
  }

和html部分

<label for="track">track position<input id="trackpos" type="checkbox" [(ngModel)]="isChecked" (change)="toggleGeolocation(isChecked)"/></label>
<div  *ngIf='geolocationerror'>{{geolocationmsg}}</div>
<div  *ngIf='geolocOn'>{{geolocLiveCoords}}</div>
<div id="map" class="map" tabindex="0"></div>

我也尝试过使用承诺

ngOnInit,改变toggleGeolocation

  getpos() {
    console.log('in');
    return new Promise(resolve => {      
     resolve(this.geolocation.getPosition());
    });
  }

  toggleGeolocation(checked){    
    this.geolocationmsg='';
    this.geolocationerror=false;
    if(checked){            
      this.getpos().then((value) => {        
        this.geolocsource.addFeatures([this.accuracyFeature, this.positionFeature]) ;   
        this.olmap.getView().animate({
          center: value,
          duration: 2000,
          zoom:10
        });
        this.geolocation.setTracking(checked);            
      });                              
    }
    else{
      this.geolocation.setTracking(checked);      
      this.geolocOn = false;
      this.geolocsource.clear();
      this.geolocLiveCoords='';
    }    
  }

getpos调用(我可以in在控制台上看到),但它从来没有值,所以它返回undefined.

4

1 回答 1

2

@geocodezip 的出色观察。我不得不改变toggleGeolocationthis.geolocation.on('change:position'它的工作原理。

有时我点击地理定位,它会获取坐标,然后再次获取它们,导致动画在运行时变得生涩和闪烁。有任何想法吗?

我猜它应该跟随运动,这就是为什么视图动画应该在this.geolocation.on('change:position'. 但是这种计算是否密集,如果用户不断移动会导致地图无响应?

谢谢

现在我的整个代码是

ngOnInit() {
this.geolocation = new Geolocation({      
      trackingOptions: {
        enableHighAccuracy: true
      },
      projection: 'EPSG:3857'
    });

    this.geolocation.on('error', (error) => {
      this.geolocationerror=true;
      this.geolocationmsg = error;
    });

    this.accuracyFeature = new Feature(); 
    this.geolocation.on('change:accuracyGeometry', ()=> {
      this.accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
    });

    this.positionFeature = new Feature();
    this.positionFeature.setStyle(new Style({
      image: new CircleStyle({
        radius: 6,
        fill: new Fill({
          color: '#3399CC'
        }),
        stroke: new Stroke({
          color: '#fff',
          width: 2
        })
      })
    }));

    this.geolocation.on('change:position', ()=> {
      console.log('in on chnage pos');
      let coordinates = this.geolocation.getPosition();
      console.log('coordinates > ',coordinates);
      this.positionFeature.setGeometry(coordinates ? new Point(coordinates) : null);
      this.geolocLiveCoords = coordinates;
      let center = coordinates;      
      this.olmap.getView().animate({
        center: center,
        duration: 2000,
        zoom:10
      }); 
    });

    if(window.innerWidth < 600){
      this.isChecked = true;
    }    

    this.geolocsource = new VectorSource({});

    this.geoloclayer = new VectorLayer({
      source: this.geolocsource,
      title:'location'
    });
    this.view = new View({  ....
    this.olmap = new Map({....
    this.toggleGeolocation(this.isChecked);

  }//ngOnInit

  toggleGeolocation(checked){    
    this.geolocationmsg='';
    this.geolocationerror=false;
    if(checked){                      
      this.geolocation.setTracking(checked);
      console.log('right before add features');
      this.geolocsource.addFeatures([this.accuracyFeature, this.positionFeature]);             
      this.geolocOn = true;   
    }
    else{
      this.geolocation.setTracking(checked);      
      this.geolocOn = false;
      this.geolocsource.clear();
      this.geolocLiveCoords='';
    }    
  }
于 2018-08-07T15:13:39.553 回答