riku
2024-12-23 329bc53486678ea26b1b63c69299509c01677aeb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/**
 * 网格绘制
 */
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]
      });
    });
  }
};