之前搜罗一堆资料,发现有个老哥用两个viewer实现了类似小地图的功能,但是我尝试了一下发现性能方面好像不太友好。而且里面是个球体,就算可以隐藏地球,但是一切都变得复杂了,而我只需要一个二维地图就行了。
1.创建小地图
2.小地图上绘制点
3.根据坐标修改点的位置
4.如何监听坐标的改变
我这里使用的mapboxgl,我很喜欢里面的自定义地图样式,用别的应该可以可以的,比如leaflet,但是我就没去试了。
mapboxgl.accessToken = 'token';
var map = new mapboxgl.Map({
container: 'map', // div的id
style: '', //自定义样式
center: [109.608275784, 18.3086668], // 开始的中心位置
zoom: 16 // 开始的缩放倍数
});
这里如果不加on,load就会报错的,说什么样式还没加载完.
var _this = this
map.on('load', function () {
map.addSource("polygon",
_this.createDot([109.608275784, 18.3086668], 0.01));//0.01是点的大小
map.addLayer({
"id": "polygon",
"type": "fill",
"source": "polygon",
"layout": {
},
"paint": {
"fill-color": "blue",
"fill-opacity": 0.6,
}
});
})
//这个方法是看了哪个老哥的帖子,现在找不到了。。
createDot(center, radiusInKm, points){
if(!points) points = 64;
var coords = {
latitude: center[1],
longitude: center[0]
};
var km = radiusInKm;
var ret = [];
var distanceX = km/(111.320*Math.cos(coords.latitude*Math.PI/180));
var distanceY = km/110.574;
var theta, x, y;
for(var i=0; i<points; i++) {
theta = (i/points)*(2*Math.PI);
x = distanceX*Math.cos(theta);
y = distanceY*Math.sin(theta);
ret.push([coords.longitude+x, coords.latitude+y]);
}
ret.push(ret[0]);
return {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [ret]
}
}]
}
};
}
我这里还有一个插入图片的方法,大家可以参考一下,尝试把点换成图片
2020.12.04改:
var _this = this
map.on('load', function () {
map.addSource("geojson", _this.createDot([xx,xx], 0.007));
map.loadImage('/static/img/pen.png',
function(error, image) {
if (error) throw error;
map.addImage('point', image);
map.addLayer({
"id": "points",
"type": "symbol",
"source": "geojson",
"layout": {
"icon-image": "point",
"icon-size": 0.1
},
});
})
})
// 更新位置的方法
this.updata = function(){
console.log(this.transPosition)
let data = this.createDot([this.transPosition[0],this.transPosition[1]], 0.007).data
map.getSource('geojson').setData(data);
}
},
// 返回json格式
createDot(center){
var coords = {
latitude: center[1],
longitude: center[0]
};
var ret = [];
ret.push([coords.longitude, coords.latitude]);
ret.push(ret[0]);
return {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": ret[0]
}
}]
}
};
}
回到我们熟悉的Cesium,这里有点小问题,用moveStart或者moveEnd其实效果都是不很好,很长一段移动的话,是不会一直显示的,比如你一直直行,就只会更新一下,但是你改变方向或者缩放还是能继续触发的,我暂时也没想到别的办法。(测试好像没有问题)
viewer.scene.camera.moveStart.addEventListener(function(e){
console.log(viewer.camera.position)
var position = viewer.camera.position
var arr = []
var cartographic = Cesium.Cartographic.fromCartesian(position)
arr.push(Cesium.Math.toDegrees(cartographic.longitude))
arr.push(Cesium.Math.toDegrees(cartographic.latitude))
_this.transPosition = arr
});
2020.12.04改:用changed会好很多。
viewer.scene.camera.changed.addEventListener(function(){
console.log(`changed,${
viewer.camera.position}`)
var position = viewer.camera.position
var arr = []
var cartographic = Cesium.Cartographic.fromCartesian(position)
arr.push(Cesium.Math.toDegrees(cartographic.longitude))
arr.push(Cesium.Math.toDegrees(cartographic.latitude))
_this.transPosition = arr
})
改变点的坐标的话,这边有个方法,写在小地图这个组件里面就行了
let data = this.createDot([this.transPosition[0],this.transPosition[1]], 0.01).data
map.getSource('polygon').setData(data);
父子组件通信我就不在这里赘述了。
最后就是监听了,在watch里面监听,然后调用上面的方法。
watch:{
transPosition(n,o){
if(o!=''){
this.XXX()//调用上面的方法
}
}
}