vue-mapvgl图标在卫星图层不正常展示

使用vue-mapvgl设置icon图标只在标准的地图类型上显示正常,当切换至卫星地图上时则会随着地图移动而移动

img

正常显示:

img



  • [ 求解决当标记在卫星图层时正常显示]

看看图层的上下关系,以及图层是否正确加载了。

参考GPT和自己的思路:根据您的描述,问题是图标在切换到卫星地图时不再与地图保持固定的位置,而是随着地图移动而移动。这可能是因为您设置的图标是以地图为基准的,而不是以视口为基准的。视口是用户在屏幕上看到的地图部分,可以随着用户的拖动和缩放而改变。

解决这个问题的一种方法是使用Mapvgl的图标绘制方法,并将图标的坐标设置为相对于视口的像素坐标。以下是一个示例代码,可以参考一下:

<template>
  <div class="map-container">
    <vue-mapvgl
      :mapOptions="mapOptions"
      :layers="layers"
    ></vue-mapvgl>
  </div>
</template>

<script>
import VueMapvgl from 'vue-mapvgl';

export default {
  name: 'MapComponent',
  components: {
    VueMapvgl
  },
  data () {
    return {
      mapOptions: {
        center: [121, 37],
        zoom: 14,
        style: 'mapbox://styles/mapbox/satellite-streets-v11'
      },
      layers: [
        {
          type: 'Icon',
          data: [
            {
              geometry: {
                type: 'Point',
                coordinates: [124.4673031945, 41.985339349],
              },
              properties: {
                icon: '@/assets/images/map/gnss.png'
              }
            },
            {
              geometry: {
                type: 'Point',
                coordinates: [124.4669295841, 41.9859151068],
              },
              properties: {
                icon: '@/assets/images/map/gnss.png'
              }
            }
          ],
          draw: {
            type: 'icon',
            size: [24, 24],
            anchor: 'bottom',
            offset: [0, 0],
            texture: 'icon'
          },
          on: {
            click: (e) => {
              console.log('Icon clicked', e);
            }
          }
        }
      ]
    }
  }
}
</script>


在这个示例中,我们使用了Mapvgl的Icon图层,并将图标的坐标设置为相对于视口的像素坐标。我们还将地图样式设置为卫星地图,并使用Vue组件的方式来渲染地图。

希望这个示例可以帮助您解决问题。

参考GPT和自己的思路,这是由于图标的位置没有正确设置所导致的。您可以尝试在数据对象的geometry属性中设置每个图标应该显示的位置,而不是在properties中仅指定Icon的文件路径。您可以像这样修改您的代码:

<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" :zoomThreshold="thresholdList"></el-bmapv-icon-layer>
                </el-bmapv-view>
            </el-bmap>
        
    
</template>

<script>
import { BMapManager } from 'vue-bmap-gl';
import VueBMap from 'vue-bmap-gl';
 
let bmapManager = new VueBMap.BMapManager();
 
export default {
    name:"bigMap",
    components: {},
    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,
            thresholdList:[{
 
            }],
            events: {
                init: (o) => {
                    this.map = o;
                    console.log(o.getCenter());
                    console.log(this.$refs.map.$$getInstance());
                },
                'moveend': () => {
                },
                'zoomchange': () => {
                },
                'click': (e) => {
                    alert('map clicked');
                }
            },
            deviceDate:[
                {
                    geometry: {
                        type: 'Point',
                        coordinates: [124.4673031885,41.9853393455],
                    },
                    properties: {
                        icon: '@/assets/images/map/gnss.png'
                    }
                },
                {
                    geometry: {
                        type: 'Point',
                        coordinates: [124.4669295841,41.9859151068],
                    },
                    properties: {
                        icon: '@/assets/images/map/gnss.png'
                    }
                }
            ]
        }
    },
    methods:{}
}

</script>

在这个修改后的代码中,我们在deviceData对象的每个图标的geometry属性中指定它应该出现的准确位置,而不是在properties中任何一个属性或字段来仅指定图标的位置或图标的文件路径。 这样,设置的图标应该会在卫星地图上正确地定位和展示。希望能帮你解决问题,还请采纳!!

该回答引用ChatGPT

如有疑问,可以回复我!



当使用 vue-mapvgl 在卫星地图上显示 icon 图标时,可能会遇到图标随地图移动的问题。这通常是因为图层没有正确绑定到卫星地图上。为了解决这个问题,您可以尝试以下方法:

为卫星地图添加图层,你可以使用 vue-bmap-gl 库的 el-bmapv-satellite-layer 组件。
在 <template> 标签中添加如下代码:


<el-bmapv-satellite-layer></el-bmapv-satellite-layer>
将 icon 属性改为 require 导入的方式,确保正确引用图标文件。
在 <script> 标签中修改 icon 的定义:


icon: require('@/assets/images/map/gnss.png'),
在 mounted 生命周期钩子中设置地图类型。
在 <script> 标签中添加如下代码:


mounted() {
  this.$nextTick(() => {
    // 设置地图类型为卫星地图
    this.map.setMapType(BMAP_HYBRID_MAP);
  });
},
修改后的 <template><script> 部分代码如下:


<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-satellite-layer></el-bmapv-satellite-layer>
        <el-bmapv-view>
          <el-bmapv-icon-layer
            :icon="icon"
            :width="width"
            :height="height"
            :data="deviceDate"
            :enable-picked="true"
            :zoomThreshold="thresholdList"
          ></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',
  components: {},
  data() {
    return {
      center: [121, 37],
      loaded: false,
      bmapManager,
      zoom: 14,
      center: [124.4673031945, 41.985339349],
      tilt: 60,
      heading: 0,
      icon: require('@/assets/images/map/gnss.png'),
      width: 24,
      height: 24,
      map: null,
      thresholdList: [{}],
      events: {
        init: (o) => {
          this.map = o;
          console.log(o.getCenter());
          console.log(this.$refs.map.$$getInstance());
        },
        moveend: () => {},
        zoomchange: () => {},
        click: (e) => {
          alert('map clicked');
        },
      },
      deviceDate: [
        // ...
      ],
    };
  },
  mounted


该回答引用GPTᴼᴾᴱᴺᴬᴵ
根据你提供的代码,似乎你正在使用 vue-bmap-gl 和 vue-mapvgl 库来实现地图展示和标注功能。可能是由于卫星图层和标准地图层的差异导致了图标不正常展示的问题。

在 vue-mapvgl 中,你可以设置 render 属性来控制标记渲染的方式。如果你希望标记在卫星图层上也能正常显示,可以尝试使用 render 属性来指定标记的渲染方式为 2d,如下所示:

<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" 
            :zoomThreshold="thresholdList"
            :render="2d"
          ></el-bmapv-icon-layer>
        </el-bmapv-view>
      </el-bmap>
    </div>
  </div>
</template>


如果以上方法不能解决问题,你可以尝试将标记的坐标数据从经纬度坐标系(WGS84)转换到其他坐标系(如Web墨卡托投影),以适应不同的地图层。你可以使用库函数如 proj4 和 proj4leaflet 来进行坐标系转换。

希望以上方法能够帮到你。