我正在使用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
。
答案 0 :(得分:2)
@geocodezip的出色观察。我必须更改toggleGeolocation
和this.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='';
}
}