等到openlayers 5地理位置返回值

时间:2018-08-07 11:57:34

标签: asynchronous geolocation openlayers es6-promise openlayers-5

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

选中“地理定位”复选框时,地理定位将开始,并通过动画过渡缩放到该位置,然后它将自动不断跟踪该位置。它将在矢量层中添加要素。

当取消选中地理位置复选框时,将关闭地理位置以及跟踪功能,并清除该矢量层。

我的问题是,我不知道如何等到地理定位值确定后,因此我可以正确地继续缩放该位置。我认为,地理位置定位需要花费一些时间才能达到正常值,但这是正常的,但是我不知道如何等到那时。我的代码只是放大其当前位置,并在一段时间后将地理位置定位在正确的位置。

我的代码(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

1 个答案:

答案 0 :(得分: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='';
    }    
  }