Skip to content

GeoJSON 地理JSON

是一种用于表示地理空间数据的开放标准格式。它使用 JSON 来描述地理要素的几何形状(点、线、面等)以及相应的属性信息。GeoJSON 在地理信息系统(GIS)中被广泛使用,用于存储、传输和共享地理数据。

使用 leaflet 、vue 、 GeoJSON 加载点、线、面、区域边界。

示例

代码实现

vue
<script setup>
import { ref, defineAsyncComponent } from 'vue';
import { geoJsonLine, geoJsonPoint, geoJsonPolygon } from './useGeoJsonData.js';

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

const mapObj = ref();

// 添加 geoJson 数据到地图
const addGeoJsonDataToMap = (data) => {
  L.geoJSON(data, {
    style: function (feature) {
      return { color: feature.properties.color ?? 'green' };
    }
  })
    .bindPopup(function (layer) {
      return layer.feature.properties.name;
    })
    .addTo(mapObj.value);
};

// 获取区域边界加载到地图
const getAreaBoundaryGeoJsonToMap = async () => {
  const geoJson = await fetch(
    'https://geo.datav.aliyun.com/areas_v3/bound/320106.json'
  ).then((res) => res.json());

  addGeoJsonDataToMap(geoJson);
};

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

  addGeoJsonDataToMap(geoJsonPoint);
  addGeoJsonDataToMap(geoJsonLine);
  addGeoJsonDataToMap(geoJsonPolygon);

  getAreaBoundaryGeoJsonToMap();
};
</script>

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

<style scoped></style>
js
// 点
export const geoJsonPoint = {
  type: 'FeatureCollection',
  features: [
    {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [118.76741, 32.04154]
      },
      properties: {
        name: '南京',
        category: 'Transportation',
        color: ''
      }
    },
    {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [118.75741, 32.09154]
      },
      properties: {
        name: '南京',
        category: 'Transportation',
        color: ''
      }
    }
  ]
};

// 线
export const geoJsonLine = {
  type: 'FeatureCollection',
  features: [
    {
      type: 'Feature',
      geometry: {
        type: 'LineString',
        coordinates: [
          [118.80029, 32.05521],
          [118.82268, 32.06092],
          [118.82268, 32.09092]
        ]
      },
      properties: {
        name: '南京',
        category: 'Recreation',
        color: 'blue'
      }
    }
  ]
};

// 面 即多边形
export const geoJsonPolygon = {
  type: 'FeatureCollection',
  features: [
    {
      type: 'Feature',
      geometry: {
        type: 'Polygon',
        coordinates: [
          [
            [118.83009, 32.08463],
            [118.84277, 32.06542],
            [118.85924, 32.07705],
            [118.84895, 32.09283],
            [118.83009, 32.08463]
          ]
        ]
      },
      properties: {
        name: '面数据',
        category: 'Park',
        color: 'red'
      }
    }
  ]
};
vue
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
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: 1,
    maxZoom: 18
  });

  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.