Leaflet 数据可视化实现地图下钻示例详解
摸鱼的汤姆 人气:0前言
说到地图下钻功能,做过可视化的应该都不陌生,地图下钻就是通过用户交互从全国地图到下一级省份地图的切换,比如在Echarts中用户点击某个省份,地图就会切换成该省份的地图,当然本篇文章不介绍echarts如何去实现地图下钻,而是用Leaflet去实现地图下钻功能。
使用的框架是Vue,如果这是你第一次使用leaflet框架,还有没对其进行了解,还有如何在vue安装leaflet,建议你去看我上篇文章,(基础篇)
获取GeoJson,如果有现成的可以本地导入。
创建文件/api/getGeoJson.ts
const getGeoJson = (code) => { return new Promise((resolve, inject) => { // /geojson代理 axios.get(`/geojson/areas_v3/bound/geojson?code=$[code]`).then((res) => { if (res.data.features){ resolve(res.data.features); } else { inject(res); } }); }); }
初始化地图
创建文件/lib/useLeaflet.ts
function useLeaflet(idName){ // options 参数 const initMap = (options) => { // 实例 map.value = L.map(idName, options); // @ts-ignore // 记载瓦片 L.tileLayer?.chinaProvider('Geoq.Normal.PurplishBlue').addTo(map.value); map.value.setView([41.02999636902566, 108.984375], 3); } }
渲染GeoJson地图&添加事件-核心部分
function useLeaflet(idName){ // options 参数 const initMap = (options) => { // 实例 map.value = L.map(idName, options); // @ts-ignore // 记载瓦片 L.tileLayer?.chinaProvider('Geoq.Normal.PurplishBlue').addTo(map.value); map.value.setView([41.02999636902566, 108.984375], 3); } const updateGeoJson = (json) => { if (isArray(json) && json.length < 1) { return; } // 每次跨层级清除面板-- 性能优化 map.value.removeLayer(geoarr.value); // 清除Layer组 feiLineGroupLayer.value.clearLayers(); feiMakerGroupLayer.value.clearLayers(); // 遍历json json.forEach((item, index) => { let areaName = item.properties.name; let Areaitems = datasArr.value[datasArr.value.length - 1][ areaName.replace(/(省|市|自治区|维吾尔自治区)$/g, '') ]; let colors = Areaitems ?? '#008c8c'; // 设置事件 const onEachFeature = (feature, layer) => { layer.on({ click: (e) => { // 点击 let codes = e.target.feature.properties.adcode; let { name } = e.target.feature.properties; // 这里根据需求来,acroutes主要限制下钻的层级 if (acroutes.value.length > 1) { return; } // 处理特殊地图 let prov = datasArr.value[datasArr.value.length - 1][ name.replace(/(省|市|自治区|维吾尔自治区)$/g, '') ]; let childrenArr = prov.children; let objs = {}; // 更改provinces的值 provinces.value = prov; childrenArr.map((item, index) => { objs[item.name] = item; }); datasArr.value.push(objs); acroutes.value.push(codes); // 根据轮廓修正地图位置,以及缩放大小 map.value.fitBounds(e.target.getBounds()); // 根据地区的code请求geojson数据 getGeoJson(`${codes}_full`).then((res) => { geoarr.value.clearLayers(geoarr.value); // 因为层级有限 可以考虑递归渲染 updateGeoJson(res); }); }, }); }; // 设置区域默认颜色+添加点击事件 let geojson = L.geoJSON(item, { style: { weight: 2, //边框粗细 opacity: 0.4, //透明度 fillColor: 'transparent', //区域填充颜色 fillOpacity: 0.3, //区域填充颜色的透明 }, onEachFeature: onEachFeature, }); // 添加geo模块 geoarr.value.addLayer(geojson); }); // 添加将geoarr添加到地图中去 map.value.addLayer(geoarr.value); } return{ initMap, updateGeoJson } }
App.vue中
<template> <div id="map"></div> </template> <script lang="ts" setup> // 插件可加载各种地图(如:智图地图,谷歌地图,高德地图等包含卫星地图) import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; import '@geoman-io/leaflet-geoman-free'; import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css'; import { getGeoJson } from '@/api/getGeoJson'; import { onMounted, unref } from '@vue/runtime-core'; import { defineExpose, defineEmits } from 'vue'; import { useLeaflet } from '@/lib/useLeaflet'; let { initMap, updateGeoJson } = useLeaflet('map'); onMounted(() => { initMap( { attributionControl: false, // 是否使用工具集 zoomAnimation: true, maxZoom: 13, minZoom: 4, zoom: 4, worldCopyJump: true, markerZoomAnimation: true, zoomControl: false, } ); // 首先加载全国地图 getGeoJson('100000_full').then((res) => { updateGeoJson(res); }) }); </script>
效果视频这里只是把大屏中核心部分下钻功能实现了,后续会更新,关于Leaflet的其他案例。
关于Leaflet实现地图下钻到这里基本就结束了,整体思路不是很难理解,核心部分建议多看一下。 俗话说“知识是无限的,生命是有限的”,充实的一天,过的才有价值!
加载全部内容