hn-map 1.1.13 → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,276 +1,450 @@
1
- import {deepMerge, wgs84ToGcj02Format} from '../util'
1
+ import { deepMerge, wgs84ToGcj02Format, convertPosition } from "../util";
2
2
  import Layer from "./layer";
3
3
 
4
4
  export default (hnMap: any) => {
5
-
6
- const defaultOption = {
7
- id: "",
8
- position: [],
9
- pixelRange: 20,
10
- cluster: true,
11
- image: '',
12
- width: 20,
13
- height: 20,
14
- data: null
5
+ const defaultOption = {
6
+ id: "",
7
+ position: [],
8
+ pixelRange: 20,
9
+ cluster: true,
10
+ image: "",
11
+ width: 20,
12
+ height: 20,
13
+ data: null,
14
+ };
15
+ class mars3d_class extends Layer(hnMap) {
16
+ type: any = "cluster";
17
+ id: any = null;
18
+ option: any = JSON.parse(JSON.stringify(defaultOption));
19
+ config_layer: any = null;
20
+ config_label: any = null;
21
+ children: any = null;
22
+ layerEntity: any = null;
23
+
24
+ constructor(option: any) {
25
+ super(option);
26
+ this.id = option.id;
27
+ this.children = [];
28
+ deepMerge(this.option, option);
29
+ this.config_layer = this.formatConfigLayer(this.option);
30
+ this.config_label = this.formatConfigLabel(this.option);
31
+ this.layerEntity = new mars3d.layer.GraphicLayer(this.config_layer);
32
+ // this.graphic = new mars3d.graphic.BillboardEntity(this.config_label);
15
33
  }
16
- class mars3d_class extends Layer(hnMap) {
17
- type: any = 'cluster'
18
- id: any = null
19
- option: any = JSON.parse(JSON.stringify(defaultOption))
20
- config_layer: any = null
21
- config_label: any = null
22
- children: any = null
23
- layerEntity: any = null
24
-
25
- constructor(option: any) {
26
- super(option)
27
- this.id = option.id
28
- this.children = []
29
- deepMerge(this.option, option)
30
- this.config_layer = this.formatConfigLayer(this.option)
31
- this.config_label = this.formatConfigLabel(this.option)
32
- this.layerEntity = new mars3d.layer.GraphicLayer(this.config_layer)
33
- }
34
-
35
- // 格式化layer配置
36
- formatConfigLayer(option: any) {
37
- return {
38
- id: option.id,
39
- cluster: {
40
- enabled: option.cluster,
41
- pixelRange: option.pixelRange
42
- }
43
- }
44
- }
45
-
46
- // 格式化点位配置
47
- formatConfigLabel(option: any) {
48
- return {
49
- id: option.id,
50
- image: option.image,
51
- width: option.width,
52
- height: option.height,
53
- }
54
- }
55
-
56
- clearEntity() {
57
- this.children = []
58
- this.layerEntity.clear()
59
- }
60
-
61
- addEntity(entity: any) {
62
- this.children.push(entity)
63
- this.layerEntity.addGraphic(entity.graphic)
64
- }
65
-
66
- setPosition(data: any) {
67
- this.clearEntity()
68
- data.forEach((item: any, index: any) => {
69
- let imagePointOption = {
70
- id: this.config_label.id + '_point' + item.id,
71
- position: item.position,
72
- image: this.config_label.image,
73
- height: this.config_label.height,
74
- width: this.config_label.width,
75
- data: item.data
76
- }
77
- const imagePoint = new hnMap.ImagePoint(imagePointOption);
78
- this.addEntity(imagePoint)
79
- })
80
- }
81
-
82
- destroy() {
83
- this.clearEntity()
84
- this.layerEntity.remove(true)
85
- hnMap.map.layerList = hnMap.map.layerList.filter((v: any) => v.id !== this.id)
86
- }
87
-
88
- // 添加属性弹窗
89
- addPopupByAttr() {
90
- this.layerEntity.bindPopup((event: any) => {
91
- const data = event.graphic.attr
92
- return mars3d.Util.getTemplateHtml({title: "详情", template: "all", attr: data})
93
- })
94
- }
95
-
96
- // 添加自定义dom弹窗
97
- addCustomPopup(getCustomDom: any) {
98
- this.layerEntity.bindPopup(async (event: any) => {
99
- if (event.graphic.attr) {
100
- const data = event.graphic.attr || {};
101
- return await getCustomDom(data);
102
- }
103
- }, {offsetY: -20});
104
- }
105
34
 
106
- flyTo() {
107
- this.layerEntity.flyTo()
108
- }
35
+ // 格式化layer配置
36
+ formatConfigLayer(option: any) {
37
+ return {
38
+ id: option.id,
39
+ cluster: {
40
+ enabled: option.cluster !== false, // 默认开启聚合
41
+ pixelRange: option.pixelRange || 20,
42
+ // 添加更多聚合样式配置
43
+ styles: [
44
+ {
45
+ scale: 1,
46
+ image: "img/marker/mark1.png",
47
+ label: {
48
+ text: "{count}",
49
+ color: "#ffffff",
50
+ font_size: 16,
51
+ stroke: true,
52
+ strokeColor: "#000000",
53
+ },
54
+ },
55
+ {
56
+ scale: 1.5,
57
+ image: "img/marker/mark2.png",
58
+ label: {
59
+ text: "{count}",
60
+ color: "#ffffff",
61
+ font_size: 18,
62
+ },
63
+ },
64
+ {
65
+ scale: 2,
66
+ image: "img/marker/mark3.png",
67
+ label: {
68
+ text: "{count}",
69
+ color: "#ffffff",
70
+ font_size: 20,
71
+ },
72
+ },
73
+ ],
74
+ },
75
+ };
76
+ }
109
77
 
110
- getEntity(entityParam: any) {
111
- let entity
112
- if (typeof entityParam == 'string') {
113
- entity = this.children.find((v: any) => v.id === entityParam)
114
- } else {
115
- entity = entityParam
116
- }
117
- if (!entity) {
118
- return Promise.reject(new Error('未找到此图形'))
119
- }
120
- return entity
121
- }
78
+ // 格式化点位配置
79
+ formatConfigLabel(option: any) {
80
+ return {
81
+ id: "label_" + option.id,
82
+ image: option.image,
83
+ width: option.width,
84
+ height: option.height,
85
+ };
86
+ }
122
87
 
123
- // 手动打开聚合功能
124
- openCluster() {
125
- deepMerge(this.option, {cluster: true,})
126
- this.config_layer = this.formatConfigLayer(this.option)
127
- this.layerEntity.clusterEnabled = true
128
- }
88
+ clearEntity() {
89
+ this.children = [];
90
+ this.layerEntity.clear();
91
+ }
129
92
 
130
- // 手动关闭聚合功能
131
- closeCluster() {
132
- deepMerge(this.option, {cluster: false,})
133
- this.config_layer = this.formatConfigLayer(this.option)
134
- this.layerEntity.clusterEnabled = false
135
- }
93
+ addEntity(entity: any) {
94
+ this.children.push(entity);
95
+ this.layerEntity.addGraphic(entity.graphic);
96
+ }
136
97
 
98
+ setPosition(data: any) {
99
+ this.clearEntity();
100
+ data.forEach((item: any, index: any) => {
101
+ let imagePointOption = {
102
+ id: this.config_label.id + "_point" + item.id,
103
+ position: item.position,
104
+ image: this.config_label.image,
105
+ height: this.config_label.height,
106
+ width: this.config_label.width,
107
+ data: item.data,
108
+ };
109
+ const imagePoint = new hnMap.ImagePoint(imagePointOption);
110
+ this.addEntity(imagePoint);
111
+ });
137
112
  }
138
113
 
139
- class gaode_class {
114
+ // 修改 cluster.ts 中的 mars3d_class 类
140
115
 
141
- id: any = null
142
- option: any = JSON.parse(JSON.stringify(defaultOption))
143
- config: any = null
144
- layerEntity: any = null
145
- // 创建全局信息窗口实例
146
- infoWindow: any = null
116
+ destroy() {
117
+ this.clearEntity();
118
+ this.layerEntity.remove(true);
119
+ hnMap.map.layerList = hnMap.map.layerList.filter(
120
+ (v: any) => v.id !== this.id
121
+ );
122
+ }
147
123
 
148
- constructor(option: any) {
149
- this.id = option.id
150
- deepMerge(this.option, option)
151
- this.config = this.formatConfig(this.option)
152
- this.layerEntity = new AMap.MarkerCluster(hnMap.map.map, this.config.position, this.config);
153
- }
124
+ // 添加属性弹窗
125
+ addPopupByAttr() {
126
+ this.layerEntity.bindPopup((event: any) => {
127
+ const data = event.graphic.attr;
128
+ return mars3d.Util.getTemplateHtml({
129
+ title: "详情",
130
+ template: "all",
131
+ attr: data,
132
+ });
133
+ });
134
+ }
154
135
 
155
- formatConfig(option: any) {
156
- const position = option.position.map((item: any, index: any) => {
157
- return {
158
- lnglat: wgs84ToGcj02Format(item),
159
- // 添加弹窗属性参数
160
- extData: {
161
- id: this.id + '_point' + index
162
- }
163
- }
164
- })
165
- const count = position.length;
166
- const _renderClusterMarker = (context: any) => {
167
- var factor = Math.pow(context.count / count, 1 / 18);
168
- var div = document.createElement('div');
169
- var Hue = 180 - factor * 180;
170
- var bgColor = 'hsla(' + Hue + ',100%,40%,0.7)';
171
- var fontColor = 'hsla(' + Hue + ',100%,90%,1)';
172
- var borderColor = 'hsla(' + Hue + ',100%,40%,1)';
173
- var shadowColor = 'hsla(' + Hue + ',100%,90%,1)';
174
- div.style.backgroundColor = bgColor;
175
- var size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20);
176
- div.style.width = div.style.height = size + 'px';
177
- div.style.border = 'solid 1px ' + borderColor;
178
- div.style.borderRadius = size / 2 + 'px';
179
- div.style.boxShadow = '0 0 5px ' + shadowColor;
180
- div.innerHTML = context.count;
181
- div.style.lineHeight = size + 'px';
182
- div.style.color = fontColor;
183
- div.style.fontSize = '14px';
184
- div.style.textAlign = 'center';
185
- context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
186
- context.marker.setContent(div)
136
+ // 添加自定义dom弹窗
137
+ addCustomPopup(getCustomDom: any) {
138
+ this.layerEntity.bindPopup(
139
+ async (event: any) => {
140
+ if (event.graphic.attr) {
141
+ const data = event.graphic.attr || {};
142
+ return await getCustomDom(data);
143
+ }
144
+ },
145
+ { offsetY: -20 }
146
+ );
147
+ }
187
148
 
188
- }
149
+ flyTo() {
150
+ this.layerEntity.flyTo();
151
+ }
189
152
 
190
- const _renderMarker = (context: any) => {
191
- let icon = new AMap.Icon({
192
- image: this.option.style.image,
193
- imageSize: new AMap.Size(this.option.style.height, this.option.style.width),
194
- size: new AMap.Size(this.option.style.height, this.option.style.width),
195
- })
196
- context.marker.setIcon(icon)
197
- }
198
- return {
199
- id: option.id,
200
- position,
201
- gridSize: option.pixelRange, // 设置网格像素大小
202
- clusterByZoomChange: true,
203
- renderClusterMarker: _renderClusterMarker, // 自定义聚合点样式
204
- renderMarker: _renderMarker, // 自定义非聚合点样式
205
- }
206
- }
153
+ getEntity(entityParam: any) {
154
+ let entity;
155
+ if (typeof entityParam == "string") {
156
+ entity = this.children.find((v: any) => v.id === entityParam);
157
+ } else {
158
+ entity = entityParam;
159
+ }
160
+ if (!entity) {
161
+ return Promise.reject(new Error("未找到此图形"));
162
+ }
163
+ return entity;
164
+ }
207
165
 
208
- setPosition(position: any) {
209
- deepMerge(this.option, {position: position})
210
- this.config = this.formatConfig(this.option)
211
- this.layerEntity.setData(this.config.position)
212
- }
166
+ // 手动打开聚合功能
167
+ openCluster() {
168
+ deepMerge(this.option, { cluster: true });
169
+ this.config_layer = this.formatConfigLayer(this.option);
170
+ this.layerEntity.clusterEnabled = true;
171
+ }
213
172
 
173
+ // 手动关闭聚合功能
174
+ closeCluster() {
175
+ deepMerge(this.option, { cluster: false });
176
+ this.config_layer = this.formatConfigLayer(this.option);
177
+ this.layerEntity.clusterEnabled = false;
178
+ }
179
+ }
180
+
181
+ class gaode_class {
182
+ id: any = null;
183
+ option: any = JSON.parse(JSON.stringify(defaultOption));
184
+ config: any = null;
185
+ layerEntity: any = null;
186
+ // 创建全局信息窗口实例
187
+ infoWindow: any = null;
188
+
189
+ constructor(option: any) {
190
+ this.id = option.id;
191
+ deepMerge(this.option, option);
192
+ this.config = this.formatConfig(this.option);
193
+ this.layerEntity = new AMap.MarkerCluster(
194
+ hnMap.map.map,
195
+ this.config.position,
196
+ this.config
197
+ );
198
+ }
214
199
 
215
- destroy() {
216
- this.layerEntity.setMap(null)
217
- hnMap.map.layerList = hnMap.map.layerList.filter((v: any) => v.id !== this.id)
218
- }
200
+ formatConfig(option: any) {
201
+ const position = option.position.map((item: any, index: any) => {
202
+ return {
203
+ lnglat: wgs84ToGcj02Format(item),
204
+ // 添加弹窗属性参数
205
+ extData: {
206
+ id: this.id + "_point" + index,
207
+ },
208
+ };
209
+ });
210
+ const count = position.length;
211
+ const _renderClusterMarker = (context: any) => {
212
+ var factor = Math.pow(context.count / count, 1 / 18);
213
+ var div = document.createElement("div");
214
+ var Hue = 180 - factor * 180;
215
+ var bgColor = "hsla(" + Hue + ",100%,40%,0.7)";
216
+ var fontColor = "hsla(" + Hue + ",100%,90%,1)";
217
+ var borderColor = "hsla(" + Hue + ",100%,40%,1)";
218
+ var shadowColor = "hsla(" + Hue + ",100%,90%,1)";
219
+ div.style.backgroundColor = bgColor;
220
+ var size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20);
221
+ div.style.width = div.style.height = size + "px";
222
+ div.style.border = "solid 1px " + borderColor;
223
+ div.style.borderRadius = size / 2 + "px";
224
+ div.style.boxShadow = "0 0 5px " + shadowColor;
225
+ div.innerHTML = context.count;
226
+ div.style.lineHeight = size + "px";
227
+ div.style.color = fontColor;
228
+ div.style.fontSize = "14px";
229
+ div.style.textAlign = "center";
230
+ context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
231
+ context.marker.setContent(div);
232
+ };
233
+
234
+ const _renderMarker = (context: any) => {
235
+ let icon = new AMap.Icon({
236
+ image: this.option.style.image,
237
+ imageSize: new AMap.Size(
238
+ this.option.style.height,
239
+ this.option.style.width
240
+ ),
241
+ size: new AMap.Size(
242
+ this.option.style.height,
243
+ this.option.style.width
244
+ ),
245
+ });
246
+ context.marker.setIcon(icon);
247
+ };
248
+ return {
249
+ id: option.id,
250
+ position,
251
+ gridSize: option.pixelRange, // 设置网格像素大小
252
+ clusterByZoomChange: true,
253
+ renderClusterMarker: _renderClusterMarker, // 自定义聚合点样式
254
+ renderMarker: _renderMarker, // 自定义非聚合点样式
255
+ };
256
+ }
219
257
 
220
- flyTo() {
221
- let totalLng = 0;
222
- let totalLat = 0;
223
- this.config.position.map((item: any) => {
224
- totalLng += item.lnglat.lng;
225
- totalLat += item.lnglat.lat;
226
- })
227
- const centerLng = totalLng / this.config.position.length;
228
- const centerLat = totalLat / this.config.position.length;
229
- hnMap.map.map.setCenter([centerLng, centerLat])
230
- }
258
+ setPosition(position: any) {
259
+ deepMerge(this.option, { position: position });
260
+ this.config = this.formatConfig(this.option);
261
+ this.layerEntity.setData(this.config.position);
262
+ }
231
263
 
232
- // 添加属性弹窗
233
- addPopupByAttr() {
234
- if (!this.infoWindow) {
235
- this.infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});
236
- }
264
+ destroy() {
265
+ this.layerEntity.setMap(null);
266
+ hnMap.map.layerList = hnMap.map.layerList.filter(
267
+ (v: any) => v.id !== this.id
268
+ );
269
+ }
237
270
 
238
- this.layerEntity.on('click', (cluster: any) => {
239
- if (cluster.clusterData.length === 1) {
240
- let content = ''
241
- const data = cluster.clusterData[0].extData
242
- for (const key in data) {
243
- content += `<div>${key}: ${data[key]}</div>`
244
- }
245
- this.infoWindow.setContent(content);
246
- this.infoWindow.open(hnMap.map.map, cluster.marker._position);
247
- }
271
+ flyTo() {
272
+ let totalLng = 0;
273
+ let totalLat = 0;
274
+ this.config.position.map((item: any) => {
275
+ totalLng += item.lnglat.lng;
276
+ totalLat += item.lnglat.lat;
277
+ });
278
+ const centerLng = totalLng / this.config.position.length;
279
+ const centerLat = totalLat / this.config.position.length;
280
+ hnMap.map.map.setCenter([centerLng, centerLat]);
281
+ }
248
282
 
249
- })
283
+ // 添加属性弹窗
284
+ addPopupByAttr() {
285
+ if (!this.infoWindow) {
286
+ this.infoWindow = new AMap.InfoWindow({
287
+ offset: new AMap.Pixel(0, -30),
288
+ });
289
+ }
290
+
291
+ this.layerEntity.on("click", (cluster: any) => {
292
+ if (cluster.clusterData.length === 1) {
293
+ let content = "";
294
+ const data = cluster.clusterData[0].extData;
295
+ for (const key in data) {
296
+ content += `<div>${key}: ${data[key]}</div>`;
297
+ }
298
+ this.infoWindow.setContent(content);
299
+ this.infoWindow.open(hnMap.map.map, cluster.marker._position);
250
300
  }
301
+ });
302
+ }
251
303
 
252
- // 添加自定义dom弹窗
253
- addCustomPopup(getCustomDom: any) {
254
- if (!this.infoWindow) {
255
- this.infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});
256
- }
257
-
258
- this.layerEntity.on('click', (cluster: any) => {
259
- if (cluster.clusterData.length === 1) {
260
- let content = ''
261
- const data = cluster.clusterData[0].extData
262
- const dom = getCustomDom(data);
263
- this.infoWindow.setContent(dom);
264
- this.infoWindow.open(hnMap.map.map, cluster.marker._position);
265
- }
266
- })
304
+ // 添加自定义dom弹窗
305
+ addCustomPopup(getCustomDom: any) {
306
+ if (!this.infoWindow) {
307
+ this.infoWindow = new AMap.InfoWindow({
308
+ offset: new AMap.Pixel(0, -30),
309
+ });
310
+ }
311
+
312
+ this.layerEntity.on("click", (cluster: any) => {
313
+ if (cluster.clusterData.length === 1) {
314
+ let content = "";
315
+ const data = cluster.clusterData[0].extData;
316
+ const dom = getCustomDom(data);
317
+ this.infoWindow.setContent(dom);
318
+ this.infoWindow.open(hnMap.map.map, cluster.marker._position);
267
319
  }
268
-
320
+ });
321
+ }
322
+ }
323
+
324
+ class siji_class {
325
+ type: any = "cluster";
326
+ id: any = null;
327
+ option: any = JSON.parse(JSON.stringify(defaultOption));
328
+ config_layer: any = null;
329
+ config_label: any = null;
330
+ config_Image: any = null;
331
+ layerEntity: any = null;
332
+ // 创建全局信息窗口实例
333
+ infoWindow: any = null;
334
+
335
+ constructor(option: any) {
336
+ this.id = option.id;
337
+ deepMerge(this.option, option);
338
+ hnMap.map.map.addSource("themeData", {
339
+ type: "geojson",
340
+ data: {
341
+ type: "FeatureCollection",
342
+ features: this.option.position.map((v: any) => ({
343
+ type: "Feature",
344
+ geometry: {
345
+ type: "Point",
346
+ coordinates: convertPosition(v.position),
347
+ },
348
+ properties: {
349
+ name: v.data.name,
350
+ },
351
+ })),
352
+ },
353
+ cluster: true,
354
+ clusterMaxZoom: 12, // 最大聚类层级
355
+ clusterRadius: 100, // 聚合点半径,默认50
356
+ });
357
+ this.config_layer = this.formatConfigLayer(this.option);
358
+ this.config_label = this.formatConfigLabel(this.option);
359
+ this.config_Image = this.formatConfigImage(this.option);
360
+ }
361
+ formatConfigLayer(option: any) {
362
+ return {
363
+ id: "clusters_" + option.id,
364
+ type: "circle",
365
+ source: "themeData",
366
+ filter: ["has", "point_count"],
367
+ paint: {
368
+ // 使用step表达式,用于分段匹配圆点的颜色和半径
369
+ // 根据当前"point_count"值匹配对应的内容
370
+ // 默认为"#9faebf"
371
+ // 当大于10小于30时,返回"#3583de"
372
+ // 大于30小于55时,返回"#04b71e"
373
+ "circle-color": [
374
+ "step",
375
+ ["get", "point_count"],
376
+ "#9faebf",
377
+ 10,
378
+ "#3583de",
379
+ 30,
380
+ "#04b71e",
381
+ 55,
382
+ "#ff9800",
383
+ 100,
384
+ "#f61402",
385
+ 300,
386
+ "#f61402",
387
+ ],
388
+ "circle-radius": [
389
+ "step",
390
+ ["get", "point_count"],
391
+ 20,
392
+ 50,
393
+ 30,
394
+ 100,
395
+ 35,
396
+ 500,
397
+ 35,
398
+ 2000,
399
+ 40,
400
+ 5000,
401
+ 40,
402
+ ],
403
+ "circle-opacity": 0.7,
404
+ "circle-stroke-width": 3,
405
+ "circle-stroke-color": "#ffffff",
406
+ },
407
+ };
408
+ }
409
+ formatConfigLabel(option: any) {
410
+ return {
411
+ id: "clusterCount_" + option.id,
412
+ type: "symbol",
413
+ source: "themeData",
414
+ filter: ["has", "point_count"],
415
+ layout: {
416
+ "text-field": "{point_count_abbreviated}",
417
+ "text-font": ["Microsoft YaHei Regular"],
418
+ "text-size": 14,
419
+ },
420
+ paint: {
421
+ "text-color": "#ffffff",
422
+ },
423
+ };
269
424
  }
270
425
 
271
- const fn:any = {
272
- mars3d: mars3d_class,
273
- gaode: gaode_class
426
+ formatConfigImage(option: any) {
427
+ return {
428
+ id: "choicePoi_" + option.id,
429
+ type: "symbol",
430
+ source: "themeData",
431
+ filter: ["!has", "point_count"],
432
+ layout: {
433
+ "icon-image": option.id + "_poiImage",
434
+ },
435
+ paint: {
436
+ "text-color": "#555252",
437
+ "text-halo-color": "#FFFFFF",
438
+ "text-halo-width": 1.33333,
439
+ },
440
+ };
274
441
  }
275
- return fn[hnMap.mapType]
276
- }
442
+ }
443
+
444
+ const fn: any = {
445
+ mars3d: mars3d_class,
446
+ gaode: gaode_class,
447
+ siji: siji_class,
448
+ };
449
+ return fn[hnMap.mapType];
450
+ };