先看最终效果图,鼠标悬停显示乡镇数据,点击下钻到乡镇地图。
一、首先需要准备你要制作地图及其下属县市的地图json数据,可以去这里进行地图下载(DataV.GeoAtlas地理小工具系列)
由于阿里云数据只到县市一级,如需获取乡镇地图数据,需要另行下载。
将下载好的地图数据配置到项目当中
二、下载ECharts
npm install echarts
三、在App.vue页面挂载到全局
import { provide,onMounted } from "vue";
import * as echarts from "echarts";
provide("echarts", echarts);
四、页面引入使用
<template>
<div id="EchartsMap"></div>
</template>
import { inject,onMounted, ref } from "vue";
const echarts = inject("echarts");
const pointListInfo = ref<any>([]);// 所有地图点位
const polygons = ref<any>([]); // 多边形内点位
onMounted(async () => {
// 页面初始化 引入默认json文件 xxx是城市名称
const jsonData = await import(`../config/xxxx.json`);
const data = await jsonData.default;
const coordinates = data.features[0].geometry.coordinates;
getEchartsMap(xxxx, data);
});
// 加载地图
const getEchartsMap = (mapName: any, mapJSON: any) => {
echarts.registerMap(mapName, mapJSON);
var myChart = echarts.getInstanceByDom(document.getElementById("EchartsMap"));
// 解决 There is a chart instance already initialized on the dom. 报错问题
if (!myChart) {
myChart = echarts.init(document.getElementById("EchartsMap"));
}
// 配置echart
const options = {
geo: [
{
map: mapName,
aspectScale: 1,
top: "20%",
bottom: "10%",
label: {
show: true,
color: "#7DFCDF",
fontSize: 14
},
itemStyle: {
areaColor: "#0c443e",
borderColor: "#20c390"
},
emphasis: {
itemStyle: {
borderWidth: 1,
borderColor: "#23D299",
areaColor: "#23D299"
},
label: {
color: "#fff"
}
}
}
],
series: [
{
type: "scatter",
animationDurationUpdate: 1000,
zlevel: 2,
coordinateSystem: "geo",
data: pointListInfo.value, // 点位数据不需要可不配置
emphasis: { // 点位样式
label: {
borderColor: "#777",
borderWidth: 1,
offset: [150, -90],
show: type == "01" ? true : false,
borderRadius: 5,
backgroundColor: "#033639",
formatter: (params: any) => {
var res = [`{title|${params.data.name}}`] as any;
res = [
`{title|${params.data.name}}`,
`{text|种植面积}{yield|${params.data.plant_area}}{unit|万亩} {text|水产面积}{yield|${params.data.aquatic_area}}{unit|万亩}`,
`{text|种植产量}{yield|${params.data.plant_production}}{unit|万吨} {text|水产产量}{yield|${params.data.aquatic_production}}{unit|万吨}`,
`{text|种植产值}{yield|${params.data.plant_output}}{unit|万元} {text|水产产值}{yield|${params.data.aquatic_output}}{unit|万元}`
].join("\n");
return res;
},
rich: {
title: {
color: "#fff",
align: "left",
fontWeight: 800,
padding: [0, 0, 0, 10],
backgroundColor: "#001b19",
width: "100%",
height: 40,
lineHeight: 40,
fontSize: 18
},
text: {
width: "25%",
align: "left",
height: 30,
lineHeight: 30,
padding: [20, 0, 0, 10]
},
yield: {
align: "left",
padding: [20, 0, 0, 10],
color: "#23D299",
fontSize: 16
},
unit: {
width: "12.5%",
align: "left",
padding: [20, 0, 0, 5]
}
},
width: 300,
height: 150,
color: "#fff",
fontSize: 14,
verticalAlign: "middle",
lineHeight: 16
}
}
}
]
};
myChart.setOption(options, true);
window.addEventListener("resize", myChart.resize());
myChart.off("click");
// 地图点击事件
myChart.on("click", async (params: any) => {
polygons.value = [];
// 动态引入地图json文件
const jsonData = await import(`../config/${params.name}.json`);
const data = await jsonData.default;
const coordinates = data.features[0].geometry.coordinates;
// 查询城镇级别点位信息(根据需求自行添加)
const paramsdata = {
areaId: params.name
};
const res = await pointList(paramsdata);
// 设置图标
res.result.forEach((item: any) => {
item.symbol = "image://" + require("@/assets/industry_location.png");
item.symbolSize = [18, 23]; // 图标大小
});
pointListInfo.value = res.result;
// 通过turf来判断点是否在多边形内
if (coordinates.length > 1) {
//解决'Each LinearRing of a Polygon must have 4 or more Positions.'错误
polygons.value.push(turf.multiPolygon(coordinates));
} else {
polygons.value.push(turf.polygon(coordinates));
}
pointListInfo.value = pointListInfo.value.filter((item: any) => {
return polygons.value.some((item1: any) => {
return turf.booleanPointInPolygon(
turf.point([item.value[0], item.value[1]]),
item1
);
});
});
// 重新加载地图
getEchartsMap(params.name, data);
});
};
下载turf npm install @turf/boolean-point-in-polygon
turf官方文档
页面引入import * as turf from "@turf/turf"