Skip to content

Marker

加载 marker 到地图,常用于在地图上展示一些点位。

示例

清除 marker

代码实现

vue
<script setup>
import { ref, defineAsyncComponent } from 'vue';

const InitMap = defineAsyncComponent(() =>
  import('../../components/InitMapTianditu.vue')
);

const mapObj = ref();

// 单个 marker 创建
const marker = ref();
const createMarker = () => {
  if (marker.value) {
    mapObj.value.removeLayer(marker.value);
    marker.value = null;
  }

  // 创建一个 marker
  marker.value = L.marker([32.0237855, 118.8075675]).addTo(mapObj.value);

  // 为 marker 绑定 popup
  marker.value.bindPopup('<b>Hello world!</b><br />这是默认 marker 绑定的 Popup');

  // 打开绑定的 popup
  marker.value.openPopup();

  // 为 marker 绑定点击事件
  marker.value.on('click', (e) => {
    console.log('默认 marker 触发点击事件', e);
  });
};

/**
 * 批量创建多个 marker
 * 与创建单个 marker 不同的是批量创建多个 marker 时会创建一个图层组
 * 先将 marker 加载到图层组中在添加到地图这样做的原因在于更容易管理不同覆盖物。
 */
const markerLayerGroup = ref();

// 清除图层组图层
const clearMarkerLayerGroup = () => {
  if (markerLayerGroup.value) {
    mapObj.value.removeLayer(markerLayerGroup.value);
    markerLayerGroup.value = null;
  }
};

// 创建多个 marker
const createMarkers = () => {
  // 加载前先清除
  clearMarkerLayerGroup();
  const points = [
    [32.0148855, 118.8276675],
    [32.0128855, 118.8477675],
    [32.0118855, 118.8678675],
    [32.0138855, 118.8979675]
  ];

  const markers = points.map((item) => {
    // 创建自定义图标
    const icon = L.icon({
      iconUrl: 'https://leafletjs-example.netlify.app/logo.png',
      iconSize: [30, 30]
    });

    return L.marker(item, { icon });
  });

  // 将 marker 加载到图层组
  markerLayerGroup.value = L.featureGroup(markers);

  // 为每个 marker 绑定 popup
  markerLayerGroup.value.bindPopup(
    '<b>你好啊!</b><br />这是批量创建的 marker'
  );

  // 绑定事件
  markerLayerGroup.value.on('click', (e) => {
    console.log('批量创建的 marker 触发点击事件', e);
  });

  // 将图层组加载到地图
  markerLayerGroup.value.addTo(mapObj.value);
};

const mapLoad = (map) => {
  mapObj.value = map;

  createMarker();
  createMarkers();
};
</script>

<template>
  <init-map @map-load="mapLoad"></init-map>

  <p class="c-button" @click="clearMarkerLayerGroup">清除 marker</p>
</template>

<style scoped></style>
vue
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
// todo 项目使用请放开 leaflet 引入
// import L from 'leaflet';

const props = defineProps({
  center: {
    type: Array,
    default: [32.0237855, 118.8075675]
  }
})

const emit = defineEmits(['mapLoad']);

const mapRef = ref();

const initMap = () => {
  const map = L.map(mapRef.value, {
    center: props.center,
    zoom: 11,
    minZoom: 6,
    maxZoom: 20
  });

  const mapType = 'vec';
  L.tileLayer(
    'https://t{s}.tianditu.gov.cn/' +
      mapType +
      '_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
      mapType +
      '&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
    {
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
      attribution:
        '&copy; <a href="http://lbs.tianditu.gov.cn/home.html">天地图 GS(2022)3124号 - 甲测资字1100471</a>'
    }
  ).addTo(map);

  const mapLabelType = 'cva';
  L.tileLayer(
    'https://t{s}.tianditu.gov.cn/' +
      mapLabelType +
      '_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
      mapLabelType +
      '&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
    {
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
    }
  ).addTo(map);

  // 地图初始化完成发送事件
  emit('mapLoad', map);

  return map;
};

const mapObj = ref();

// 在 onMounted 中初始化地图
onMounted(() => {
  mapObj.value = initMap();
});

const removeMap = () => {
  if (mapObj.value) {
    mapObj.value.remove();
  }
};

// 在组件卸载时删除地图
onUnmounted(() => {
  removeMap();
});
</script>

<template>
  <div ref="mapRef" class="map"></div>
</template>

<style scoped>
.map {
  height: 40vh;
  z-index: 0;
}
</style>

配置参考

贡献者

Released under the MIT License.