- 首先绘画地图板块的坐标数据,阿里云免费的省市区坐标数据,链接https://datav.aliyun.com/portal/school/atlas/area_selector, 看自己嵌套情况下载数据粒度,如果需要省市区跳转就全部下载, 文件下载后市和区的文件名是重名的 需要自己区分 还有一些地区的adcode嵌套的更深需要自己判断查找文件
- 加载坐标文件,通过echarts渲染地图板块
js
// 地图模版
<div class="initEchartsMap" id="mapContainer"></div>
import * as echarts from 'echarts'
import chinaGeoJson from '@/assets/map/china.json' // 导入中国地图 GeoJSON 数据
export default {
data(){
return {
// 地图数据
mapDatas: {},
//当前点击的层级
currentIndex: 1,
}
},
mounted(){
//这里根据t返回的地区名称加载坐标数据 默认加载全国
const response = await import(`@/assets/map/${t}.json`)
console.log(response, '=>respinse')
this.mapData = response.default
//初始化地图数据
this.initMap(response.default)
},
methods:{
initMap(mapJson) {
this.mapInstance = echarts.init(document.getElementById('mapContainer'))
echarts.registerMap(this.regionCity, mapJson) // 注册地图
this.loadMap(this.regionCity)
},
//绘画地图
loadMap(regionName) {
let that = this
const options = {
tooltip: {
trigger: 'item',
position: function(point, params, dom, rect, size) {
return [point[0] - 40, point[1] - 60] // 手动调整位置(x, y)//控制地图板块位置
},
formatter: params => {
const data = this.tooltipData.find(
item => item.rangeName === params.name,
)
if (data) {
return this.tooltipTemplate(data) //自定义鼠标划过显示的模版
}
return params.name
},
backgroundColor: '#fff',
padding: [0, 0],
borderRadius: 5,
boxShadow: '0 2px 5px rgba(0, 0, 0, 0.2)',
borderWidth: 0, // 禁用边框
},
grid: {
right: '0%',
top: '0%',
bottom: '5%',
width: '100%',
height: '100%',
},
select: {
label: {
show: false,
},
itemStyle: {
color: '#fff',
areaColor: '#D7EEFF',
},
},
series: [
{
name: '区域',
type: 'map',
map: regionName, //当前加载的区域名称
roam: false, // 开启缩放和拖拽
itemStyle: {
normal: {
areaColor: '#DEF0FF',
borderColor: '#ACD8FF',
borderWidth: 1.3
shadowBlur: 15,
shadowColor: 'rgba(60,107,255,0.8)',
shadowOffsetX: 7,
shadowOffsetY: 6,
},
emphasis: {
areaColor: '#87D1FC',
borderWidth: 1.6,
shadowBlur: 25,
},
},
label: {
show: false, // 禁用区域名称显示
fontSize: 0,
},
//获取后面点击所获取的地区名称和adcode
data: this.mapData.features.map(item => ({
name: item.properties.name,
value: item.properties.adcode,
item: item,
})), // 数据可以动态绑定
// 动态设置地图的中心点和缩放级别
geo: {
center: [0, 0], // 设置地图的中心点
},
},
],
}
this.mapInstance.setOption(options)
//echarts自适应记
window.addEventListener('resize', () => {
this.mapInstance.resize()
})
// 添加点击事件监听
that.mapInstance.off('click') // 避免重复绑定
that.mapInstance.on('click', params => {
this.regionProvince = params.name
//这里因为数据问题需要手动查找,我就直接禁用了
const restrictedRegions = ['台湾省', '南海诸岛', '海南省', '上海市'] // 禁止点击的特殊区
const currentRegion = params.name // 当前点击区域的名称
console.log(currentRegion, '当前点击的区域')
let valisCode = params.data.item.properties.parent.adcode
// 判断是否是禁止点击的区域
if (restrictedRegions.includes(currentRegion)) {
console.log(`${currentRegion} 不允许点击`)
// this.$message.warning(`${currentRegion} 暂无数据`)
return // 阻止点击操作
}
// 判断当前是否为第三级,使用自定义逻辑
// 假设 yourCondition 是判断第三级的方法(如通过 params 层级属性判断)
const isThirdLevel = this.currentIndex == 3 // 假设第三级的数据含有 level 属性
if (isThirdLevel) {
console.log('当前为第三级,禁止点击')
// this.$message.warning(`${currentRegion} 暂无数据`)
return // 阻止点击操作
}
//切换地图数据的操作
this.handleMapClick(params)
})
},
async handleMapClick(params) {
const { name, value } = params // 当前点击的区域名称
if (!name) return
this.loading = true
try {
const geoJson = await this.fetchGeoJson(
name,
value,
params.data.item.properties.parent.adcode,
) // 获取下一级地图数据
if (geoJson) {
this.initMap(mapJson)
}
} catch (error) {
console.error('无法加载该区域数据:', error)
}
},
async fetchGeoJson(regionName, value, parAdcode) {
let t = 'china'
let that = this
//这里判断一下点击是否是市
if (
regionName.includes('市') &&
(value === 110000 ||
value === 120000 ||
value === 310000 ||
value === 500000)
) {
this.currentIndex = 2
this.regionCity = regionName
t = regionName + 'd' //这里加d时因为我的文件名称
//这里要自己处理一下获取的数据,直接获取的echarts识别不了
let nationalMapRangeList = {
type: 'FeatureCollection',
features: [],
}
//这里应该做一个封装的
const response = await import(`@/assets/map/${t}.json`)
response.default.features.map(item => {
if (item.properties.parent.adcode === value) {
nationalMapRangeList.features.push(item)
}
})
this.mapData = nationalMapRangeList
return nationalMapRangeList
}
if (this.currentIndex === 1) {
t = regionName + 'c'
this.currentIndex = 2
this.regionCity = regionName
try {
const response = await import(`@/assets/map/${t}.json`)
console.log(response, 'respinse1')
this.mapData = response.default
return response.default
} catch (error) {
console.error('加载 GeoJSON 数据失败:', error)
return null
}
} else if (this.currentIndex === 2) {
this.currentIndex = 3
t = this.regionCity + 'd'
let nationalMapRangeList = {
type: 'FeatureCollection',
features: [],
}
const response = await import(`@/assets/map/${t}.json`)
response.default.features.map(item => {
if (item.properties.parent.adcode === value) {
nationalMapRangeList.features.push(item)
}
})
this.mapData = nationalMapRangeList
return nationalMapRangeList
}
},
},
}
}
这样就实现了一个 基础的 地图板块渲染+省市区跳转