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>
效果图