tdt-map-vue2 0.1.3 → 0.1.5
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 +3 -0
- package/lib/BaseMap.vue +60 -34
- package/lib/utils/controls.js +17 -13
- package/lib/utils/tianDiMapMarker.js +103 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,6 +37,8 @@ Vue.use(TdtMap, {
|
|
|
37
37
|
| viewDatas | array | 否 | [] | 数据,格式同 datas |
|
|
38
38
|
| viewTimer | number | 否 | 800 | 地图视图改变防抖毫秒数 |
|
|
39
39
|
| viewLocation | boolean | 否 | false | changeView 是否携带城市地址信息 |
|
|
40
|
+
| positionControl | boolean | 否 | true | 是否显示缩放平移控件 |
|
|
41
|
+
| zoomControl | boolean | 否 | true | 是否显示地图缩放控件 |
|
|
40
42
|
| tk | string | 否 | - | 天地图 tk |
|
|
41
43
|
| center | number[] | 否 | 杭州经纬度 | 地图 center |
|
|
42
44
|
| zoom | number | 否 | 15 | 地图 zoom |
|
|
@@ -59,6 +61,7 @@ Vue.use(TdtMap, {
|
|
|
59
61
|
| titleKeys | string | 否 | - | 指定 infos 中哪个数据有悬浮 title |
|
|
60
62
|
| infoBtn | {text:'xxx'} | 否 | - | 添加按钮,会触发全局的 mapClick 事件 |
|
|
61
63
|
| labelFn | function | 否 | - | 自定义 Label,返回{content,style,anchor},高优先级 |
|
|
64
|
+
| isCustomMarker | boolean | 否 | - | 是否自定义 marker,默认 false,为 true 时,会使用 initTianDiMapMarker 方法渲染 marker |
|
|
62
65
|
|
|
63
66
|
- labelFn 回调接受两个参数(data, point)。需要返回包含 content(渲染内容)、style(对应样式)、anchor(label 偏移量)的对象
|
|
64
67
|
|
package/lib/BaseMap.vue
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import gcoord from "gcoord";
|
|
10
10
|
import { installTMap } from "./utils/installMap";
|
|
11
11
|
import installControls from "./utils/controls";
|
|
12
|
+
import { initTianDiMapMarker } from "./utils/tianDiMapMarker";
|
|
12
13
|
import markerIcon from "./map1.svg";
|
|
13
14
|
|
|
14
15
|
export default {
|
|
@@ -77,6 +78,16 @@ export default {
|
|
|
77
78
|
type: Number,
|
|
78
79
|
default: 20,
|
|
79
80
|
},
|
|
81
|
+
positionControl: {
|
|
82
|
+
// 是否显示缩放平移控件
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: true,
|
|
85
|
+
},
|
|
86
|
+
zoomControl: {
|
|
87
|
+
// 是否显示比例尺控件
|
|
88
|
+
type: Boolean,
|
|
89
|
+
default: true,
|
|
90
|
+
},
|
|
80
91
|
},
|
|
81
92
|
|
|
82
93
|
data() {
|
|
@@ -170,15 +181,24 @@ export default {
|
|
|
170
181
|
});
|
|
171
182
|
this.map = mapInstance;
|
|
172
183
|
|
|
184
|
+
var globalSw = new TMap.LngLat(-1000, -90); // 全球西南角:西经180,南纬90
|
|
185
|
+
var globalNe = new TMap.LngLat(1000, 90); // 全球东北角:东经180,北纬90
|
|
186
|
+
var globalBounds = new TMap.LngLatBounds(globalSw, globalNe);
|
|
187
|
+
mapInstance.setMaxBounds(globalBounds); // 拖拽超出全球范围会自动弹回
|
|
188
|
+
|
|
189
|
+
// 2. 设置最小缩放等级为3(核心,无法缩放到3级以下)
|
|
190
|
+
mapInstance.setMinZoom(3);
|
|
191
|
+
|
|
173
192
|
const result = this.gcoordTransform(this.center);
|
|
174
193
|
const point = new TMap.LngLat(...result);
|
|
175
194
|
mapInstance.centerAndZoom(point, this.zoom);
|
|
176
195
|
mapInstance.enableScrollWheelZoom();
|
|
177
196
|
mapInstance.enableDoubleClickZoom();
|
|
178
197
|
mapInstance.disableInertia();
|
|
198
|
+
|
|
179
199
|
|
|
180
200
|
// 初始化控制器
|
|
181
|
-
installControls(mapInstance, TMap);
|
|
201
|
+
installControls({map:mapInstance, T:TMap,positionControl:this.positionControl,zoomControl:this.zoomControl});
|
|
182
202
|
mapInstance.addEventListener("click", this.removeRichInfo); // TODO
|
|
183
203
|
this.addEvents();
|
|
184
204
|
this.initAllMarkers(this.datas);
|
|
@@ -226,23 +246,10 @@ export default {
|
|
|
226
246
|
this.ifChangeViewEmit = false;
|
|
227
247
|
|
|
228
248
|
const bounds = this.map.getBounds(); // 获取地图可视区域
|
|
229
|
-
|
|
230
|
-
[bounds.kq.lng, bounds.kq.lat],
|
|
231
|
-
this.coordTrans?.to,
|
|
232
|
-
this.coordTrans?.from
|
|
233
|
-
);
|
|
234
|
-
const [lng_ne, lat_ne] = this.gcoordTransform(
|
|
235
|
-
[bounds.Lq.lng, bounds.Lq.lat],
|
|
236
|
-
this.coordTrans?.to,
|
|
237
|
-
this.coordTrans?.from
|
|
238
|
-
);
|
|
249
|
+
|
|
239
250
|
|
|
240
251
|
this.$emit("changeView", {
|
|
241
|
-
bounds
|
|
242
|
-
...bounds,
|
|
243
|
-
sw: { lng: lng_sw, lat: lat_sw },
|
|
244
|
-
ne: { lng: lng_ne, lat: lat_ne },
|
|
245
|
-
},
|
|
252
|
+
bounds,
|
|
246
253
|
zoom: this.map.getZoom(),
|
|
247
254
|
location,
|
|
248
255
|
});
|
|
@@ -264,6 +271,7 @@ export default {
|
|
|
264
271
|
|
|
265
272
|
// 分批次渲染管线
|
|
266
273
|
renderPipelinesInBatches(lines) {
|
|
274
|
+
console.log("----------renderPipelinesInBatches--------",lines);
|
|
267
275
|
if (!lines || lines.length === 0) return;
|
|
268
276
|
let pipelines = JSON.parse(JSON.stringify(lines));
|
|
269
277
|
this.removeAllPipelines();
|
|
@@ -276,15 +284,7 @@ export default {
|
|
|
276
284
|
);
|
|
277
285
|
const batch = pipelines.slice(batchIndex, endIndex);
|
|
278
286
|
batch.forEach((pipe) => {
|
|
279
|
-
const
|
|
280
|
-
(c) => new this.TMapGL.LngLat(c[0], c[1])
|
|
281
|
-
);
|
|
282
|
-
const polyline = new this.TMapGL.Polyline(lngLatArr, {
|
|
283
|
-
color: pipe.color,
|
|
284
|
-
weight: 3,
|
|
285
|
-
opacity: 0.7,
|
|
286
|
-
lineJoin: "round",
|
|
287
|
-
});
|
|
287
|
+
const polyline = this.getLine(pipe);
|
|
288
288
|
this.map.addOverLay(polyline);
|
|
289
289
|
// 存储管线图层,便于后续操作
|
|
290
290
|
pipe.layer = polyline;
|
|
@@ -295,12 +295,30 @@ export default {
|
|
|
295
295
|
// 异步渲染下一批,避免阻塞主线程
|
|
296
296
|
requestAnimationFrame(renderBatch);
|
|
297
297
|
} else {
|
|
298
|
-
console.log("所有管线渲染完成,总数:", pipelines.length);
|
|
299
|
-
this.$emit("renderLine");
|
|
298
|
+
console.log("所有管线渲染完成,总数:", pipelines.length,pipelines);
|
|
299
|
+
this.$emit("renderLine",this.pipelineLayers);
|
|
300
300
|
}
|
|
301
301
|
};
|
|
302
302
|
renderBatch();
|
|
303
303
|
},
|
|
304
|
+
getLine(pipe) {
|
|
305
|
+
const lngLatArr = pipe.points.map(
|
|
306
|
+
(c) => {
|
|
307
|
+
const coord = this.gcoordTransform(c)
|
|
308
|
+
return new this.TMapGL.LngLat(...coord)
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
console.log('--------getLine------',pipe,lngLatArr);
|
|
312
|
+
|
|
313
|
+
const polyline = new this.TMapGL.Polyline(lngLatArr, pipe.lineOptions);
|
|
314
|
+
polyline.addEventListener("mouseover", (e) => {
|
|
315
|
+
this.$emit("lineMouseover", { line:polyline,data:pipe, e });
|
|
316
|
+
});
|
|
317
|
+
polyline.addEventListener("mouseout", (e) => {
|
|
318
|
+
this.$emit("lineMouseout", { line:polyline,data:pipe, e });
|
|
319
|
+
});
|
|
320
|
+
return polyline;
|
|
321
|
+
},
|
|
304
322
|
|
|
305
323
|
// 清空所有管线
|
|
306
324
|
removeAllPipelines() {
|
|
@@ -362,13 +380,20 @@ export default {
|
|
|
362
380
|
const point = new this.TMapGL.LngLat(...result);
|
|
363
381
|
|
|
364
382
|
if (data.labelFn) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
383
|
+
if(data.isCustomMarker) {
|
|
384
|
+
marker = initTianDiMapMarker({
|
|
385
|
+
map: this.map,
|
|
386
|
+
data,
|
|
387
|
+
point,
|
|
388
|
+
})
|
|
389
|
+
}else {
|
|
390
|
+
const labelRes = data.labelFn(data, point);
|
|
391
|
+
const label = new this.TMapGL.Label({
|
|
392
|
+
text: labelRes.content,
|
|
393
|
+
position: point,
|
|
394
|
+
offset: new this.TMapGL.Point(...(labelRes.anchor || [0, 0])),
|
|
395
|
+
});
|
|
396
|
+
marker = label;}
|
|
372
397
|
} else {
|
|
373
398
|
const icon = new this.TMapGL.Icon({
|
|
374
399
|
iconUrl: data.img || markerIcon,
|
|
@@ -376,6 +401,7 @@ export default {
|
|
|
376
401
|
});
|
|
377
402
|
marker = new this.TMapGL.Marker(point, { icon });
|
|
378
403
|
}
|
|
404
|
+
if(data.noClick) return
|
|
379
405
|
|
|
380
406
|
marker.addEventListener("click", (e) => {
|
|
381
407
|
setTimeout(() => {
|
package/lib/utils/controls.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
export default (map, T) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
scale.
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
export default ({map, T, positionControl = true, zoomControl = true}) => {
|
|
2
|
+
if(positionControl) {
|
|
3
|
+
// 创建缩放平移控件
|
|
4
|
+
const control = new T.Control.Zoom()
|
|
5
|
+
map.addControl(control)
|
|
6
|
+
const controlPosition = window.T_ANCHOR_BOTTOM_RIGHT
|
|
7
|
+
control.setPosition(controlPosition)
|
|
8
|
+
}
|
|
9
|
+
if(zoomControl) {
|
|
10
|
+
// 创建比例尺控件
|
|
11
|
+
const scale = new T.Control.Scale({ position: window.T_ANCHOR_BOTTOM_RIGHT })
|
|
12
|
+
setTimeout(() => {
|
|
13
|
+
scale.setOffset({ x: -60, y: 60 })
|
|
14
|
+
}, 0)
|
|
15
|
+
map.addControl(scale)
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// 天地图自定义覆盖物实现方案
|
|
2
|
+
// 对应百度地图的 BMapGL.CustomOverlay 功能
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 创建天地图自定义覆盖物
|
|
6
|
+
* @param {Object} options - 配置项
|
|
7
|
+
* @param {Object} options.map - 天地图实例
|
|
8
|
+
* @param {Array} options.data - 覆盖物数据
|
|
9
|
+
* @param {Array} options.point - marker坐标
|
|
10
|
+
* @param {Function} options.data.labelFn - 生成DOM的函数
|
|
11
|
+
* @param {Array} options.data.anchor - 锚点偏移量
|
|
12
|
+
* @returns {Object} 自定义覆盖物实例
|
|
13
|
+
*/
|
|
14
|
+
export function initTianDiMapMarker({
|
|
15
|
+
map,
|
|
16
|
+
data,
|
|
17
|
+
point
|
|
18
|
+
}) {
|
|
19
|
+
if (!data.lng || !data.lat) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 创建自定义覆盖物类
|
|
24
|
+
const CustomOverlay = T.Overlay.extend({
|
|
25
|
+
// 初始化方法
|
|
26
|
+
initialize: function(map) {
|
|
27
|
+
console.log("----------initialize----------------",map);
|
|
28
|
+
this.map = map;
|
|
29
|
+
this.lnglat = point;
|
|
30
|
+
this.data = data;
|
|
31
|
+
// return this.onAdd(map);
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
onAdd: function(map) {
|
|
35
|
+
console.log("----------onAdd----------------");
|
|
36
|
+
// 创建DOM元素
|
|
37
|
+
const div = (this._div = document.createElement('div'));
|
|
38
|
+
div.style.position = 'absolute';
|
|
39
|
+
div.style.zIndex = 1000;
|
|
40
|
+
|
|
41
|
+
// 生成自定义DOM内容
|
|
42
|
+
if (this.data.labelFn) {
|
|
43
|
+
const domElement = this.data.labelFn(this.data);
|
|
44
|
+
div.appendChild(domElement);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 添加到覆盖物层
|
|
48
|
+
map.getPanes().overlayPane.appendChild(div);
|
|
49
|
+
|
|
50
|
+
// 执行绘制
|
|
51
|
+
this.update();
|
|
52
|
+
|
|
53
|
+
return div;
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
onRemove: function () {
|
|
57
|
+
console.log("----------onRemove----------------",this._div);
|
|
58
|
+
var parent = this._div.parentNode;
|
|
59
|
+
if (parent) {
|
|
60
|
+
parent.removeChild(this._div);
|
|
61
|
+
this.map = null;
|
|
62
|
+
this._div = null;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// 绘制方法
|
|
67
|
+
update: function() {
|
|
68
|
+
console.log("----------update----------------",this.lnglat,this.data);
|
|
69
|
+
// 获取地理坐标转换为容器像素坐标
|
|
70
|
+
const pixel = this.map.lngLatToLayerPoint(this.lnglat);
|
|
71
|
+
const anchor = this.data.anchor || [0, 0];
|
|
72
|
+
console.log("----------draw----------------",this.lnglat,pixel,anchor);
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// 设置DOM元素位置
|
|
76
|
+
this._div.style.left = (pixel.x + anchor[0]) + 'px';
|
|
77
|
+
this._div.style.top = (pixel.y + anchor[1]) + 'px';
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// 创建自定义覆盖物实例
|
|
82
|
+
const customOverlay = new CustomOverlay(map);
|
|
83
|
+
|
|
84
|
+
return customOverlay;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
// 默认导出
|
|
89
|
+
export default ({
|
|
90
|
+
map,
|
|
91
|
+
data,
|
|
92
|
+
point
|
|
93
|
+
}) => {
|
|
94
|
+
const overlay = initTianDiMapMarker({
|
|
95
|
+
map,
|
|
96
|
+
data,
|
|
97
|
+
point
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
overlay
|
|
102
|
+
};
|
|
103
|
+
};
|