tdt-map-vue2 0.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 +124 -0
- package/index.js +11 -0
- package/lib/BaseMap.vue +440 -0
- package/lib/map1.svg +15 -0
- package/lib/utils/config.js +9 -0
- package/lib/utils/controls.js +14 -0
- package/lib/utils/installMap.js +34 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# tdt-map-vue2
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## 主要功能介绍
|
|
6
|
+
|
|
7
|
+
1. 传入 datas 坐标,可渲染点
|
|
8
|
+
2. 地图渲染完会触发 init 事件,暴露 map 和 BMapGL 两个对象,可在直接操作地图
|
|
9
|
+
3. 地图移动或者 zoom 改变会触发 changeView,监听事件可获取相关地图数据,再从后台重新获取 datas,更新地图点(浏览器变化不会触发 changeView 事件)
|
|
10
|
+
4. 传入 viewDatas 坐标,同样渲染点(与 datas 一起,谁改变,就渲染谁,不会同时渲染),viewDatas 的改变会触发地图视图移动,即会把所有 viewDatas 渲染到视图中
|
|
11
|
+
<!-- 5. 传入 paths 可渲染移动路径 -->
|
|
12
|
+
|
|
13
|
+
## 使用步骤
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
// main.js中引入,并注册
|
|
17
|
+
import TdtMap from "tdt-map-vue2";
|
|
18
|
+
Vue.use(TdtMap, {
|
|
19
|
+
tk: "tk",
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<tdt-map
|
|
25
|
+
style="width:100vw;height:90vh;"
|
|
26
|
+
:datas="datas"
|
|
27
|
+
:viewDatas="viewDatas"
|
|
28
|
+
:imgs="iconImgs"
|
|
29
|
+
@changeView="getNewData"
|
|
30
|
+
/>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## props
|
|
34
|
+
|
|
35
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
36
|
+
| ----------------- | -------------- | ---- | ----------- | ------------------------------------------ |
|
|
37
|
+
| datas | array | 否 | [] | 数据,具体看下面 ☆ |
|
|
38
|
+
| viewDatas | array | 否 | [] | 数据,格式同 datas |
|
|
39
|
+
| viewTimer | number | 否 | 800 | 地图视图改变防抖毫秒数 |
|
|
40
|
+
| viewLocation | boolean | 否 | false | changeView 是否携带城市地址信息 |
|
|
41
|
+
| tk | string | 否 | - | 天地图 tk |
|
|
42
|
+
| center | number[] | 否 | 杭州经纬度 | 地图 center |
|
|
43
|
+
| zoom | number | 否 | 15 | 地图 zoom |
|
|
44
|
+
| mapOptions | object | 否 | - | 百度地图初始化参数 minZoom/maxZoom/mapType |
|
|
45
|
+
| denyRefresh | boolean | 否 | false | 拒绝地图刷新,即地图移动或 zoom 改变不会触发 changeView 事件 |
|
|
46
|
+
| lines | Array | 否 | [] | 线数据{id:1,coords:[[116.397428, 39.90923],[116.397428, 39.90923]]} |
|
|
47
|
+
| coordTrans | Object | 否 | null | 坐标系转换库,传入当前坐标系和目标坐标系{from: 'BD09', to: 'WGS84'}, [坐标系转换](https://www.npmjs.com/package/gcoord) |
|
|
48
|
+
|
|
49
|
+
## datas ☆ 介绍
|
|
50
|
+
|
|
51
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
52
|
+
| --------- | --------------- | ---- | ------ | ----------------------------------------------------- |
|
|
53
|
+
| id | string/number | 是 | - | 唯一标识,用于点清理等工作,必传 |
|
|
54
|
+
| lng | string | 是 | - | 点经度 |
|
|
55
|
+
| lat | string | 是 | - | 点纬度 |
|
|
56
|
+
| img | image | 否 | - | 展示图片 |
|
|
57
|
+
| infos | 二维数组/string | 否 | - | 展示的文字 |
|
|
58
|
+
| icon | index | 否 | - | 根据传入的 imgs,设置每个点的图标,不传则使用百度默认 |
|
|
59
|
+
| noClick | boolean | 否 | - | 不触发点击 marker 事件 |
|
|
60
|
+
| titleKeys | string | 否 | - | 指定 infos 中哪个数据有悬浮 title |
|
|
61
|
+
| infoBtn | {text:'xxx'} | 否 | - | 添加按钮,会触发全局的 mapClick 事件 |
|
|
62
|
+
| labelFn | function | 否 | - | 自定义 Label,返回{content,style,anchor},高优先级 |
|
|
63
|
+
|
|
64
|
+
- labelFn 回调接受两个参数(data, point)。需要返回包含 content(渲染内容)、style(对应样式)、anchor(label 偏移量)的对象
|
|
65
|
+
|
|
66
|
+
例如:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
[
|
|
70
|
+
{
|
|
71
|
+
id: "4968-a081",
|
|
72
|
+
lat: "31.792512",
|
|
73
|
+
lng: "116.829919",
|
|
74
|
+
img: "http://192.168.0.222:10010/static/media/default.jpg",
|
|
75
|
+
infos: [
|
|
76
|
+
["名称", "#次高压4#"],
|
|
77
|
+
["压力", "六安次高压"],
|
|
78
|
+
["标号", "站至合肥新奥啊啊啊啊啊啊啊门站"],
|
|
79
|
+
["标号222", "站至合肥新奥啊啊啊啊啊啊啊门站"],
|
|
80
|
+
],
|
|
81
|
+
icon: 0,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: 2,
|
|
85
|
+
lat: 20,
|
|
86
|
+
lng: 116,
|
|
87
|
+
infos: "将会被渲染成richInfo",
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## emits
|
|
94
|
+
|
|
95
|
+
| 名称 | 说明 |
|
|
96
|
+
| ------------ | ----------------------------------------------------------------------------- |
|
|
97
|
+
| init | 地图初始化后暴露,{ BMapGL, map } |
|
|
98
|
+
| changeView | 地图 zoom 或 center 改变后触发,返回地图数据{bounds:{ne:xxx,sw:xxx},zoom:xxx} |
|
|
99
|
+
| markerClick | 地图上点被点击后触发{ marker, data, e } |
|
|
100
|
+
| renderMarker | 地图上点渲染完后触发 |
|
|
101
|
+
| moveStart | 地图移动开始 |
|
|
102
|
+
| moveEnd | 地图移动结束 |
|
|
103
|
+
| mapClick | 点击地图 |
|
|
104
|
+
| renderLine | 渲染线 |
|
|
105
|
+
|
|
106
|
+
- changeView: 因为 viewDatas 改变导致视图发生改变,不应该触发 changeView,这个时候如果想获取地图视图,建议使用 map.getBounds()和 map.getZoom()手动获取相关数据
|
|
107
|
+
|
|
108
|
+
## 天地图 zoom 大致范围
|
|
109
|
+
|
|
110
|
+
| zoom | 级别 |
|
|
111
|
+
| ------- | -------------------------------- |
|
|
112
|
+
| 16 往上 | 更细节 |
|
|
113
|
+
| 14-15 | 看清居民区、商业区、医院的颜色块 |
|
|
114
|
+
| 12-13 | 市区、城市、地铁线 |
|
|
115
|
+
| 11-12 | 市级,周围市 |
|
|
116
|
+
| 9-10 | 省级,1-2 个省 |
|
|
117
|
+
| 7-8 | 省级,4-5 个省 |
|
|
118
|
+
| 6-7 | 省级,小半个中国 |
|
|
119
|
+
| 4-6 | 基本上整个中国,全球 |
|
|
120
|
+
|
|
121
|
+
## 备注
|
|
122
|
+
|
|
123
|
+
1. `map`, `TMap`: 组件中地图挂载完后,会将暴露这两个对象,可参照[天地图](https://lbsyun.tianditu.gov.cn/index.html)直接操作这两个对象
|
|
124
|
+
2. viewDatas 的用法:在父组件提供 input 搜索框,请求后台得到数据后提交给地图组件,地图组件会依据请求到的数据确定地图中心;地图组件会同时监听 datas,而它们的基本逻辑是(地图 center、zoom 改变会需要得到新的 datas),(viewDatas 改变会得到地图新的 center、zoom)
|
package/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import EnnTMap from './lib/BaseMap.vue'
|
|
2
|
+
import { setTk } from './lib/utils/config'
|
|
3
|
+
|
|
4
|
+
const installTMap = {
|
|
5
|
+
install(app,option) {
|
|
6
|
+
const {tk} = option
|
|
7
|
+
setTk(tk)
|
|
8
|
+
app.component('EnnTMap', EnnTMap)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export { installTMap as default, EnnTMap }
|
package/lib/BaseMap.vue
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="enn-map-box" ref="mapBox">
|
|
3
|
+
<div ref="baseMap" class="enn-base-map"></div>
|
|
4
|
+
<slot></slot>
|
|
5
|
+
</div>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script>
|
|
9
|
+
import gcoord from "gcoord";
|
|
10
|
+
import { installTMap } from "./utils/installMap";
|
|
11
|
+
import installControls from "./utils/controls";
|
|
12
|
+
import markerIcon from "./map1.svg";
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
name: "EnnTMap",
|
|
16
|
+
|
|
17
|
+
props: {
|
|
18
|
+
tk: {
|
|
19
|
+
type: String,
|
|
20
|
+
default: "",
|
|
21
|
+
},
|
|
22
|
+
center: {
|
|
23
|
+
type: Array,
|
|
24
|
+
default: () => ["120.14912421539132", "30.183802187197283"],
|
|
25
|
+
},
|
|
26
|
+
zoom: {
|
|
27
|
+
type: Number,
|
|
28
|
+
default: 15,
|
|
29
|
+
},
|
|
30
|
+
mapOptions: {
|
|
31
|
+
// 地图配置
|
|
32
|
+
type: Object,
|
|
33
|
+
default: () => ({}),
|
|
34
|
+
},
|
|
35
|
+
// markerOptions: {
|
|
36
|
+
// // marker配置
|
|
37
|
+
// type: Object,
|
|
38
|
+
// default: () => ({}),
|
|
39
|
+
// },
|
|
40
|
+
datas: {
|
|
41
|
+
// marker数据
|
|
42
|
+
type: Array,
|
|
43
|
+
default: () => [],
|
|
44
|
+
},
|
|
45
|
+
viewDatas: {
|
|
46
|
+
// 视图数据,变化时重新渲染marker,并改变视野
|
|
47
|
+
type: Array,
|
|
48
|
+
default: () => [],
|
|
49
|
+
},
|
|
50
|
+
viewTimer: {
|
|
51
|
+
// 视图变化时请求接口重新渲染marker的间隔时间(防抖)
|
|
52
|
+
type: Number,
|
|
53
|
+
default: 800,
|
|
54
|
+
},
|
|
55
|
+
viewLocation: {
|
|
56
|
+
// 是否返回城市地址信息
|
|
57
|
+
type: Boolean,
|
|
58
|
+
default: false,
|
|
59
|
+
},
|
|
60
|
+
denyRefresh: {
|
|
61
|
+
// 阻止刷新,用在视野变化时
|
|
62
|
+
type: Boolean,
|
|
63
|
+
default: false,
|
|
64
|
+
},
|
|
65
|
+
coordTrans: {
|
|
66
|
+
// 坐标转换配置{from, to}
|
|
67
|
+
type: Object,
|
|
68
|
+
default: null,
|
|
69
|
+
},
|
|
70
|
+
lines: {
|
|
71
|
+
// 线数据{id,coords:[点集合],color}
|
|
72
|
+
type: Array,
|
|
73
|
+
default: () => [],
|
|
74
|
+
},
|
|
75
|
+
renderBatchLineSize: {
|
|
76
|
+
// 每次渲染的line数量
|
|
77
|
+
type: Number,
|
|
78
|
+
default: 20,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
data() {
|
|
83
|
+
return {
|
|
84
|
+
map: null,
|
|
85
|
+
TMapGL: null,
|
|
86
|
+
MapGeocoder: null,
|
|
87
|
+
markersMap: new Map(),
|
|
88
|
+
ifChangeViewEmit: false,
|
|
89
|
+
changeViewTimer: null,
|
|
90
|
+
followDatas: true,
|
|
91
|
+
pipelineLayers: [], // 存储管线图层引用
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
computed: {
|
|
96
|
+
// 计算属性:判断 gcoord 是否为空对象
|
|
97
|
+
isGcoordEmpty() {
|
|
98
|
+
if (!this.coordTrans) return true;
|
|
99
|
+
return Object.keys(this.coordTrans).length === 0;
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
mounted() {
|
|
104
|
+
console.log("----------initMap----------");
|
|
105
|
+
installTMap(this.initMap, this.tk);
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
beforeDestroy() {
|
|
109
|
+
this.removeAll();
|
|
110
|
+
this.map = null;
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
watch: {
|
|
114
|
+
datas: {
|
|
115
|
+
handler() {
|
|
116
|
+
this.removeAllMarkers();
|
|
117
|
+
this.followDatas = false;
|
|
118
|
+
this.initAllMarkers(this.datas);
|
|
119
|
+
},
|
|
120
|
+
deep: true,
|
|
121
|
+
},
|
|
122
|
+
viewDatas: {
|
|
123
|
+
handler() {
|
|
124
|
+
this.removeEvents();
|
|
125
|
+
this.removeAllMarkers();
|
|
126
|
+
this.followDatas = true;
|
|
127
|
+
this.initAllMarkers(this.viewDatas);
|
|
128
|
+
},
|
|
129
|
+
deep: true,
|
|
130
|
+
},
|
|
131
|
+
lines: {
|
|
132
|
+
handler() {
|
|
133
|
+
console.log("----------props.lines------------");
|
|
134
|
+
|
|
135
|
+
this.removeAllPipelines();
|
|
136
|
+
this.initAllLines(this.lines);
|
|
137
|
+
},
|
|
138
|
+
deep: true,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
methods: {
|
|
143
|
+
// 坐标系转换方法
|
|
144
|
+
gcoordTransform(
|
|
145
|
+
arr,
|
|
146
|
+
from = this.coordTrans?.from,
|
|
147
|
+
to = this.coordTrans?.to
|
|
148
|
+
) {
|
|
149
|
+
return this.isGcoordEmpty
|
|
150
|
+
? arr
|
|
151
|
+
: gcoord.transform(arr, gcoord[from], gcoord[to]);
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
// 初始化地图
|
|
155
|
+
initMap(TMap) {
|
|
156
|
+
this.TMapGL = TMap;
|
|
157
|
+
this.init(TMap);
|
|
158
|
+
if (this.viewLocation) {
|
|
159
|
+
this.MapGeocoder = new TMap.Geocoder();
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
init(TMap) {
|
|
164
|
+
if (this.map) return;
|
|
165
|
+
|
|
166
|
+
const $el = this.$refs.baseMap;
|
|
167
|
+
const mapInstance = new TMap.Map($el, {
|
|
168
|
+
...this.mapOptions,
|
|
169
|
+
});
|
|
170
|
+
this.map = mapInstance;
|
|
171
|
+
|
|
172
|
+
const result = this.gcoordTransform(this.center);
|
|
173
|
+
const point = new TMap.LngLat(...result);
|
|
174
|
+
mapInstance.centerAndZoom(point, this.zoom);
|
|
175
|
+
mapInstance.enableScrollWheelZoom();
|
|
176
|
+
mapInstance.enableDoubleClickZoom();
|
|
177
|
+
mapInstance.disableInertia();
|
|
178
|
+
|
|
179
|
+
// 初始化控制器
|
|
180
|
+
installControls(mapInstance, TMap);
|
|
181
|
+
mapInstance.addEventListener("click", this.removeRichInfo); // TODO
|
|
182
|
+
this.addEvents();
|
|
183
|
+
this.initAllMarkers(this.datas);
|
|
184
|
+
|
|
185
|
+
this.$emit("init", { TMap, map: mapInstance });
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
// 事件监听
|
|
189
|
+
addEvents() {
|
|
190
|
+
if (!this.map) return;
|
|
191
|
+
this.map.addEventListener("movestart", this.removeRichInfo);
|
|
192
|
+
this.map.addEventListener("moveend", this.getMapView);
|
|
193
|
+
this.map.addEventListener("zoomend", this.getMapView);
|
|
194
|
+
this.map.addEventListener("click", this.mapClick);
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
removeEvents() {
|
|
198
|
+
if (!this.map) return;
|
|
199
|
+
this.map.removeEventListener("movestart", this.removeRichInfo);
|
|
200
|
+
this.map.removeEventListener("moveend", this.getMapView);
|
|
201
|
+
this.map.removeEventListener("zoomend", this.getMapView);
|
|
202
|
+
this.map.removeEventListener("click", this.mapClick);
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
mapClick(e) {
|
|
206
|
+
this.$emit("mapClick", e);
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
getMapView() {
|
|
210
|
+
if (this.followDatas || this.denyRefresh) {
|
|
211
|
+
this.$emit("moveEnd");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (this.ifChangeViewEmit) {
|
|
216
|
+
clearTimeout(this.changeViewTimer);
|
|
217
|
+
}
|
|
218
|
+
this.ifChangeViewEmit = true;
|
|
219
|
+
|
|
220
|
+
this.changeViewTimer = setTimeout(async () => {
|
|
221
|
+
let location = null;
|
|
222
|
+
if (this.viewLocation) {
|
|
223
|
+
location = await this.getLocationByCenter();
|
|
224
|
+
}
|
|
225
|
+
this.ifChangeViewEmit = false;
|
|
226
|
+
|
|
227
|
+
const bounds = this.map.getBounds(); // 获取地图可视区域
|
|
228
|
+
const [lng_sw, lat_sw] = this.gcoordTransform(
|
|
229
|
+
[bounds.kq.lng, bounds.kq.lat],
|
|
230
|
+
this.coordTrans?.to,
|
|
231
|
+
this.coordTrans?.from
|
|
232
|
+
);
|
|
233
|
+
const [lng_ne, lat_ne] = this.gcoordTransform(
|
|
234
|
+
[bounds.Lq.lng, bounds.Lq.lat],
|
|
235
|
+
this.coordTrans?.to,
|
|
236
|
+
this.coordTrans?.from
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
this.$emit("changeView", {
|
|
240
|
+
bounds: {
|
|
241
|
+
...bounds,
|
|
242
|
+
sw: { lng: lng_sw, lat: lat_sw },
|
|
243
|
+
ne: { lng: lng_ne, lat: lat_ne },
|
|
244
|
+
},
|
|
245
|
+
zoom: this.map.getZoom(),
|
|
246
|
+
location,
|
|
247
|
+
});
|
|
248
|
+
clearTimeout(this.changeViewTimer);
|
|
249
|
+
}, this.viewTimer || 800);
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
// 逆地址解析
|
|
253
|
+
getLocationByCenter(point) {
|
|
254
|
+
return new Promise((resolve) => {
|
|
255
|
+
this.MapGeocoder.getLocation(
|
|
256
|
+
point || this.map.getCenter(),
|
|
257
|
+
(result) => {
|
|
258
|
+
if (result) resolve(result);
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
});
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
// 分批次渲染管线
|
|
265
|
+
renderPipelinesInBatches(lines) {
|
|
266
|
+
if (!lines || lines.length === 0) return;
|
|
267
|
+
let pipelines = JSON.parse(JSON.stringify(lines));
|
|
268
|
+
this.removeAllPipelines();
|
|
269
|
+
let batchIndex = 0;
|
|
270
|
+
const { renderBatchLineSize } = this;
|
|
271
|
+
const renderBatch = () => {
|
|
272
|
+
const endIndex = Math.min(
|
|
273
|
+
batchIndex + renderBatchLineSize,
|
|
274
|
+
pipelines.length
|
|
275
|
+
);
|
|
276
|
+
const batch = pipelines.slice(batchIndex, endIndex);
|
|
277
|
+
batch.forEach((pipe) => {
|
|
278
|
+
const lngLatArr = pipe.coords.map(
|
|
279
|
+
(c) => new this.TMapGL.LngLat(c[0], c[1])
|
|
280
|
+
);
|
|
281
|
+
const polyline = new this.TMapGL.Polyline(lngLatArr, {
|
|
282
|
+
color: pipe.color,
|
|
283
|
+
weight: 3,
|
|
284
|
+
opacity: 0.7,
|
|
285
|
+
lineJoin: "round",
|
|
286
|
+
});
|
|
287
|
+
this.map.addOverLay(polyline);
|
|
288
|
+
// 存储管线图层,便于后续操作
|
|
289
|
+
pipe.layer = polyline;
|
|
290
|
+
this.pipelineLayers.push(polyline);
|
|
291
|
+
});
|
|
292
|
+
batchIndex = endIndex;
|
|
293
|
+
if (batchIndex < pipelines.length) {
|
|
294
|
+
// 异步渲染下一批,避免阻塞主线程
|
|
295
|
+
requestAnimationFrame(renderBatch);
|
|
296
|
+
} else {
|
|
297
|
+
console.log("所有管线渲染完成,总数:", pipelines.length);
|
|
298
|
+
this.$emit("renderLine");
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
renderBatch();
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
// 清空所有管线
|
|
305
|
+
removeAllPipelines() {
|
|
306
|
+
if (!this.map || this.pipelineLayers.length === 0) return;
|
|
307
|
+
|
|
308
|
+
this.pipelineLayers.forEach((layer) => {
|
|
309
|
+
this.map.removeOverLay(layer);
|
|
310
|
+
});
|
|
311
|
+
this.pipelineLayers = [];
|
|
312
|
+
|
|
313
|
+
// 同时清空管线数据中的图层引用
|
|
314
|
+
if (this.lines && this.lines.length > 0) {
|
|
315
|
+
this.lines.forEach((pipe) => {
|
|
316
|
+
pipe.layer = null;
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
// 线段管理
|
|
322
|
+
initAllLines(lines) {
|
|
323
|
+
console.log("----------渲染管线initAllLines--------");
|
|
324
|
+
|
|
325
|
+
this.renderPipelinesInBatches(lines);
|
|
326
|
+
},
|
|
327
|
+
|
|
328
|
+
// 标记点管理
|
|
329
|
+
initAllMarkers(datas) {
|
|
330
|
+
this.removeAllMarkers();
|
|
331
|
+
const viewPoints = [];
|
|
332
|
+
|
|
333
|
+
datas.forEach((data) => {
|
|
334
|
+
const { marker } = this.getMarker({ data });
|
|
335
|
+
this.markersMap.set(data.id, { marker, show: true });
|
|
336
|
+
this.map.addOverLay(marker);
|
|
337
|
+
|
|
338
|
+
if (this.followDatas) {
|
|
339
|
+
const result = this.gcoordTransform([data.lng, data.lat]);
|
|
340
|
+
viewPoints.push(new this.TMapGL.LngLat(...result));
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
if (this.followDatas && datas.length) {
|
|
345
|
+
this.map.setViewport(viewPoints);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
setTimeout(
|
|
349
|
+
() => {
|
|
350
|
+
this.addEvents();
|
|
351
|
+
this.followDatas = false;
|
|
352
|
+
this.$emit("renderMarker");
|
|
353
|
+
},
|
|
354
|
+
this.followDatas ? 200 : 0
|
|
355
|
+
);
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
getMarker({ data }) {
|
|
359
|
+
let marker = undefined;
|
|
360
|
+
const result = this.gcoordTransform([data.lng, data.lat]);
|
|
361
|
+
const point = new this.TMapGL.LngLat(...result);
|
|
362
|
+
|
|
363
|
+
if (data.labelFn) {
|
|
364
|
+
const labelRes = data.labelFn(data, point);
|
|
365
|
+
const label = new this.TMapGL.Label({
|
|
366
|
+
text: labelRes.content,
|
|
367
|
+
position: point,
|
|
368
|
+
offset: new this.TMapGL.Point(...(labelRes.anchor || [0, 0])),
|
|
369
|
+
});
|
|
370
|
+
marker = label;
|
|
371
|
+
} else {
|
|
372
|
+
const icon = new this.TMapGL.Icon({
|
|
373
|
+
iconUrl: data.img || markerIcon,
|
|
374
|
+
iconSize: new this.TMapGL.Point(38, 54),
|
|
375
|
+
});
|
|
376
|
+
marker = new this.TMapGL.Marker(point, { icon });
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
marker.addEventListener("click", (e) => {
|
|
380
|
+
setTimeout(() => {
|
|
381
|
+
this.$emit("markerClick", { marker, data, e });
|
|
382
|
+
}, 0);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
return { marker };
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
removeAll() {
|
|
389
|
+
if (!this.map) return;
|
|
390
|
+
this.removeRichInfo();
|
|
391
|
+
this.removeAllMarkers();
|
|
392
|
+
this.removeAllPipelines();
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
removeRichInfo() {
|
|
396
|
+
// 清理弹窗信息
|
|
397
|
+
},
|
|
398
|
+
|
|
399
|
+
removeAllMarkers() {
|
|
400
|
+
const markers = [...this.markersMap.values()];
|
|
401
|
+
markers.forEach(({ marker }) => {
|
|
402
|
+
if (this.map) {
|
|
403
|
+
this.map.removeOverLay(marker);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
this.markersMap.clear();
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
};
|
|
410
|
+
</script>
|
|
411
|
+
|
|
412
|
+
<style scoped>
|
|
413
|
+
.enn-map-box {
|
|
414
|
+
width: 100%;
|
|
415
|
+
height: 100%;
|
|
416
|
+
position: relative;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.enn-base-map {
|
|
420
|
+
width: 100%;
|
|
421
|
+
height: 100%;
|
|
422
|
+
}
|
|
423
|
+
</style>
|
|
424
|
+
|
|
425
|
+
<style>
|
|
426
|
+
.tdt-control-copyright {
|
|
427
|
+
opacity: 0;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.tdt-container .tdt-control-copyright {
|
|
431
|
+
opacity: 0;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
html .tdt-label {
|
|
435
|
+
background: transparent;
|
|
436
|
+
padding: 0;
|
|
437
|
+
border: none;
|
|
438
|
+
box-shadow: none;
|
|
439
|
+
}
|
|
440
|
+
</style>
|
package/lib/map1.svg
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="38px" height="48px" viewBox="0 0 38 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
+
<title>编组 5</title>
|
|
4
|
+
<g id="阀门井监测系统" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
5
|
+
<g id="阀门井分布" transform="translate(-2183.000000, -2167.000000)">
|
|
6
|
+
<g id="编组-5" transform="translate(2183.000000, 2167.000000)">
|
|
7
|
+
<g id="编组-7备份">
|
|
8
|
+
<path d="M18.4818857,47.656875 L17.7426857,46.973758 L17.3787429,46.6337661 L17.3787429,46.6337661 L16.6621714,45.9569154 L16.3095429,45.6200566 L16.3095429,45.6200566 L15.6156,44.9494722 L14.9367429,44.2830652 L14.2729714,43.6208357 C13.9592797,43.3052739 13.6507588,42.991144 13.3474086,42.678446 L12.7476025,42.0549591 C12.2535094,41.5369776 11.7737795,41.0229735 11.3084127,40.5129468 L10.7568669,39.902824 C10.6660916,39.801455 10.5758909,39.7002452 10.4862647,39.5991944 L9.95540188,38.994799 C9.86807379,38.8943847 9.78132023,38.7941294 9.6951412,38.6940332 L9.18496133,38.0953653 C8.7655567,37.5980663 8.36051524,37.1047448 7.96983696,36.6154006 L7.50791735,36.0300968 C2.50263912,29.6127554 0,23.8884374 0,18.8571429 C0,8.44263043 8.44263043,0 18.8571429,0 L19.1689802,0.00252631838 C29.4396636,0.169049797 37.7142857,8.54677556 37.7142857,18.8571429 C37.7142857,23.8884374 35.2116466,29.6127554 30.2063684,36.0300968 L29.7444488,36.6154006 C29.3537705,37.1047448 28.948729,37.5980663 28.5293244,38.0953653 L28.0191445,38.6940332 C27.9329655,38.7941294 27.8462119,38.8943847 27.7588838,38.994799 L27.228021,39.5991944 C27.1383948,39.7002452 27.0481941,39.801455 26.9574188,39.902824 L26.405873,40.5129468 C25.9405062,41.0229735 25.4607763,41.5369776 24.9666832,42.0549591 L24.3668771,42.678446 C24.1646436,42.8869114 23.9601121,43.0960131 23.7532824,43.3057512 L23.4413143,43.6208357 L22.7775429,44.2830652 L22.0986857,44.9494722 L21.4047429,45.6200566 L21.0521143,45.9569154 L20.3355429,46.6337661 L19.9716,46.973758 L19.2324,47.656875 L18.8571429,48 L18.4818857,47.656875 Z" id="形状" fill="#E72B00" fill-rule="nonzero"></path>
|
|
9
|
+
<circle id="椭圆形" fill="#FFFFFF" cx="18.8571429" cy="18.8571429" r="15.4285714"></circle>
|
|
10
|
+
</g>
|
|
11
|
+
<path d="M23.5,8 C28.1944204,8 32,11.8055796 32,16.5 C32,21.0016108 28.5006068,24.6858945 24.0737285,24.980943 C22.6048016,27.9547528 19.5412473,30 16,30 C11.0294373,30 7,25.9705627 7,21 C7,16.0294373 11.0294373,12 16,12 C16.0958474,12 16.1913448,12.0014983 16.2864701,12.0044727 C17.7866766,9.59952477 20.4565438,8 23.5,8 Z M11.1649072,21.6543476 L9.76925626,21.6544912 C10.0852398,24.512043 12.3336488,26.7871384 15.1786888,27.1439831 L15.269689,27.1547188 L15.269762,25.7590653 C13.1473373,25.4555191 11.4685225,23.77675 11.1649072,21.6543476 Z M22.1546933,21.6544912 L20.7590424,21.6543476 C20.4595937,23.7476234 18.8224315,25.4093587 16.7413153,25.7457937 L16.6543476,25.7590424 L16.6544912,27.1546933 C19.511967,26.8387182 21.7870174,24.5904205 22.1439546,21.7454879 L22.1546933,21.6544912 Z M16,18.2307692 C14.4705961,18.2307692 13.2307692,19.4705961 13.2307692,21 C13.2307692,22.5294039 14.4705961,23.7692308 16,23.7692308 C17.5294039,23.7692308 18.7692308,22.5294039 18.7692308,21 C18.7692308,19.4705961 17.5294039,18.2307692 16,18.2307692 Z M23.5,9.21428571 C21.1057644,9.21428571 18.9812659,10.3691672 17.6531831,12.1522513 C21.834495,12.9281473 25,16.594402 25,21 C25,21.942477 24.8551312,22.8511182 24.5864468,23.7048702 C28.0947399,23.1809099 30.7857143,20.1547103 30.7857143,16.5 C30.7857143,12.4762111 27.5237889,9.21428571 23.5,9.21428571 Z M16,19.6153846 C16.764702,19.6153846 17.3846154,20.235298 17.3846154,21 C17.3846154,21.764702 16.764702,22.3846154 16,22.3846154 C15.235298,22.3846154 14.6153846,21.764702 14.6153846,21 C14.6153846,20.235298 15.235298,19.6153846 16,19.6153846 Z M16.6544912,14.7692563 L16.6543476,16.1649072 C18.747676,16.4643634 20.4094422,18.1016004 20.745819,20.1827912 L20.7590653,20.269762 L22.1547188,20.269689 C21.8354788,17.381706 19.5424425,15.0886013 16.6544912,14.7692563 Z M15.269689,14.7692308 C12.4120298,15.0851188 10.1368221,17.333571 9.77996684,20.1786864 L9.76923077,20.269689 L11.1648843,20.269762 C11.4642798,18.176359 13.1015462,16.5145171 15.182789,16.1781309 L15.269762,16.1648843 L15.269689,14.7692308 Z" id="形状结合" fill="#E72B00" fill-rule="nonzero"></path>
|
|
12
|
+
</g>
|
|
13
|
+
</g>
|
|
14
|
+
</g>
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export default (map, T) => {
|
|
2
|
+
// 创建缩放平移控件
|
|
3
|
+
const control = new T.Control.Zoom()
|
|
4
|
+
map.addControl(control)
|
|
5
|
+
const controlPosition = window.T_ANCHOR_BOTTOM_RIGHT
|
|
6
|
+
control.setPosition(controlPosition)
|
|
7
|
+
|
|
8
|
+
// 创建比例尺控件
|
|
9
|
+
const scale = new T.Control.Scale({ position: window.T_ANCHOR_BOTTOM_RIGHT })
|
|
10
|
+
setTimeout(() => {
|
|
11
|
+
scale.setOffset({ x: -60, y: 60 })
|
|
12
|
+
}, 0)
|
|
13
|
+
map.addControl(scale)
|
|
14
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getTk } from "./config";
|
|
2
|
+
// 初始化天地图API
|
|
3
|
+
export function installTMap(initMap, tk) {
|
|
4
|
+
getMapScript(tk).then(initMap);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function getMapScript(propsTk) {
|
|
8
|
+
if (!window.T) {
|
|
9
|
+
const tk = propsTk || getTk()
|
|
10
|
+
|
|
11
|
+
window.T = {};
|
|
12
|
+
window.T._preloader = new Promise((resolve) => {
|
|
13
|
+
window._initTMapGL = function () {
|
|
14
|
+
window.document.body.removeChild($script);
|
|
15
|
+
window.T._preloader = null;
|
|
16
|
+
window._initTMapGL = null;
|
|
17
|
+
resolve(window.T);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const $script = document.createElement("script");
|
|
21
|
+
window.document.body.appendChild($script);
|
|
22
|
+
$script.src = `https://api.tianditu.gov.cn/api?v=4.0&tk=${tk}`;
|
|
23
|
+
$script.onload = window._initTMapGL;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return window.T._preloader;
|
|
27
|
+
} else if (!window.T._preloader) {
|
|
28
|
+
return Promise.resolve(window.T);
|
|
29
|
+
} else {
|
|
30
|
+
return window.T._preloader;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default installTMap;
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tdt-map-vue2",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "基于天地图封装的组件",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"serve": "vue-cli-service serve",
|
|
8
|
+
"build": "vue-cli-service build"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"tdt-map",
|
|
12
|
+
"天地图"
|
|
13
|
+
],
|
|
14
|
+
"author": "weiyun",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@babel/core": "^7.12.16",
|
|
18
|
+
"@vue/cli-service": "~5.0.0",
|
|
19
|
+
"@vue/cli-plugin-babel": "~5.0.0",
|
|
20
|
+
"gcoord": "^1.0.7",
|
|
21
|
+
"vue": "^2.6.11",
|
|
22
|
+
"vue-router": "^3.5.3",
|
|
23
|
+
"vue-template-compiler": "^2.6.11"
|
|
24
|
+
}
|
|
25
|
+
}
|