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.
@@ -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
+
@@ -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
+ }