import * as echarts from 'echarts';
|
// import * as shanghaiMap from 'echarts-china-cities-js/echarts-china-cities-js/shanghai.js'; // 修正地图数据文件路径
|
// import 'echarts-china-cities-js/echarts-china-cities-js/shanghai.js'; // 修正地图数据文件路径
|
import { shanghai, jingan } from '@/utils/chart/shanghai.js'; // 确保路径正确
|
import calculate from '@/utils/map/calculate.js';
|
|
// 偏移纬度,对应约100米
|
const OFFSET_LAT = 0.00082;
|
// 偏移纬度,对应约100米
|
const OFFSET_LNG = 0.0009;
|
|
/**
|
* 计算地图中心点和缩放比例
|
* @param {*} gridData 网格数据
|
* @returns
|
*/
|
function calCenterPointAndZoom(gridData) {
|
const coordinates = [];
|
let maxLng = -180;
|
let minLng = 180;
|
let maxLat = -90;
|
let minLat = 90;
|
let zoom = 1;
|
gridData.forEach((g) => {
|
g.coordinates.forEach((coordArr) => {
|
coordinates.push({
|
lng: coordArr[0],
|
lat: coordArr[1]
|
});
|
maxLng = Math.max(maxLng, coordArr[0]);
|
minLng = Math.min(minLng, coordArr[0]);
|
maxLat = Math.max(maxLat, coordArr[1]);
|
minLat = Math.min(minLat, coordArr[1]);
|
});
|
});
|
|
console.log('zoom', zoom);
|
|
return {
|
centerLng: (maxLng + minLng) / 2,
|
centerLat: (maxLat + minLat) / 2,
|
zoom,
|
bounds: [
|
minLng - OFFSET_LNG,
|
minLat - OFFSET_LAT,
|
maxLng + OFFSET_LNG,
|
maxLat + OFFSET_LAT
|
]
|
};
|
}
|
|
function generateGridMap(gridData) {
|
const width = 800;
|
const height = 400;
|
// 1. 创建临时DOM元素
|
const div = document.createElement('div');
|
div.style.width = `${width}px`;
|
div.style.height = `${height}px`;
|
document.body.appendChild(div);
|
// 注册上海市地图数据
|
// console.log(shanghaiMap);
|
|
// shanghaiMap(echarts);
|
echarts.registerMap('shanghai', { geoJSON: shanghai });
|
const chart = echarts.init(div);
|
|
// 1. 准备网格数据(转换为ECharts多边形格式)
|
const gridPolygons = gridData.map((grid, index) => ({
|
name: `grid_${index}`,
|
value: [grid.centerLng, grid.centerLat, grid.value], // 中心点经纬度和数值
|
coords: grid.coordinates // 网格四角经纬度坐标数组 [[lng1,lat1], [lng2,lat2], ...]
|
}));
|
const { centerLng, centerLat, zoom, bounds } =
|
calCenterPointAndZoom(gridData);
|
|
// 2. 配置项
|
const option = {
|
// title: {
|
// text: 'Travel Routes'
|
// },
|
geo: {
|
map: 'shanghai', // 基础地图
|
center: [centerLng, centerLat],
|
roam: true, // 禁止缩放平移
|
zoom: zoom, // 地图缩放比例
|
label: { show: true }, // 显示地名标签
|
itemStyle: { areaColor: '#ddddddff', borderColor: '#999' }
|
},
|
series: [
|
{
|
type: 'custom',
|
coordinateSystem: 'geo',
|
renderItem: (params, api) => {
|
// 将经纬度转换为屏幕坐标
|
const grid = gridPolygons[params.dataIndex];
|
// const v = api.value(0);
|
const points = grid.coords.map((coord) => api.coord(coord));
|
// const points = grid.coords;
|
return {
|
type: 'polygon',
|
transition: ['shape'],
|
shape: { points },
|
style: api.style({
|
fill: grid.value[2],
|
stroke: 'white',
|
lineWidth: 1
|
})
|
};
|
},
|
data: gridPolygons,
|
label: { show: false }
|
}
|
]
|
};
|
|
chart.setOption(option);
|
|
// 将像素坐标转换为经纬度
|
// const convert = (x, y) => {
|
// return chart.convertFromPixel(
|
// {
|
// geoIndex: 0
|
// },
|
// [x, y]
|
// );
|
// };
|
|
// 将经纬度转换为像素坐标
|
const convert = (lng, lat) => {
|
return chart.convertToPixel(
|
{
|
geoIndex: 0
|
},
|
[lng, lat]
|
);
|
};
|
|
// 计算画布的左上角和右下角对应的经纬度
|
// 计算网格区域的左上角和右下角经纬度对应的像素坐标
|
const topLeft = convert(bounds[0], bounds[3]);
|
const bottomRight = convert(bounds[2], bounds[1]);
|
// 计算合适的缩放倍数
|
const scale = Math.min(
|
Math.abs(width / (bottomRight[0] - topLeft[0])),
|
Math.abs(height / (bottomRight[1] - topLeft[1]))
|
);
|
console.log('scale', scale);
|
|
// 地图缩放比例
|
chart.setOption({
|
geo: {
|
zoom: scale
|
}
|
});
|
|
// 3. 导出为图片(返回base64)
|
return new Promise((resolve, reject) => {
|
// 延迟执行确保绘制完成
|
setTimeout(() => {
|
const url = chart.getDataURL({
|
type: 'png',
|
pixelRatio: 2,
|
backgroundColor: '#fff'
|
});
|
resolve(url);
|
}, 1000);
|
});
|
// return captureMapByBounds({
|
// chart: chart,
|
// bounds: bounds
|
// }).catch((err) => {
|
// console.error('截图失败:', err);
|
// });
|
}
|
|
/**
|
* 根据经纬度范围截取地图区域
|
* @param {Object} params - 截取参数
|
* @param {Array} params.bounds - 经纬度范围 [minLng, minLat, maxLng, maxLat]
|
* @param {Object} params.chart - ECharts实例
|
* @returns {Promise<string>} 截取区域的base64图片
|
*/
|
// function captureMapByBounds(params) {
|
// const { bounds, chart } = params;
|
// const [minLng, minLat, maxLng, maxLat] = bounds;
|
|
// // 获取地图坐标系
|
// // const geo = chart.getModel().getComponent('geo');
|
// // if (!geo) return Promise.reject('未找到地图组件');
|
|
// // 将经纬度转换为像素坐标
|
// const convert = (lng, lat) => {
|
// return chart.convertToPixel(
|
// {
|
// geoIndex: 0
|
// },
|
// [lng, lat]
|
// );
|
// };
|
|
// // 计算四个角的像素坐标
|
// const topLeft = convert(minLng, maxLat);
|
// const bottomRight = convert(maxLng, minLat);
|
|
// // 创建临时Canvas
|
// const canvas = document.createElement('canvas');
|
// const ctx = canvas.getContext('2d');
|
|
// // 获取原始图表Canvas
|
// const originalCanvas = chart.getDom().querySelector('canvas');
|
|
// // 设置Canvas尺寸为截取区域大小
|
// topLeft[0] -= 10;
|
// topLeft[1] -= 10;
|
// bottomRight[0] += 10;
|
// bottomRight[1] += 10;
|
// topLeft[0] = Math.max(topLeft[0], 0);
|
// topLeft[1] = Math.max(topLeft[1], 0);
|
// bottomRight[0] = Math.min(bottomRight[0], originalCanvas.width);
|
// bottomRight[1] = Math.min(bottomRight[1], originalCanvas.height);
|
// const width = bottomRight[0] - topLeft[0];
|
// const height = bottomRight[1] - topLeft[1];
|
// canvas.width = width;
|
// canvas.height = height;
|
|
// // 裁剪指定区域
|
// ctx.drawImage(
|
// originalCanvas,
|
// topLeft[0],
|
// topLeft[1], // 源图像裁剪起点
|
// width,
|
// height, // 源图像裁剪尺寸
|
// 0,
|
// 0, // 目标图像绘制起点
|
// width,
|
// height // 目标图像绘制尺寸
|
// );
|
|
// // 转换为base64图片
|
// return new Promise((resolve) => {
|
// // 延迟执行确保绘制完成
|
// setTimeout(() => {
|
// const base64 = canvas.toDataURL('image/png', 1.0);
|
// resolve(base64);
|
// }, 100);
|
// });
|
// }
|
|
export default { generateGridMap };
|