vue3使用leaflet地图

发布于:2025-08-15 ⋅ 阅读:(14) ⋅ 点赞:(0)

npm  i  leaflet@1.7.1  axios

下载全国省市区的json数据,可放在public目录下,也可放在后台服务器,有跨域问题,后端解决。

链接: https://pan.baidu.com/s/1LpO17UJgR4dyDO5VZW5hVw?pwd=w2re

页面代码

<template>
	<div id="map" style="z-index:1"></div>
</template>
<script lang="ts">
import { reactive, getCurrentInstance, toRefs, onMounted, nextTick, defineComponent, watch } from 'vue';
import "leaflet/dist/leaflet.css";
import * as L from "leaflet";
import axios from "axios";

export default defineComponent({
	setup(props: any, { emit }: any) {
		onMounted(async () => {
			nextTick(() => {
				initMap();
				getmarkers()
			});
		});
		const { proxy } = getCurrentInstance() as any;

		const data = reactive({
			geoJSONlayer: {} as any,
			map: {} as any,
			provinceZoom: 5, // 省级别
			cityZoom: 7, // 市级别
			areaZoom: 9, // 区级别
			townZoom: 11, // 镇级别
			currentZoom: 5, // 当前级别

			markers: [] as any[],
			initCode: "100000", // 初始code
			currentCode: "100000", //当前code
			initName: "全国", //初始name
			currentName: "全国", //当前name
			currentlatlng: [] as any,
			defaultlatlng: [113.88308, 22.55329], // [经度,维度]
			superiorCodeArr: [] as any, //上一级的code
			superiorNameArr: [] as any, //上一级的name
			allBgColor: ["#f7acbc", "#deab8a", "#817936", "#444693", "#ef5b9c", "#fedcbd",],
		});

		// 初始化地图
		const initMap = async () => {
			let mapData = {
				minZoom: 4,
				maxZoom: 18,
				center: [data.defaultlatlng[1], data.defaultlatlng[0]],
				zoom: data.provinceZoom,
				zoomControl: true,
				attributionControl: false,
				crs: L.CRS.EPSG3857,
			}

			let map = L.map("map", mapData);
			var center = map.getCenter(); // 获取新的中心点

			data.map = map; //data上需要挂载
			L.tileLayer(
				"http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
			).addTo(map);

			getJson();

			map.on("click", (e: any) => {
			});

			map.on("zoomend", (e: any) => {
				//获取当前放大或者缩小的等级
				data.currentZoom = e.target.getZoom();
				backMapArea(data.currentZoom)
			});
			map.on("moveend", (e: any) => {

			});
		}

		// 显示高亮地图
		const getJson = (val?: any) => {
			let code = val ? val : data.initCode;
			data.currentCode = code
			axios
				.get(`${proxy.VITE_API_REQUEST_URL}/js/mapgeo/${code}.geojson`)
				.then((res) => {
					if (res.status === 200) {
						data.geoJSONlayer = L.geoJSON(res.data, {
							style: () => {
								return {
									color: "white",
									fillColor: data.allBgColor[Math.floor(Math.random() * data.allBgColor.length)],
									weight: 1,
									fillOpacity: 0.5,
								};
							},
							onEachFeature: (feature: any, layer: any) => {
								feature.properties &&
									feature.properties.name &&
									layer.bindTooltip(feature.properties.name, {
										direction: "bottom",
										className: "my_tooltip",
										permanent: true,
									});
							},
						})
							.on("click", (e: any) => {
								let proObj = e.layer.feature.properties;
								console.log("proObj===", proObj);

								if (proObj.childrenNum > 0 && proObj.adcode) {
									data.currentCode = proObj.adcode;
									data.currentName = proObj.name;
									data.superiorNameArr.push(proObj.name)
									let tempAcroutes = [...data.superiorCodeArr, ...proObj.acroutes]
									data.superiorCodeArr = Array.from(new Set(tempAcroutes));
									let zoom =
										data.superiorCodeArr.length === 1
											? data.cityZoom
											: data.superiorCodeArr.length === 2
												? data.areaZoom
												: data.townZoom;
									data.currentZoom = zoom;

									if (proObj.center) { // 根据点击的管辖市区镇的中心经纬度
										data.currentlatlng = proObj.center;
										data.map.flyTo([proObj.center[1], proObj.center[0]], zoom)
									} else { // 根据点击所在点的经纬度
										data.currentlatlng = [e.latlng.lng, e.latlng.lat]
										data.map.flyTo([e.latlng.lat, e.latlng.lng], zoom)
									}

									// 移除数据
									data.geoJSONlayer.remove();
									// 重新加载数据
									getJson(proObj.adcode);
								} else {
									proxy.$message.warning("没有数据");
								}
							})
							.addTo(data.map);
					}
				})
				.catch((err) => {
					// 请求失败时的处理逻辑
					console.log(err);
				});
		}


		// 获取所有的markers
		const getmarkers = () => {
			let list = [
				{ dev_latitude: 22.15329, dev_longitude: 113.12308 },
				{ dev_latitude: 22.25229, dev_longitude: 113.21308 },
				{ dev_latitude: 22.35129, dev_longitude: 113.38138 },
				{ dev_latitude: 22.45429, dev_longitude: 113.48318 },
				{ dev_latitude: 22.55529, dev_longitude: 113.58328 },
				{ dev_latitude: 22.65629, dev_longitude: 113.68358 },
				{ dev_latitude: 24.75729, dev_longitude: 113.78398 },
				{ dev_latitude: 25.75729, dev_longitude: 114.78398 },
				{ dev_latitude: 26.75729, dev_longitude: 115.78398 },
				{ dev_latitude: 27.75729, dev_longitude: 116.78398 },
				{ dev_latitude: 28.75729, dev_longitude: 117.78398 },
			];
			list.map((v) => {
				addmarker(v);
			});
		}
		// 添加marker
		const addmarker = (item: any) => {
			var marker = L.marker([item.dev_latitude, item.dev_longitude]).addTo(data.map);
			marker.bindPopup(`标题`).openPopup();
			data.markers.push(marker);
		}

		const backMapArea = (scale: any) => {
			if (data.superiorCodeArr.length > 1 && scale < data.currentZoom) {
				data.currentCode = data.superiorCodeArr[data.superiorCodeArr.length - 1];
				data.superiorCodeArr.pop();
				data.superiorNameArr.pop();
				data.currentName = data.superiorNameArr.length > 0 ? data.superiorNameArr[data.superiorNameArr.length - 1] : data.initName
				data.geoJSONlayer.remove();
				getJson(data.currentCode)
			} else if (scale <= 5 && data.currentZoom > 5 && data.currentCode != data.initCode) {
				data.currentCode = data.initCode;
				data.superiorCodeArr = [];
				data.superiorNameArr = [];
				data.currentName = data.initName
				data.geoJSONlayer.remove();
				getJson()
			}
		}


		return { ...toRefs(data), }
	}
})
</script>
<style scoped lang="scss">
#map {
	height: 100%;
	width: 100%;
	background-color: #040823;
}

:deep(.my_tooltip) {
	color: #fff;
	background: transparent;
	border: none;
	font-size: 18px;
	box-shadow: none;
}
</style>

效果图


网站公告

今日签到

点亮在社区的每一天
去签到