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} 截取区域的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 };