feiyu02
2025-01-03 4f1fb28dad6a4df83752dc9b60f504764f8e3dcb
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
/**
 * 网格绘制
 */
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'
    }
  });
}
 
/**
 * 海量文本标注
 */
function textLabelMarker(position, text, direction) {
  // eslint-disable-next-line no-undef
  return new AMap.LabelMarker({
    position: position,
    zooms: [10, 20],
    opacity: 1,
    zIndex: 2,
    // icon: {
    //   image: 'https://a.amap.com/jsapi_demos/static/images/poi-marker.png',
    //   anchor: 'bottom-center',
    //   size: [25, 34],
    //   clipOrigin: [459, 92],
    //   clipSize: [50, 68]
    // },
    text: {
      // 注意内容格式必须是string
      content: text ? text + '' : '',
      direction: direction ? direction : 'center',
      style: {
        fontSize: 12,
        fillColor: '#fff',
        // strokeColor: 'rgba(0, 0, 0, 0.5)',
        // strokeWidth: 3,
        backgroundColor: '#122b54a9'
        // padding: [3, 10],
        // backgroundColor: 'yellow',
        // borderColor: '#ccc',
        // borderWidth: 3
      }
    }
  });
}
 
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;
    }
  },
 
  drawGridTextLabel(points, textViews, labelsLayer, direction) {
    if (textViews) {
      points.forEach((p, i) => {
        textViews[i].setPosition(p.lnglat_GD);
        textViews[i].setText({
          content: p.data ? p.data + '' : ''
        });
      });
      return { textViews, labelsLayer };
    } else {
      // 创建一个 LabelsLayer 实例来承载 LabelMarker,[LabelsLayer 文档](https://lbs.amap.com/api/jsapi-v2/documentation#labelslayer)
      // eslint-disable-next-line no-undef
      const labelsLayer = new AMap.LabelsLayer({
        zooms: [12, 20],
        zIndex: 1000,
        // 开启标注避让,默认为开启,v1.4.15 新增属性
        collision: false,
        // 开启标注淡入动画,默认为开启,v1.4.15 新增属性
        animation: false
      });
      const _textViews = [];
      // const m = textLabelMarker([121.329723, 31.240625], 25);
      // _textViews.push(m);
      // labelsLayer.add(m);
      points.forEach((p) => {
        const m = textLabelMarker(p.lnglat_GD, p.data, direction);
        _textViews.push(m);
        // 将 LabelMarker 实例添加到 LabelsLayer 上
        labelsLayer.add(m);
      });
      map.add(labelsLayer);
      map.on('zoomend', () => {
        console.log(map.getZoom());
      });
      return { textViews: _textViews, labelsLayer };
    }
  },
 
  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] == 0 ? 0 : 0.7
      });
    });
  },
 
  drawGridColorCustom(gridViews, texts) {
    var max,min
    texts.forEach(t => {
      if (!max || t > max) {
        max = t
      }
      if (!min || t < min) {
        min = t
      }
    });
    gridViews.forEach((g, i) => {
      const data = parseFloat(texts[i]);
      const { color, nextColor, range, nextRange } =
        Legend.getCustomColorAndNext(data, min, max);
      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]
        fillOpacity: color[3] == 0 ? 0 : 0.7
      });
    });
  },
};