推荐两个写地图组件常用到的网站:
获取地图json网站:https://datav.aliyun.com/portal/school/atlas/area_selector
拾取坐标点网站:拾取坐标系统
import React, {forwardRef, useEffect, useState} from "react";
import * as echarts from "echarts";
import chinaMap from "./chinaMap.json" //地图json
import locationPng from "./location.png";
const ThreeModelMap = ({height, width, chartInfo}) => {
const [myMap, setMyMap] = useState()
const [areaData, setAreaData] = useState([])
const getPointColor = (value) => {
if (value >= 100 && value < 200) {
return '#00ff07'
} else if (value >= 200 && value < 500) {
return '#ffff00'
} else if (value >= 500 && value < 900) {
return '#ff5100'
}
}
useEffect(async () => {
const mapDom = document.getElementById('myMap')
const myChart = echarts.init(mapDom)
echarts.registerMap('chinaMap', chinaMap);
//const scatterData = [
// 每个数据点的格式为 [经度, 纬度, 数值(越大距离地面越高)]
//{name: '上海市', value: [121.474216,31.234941, 300]},
//{name: '南昌市', value: [115.871484,28.688441, 700]}
//]
//scatter3D陷入地图(解决方案一: 当点过多时可能会不生效):
//需要有几个垫底数值的点防止值比较小的点陷入地图(定位到上海,不会影响当前区域)
// for (let i = 0; i < 10; i++) {
// scatterData.push({
// name: `陷进地图垫底打点00${i+1}`,
// value: [121.475366, 31.232471, 101],
// id: `test00${i+1}`,
// symbol: 'circle',
// symbolSize: pointSymbolSize
// })
// }
//解决方案二:所有点的数值都使用一个高度适中的值,给每个点自定义区间的颜色或者symbol等样式,配合geo3D设置boxHeight=1可使地图地名处于地图表面而不偏移
const resData = [
{
id: '001',
value: 800,
name: 'point1',
ln: 121.474216,
la: 31.239941
},
{
id: '002',
value: 200,
name: 'point2',
ln: 121.474216,
la: 31.239941
},
{
id: '003',
value: 400,
name: 'point3',
ln: 121.474216,
la: 31.239941
},
{
id: '004',
value: 600,
name: 'point4',
ln: 121.474216,
la: 31.239941
}
]
const scatterData = resData.map(item => {
return {
name: 'point1',
value: [item.ln, item.la, 800],
itemStyle: {color: getPointColor(item.value)}
}
})
//实现地图渐变
let canvas = document.createElement("canvas");
let ctx = canvas.getContext('2d');
canvas.width = 65;
canvas.height = 65;
//绘制颜色偏向
const Grd = ctx.createLinearGradient(0, 100, 100, 0);
Grd.addColorStop(0, "orange");
Grd.addColorStop(1, "blue");
ctx.fillStyle = Grd;
ctx.fillRect(0, 0, 100, 100);
const option = {
backgroundColor: 'rgba(0,0,0,1)',
tooltip:{
show:true
},
visualMap: { //可视化图例(点击可控制地图点的显隐)
type: 'piecewise',
right: 0,
bottom: 0,
textStyle: {
color: '#FFFF',
fontSize: 12,
},
align: 'left',
itemWidth: 9.5,
itemHeight: 9.5,
itemSymbol: 'rect',
itemGap: 15,
inverse: true, //图例展示顺序:上小下大
z: 4,
pieces: [
{
gte: 500,
lt: 900,
color: '#ff5100',
label: '500-900'
},
{
gte: 200,
lt:500,
color: '#ffff00',
label: '200-500'
},
{
gte: 100,
lt: 200,
color: '#00ff07',
label: '100-200'
},
]
},
geo3D: {
map: 'chinaMap', // 地图类型,这里以中国地图为例
roam: false, // 是否开启鼠标缩放和平移漫游
viewControl: {
beta: 10, // 设置视角的左右旋转度数
alpha: 40, // 设置视角的上下旋转度数
// 设置视角的距离
distance: 140
},
shading: 'realistic',
// 设置渐变色
realisticMaterial: {
roughness: 1,
textureTiling: 1,
detailTexture: ctx.canvas.toDataURL()
},
label: {
show: true,
textStyle: {
color: '#fff',
},
formatter: (params) => {
return params.name;
},
borderRadius: 4,
},
regionHeight: 10, //地图厚度,
boxHeight: 1,
itemStyle: {
color: '#65a9dc',
borderColor: '#FFFFFF',
borderWidth: 1,
opacity: 1,
},
aspectScale: 0.9, //长宽比
selectedMode: false, //是否允许选中多个区域
data: [],
},
series: [
{
type: 'scatter3D',
coordinateSystem: 'geo3D',
itemStyle: {
color: '#00FFF6',
},
// symbol: 'image://' + locationPng, //使用图片需加上前缀
symbol: 'circle',
symbolSize: 20,
z: 999,
data: scatterData,
},
],
}
myChart.setOption(option);
},[])
return <div id={"myMap"} style={{height: height, width: width}}></div>
}