@hzab/map-combine 0.0.1

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +67 -0
  3. package/package.json +56 -0
  4. package/src/assets/Thumbs.db +0 -0
  5. package/src/assets/add.png +0 -0
  6. package/src/assets/point.png +0 -0
  7. package/src/basic/ContextMenu.tsx +49 -0
  8. package/src/basic/MapCombine.ts +67 -0
  9. package/src/basic/MapElement.ts +32 -0
  10. package/src/basic/MapEvent.ts +18 -0
  11. package/src/basic/Point.ts +176 -0
  12. package/src/basic/PointAggregation.tsx +189 -0
  13. package/src/basic/Polygon.ts +180 -0
  14. package/src/basic/Polyline.ts +194 -0
  15. package/src/basic/ReactPoint.tsx +357 -0
  16. package/src/basic/ReactPopup.tsx +34 -0
  17. package/src/basic/Tile3D.ts +99 -0
  18. package/src/cesium/CesiumEvent.ts +86 -0
  19. package/src/cesium/CesiumMap.ts +167 -0
  20. package/src/cesium/CesiumPoint.ts +137 -0
  21. package/src/cesium/CesiumPolygon.ts +368 -0
  22. package/src/cesium/CesiumPolyline.ts +382 -0
  23. package/src/cesium/CesiumTile3D.ts +100 -0
  24. package/src/mine/MineEvent.ts +29 -0
  25. package/src/mine/MineMap.ts +90 -0
  26. package/src/mine/MinePoint.ts +139 -0
  27. package/src/mine/MinePolygon.ts +388 -0
  28. package/src/mine/MinePolyline.ts +359 -0
  29. package/src/mine/MineTile3D.ts +32 -0
  30. package/src/openlayer/OpenlayerEvent.ts +75 -0
  31. package/src/openlayer/OpenlayerMap.ts +149 -0
  32. package/src/openlayer/OpenlayerPoint.ts +177 -0
  33. package/src/openlayer/OpenlayerPolygon.ts +300 -0
  34. package/src/openlayer/OpenlayerPolyline.ts +289 -0
  35. package/src/utils/Image.ts +46 -0
  36. package/src/utils/PolygonEditor.ts +159 -0
  37. package/src/utils/PolylineEditor.ts +149 -0
  38. package/src/utils/Projection.ts +46 -0
  39. package/src/utils/index.ts +131 -0
  40. package/src/utils/static.ts +7 -0
@@ -0,0 +1,177 @@
1
+ import { Point } from "../basic/Point";
2
+ import { OpenlayerMap } from "./OpenlayerMap";
3
+ import Feature from 'ol/Feature.js'
4
+ import OlPoint from 'ol/geom/Point.js'
5
+ import { Icon, Style } from 'ol/style.js'
6
+ import { fromLonLat } from "ol/proj";
7
+ import VectorSource from "ol/source/Vector";
8
+ import VectorLayer from "ol/layer/Vector";
9
+ const RD = 0.017453292519943295
10
+
11
+ export function drawPoint(map: OpenlayerMap, point: Point<unknown>) {
12
+ const { viewer, event } = map
13
+ let status = 0
14
+
15
+ const source = new VectorSource();
16
+ const layer = new VectorLayer({
17
+ source,
18
+ visible: point.show
19
+ })
20
+ viewer.addLayer(layer)
21
+ const feature = new Feature()
22
+ const geometry = new OlPoint([0, 0])
23
+ const style = new Style({
24
+ image: new Icon({
25
+ width: point.size[0],
26
+ height: point.size[1],
27
+ src: point.src,
28
+ rotation: point.rotation * RD,
29
+ anchor: point.center,
30
+ crossOrigin: 'anonymous'
31
+ })
32
+ });
33
+
34
+ const _event = {
35
+ cursor: point.cursor,
36
+ silent: point.silent,
37
+ onPointerIn() {
38
+ point.event.trigger('pointer-in')
39
+ },
40
+ onPointerOut() {
41
+ point.event.trigger('pointer-out')
42
+ },
43
+ onLClick() {
44
+ point.event.trigger('left-click')
45
+ },
46
+ onRClick() {
47
+ point.event.trigger('right-click')
48
+ },
49
+ onPointerDown() {
50
+ if (point.editable && status == 2) {
51
+ status = 3
52
+ map.moveable = false
53
+ }
54
+ },
55
+ onPointerUp() {
56
+ if (point.editable && status == 3) {
57
+ status = 2;
58
+ map.moveable = true;
59
+ point.coordinates = [event.geography[0], event.geography[1], point.height];
60
+ point.event.trigger('data-update')
61
+ }
62
+ }
63
+ }
64
+
65
+ feature.setGeometry(geometry)
66
+ feature.setStyle(style)
67
+ feature.set('event', _event, true)
68
+ if (point.coordinates) {
69
+ status = 2
70
+ geometry.setCoordinates(fromLonLat(point.coordinates))
71
+ layer.setZIndex(point.coordinates[2] ?? 1)
72
+ point.event.trigger('data-loaded')
73
+ source.addFeature(feature)
74
+ }
75
+
76
+
77
+ const onUpdate = (e: Set<string>) => {
78
+ const keys = new Set()
79
+ e.forEach(key => {
80
+ switch (key) {
81
+ case 'show':
82
+ if (status) {
83
+ layer.setVisible(point.show)
84
+ }
85
+ break;
86
+ case 'editable':
87
+ break;
88
+ case 'coordinates':
89
+ if (point.coordinates) {
90
+ geometry.setCoordinates(fromLonLat(point.coordinates))
91
+ layer.setZIndex(point.coordinates[2])
92
+ switch (status) {
93
+ case 0:
94
+ source.addFeature(feature)
95
+ status = 2;
96
+ break;
97
+ case 1:
98
+ status = 2;
99
+ break;
100
+ }
101
+ } else {
102
+ source.removeFeature(feature)
103
+ status = 0
104
+ }
105
+ break;
106
+ case 'src':
107
+ keys.add('icon')
108
+ break;
109
+ case 'size':
110
+ keys.add('icon')
111
+ break;
112
+ case 'center':
113
+ keys.add('icon')
114
+ break;
115
+ case 'rotation':
116
+ keys.add('icon')
117
+ break;
118
+ default:
119
+ throw new Error(`${key} 还不支持修改`)
120
+ }
121
+ })
122
+
123
+ keys.forEach(e => {
124
+ switch (e) {
125
+ case 'icon':
126
+ style.setImage(new Icon({
127
+ width: point.size[0],
128
+ height: point.size[1],
129
+ src: point.src,
130
+ rotation: point.rotation * RD,
131
+ anchor: point.center,
132
+ crossOrigin: 'anonymous'
133
+ }))
134
+ break;
135
+ }
136
+ })
137
+ feature.changed()
138
+ }
139
+
140
+ const onMouseMove = () => {
141
+ const coordinates = [event.geography[0], event.geography[1], point.height]
142
+ switch (status) {
143
+ case 0:
144
+ status = 1
145
+ geometry.setCoordinates(fromLonLat(coordinates))
146
+ source.addFeature(feature)
147
+ break;
148
+ case 1:
149
+ case 3:
150
+ geometry.setCoordinates(fromLonLat(coordinates))
151
+ break
152
+ }
153
+ }
154
+
155
+ const onClick = () => {
156
+ if (status == 1) {
157
+ status = 2
158
+ point.coordinates = [event.geography[0], event.geography[1], point.height];
159
+ point.event.trigger('pointer-in')
160
+ }
161
+ }
162
+
163
+
164
+ const onDestroy = () => {
165
+ source.removeFeature(feature)
166
+ event.off('pointer-move', onMouseMove)
167
+ event.off('left-click', onClick)
168
+ point.event.off('update', onUpdate)
169
+ point.event.off('destroy', onDestroy)
170
+
171
+ }
172
+
173
+ event.on('pointer-move', onMouseMove)
174
+ event.on('left-click', onClick)
175
+ point.event.on('update', onUpdate)
176
+ point.event.on('destroy', onDestroy)
177
+ }
@@ -0,0 +1,300 @@
1
+
2
+ import { OpenlayerMap } from "./OpenlayerMap";
3
+ import Feature from 'ol/Feature.js'
4
+ import OlPolygon from 'ol/geom/Polygon.js'
5
+ import { Icon, Fill, Stroke, Style } from 'ol/style.js'
6
+ import { fromLonLat, toLonLat } from "ol/proj";
7
+ import { Polygon } from "../basic/Polygon";
8
+ import VectorSource from "ol/source/Vector";
9
+ import VectorLayer from "ol/layer/Vector";
10
+ import iconPoint from '../assets/point.png'
11
+ import iconAdd from '../assets/add.png'
12
+ import Point from 'ol/geom/Point.js'
13
+ import { ChainNode, PolygonEditor } from "../utils/PolygonEditor";
14
+ const styleNode = new Style({
15
+ image: new Icon({
16
+ width: 16,
17
+ height: 16,
18
+ src: iconPoint,
19
+ crossOrigin: 'anonymous'
20
+ })
21
+ });
22
+
23
+ const styleVirtual = new Style({
24
+ image: new Icon({
25
+ width: 16,
26
+ height: 16,
27
+ src: iconAdd,
28
+ crossOrigin: 'anonymous'
29
+ })
30
+ });
31
+
32
+
33
+
34
+
35
+
36
+ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
37
+ const { event, viewer, vectors } = map
38
+
39
+ const source = new VectorSource();
40
+
41
+ const layer = new VectorLayer({
42
+ source,
43
+ visible: polygon.show
44
+ })
45
+ viewer.addLayer(layer)
46
+
47
+ let status = 0
48
+ let skip = 0
49
+
50
+ const feature = new Feature()
51
+ const geometry = new OlPolygon([[[0, 0], [0, 0]]])
52
+ const fill = new Fill({
53
+ color: polygon.fill
54
+ })
55
+ const stroke = new Stroke({
56
+ color: polygon.stroke,
57
+ width: polygon.lineWidth,
58
+ lineDash: polygon.dash ? [10, 10] : undefined,
59
+ })
60
+ const style = new Style({
61
+ zIndex: 50,
62
+ stroke,
63
+ fill
64
+ })
65
+
66
+ const _event = {
67
+ cursor: polygon.cursor,
68
+ silent: polygon.silent,
69
+ onPointerIn() {
70
+ status == 2 && polygon.event.trigger('pointer-in')
71
+ },
72
+ onPointerOut() {
73
+ status == 2 && polygon.event.trigger('pointer-out')
74
+ },
75
+ onLClick() {
76
+ status == 2 && polygon.event.trigger('left-click')
77
+ },
78
+ onRClick() {
79
+ if (polygon.menu) {
80
+ map.menu.show(polygon.menu);
81
+ }
82
+ status == 2 && polygon.event.trigger('right-click')
83
+ },
84
+ onDbClick() {
85
+ polygon.editable && status == 2 && setTimeout(() => {
86
+ polygon.event.trigger('start-edit')
87
+ });
88
+ }
89
+ }
90
+
91
+ feature.setGeometry(geometry)
92
+ feature.setStyle(style)
93
+ feature.set('event', _event, true)
94
+ if (polygon.coordinates) {
95
+ status = 2
96
+ geometry.setCoordinates([polygon.coordinates.map(e => fromLonLat(e))])
97
+ layer.setZIndex(polygon.coordinates[0][2] ?? 1)
98
+ source.addFeature(feature)
99
+ }
100
+
101
+
102
+
103
+
104
+ const onUpdate = (e: Set<string>) => {
105
+ if (skip) {
106
+ skip--
107
+ return
108
+ }
109
+
110
+ e.forEach(key => {
111
+ switch (key) {
112
+ case 'show':
113
+ layer.setVisible(polygon.show)
114
+ break;
115
+ case 'editable':
116
+ break;
117
+ case 'coordinates':
118
+ if (polygon.coordinates) {
119
+ geometry.setCoordinates([polygon.coordinates.map(e => fromLonLat(e))])
120
+ layer.setZIndex(polygon.coordinates[0][2] ?? 1)
121
+ switch (status) {
122
+ case 0:
123
+ source.addFeature(feature)
124
+ status = 2;
125
+ break;
126
+ case 1:
127
+ status = 2;
128
+ break;
129
+ }
130
+ } else {
131
+ source.removeFeature(feature)
132
+ status == 3 && editor.setCoordinates([])
133
+ status = 0
134
+ }
135
+ break;
136
+ case 'lineWidth':
137
+ stroke.setWidth(polygon.lineWidth)
138
+ break;
139
+ case 'stroke':
140
+ stroke.setColor(polygon.stroke)
141
+ break;
142
+ case 'dash':
143
+ stroke.setLineDash(polygon.dash ? [10, 10] : undefined)
144
+ break;
145
+ case 'fill':
146
+ fill.setColor(polygon.fill)
147
+ break;
148
+ default:
149
+ throw new Error(`${key} 还不支持修改`)
150
+ }
151
+ })
152
+
153
+ feature.changed()
154
+ }
155
+ let cache = [[0]]
156
+ let activeNode: ChainNode<Feature, Feature>
157
+ const onMouseMove = () => {
158
+ switch (status) {
159
+ case 1:
160
+ cache.pop()
161
+ cache.push(fromLonLat(event.geography))
162
+ geometry.setCoordinates([cache])
163
+ break
164
+ case 4:
165
+ activeNode.update(fromLonLat(event.geography))
166
+ geometry.setCoordinates([editor.getCoordinates()])
167
+ break;
168
+ }
169
+ }
170
+
171
+ const onClick = () => {
172
+ switch (status) {
173
+ case 0:
174
+ status = 1
175
+
176
+ cache = [fromLonLat(event.geography)]
177
+ cache.push(cache[0])
178
+ geometry.setCoordinates([cache])
179
+ source.addFeature(feature)
180
+ break;
181
+ case 1:
182
+ cache.push(cache[cache.length - 1])
183
+ geometry.setCoordinates([cache])
184
+ break
185
+ }
186
+ }
187
+
188
+ const onDbClick = () => {
189
+ switch (status) {
190
+ case 1:
191
+ status = 2
192
+ skip++
193
+ cache.pop()
194
+ cache.pop()
195
+ geometry.setCoordinates([cache])
196
+ polygon.coordinates = cache.map(e => toLonLat(e))
197
+ polygon.event.trigger('data-loaded')
198
+ polygon.event.trigger('pointer-in')
199
+ break
200
+ case 3:
201
+ polygon.event.trigger('stop-edit')
202
+ break
203
+ }
204
+ }
205
+
206
+ const editor = new PolygonEditor<Feature<Point>, Feature<Point>>()
207
+
208
+ editor.on('create-node', (n) => {
209
+ if (n.type == 'node') {
210
+ const feature = new Feature(new Point(n.position))
211
+ feature.setStyle(styleNode)
212
+ feature.set('event', {
213
+ cursor: 'move',
214
+ onPointerDown() {
215
+ status = 4
216
+ activeNode = n
217
+ map.moveable = false
218
+ },
219
+ onPointerUp() {
220
+ if (status == 4) {
221
+ status = 3
222
+ map.moveable = true
223
+ activeNode = undefined
224
+ }
225
+ },
226
+ onDbClick() {
227
+ n.destroy()
228
+ geometry.setCoordinates([editor.getCoordinates()])
229
+ }
230
+ }, true)
231
+ source.addFeature(feature)
232
+ n.shape = feature
233
+ } else {
234
+ const feature = new Feature(new Point(n.position))
235
+ feature.setStyle(styleVirtual)
236
+ feature.set('event', {
237
+ cursor: 'pointer',
238
+ onPointerDown() {
239
+ status = 4
240
+ activeNode = n.insert()
241
+ map.cursor = 'move'
242
+ map.moveable = false
243
+ },
244
+ }, true)
245
+ source.addFeature(feature)
246
+ n.shape = feature
247
+ }
248
+ })
249
+ editor.on('update-node', (n) => {
250
+ n.shape.getGeometry().setCoordinates(n.position)
251
+ })
252
+ editor.on('remove-node', (n) => {
253
+ source.removeFeature(n.shape)
254
+ })
255
+ editor.on('empty', () => {
256
+ source.removeFeature(feature)
257
+ status = 0
258
+ })
259
+ const onStartEdit = () => {
260
+ switch (status) {
261
+ case 2:
262
+ status = 3
263
+ editor.setCoordinates(geometry.getCoordinates()[0])
264
+ break
265
+ }
266
+
267
+ }
268
+
269
+ const onStopEdit = () => {
270
+ if (status == 3) {
271
+ status = 2
272
+ skip++
273
+ polygon.coordinates = editor.getCoordinates().map(e => toLonLat(e))
274
+ editor.setCoordinates([])
275
+ polygon.event.trigger('pointer-in')
276
+ }
277
+
278
+ }
279
+
280
+
281
+ const onDestroy = () => {
282
+ viewer.removeLayer(layer)
283
+ event.off('pointer-move', onMouseMove)
284
+ event.off('left-click', onClick)
285
+ event.off('double-click', onDbClick)
286
+ polygon.event.off('update', onUpdate)
287
+ polygon.event.off('start-edit', onStartEdit)
288
+ polygon.event.off('stop-edit', onStopEdit)
289
+ polygon.event.off('destroy', onDestroy)
290
+
291
+ }
292
+
293
+ event.on('pointer-move', onMouseMove)
294
+ event.on('left-click', onClick)
295
+ event.on('double-click', onDbClick)
296
+ polygon.event.on('update', onUpdate)
297
+ polygon.event.on('start-edit', onStartEdit)
298
+ polygon.event.on('stop-edit', onStopEdit)
299
+ polygon.event.on('destroy', onDestroy)
300
+ }