hn-map 1.0.9 → 1.1.0
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.
- package/README.md +5 -22
- package/dist/index.js +2317 -609
- package/package.json +11 -8
- package/src/base/gaode_entity.ts +61 -0
- package/src/base/mars3d_entity.ts +64 -0
- package/src/base/siji_entity.ts +118 -0
- package/src/graphic/circle.ts +218 -0
- package/src/graphic/divPoint.ts +133 -0
- package/src/graphic/imagePoint.ts +237 -0
- package/src/graphic/label.ts +330 -0
- package/src/graphic/line.ts +345 -0
- package/src/graphic/numPoint.ts +290 -0
- package/src/graphic/point.ts +234 -0
- package/src/graphic/polygon.ts +188 -0
- package/src/graphic/rectangle.ts +202 -0
- package/src/index.ts +202 -0
- package/src/layer/cluster.ts +276 -0
- package/src/layer/geoJson.ts +174 -0
- package/src/layer/heatMap.ts +163 -0
- package/src/layer/layer.ts +464 -0
- package/src/layer/pointCloud.ts +78 -0
- package/src/map.ts +433 -0
- package/src/other/route.ts +457 -0
- package/src/types/globals.d.ts +5 -0
- package/src/util.ts +217 -0
- package/src/base/gaode_entity.js +0 -59
- package/src/base/mars3d_entity.js +0 -50
- package/src/graphic/circle.js +0 -159
- package/src/graphic/divPoint.js +0 -86
- package/src/graphic/imagePoint.js +0 -163
- package/src/graphic/label.js +0 -176
- package/src/graphic/line.js +0 -203
- package/src/graphic/numPoint.js +0 -119
- package/src/graphic/point.js +0 -144
- package/src/graphic/polygon.js +0 -111
- package/src/graphic/rectangle.js +0 -115
- package/src/index.js +0 -104
- package/src/layer/cluster.js +0 -277
- package/src/layer/geoJson.js +0 -174
- package/src/layer/heatMap.js +0 -163
- package/src/layer/layer.js +0 -311
- package/src/layer/pointCloud.js +0 -78
- package/src/map.js +0 -303
- package/src/other/route.js +0 -217
- package/src/util.js +0 -103
package/src/index.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import map from "./map";
|
|
2
|
+
import layer from "./layer/layer";
|
|
3
|
+
import point from "./graphic/point";
|
|
4
|
+
import numPoint from "./graphic/numPoint";
|
|
5
|
+
import imagePoint from "./graphic/imagePoint";
|
|
6
|
+
import divPoint from "./graphic/divPoint";
|
|
7
|
+
import label from "./graphic/label";
|
|
8
|
+
import line from "./graphic/line";
|
|
9
|
+
import circle from "./graphic/circle";
|
|
10
|
+
import rectangle from "./graphic/rectangle";
|
|
11
|
+
import polygon from "./graphic/polygon";
|
|
12
|
+
import route from "./other/route";
|
|
13
|
+
import heatMap from "./layer/heatMap";
|
|
14
|
+
import cluster from "./layer/cluster";
|
|
15
|
+
import pointCloud from "./layer/pointCloud";
|
|
16
|
+
import geoJson from "./layer/geoJson";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* HnMap类是一个地图工具类,用于创建和管理地图对象及其相关元素
|
|
20
|
+
*/
|
|
21
|
+
export default class HnMap {
|
|
22
|
+
id: any = null;
|
|
23
|
+
option: any = null;
|
|
24
|
+
mapType: any = null;
|
|
25
|
+
map: any = null;
|
|
26
|
+
Layer: any = null;
|
|
27
|
+
Point: any = null;
|
|
28
|
+
NumPoint: any = null;
|
|
29
|
+
ImagePoint: any = null;
|
|
30
|
+
DivPoint: any = null;
|
|
31
|
+
Label: any = null;
|
|
32
|
+
Line: any = null;
|
|
33
|
+
Circle: any = null;
|
|
34
|
+
Rectangle: any = null;
|
|
35
|
+
Polygon: any = null;
|
|
36
|
+
Route: any = null;
|
|
37
|
+
HeatMap: any = null;
|
|
38
|
+
Cluster: any = null;
|
|
39
|
+
PointCloud: any = null;
|
|
40
|
+
GeoJson: any = null;
|
|
41
|
+
|
|
42
|
+
// 允许构造函数
|
|
43
|
+
private static allowConstruction = false;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* HnMap类的构造函数
|
|
47
|
+
* @param id 地图容器的ID
|
|
48
|
+
* @param option 地图的配置选项
|
|
49
|
+
* @param mapType 地图的类型
|
|
50
|
+
* @param map
|
|
51
|
+
*/
|
|
52
|
+
private constructor(id: string, option: any, mapType: string, map: any) {
|
|
53
|
+
if (!HnMap.allowConstruction) {
|
|
54
|
+
throw new Error("请使用 HnMap.create() 创建实例");
|
|
55
|
+
}
|
|
56
|
+
this.id = id;
|
|
57
|
+
this.option = option;
|
|
58
|
+
this.mapType = mapType;
|
|
59
|
+
this.map = map; // ✅ 此时 map 已创建
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 创建HnMap实例的方法
|
|
64
|
+
* @param id 地图容器的ID
|
|
65
|
+
* @param option 地图的配置选项
|
|
66
|
+
* @param mapType 地图的类型
|
|
67
|
+
*/
|
|
68
|
+
static async create(id: string, option: any, mapType: string) {
|
|
69
|
+
// 判断是否在子路径下
|
|
70
|
+
const basePath = window.location.pathname.endsWith("/")
|
|
71
|
+
? window.location.pathname
|
|
72
|
+
: window.location.pathname.substring(
|
|
73
|
+
0,
|
|
74
|
+
window.location.pathname.lastIndexOf("/") + 1
|
|
75
|
+
);
|
|
76
|
+
await loadResource(basePath + "lib/turf/turf.min.js", "js");
|
|
77
|
+
|
|
78
|
+
// 1.根据不同的地图类型,加载相应的资源
|
|
79
|
+
switch (mapType) {
|
|
80
|
+
case "mars3d":
|
|
81
|
+
|
|
82
|
+
await loadResource(basePath + "lib/Cesium/Widgets/widgets.css", "css");
|
|
83
|
+
await loadResource(basePath + "lib/Cesium/Cesium.js", "js");
|
|
84
|
+
await loadResource(basePath + "lib/mars3d/mars3d.css", "css");
|
|
85
|
+
await loadResource(basePath + "lib/mars3d/mars3d.js", "js");
|
|
86
|
+
await loadResource(
|
|
87
|
+
basePath + "lib/mars3d/plugins/heatmap/heatmap.js",
|
|
88
|
+
"js"
|
|
89
|
+
);
|
|
90
|
+
await loadResource(
|
|
91
|
+
basePath + "lib/mars3d/plugins/heatmap/mars3d-heatmap.js",
|
|
92
|
+
"js"
|
|
93
|
+
);
|
|
94
|
+
break;
|
|
95
|
+
case "gaode":
|
|
96
|
+
await loadResource(
|
|
97
|
+
`https://webapi.amap.com/maps?v=2.0&key=${option.gaode_key}&plugin=AMap.HeatMap,AMap.MarkerCluster,AMap.MoveAnimation`,
|
|
98
|
+
"js"
|
|
99
|
+
);
|
|
100
|
+
await loadResource(
|
|
101
|
+
"https://a.amap.com/jsapi_demos/static/data3d/lib/three.117.js",
|
|
102
|
+
"js"
|
|
103
|
+
);
|
|
104
|
+
await loadResource(
|
|
105
|
+
"https://a.amap.com/jsapi_demos/static/data3d/lib/GLTFLoader.117.min.js",
|
|
106
|
+
"js"
|
|
107
|
+
);
|
|
108
|
+
break;
|
|
109
|
+
case "siji":
|
|
110
|
+
await loadResource("https://map.sgcc.com.cn/maps?v=3.0.0", "js");
|
|
111
|
+
await SGMap.tokenTask.login(option.sj_app_key, option.sj_app_secret);
|
|
112
|
+
await SGMap.plugin([
|
|
113
|
+
"SGMap.DrawPolygonHandler",
|
|
114
|
+
"SGMap.DrawCircleHandler",
|
|
115
|
+
"SGMap.DrawRectangleHandler",
|
|
116
|
+
"SGMap.GeocodingTask",
|
|
117
|
+
]);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 2. 创建地图对象
|
|
122
|
+
const MapClass = map({id, option, mapType}); // 假设 map 是一个工厂
|
|
123
|
+
const innerMap = await MapClass.create(id, option); // 真正的地图实例
|
|
124
|
+
// 3. 创建 HnMap 实例(此时传入 map)
|
|
125
|
+
HnMap.allowConstruction = true;
|
|
126
|
+
try {
|
|
127
|
+
const instance = new HnMap(id, option, mapType, innerMap);
|
|
128
|
+
|
|
129
|
+
// 4. ✅ 此时 this.map 已存在,再初始化所有模块
|
|
130
|
+
instance.initModules();
|
|
131
|
+
return instance;
|
|
132
|
+
} finally {
|
|
133
|
+
HnMap.allowConstruction = false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ✅ 添加一个初始化方法,用于注册所有图形类
|
|
138
|
+
private initModules() {
|
|
139
|
+
this.Layer = layer(this);
|
|
140
|
+
this.Point = point(this);
|
|
141
|
+
this.NumPoint = numPoint(this);
|
|
142
|
+
this.ImagePoint = imagePoint(this);
|
|
143
|
+
this.DivPoint = divPoint(this);
|
|
144
|
+
this.Label = label(this);
|
|
145
|
+
this.Line = line(this);
|
|
146
|
+
this.Circle = circle(this);
|
|
147
|
+
this.Rectangle = rectangle(this);
|
|
148
|
+
this.Polygon = polygon(this);
|
|
149
|
+
this.Route = route(this);
|
|
150
|
+
this.HeatMap = heatMap(this);
|
|
151
|
+
this.Cluster = cluster(this);
|
|
152
|
+
this.PointCloud = pointCloud(this);
|
|
153
|
+
this.GeoJson = geoJson(this);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 检查资源是否已加载
|
|
159
|
+
* @param path 资源的路径
|
|
160
|
+
* @returns {boolean} 资源是否已加载
|
|
161
|
+
*/
|
|
162
|
+
const isResourceLoaded = (path: string): boolean => {
|
|
163
|
+
// 检查脚本
|
|
164
|
+
const scripts = Array.from(document.getElementsByTagName("script"));
|
|
165
|
+
if (scripts.some((script) => script.src.includes(path))) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 检查样式
|
|
170
|
+
const links = Array.from(document.getElementsByTagName("link"));
|
|
171
|
+
return links.some((link) => link.href.includes(path));
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* 加载资源的方法
|
|
176
|
+
* @param path 资源的路径
|
|
177
|
+
* @param type 资源的类型,'css'或'js'
|
|
178
|
+
* @returns {Promise<void>} 加载完成的Promise
|
|
179
|
+
*/
|
|
180
|
+
const loadResource = (path: string, type: string): Promise<void> => {
|
|
181
|
+
return new Promise<void>((resolve, reject) => {
|
|
182
|
+
// 如果资源已加载,直接返回
|
|
183
|
+
if (isResourceLoaded(path)) {
|
|
184
|
+
resolve();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (type === "css") {
|
|
188
|
+
const link = document.createElement("link");
|
|
189
|
+
link.rel = "stylesheet";
|
|
190
|
+
link.href = path;
|
|
191
|
+
link.onload = () => resolve();
|
|
192
|
+
link.onerror = reject;
|
|
193
|
+
document.head.appendChild(link);
|
|
194
|
+
} else {
|
|
195
|
+
const script = document.createElement("script");
|
|
196
|
+
script.src = path;
|
|
197
|
+
script.onload = () => resolve();
|
|
198
|
+
script.onerror = reject;
|
|
199
|
+
document.body.appendChild(script);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import {deepMerge, wgs84ToGcj02Format} from '../util'
|
|
2
|
+
import Layer from "./layer";
|
|
3
|
+
|
|
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
|
|
15
|
+
}
|
|
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
|
+
|
|
106
|
+
flyTo() {
|
|
107
|
+
this.layerEntity.flyTo()
|
|
108
|
+
}
|
|
109
|
+
|
|
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
|
+
}
|
|
122
|
+
|
|
123
|
+
// 手动打开聚合功能
|
|
124
|
+
openCluster() {
|
|
125
|
+
deepMerge(this.option, {cluster: true,})
|
|
126
|
+
this.config_layer = this.formatConfigLayer(this.option)
|
|
127
|
+
this.layerEntity.clusterEnabled = true
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 手动关闭聚合功能
|
|
131
|
+
closeCluster() {
|
|
132
|
+
deepMerge(this.option, {cluster: false,})
|
|
133
|
+
this.config_layer = this.formatConfigLayer(this.option)
|
|
134
|
+
this.layerEntity.clusterEnabled = false
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
class gaode_class {
|
|
140
|
+
|
|
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
|
|
147
|
+
|
|
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
|
+
}
|
|
154
|
+
|
|
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)
|
|
187
|
+
|
|
188
|
+
}
|
|
189
|
+
|
|
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
|
+
}
|
|
207
|
+
|
|
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
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
destroy() {
|
|
216
|
+
this.layerEntity.setMap(null)
|
|
217
|
+
hnMap.map.layerList = hnMap.map.layerList.filter((v: any) => v.id !== this.id)
|
|
218
|
+
}
|
|
219
|
+
|
|
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
|
+
}
|
|
231
|
+
|
|
232
|
+
// 添加属性弹窗
|
|
233
|
+
addPopupByAttr() {
|
|
234
|
+
if (!this.infoWindow) {
|
|
235
|
+
this.infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});
|
|
236
|
+
}
|
|
237
|
+
|
|
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
|
+
}
|
|
248
|
+
|
|
249
|
+
})
|
|
250
|
+
}
|
|
251
|
+
|
|
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
|
+
})
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const fn:any = {
|
|
272
|
+
mars3d: mars3d_class,
|
|
273
|
+
gaode: gaode_class
|
|
274
|
+
}
|
|
275
|
+
return fn[hnMap.mapType]
|
|
276
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {deepMerge, wgs84ToGcj02Format} from '../util'
|
|
2
|
+
|
|
3
|
+
let baseGeoData: any = {
|
|
4
|
+
type: 'FeatureCollection',
|
|
5
|
+
name: '',
|
|
6
|
+
crs: {},
|
|
7
|
+
features: [
|
|
8
|
+
{
|
|
9
|
+
type: 'Feature',
|
|
10
|
+
properties: {},
|
|
11
|
+
geometry: {
|
|
12
|
+
type: 'MultiPolygon',
|
|
13
|
+
coordinates: [[[]]]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
export default (hnMap: any) => {
|
|
19
|
+
|
|
20
|
+
const defaultOption = {
|
|
21
|
+
id: "",
|
|
22
|
+
data: baseGeoData,
|
|
23
|
+
opacity: 1,
|
|
24
|
+
line: {
|
|
25
|
+
show: true,
|
|
26
|
+
color: "#ff00ff",
|
|
27
|
+
opacity: 1,
|
|
28
|
+
width: 2,
|
|
29
|
+
},
|
|
30
|
+
area: {
|
|
31
|
+
show: false,
|
|
32
|
+
color: "#ffff00",
|
|
33
|
+
opacity: 1,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class mars3d_class {
|
|
38
|
+
type: any = 'geoJson'
|
|
39
|
+
id: any = null
|
|
40
|
+
option: any = JSON.parse(JSON.stringify(defaultOption))
|
|
41
|
+
config: any = null
|
|
42
|
+
layerEntity: any = null
|
|
43
|
+
|
|
44
|
+
constructor(option: any) {
|
|
45
|
+
this.id = option.id
|
|
46
|
+
deepMerge(this.option, option)
|
|
47
|
+
this.config = this.formatConfig(this.option)
|
|
48
|
+
this.layerEntity = new mars3d.layer.GeoJsonLayer(this.config)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
formatConfig(option: any) {
|
|
52
|
+
return {
|
|
53
|
+
name: option.id,
|
|
54
|
+
id: option.id,
|
|
55
|
+
allowDrillPick: true,
|
|
56
|
+
data: option.data,
|
|
57
|
+
symbol: {
|
|
58
|
+
styleOptions: {
|
|
59
|
+
clampToGround: true,
|
|
60
|
+
fill: option.area.show,
|
|
61
|
+
randomColor: !!(option.area.show && option.area.color), // 随机色
|
|
62
|
+
outline: option.line.show,
|
|
63
|
+
opacity: option.opacity,
|
|
64
|
+
outlineStyle: {
|
|
65
|
+
color: option.line.color,
|
|
66
|
+
width: option.line.width,
|
|
67
|
+
opacity: option.line.opacity,
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
// flyTo: true,
|
|
72
|
+
// attr: option.data
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
set(option: any) {
|
|
77
|
+
deepMerge(this.option, option)
|
|
78
|
+
this.config = this.formatConfig(this.option)
|
|
79
|
+
this.layerEntity.setOptions(this.config)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
customStyle(callback: any) {
|
|
83
|
+
this.layerEntity.options.symbol.callback = (attr: any) => {
|
|
84
|
+
return callback(attr)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
destroy() {
|
|
89
|
+
this.layerEntity.remove(true)
|
|
90
|
+
hnMap.map.layerList = hnMap.map.layerList.filter((v: any) => v.id !== this.id)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
setData(data: any) {
|
|
94
|
+
this.layerEntity.loadGeoJSON(data, {clear: true})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
clear() {
|
|
98
|
+
this.layerEntity.clear()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
flyTo() {
|
|
102
|
+
this.layerEntity.flyTo()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 添加属性弹窗
|
|
106
|
+
addPopupByAttr() {
|
|
107
|
+
this.layerEntity.bindPopup((event: any) => {
|
|
108
|
+
if (event.graphic.attr) {
|
|
109
|
+
const data = event.graphic.attr
|
|
110
|
+
return mars3d.Util.getTemplateHtml({title: "详情", template: "all", attr: data})
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 添加自定义dom弹窗
|
|
116
|
+
addCustomPopup(getCustomDom: any) {
|
|
117
|
+
this.layerEntity.bindPopup(async (event: any) => {
|
|
118
|
+
if (event.graphic.attr) {
|
|
119
|
+
const data = event.graphic.attr || {};
|
|
120
|
+
return await getCustomDom(data);
|
|
121
|
+
}
|
|
122
|
+
}, {offsetY: -20});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
class gaode_class {
|
|
128
|
+
|
|
129
|
+
id: any = null
|
|
130
|
+
option: any = JSON.parse(JSON.stringify(defaultOption))
|
|
131
|
+
config: any = null
|
|
132
|
+
layerEntity: any = null
|
|
133
|
+
|
|
134
|
+
constructor(option: any) {
|
|
135
|
+
this.id = option.id
|
|
136
|
+
deepMerge(this.option, option)
|
|
137
|
+
this.config = this.formatConfig(this.option)
|
|
138
|
+
this.layerEntity = new AMap.HeatMap(hnMap.map.map, this.config)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
formatConfig(option: any) {
|
|
142
|
+
const data = option.position.map((v: any) => {
|
|
143
|
+
return {lng: v.lng, lat: v.lat, count: v.value}
|
|
144
|
+
})
|
|
145
|
+
const amapData = wgs84ToGcj02Format(data)
|
|
146
|
+
|
|
147
|
+
return {}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
set(option: any) {
|
|
151
|
+
deepMerge(this.option, option)
|
|
152
|
+
this.config = this.formatConfig(this.option)
|
|
153
|
+
this.layerEntity.setOptions(this.config)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
destroy() {
|
|
157
|
+
this.layerEntity.setMap(null)
|
|
158
|
+
hnMap.map.layerList = hnMap.map.layerList.filter((v: any) => v.id !== this.id)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
flyTo() {
|
|
163
|
+
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const fn: any = {
|
|
169
|
+
mars3d: mars3d_class,
|
|
170
|
+
gaode: gaode_class
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return fn[hnMap.mapType]
|
|
174
|
+
}
|