问的是人不是AI,使用GPT回答的统统不采纳。
问题:使用vue-bmap-gl与vue-mapvgl在Vue2.0中使用el-bmapv-icon-layer在卫星地图上设置标点,在正常图层正常显示且固定,在卫星图层显示但是会随着地图的移动而移动,与坐标无关,目前代码无报错
默认图层(正确):
<template>
<div class="app-container" style="padding: 0;">
<div class="map-box">
<el-bmap
ref="map"
vid="bmapDemo"
:min-zoom="14"
:max-zoom="20"
:tilt="tilt"
:heading="heading"
:bmap-manager="bmapManager"
:center="center"
:zoom="zoom"
:events="events" class="bmap-demo">
<el-bmapv-view>
<el-bmapv-icon-layer :icon="icon" :width="width" :height="height" :data="deviceDate" :enable-picked="true" render="2d">el-bmapv-icon-layer>
el-bmapv-view>
el-bmap>
div>
div>
template>
<script>
import { BMapManager } from 'vue-bmap-gl';
import VueBMap from 'vue-bmap-gl';
let bmapManager = new VueBMap.BMapManager();
export default({
name:"bigMap",
data(){
return{
center:[121, 37],
loaded:false,
bmapManager,
zoom: 14,
center: [124.4673031945, 41.985339349],
tilt: 60,
heading: 0,
icon: '@/assets/images/map/gnss.png',
width: 24,
height: 24,
map: null,
events: {
init: (o) => {
this.map = o;
o.setMapType('B_EARTH_MAP');
console.log(o.getCenter());
console.log(this.$refs.map.$$getInstance());
},
'moveend': () => {
},
'zoomchange': () => {
},
'click': (e) => {
alert('map clicked');
}
},
deviceDate:[{
geometry: {
type: 'Point',
coordinates: [13855636.810095014,5158783.601831172],
},
properties: {
icon: '@/assets/images/map/gnss.png'
}
}]
}
},
methods:{
}
})
script>
<style>
.map-box {
width: 100%;
height: 91vh;
}
style>
这个问题得慢慢试出来,我之前做好像遇到过类似的,应该是卫星地图和普通地图的坐标系不一样导致的。你移动之后,标点的坐标有没有变化。如果有变化的话,那就找一下你卫星地图用的啥坐标系,在el-bmapv-icon-layer上用projection转换一下应该就可以了。
在el-bmapv-icon-layer组件的标签中添加coordinate-system="BMAP_SATELLITE_MAP"属性试一下呢,
指定卫星图层的底图坐标系。这样,标注层的位置计算将基于卫星图层的底图坐标系,从而保证标注固定在卫星图层上,不知道可不可行
该回答引用GPTᴼᴾᴱᴺᴬᴵ
可能是因为卫星图层的投影方式与默认图层不同,导致标点的位置计算出现偏差。可以尝试使用百度地图提供的API函数BMap.MapType.getProjection()获取当前地图类型的投影方式,并将标点的经纬度坐标转换为对应的像素坐标进行定位。
修改代码如下:
<template>
<div class="app-container" style="padding: 0;">
<div class="map-box">
<el-bmap
ref="map"
vid="bmapDemo"
:min-zoom="14"
:max-zoom="20"
:tilt="tilt"
:heading="heading"
:bmap-manager="bmapManager"
:center="center"
:zoom="zoom"
:events="events" class="bmap-demo">
<el-bmapv-view>
<el-bmapv-icon-layer
:icon="icon"
:width="width"
:height="height"
:data="deviceDate"
:enable-picked="true"
render="2d"
:offset="[0, 0]"
:position="getPosition"
></el-bmapv-icon-layer>
</el-bmapv-view>
</el-bmap>
</div>
</div>
</template>
<script>
import { BMapManager } from 'vue-bmap-gl';
import VueBMap from 'vue-bmap-gl';
let bmapManager = new VueBMap.BMapManager();
export default({
name:"bigMap",
data(){
return{
center:[121, 37],
loaded:false,
bmapManager,
zoom: 14,
center: [124.4673031945, 41.985339349],
tilt: 60,
heading: 0,
icon: '@/assets/images/map/gnss.png',
width: 24,
height: 24,
map: null,
events: {
init: (o) => {
this.map = o;
o.setMapType('B_SATELLITE_MAP');
console.log(o.getCenter());
console.log(this.$refs.map.$$getInstance());
},
'moveend': () => {
},
'zoomchange': () => {
},
'click': (e) => {
alert('map clicked');
}
},
deviceDate:[{
geometry: {
type: 'Point',
coordinates: [121.4673031945, 41.985339349],
},
properties: {
icon: '@/assets/images/map/gnss.png'
}
}]
}
},
methods:{
getPosition(item) {
const pt = new BMap.Point(item.geometry.coordinates[0], item.geometry.coordinates[1]);
const projection = this.map.getMapType().getProjection();
const pixel = projection.lngLatToPoint(pt);
return [pixel.x, pixel.y];
}
}
})
</script>
<style>
.map-box {
width: 100%;
height: 91vh;
}
</style>
这里的关键是getPosition方法,它将标点的经纬度坐标转换为像素坐标,用于定位标点的位置。在这个方法中,我们使用BMap.MapType.getProjection()获取当前地图投影坐标系,并使用该投影坐标系将经纬度坐标转换为像素坐标。而在卫星图层中,投影坐标系与普通地图层不同,因此使用普通地图层的投影坐标系进行坐标转换会导致标点位置的偏移。
·
因此,要解决这个问题,需要使用卫星图层对应的投影坐标系进行坐标转换,可以通过BMap.MapType.getBMapType()方法获取当前地图类型对应的BMap.MapType实例,然后使用该实例的getProjection方法获取对应的投影坐标系进行坐标转换。修改代码如下:
getPosition(point) {
let pixel = null;
const mapType = this.map.getMapType();
const projection = mapType.getProjection();
if (projection) {
pixel = this.map.pointToOverlayPixel(point);
pixel = projection.pointToLngLat(pixel);
pixel = this.map.pointToPixel(pixel);
} else {
pixel = this.map.pointToPixel(point);
}
return pixel;
}
这样就可以根据当前地图类型选择不同的坐标转换方式,解决标点位置随地图移动的问题。
参考GPT和自己的思路:你可以试试呗,gtp也是能解决问题的,万一这个又解决了呢,试试也不吃亏,有报错很正常,你继续问就是了,很多问题多改几遍就改出结果了。根据您的描述,您可以尝试在地图加载完成后,通过BMap API中的setMapType方法将地图类型设置为卫星地图,然后再添加标点。此外,您还需要在设备数据中将坐标系从WGS84转换为BD09,以便在百度地图上正确显示标点。
以下是您提供的代码的修改版本,我已经根据上述建议进行了更改:
<template>
<div class="app-container" style="padding: 0;">
<div class="map-box">
<el-bmap
ref="map"
vid="bmapDemo"
:min-zoom="14"
:max-zoom="20"
:tilt="tilt"
:heading="heading"
:bmap-manager="bmapManager"
:center="center"
:zoom="zoom"
:events="events"
class="bmap-demo"
>
<el-bmapv-view>
<el-bmapv-icon-layer
:icon="icon"
:width="width"
:height="height"
:data="deviceData"
:enable-picked="true"
render="2d"
></el-bmapv-icon-layer>
</el-bmapv-view>
</el-bmap>
</div>
</div>
</template>
<script>
import { BMapManager } from 'vue-bmap-gl';
import VueBMap from 'vue-bmap-gl';
let bmapManager = new VueBMap.BMapManager();
export default {
name: "bigMap",
data() {
return {
center: [121, 37],
loaded: false,
bmapManager,
zoom: 14,
tilt: 60,
heading: 0,
icon: '@/assets/images/map/gnss.png',
width: 24,
height: 24,
map: null,
events: {
init: (o) => {
this.map = o;
this.map.setMapType(BMAP_SATELLITE_MAP); // 将地图类型设置为卫星地图
console.log(o.getCenter());
console.log(this.$refs.map.$$getInstance());
},
'moveend': () => {
},
'zoomchange': () => {
},
'click': (e) => {
alert('map clicked');
}
},
deviceData: [
{
geometry: {
type: 'Point',
// 将WGS84坐标系转换为BD09坐标系
coordinates: this.wgs84tobd09([124.4673031945, 41.985339349]),
},
properties: {
icon: '@/assets/images/map/gnss.png'
}
}
]
}
},
methods: {
// 转换坐标系从WGS84到BD09
wgs84tobd09(point) {
let [lng, lat] = point;
let ggPoint = new BMap.Point(lng, lat);
let convertor = new BMap.Convertor();
let pointArr = [];
pointArr.push(ggPoint);
convertor.translate(pointArr, 1, 5, (data) => {
let bdPoint = data.points[0];
lng = bdPoint.lng
lat = bdPoint.lat;
let bd09Point = [lng, lat];
return bd09Point;
});
},
async fetchDeviceList() {
try {
const res = await axios.get('/api/deviceList');
const deviceList = res.data.data;
// 转换设备坐标系
const deviceData = deviceList.map((device) => {
const [lng, lat] = this.wgs84tobd09([device.lng, device.lat]);
return {
geometry: {
type: 'Point',
coordinates: [lng, lat],
},
properties: {
icon: this.icon,
},
};
});
this.deviceDate = deviceData;
} catch (error) {
console.log(error);
}
},
},
});
</script>
<style>
.map-box {
width: 100%;
height: 91vh;
}
</style>