/** * 网格绘制 */ import { map } from './index_old'; import calculate from './calculate'; import { Legend } from '@/model/Legend'; import { getHexColor, getColorBetweenTwoColors } from '../color'; /** * 角度增减,确保角度处于0 - 360度之间 * @param {number} angle 原角度 * @param {number} offset 偏移量 */ function plusAngle(angle, offset) { const result = angle + offset; if (result > 360) { return result - 360; } else if (result < 0) { return result + 360; } else { return result; } } /** * 根据网格中心点,生成正方形网格4个顶点的坐标 * @param {Array} points 网格中心点经纬度数组 */ function parseGridPoint(points) { if (points.length < 2) throw new Error('坐标点数量小于2'); const p1 = points[0]; const p2 = points[1]; // 两中心点间的角度 const angle = calculate.getAngle(p1[0], p1[1], p2[0], p2[1]); // const angle = calculate.bearing( // { latitude: p1[0], longitude: p1[1] }, // { latitude: p2[0], longitude: p2[1] } // ); // 两中心点间的距离 const dis = calculate.getDistance(p1[0], p1[1], p2[0], p2[1]); // 网格正方形对角线的一半长度 const halfDiagonal = Math.sqrt((dis / 2) * (dis / 2) * 2); // 计算首个正方形各顶点相对于中心点的角度,得到正方形各顶点的坐标 const angle1 = plusAngle(angle, 45); const gp1 = calculate.getLatLon(p1, halfDiagonal, angle1); const angle2 = plusAngle(angle1, 90); const gp2 = calculate.getLatLon(p1, halfDiagonal, angle2); const angle3 = plusAngle(angle2, 90); const gp3 = calculate.getLatLon(p1, halfDiagonal, angle3); const angle4 = plusAngle(angle3, 90); const gp4 = calculate.getLatLon(p1, halfDiagonal, angle4); // 计算4个顶点分别与中心点的经纬度差值 const diff = { diff1: { dx: gp1[0] - p1[0], dy: gp1[1] - p1[1] }, diff2: { dx: gp2[0] - p1[0], dy: gp2[1] - p1[1] }, diff3: { dx: gp3[0] - p1[0], dy: gp3[1] - p1[1] }, diff4: { dx: gp4[0] - p1[0], dy: gp4[1] - p1[1] } }; // 得到所有正方形网格的4个顶点信息 return points.map((p) => { return [ [p[0] + diff.diff1.dx, p[1] + diff.diff1.dy], [p[0] + diff.diff2.dx, p[1] + diff.diff2.dy], [p[0] + diff.diff3.dx, p[1] + diff.diff3.dy], [p[0] + diff.diff4.dx, p[1] + diff.diff4.dy] ]; }); } /** * 文本标记 * 可修改position */ function textMaker(position, text) { // eslint-disable-next-line no-undef return new AMap.Text({ text: text, position: position, style: { 'font-size': '13px', 'text-align': 'center', color: 'white', 'background-color': 'transparent', 'text-shadow': 'black 2px 2px 2px', 'border-radius': '2px', border: '0px', padding: '4px' } }); } export default { parseGridPoint, /** * 绘制网格风险图 * @param {*} points */ drawRectangle(points) { const gridViews = []; points.forEach((p) => { const { lb, rt, c } = p; let pList = [lb, rt].map((v) => { // eslint-disable-next-line no-undef return new AMap.LngLat(v[0], v[1]); }); // eslint-disable-next-line no-undef var bounds = new AMap.Bounds(...pList); // eslint-disable-next-line no-undef var rectangle = new AMap.Rectangle({ bounds: bounds, strokeColor: '#ffffffff', strokeWeight: 1, strokeOpacity: 1, // strokeStyle还支持 solid strokeStyle: 'solid', fillColor: '#990D0D', fillOpacity: 0.8, cursor: 'pointer', zIndex: 50 }); gridViews.push(rectangle); }); map.add(gridViews); map.setFitView(gridViews); }, /** * 绘制一组多边形 * @param {*} points */ drawPolylines(points) { const gridViews = []; points.forEach((p) => { let path = p.map((v) => { // eslint-disable-next-line no-undef return new AMap.LngLat(v[0], v[1]); }); //创建多边形 Polygon 实例 // eslint-disable-next-line no-undef var polygon = new AMap.Polygon({ path: path, //路径 fillColor: '#fff', //多边形填充颜色 strokeWeight: 1, //线条宽度,默认为 2 strokeColor: 'white', //线条颜色 fillOpacity: 0 }); gridViews.push(polygon); }); map.add(gridViews); map.setFitView(gridViews); return gridViews; }, drawGridText(points, textViews) { if (textViews) { points.forEach((p, i) => { textViews[i].setPosition(p.lnglat_GD); textViews[i].setText(p.data); }); return textViews; } else { const _textViews = []; points.forEach((p) => { const m = textMaker(p.lnglat_GD, p.data); _textViews.push(m); }); map.add(_textViews); return _textViews; } }, drawGridColor(gridViews, texts, factorName) { gridViews.forEach((g, i) => { const data = parseFloat(texts[i]); const { color, nextColor, range, nextRange } = Legend.getStandardColorAndNext(factorName, data); const ratio = (data - range) / (nextRange - range); const _color = getColorBetweenTwoColors( color.map((v) => v * 255), nextColor.map((v) => v * 255), ratio ); g.setOptions({ fillColor: _color, fillOpacity: color[3] }); }); } };