xy-map 1.0.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/compontents/detail-dialog.vue +141 -0
- package/image/arrow_white.png +0 -0
- package/image/map_end.png +0 -0
- package/image/map_start.png +0 -0
- package/image/marker.png +0 -0
- package/layers/Line.js +175 -0
- package/layers/Point.js +251 -0
- package/layers/Polygon.js +94 -0
- package/layers/Text.js +46 -0
- package/layers/index.js +119 -0
- package/map.js +400 -0
- package/package.json +13 -0
- package/style/hoverHtml.css +29 -0
- package/style/map.css +7 -0
- package/util/mapEvent.js +108 -0
- package/util/mapHoverHtml.js +54 -0
- package/util/mapTools.js +117 -0
- package/util/measure-area.js +215 -0
- package/util/measure-distance.js +600 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import mapSdk from '../map'
|
|
2
|
+
import '../style/hoverHtml.css'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 地图hover、array生成html
|
|
6
|
+
* @param {*} arr = [{
|
|
7
|
+
* label: 名称
|
|
8
|
+
* key: data的属性名
|
|
9
|
+
* dicData: 字典数据、label,value
|
|
10
|
+
* suffixText: 后缀文字
|
|
11
|
+
* customItemClass: 自定义行类型
|
|
12
|
+
* customLabelClass: 自定义label类型
|
|
13
|
+
* customValueClass: 自定义value类名
|
|
14
|
+
* }]
|
|
15
|
+
* @param {*} e mapHover 回调函数返回的值
|
|
16
|
+
* @param {*} beforeHtml: 放到前面的html
|
|
17
|
+
* @param {*} afterHtml: 放到后面的html
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export const mapHoverHtml = (arr, e, beforeHtml, afterHtml) => {
|
|
22
|
+
const data = e.properties
|
|
23
|
+
if (!Array.isArray(arr)) {
|
|
24
|
+
console.error('hover-html:入参异常!')
|
|
25
|
+
console.log(data)
|
|
26
|
+
console.log(arr)
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
if (arr.length === 0) {
|
|
30
|
+
console.error('hover-html:入参数组为空!')
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let html = ''
|
|
35
|
+
let content = []
|
|
36
|
+
if (beforeHtml) html += beforeHtml
|
|
37
|
+
arr.forEach(item => {
|
|
38
|
+
let label = item.label || ''
|
|
39
|
+
let value = data[item.key] || '-'
|
|
40
|
+
if (item.dicData && item.dicData.length > 0) {
|
|
41
|
+
value = item.dicData.find(f => f.value == data[item.key]).label || '-'
|
|
42
|
+
}
|
|
43
|
+
// 是否有后缀
|
|
44
|
+
if (item.suffixText) value += item.suffixText
|
|
45
|
+
content.push(`<p class="hover-item ${item.customItemClass || ''}">
|
|
46
|
+
<span class="label ${item.labelValueClass || ''}">${label}:</span>
|
|
47
|
+
<span class="value ${item.customValueClass || ''}">${value}</span>
|
|
48
|
+
</p>`)
|
|
49
|
+
})
|
|
50
|
+
content.map(m => html += m)
|
|
51
|
+
if (afterHtml) html += afterHtml
|
|
52
|
+
mapSdk.addPopup([e.properties.lgtd, e.properties.lttd], `<div class="xy-hover-html line-height-2">${html}</div>`)
|
|
53
|
+
}
|
|
54
|
+
|
package/util/mapTools.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import mapSdk from '../map'
|
|
2
|
+
import * as turf from '@turf/turf'
|
|
3
|
+
|
|
4
|
+
// 工具
|
|
5
|
+
import {
|
|
6
|
+
measureLineLength,
|
|
7
|
+
closeMeasureLine
|
|
8
|
+
} from './measure-distance.js'
|
|
9
|
+
import {
|
|
10
|
+
measureArea,
|
|
11
|
+
closeMeasureArea
|
|
12
|
+
} from './measure-area.js'
|
|
13
|
+
|
|
14
|
+
// list转geoJson
|
|
15
|
+
export const toGeoJson = (list, type, props = 'position') => {
|
|
16
|
+
let pointsData = list.map((item, index) => {
|
|
17
|
+
return {
|
|
18
|
+
type: 'Feature',
|
|
19
|
+
geometry: {
|
|
20
|
+
type: type,
|
|
21
|
+
coordinates: item[props]
|
|
22
|
+
},
|
|
23
|
+
properties: item
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
let data = {
|
|
28
|
+
type: 'FeatureCollection',
|
|
29
|
+
features: pointsData
|
|
30
|
+
}
|
|
31
|
+
return data
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 测距
|
|
35
|
+
export const ranging = () => {
|
|
36
|
+
let {
|
|
37
|
+
map
|
|
38
|
+
} = mapSdk
|
|
39
|
+
measureLineLength(map)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 测面积
|
|
43
|
+
export const drawArea = () => {
|
|
44
|
+
let {
|
|
45
|
+
map
|
|
46
|
+
} = mapSdk
|
|
47
|
+
measureArea(map)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 清除测量
|
|
51
|
+
export const clearDraw = () => {
|
|
52
|
+
let {
|
|
53
|
+
map
|
|
54
|
+
} = mapSdk
|
|
55
|
+
closeMeasureLine(map)
|
|
56
|
+
closeMeasureArea(map)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 判断点是否在区域内
|
|
60
|
+
export const pointInPolygon = (point, area) => {
|
|
61
|
+
// point = [-77, 44]
|
|
62
|
+
/* area = [
|
|
63
|
+
[
|
|
64
|
+
[-81, 41],
|
|
65
|
+
[-81, 47],
|
|
66
|
+
[-72, 47],
|
|
67
|
+
[-72, 41],
|
|
68
|
+
[-81, 41]
|
|
69
|
+
]
|
|
70
|
+
]*/
|
|
71
|
+
|
|
72
|
+
let pt = turf.point(point)
|
|
73
|
+
let poly = turf.polygon(area)
|
|
74
|
+
return turf.booleanPointInPolygon(pt, poly)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 计算两点间的距离
|
|
78
|
+
export const distance = (fromLngLat, toLngLat) => {
|
|
79
|
+
// from = [-75.343, 39.984]
|
|
80
|
+
// to = [-75.534, 39.123]
|
|
81
|
+
|
|
82
|
+
let from = turf.point(fromLngLat)
|
|
83
|
+
let to = turf.point(toLngLat)
|
|
84
|
+
let distance = turf.distance(from, to, {
|
|
85
|
+
units: 'miles'
|
|
86
|
+
})
|
|
87
|
+
return distance
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 两点间中点坐标
|
|
91
|
+
export const lineCenter = (LngLat1, LngLat2) => {
|
|
92
|
+
// LngLat1 = [-75.343, 39.984]
|
|
93
|
+
// LngLat2 = [-75.534, 39.123]
|
|
94
|
+
|
|
95
|
+
var point1 = turf.point(LngLat1)
|
|
96
|
+
var point2 = turf.point(LngLat2)
|
|
97
|
+
|
|
98
|
+
var midpoint = turf.midpoint(point1, point2)
|
|
99
|
+
return midpoint
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 多边形的中点坐标
|
|
103
|
+
export const polygonCenter = (area) => {
|
|
104
|
+
/* area = [
|
|
105
|
+
[
|
|
106
|
+
[-81, 41],
|
|
107
|
+
[-81, 47],
|
|
108
|
+
[-72, 47],
|
|
109
|
+
[-72, 41],
|
|
110
|
+
[-81, 41]
|
|
111
|
+
]
|
|
112
|
+
]*/
|
|
113
|
+
|
|
114
|
+
let polygon = turf.polygon(area)
|
|
115
|
+
let center = turf.centerOfMass(polygon)
|
|
116
|
+
return center
|
|
117
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import mapboxgl from 'mapbox-gl'
|
|
2
|
+
import * as turf from '@turf/turf'
|
|
3
|
+
|
|
4
|
+
let isMeasure = true // 测面的状态
|
|
5
|
+
let points = []
|
|
6
|
+
let jsonPoint = {
|
|
7
|
+
type: 'FeatureCollection',
|
|
8
|
+
features: []
|
|
9
|
+
}
|
|
10
|
+
let jsonLine = {
|
|
11
|
+
type: 'FeatureCollection',
|
|
12
|
+
features: []
|
|
13
|
+
}
|
|
14
|
+
let measureAreaEle = null
|
|
15
|
+
let tooltip = null
|
|
16
|
+
|
|
17
|
+
let textColor = '#fff'
|
|
18
|
+
let lineColor = '#ff0'
|
|
19
|
+
|
|
20
|
+
// 测面
|
|
21
|
+
export function measureArea(map) {
|
|
22
|
+
clearMeasure(map)
|
|
23
|
+
isMeasure = true
|
|
24
|
+
// 禁止双击缩放
|
|
25
|
+
map.doubleClickZoom.disable()
|
|
26
|
+
map.getCanvas().style.cursor = 'default'
|
|
27
|
+
measureAreaEle = document.createElement('div')
|
|
28
|
+
measureAreaEle.setAttribute('class', 'measure-area-result')
|
|
29
|
+
const option = {
|
|
30
|
+
element: measureAreaEle,
|
|
31
|
+
anchor: 'left',
|
|
32
|
+
offset: [8, 0]
|
|
33
|
+
}
|
|
34
|
+
tooltip = new mapboxgl.Marker(option).setLngLat([0, 0]).addTo(map)
|
|
35
|
+
const source = map.getSource('measure-area-points')
|
|
36
|
+
if (source) {
|
|
37
|
+
map.getSource('measure-area-points').setData(jsonPoint)
|
|
38
|
+
map.getSource('measure-area-line').setData(jsonLine)
|
|
39
|
+
} else {
|
|
40
|
+
map.addSource('measure-area-points', {
|
|
41
|
+
type: 'geojson',
|
|
42
|
+
data: jsonPoint
|
|
43
|
+
})
|
|
44
|
+
map.addSource('measure-area-line', {
|
|
45
|
+
type: 'geojson',
|
|
46
|
+
data: jsonLine
|
|
47
|
+
})
|
|
48
|
+
map.addLayer({
|
|
49
|
+
id: 'measure-area-line',
|
|
50
|
+
type: 'fill',
|
|
51
|
+
source: 'measure-area-line',
|
|
52
|
+
paint: {
|
|
53
|
+
'fill-color': lineColor,
|
|
54
|
+
'fill-opacity': 0.1
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
map.addLayer({
|
|
58
|
+
id: 'line-area-stroke',
|
|
59
|
+
type: 'line',
|
|
60
|
+
source: 'measure-area-line',
|
|
61
|
+
paint: {
|
|
62
|
+
'line-color': lineColor,
|
|
63
|
+
'line-width': 2,
|
|
64
|
+
'line-opacity': 0.65
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
map.addLayer({
|
|
68
|
+
id: 'measure-area-points',
|
|
69
|
+
type: 'circle',
|
|
70
|
+
source: 'measure-area-points',
|
|
71
|
+
paint: {
|
|
72
|
+
'circle-color': textColor,
|
|
73
|
+
'circle-radius': 3,
|
|
74
|
+
'circle-stroke-width': 2,
|
|
75
|
+
'circle-stroke-color': lineColor
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
map.on('click', drawPointHandler)
|
|
81
|
+
map.on('dblclick', drawResultHandler)
|
|
82
|
+
map.on('mousemove', drawMoveHandler)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 获取面积
|
|
86
|
+
function getArea(coords) {
|
|
87
|
+
let pts = points.concat([coords])
|
|
88
|
+
pts = pts.concat([points[0]])
|
|
89
|
+
const polygon = turf.polygon([pts])
|
|
90
|
+
let area = turf.area(polygon)
|
|
91
|
+
if (area < 1000) {
|
|
92
|
+
area = Math.round(area) + 'm²' + ', 双击结束绘制'
|
|
93
|
+
} else {
|
|
94
|
+
area = (area / 1000000).toFixed(4) + 'km²' + ', 双击结束绘制'
|
|
95
|
+
}
|
|
96
|
+
return area
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 绘制测面的点位
|
|
100
|
+
function drawPointHandler(e) {
|
|
101
|
+
if (isMeasure) {
|
|
102
|
+
const coords = [e.lngLat.lng, e.lngLat.lat]
|
|
103
|
+
const map = e.target
|
|
104
|
+
points.push(coords)
|
|
105
|
+
jsonPoint.features.push({
|
|
106
|
+
type: 'Feature',
|
|
107
|
+
geometry: {
|
|
108
|
+
type: 'Point',
|
|
109
|
+
coordinates: coords
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
map.getSource('measure-area-points').setData(jsonPoint)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 绘制显示结果
|
|
117
|
+
function drawResultHandler(e) {
|
|
118
|
+
if (isMeasure) {
|
|
119
|
+
const coords = [e.lngLat.lng, e.lngLat.lat]
|
|
120
|
+
const map = e.target
|
|
121
|
+
points.push(coords)
|
|
122
|
+
isMeasure = false
|
|
123
|
+
measureAreaEle.innerHTML = getArea(coords).split(',')[0]
|
|
124
|
+
tooltip.setLngLat(coords)
|
|
125
|
+
|
|
126
|
+
// 添加关闭按钮
|
|
127
|
+
const _ele = document.createElement('div')
|
|
128
|
+
_ele.setAttribute('class', 'measure-area-result close')
|
|
129
|
+
const option = {
|
|
130
|
+
element: _ele,
|
|
131
|
+
anchor: 'bottom-left',
|
|
132
|
+
offset: [-5, -10]
|
|
133
|
+
}
|
|
134
|
+
_ele.innerHTML = '清除'
|
|
135
|
+
_ele.style.color = '#ccc'
|
|
136
|
+
new mapboxgl.Marker(option).setLngLat(coords).addTo(map)
|
|
137
|
+
_ele.onclick = function (__e) {
|
|
138
|
+
__e.stopPropagation()
|
|
139
|
+
map.doubleClickZoom.enable()
|
|
140
|
+
clearMeasure(map)
|
|
141
|
+
_ele.remove()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 绘制鼠标跟随时的相关内容
|
|
147
|
+
function drawMoveHandler(e) {
|
|
148
|
+
if (isMeasure) {
|
|
149
|
+
const coords = [e.lngLat.lng, e.lngLat.lat]
|
|
150
|
+
const map = e.target
|
|
151
|
+
const len = jsonPoint.features.length
|
|
152
|
+
if (len === 0) {
|
|
153
|
+
measureAreaEle.innerHTML = '点击地图开始测量'
|
|
154
|
+
} else if (len === 1) {
|
|
155
|
+
measureAreaEle.innerHTML = '点击地图继续绘制'
|
|
156
|
+
} else {
|
|
157
|
+
let pts = points.concat([coords])
|
|
158
|
+
pts = pts.concat([points[0]])
|
|
159
|
+
const json = {
|
|
160
|
+
type: 'Feature',
|
|
161
|
+
geometry: {
|
|
162
|
+
type: 'Polygon',
|
|
163
|
+
coordinates: [pts]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
map.getSource('measure-area-line').setData(json)
|
|
168
|
+
measureAreaEle.innerHTML = getArea(coords)
|
|
169
|
+
}
|
|
170
|
+
measureAreaEle.style.color = textColor
|
|
171
|
+
tooltip.setLngLat(coords)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 清除
|
|
176
|
+
function clearMeasure(map) {
|
|
177
|
+
const measureResult = map._container.querySelectorAll('.measure-area-result')
|
|
178
|
+
if (measureResult && measureResult.length > 0) {
|
|
179
|
+
Array.from(measureResult).forEach((m) => {
|
|
180
|
+
m.remove()
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
const json = {
|
|
184
|
+
type: 'FeatureCollection',
|
|
185
|
+
features: []
|
|
186
|
+
}
|
|
187
|
+
const sourceArea = map.getSource('measure-area-points')
|
|
188
|
+
if (sourceArea) {
|
|
189
|
+
map.getSource('measure-area-points').setData(json)
|
|
190
|
+
map.getSource('measure-area-line').setData(json)
|
|
191
|
+
}
|
|
192
|
+
isMeasure = true
|
|
193
|
+
points = []
|
|
194
|
+
jsonPoint = {
|
|
195
|
+
type: 'FeatureCollection',
|
|
196
|
+
features: []
|
|
197
|
+
}
|
|
198
|
+
jsonLine = {
|
|
199
|
+
type: 'FeatureCollection',
|
|
200
|
+
features: []
|
|
201
|
+
}
|
|
202
|
+
measureAreaEle = null
|
|
203
|
+
tooltip = null
|
|
204
|
+
|
|
205
|
+
map.off('click', drawPointHandler)
|
|
206
|
+
map.off('dblclick', drawResultHandler)
|
|
207
|
+
map.off('mousemove', drawMoveHandler)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 关闭测面
|
|
211
|
+
export function closeMeasureArea(map) {
|
|
212
|
+
if (!map) return
|
|
213
|
+
map.doubleClickZoom.enable()
|
|
214
|
+
clearMeasure(map)
|
|
215
|
+
}
|