@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,34 @@
1
+ import { ReactElement } from "react";
2
+ import ReactDOM from "react-dom";
3
+
4
+
5
+ export interface ReactPopupOption {
6
+ /** 弹框内容 */
7
+ element: ReactElement;
8
+ /** 层高 */
9
+ zIndex?: number;
10
+ }
11
+
12
+ export class ReactPopup {
13
+ private dom: HTMLDivElement;
14
+ option: ReactPopupOption;
15
+ node: HTMLDivElement;
16
+ constructor(map, option: ReactPopupOption = {
17
+ element: <></>,
18
+ zIndex: 10
19
+ }) {
20
+ this.dom = document.createElement("div");
21
+ this.option = option;
22
+ const coordinate = map.geographyTcanvas(map.event.geography)
23
+ this.dom.style.position = "absolute";
24
+ this.dom.style.top = coordinate[1] + "px";
25
+ this.dom.style.left = coordinate[0] + "px";
26
+ map.container.appendChild(this.dom);
27
+ ReactDOM.render(option.element ?? <></>, this.dom);
28
+ }
29
+
30
+ destroy() {
31
+ this.dom.remove();
32
+ ReactDOM.unmountComponentAtNode(this.dom);
33
+ }
34
+ }
@@ -0,0 +1,99 @@
1
+ import Eventful from "zrender/lib/core/Eventful"
2
+
3
+ import { MapElement, MapElementOption } from "./MapElement"
4
+ import { MapCombine } from "./MapCombine"
5
+
6
+ export interface Tile3DOption extends MapElementOption {
7
+ show: boolean
8
+ src: string
9
+ coordinates?: number[]
10
+ quality: number
11
+ }
12
+
13
+ export class Tile3D extends MapElement<Tile3DOption>{
14
+ type = 'Tile3D'
15
+ event = new Eventful<{
16
+ 'ready': () => void
17
+ 'update': (keys: Set<string>) => void
18
+ 'destroy': () => void
19
+ 'focus': () => void
20
+ }>()
21
+
22
+ get show() {
23
+ return this._option.show
24
+ }
25
+
26
+ set show(val) {
27
+ if (this._option.show != val) {
28
+ this._option.show = val
29
+ this._update('show')
30
+ }
31
+ }
32
+
33
+ get src() {
34
+ return this._option.src
35
+ }
36
+
37
+ set src(val) {
38
+ if (this._option.src != val) {
39
+ this._option.src = val
40
+ this._update('src')
41
+ }
42
+ }
43
+
44
+ get coordinates() {
45
+ return this._option.coordinates
46
+ }
47
+
48
+ set coordinates(val) {
49
+ if (this._option.coordinates != val) {
50
+ this._option.coordinates = val
51
+ this._update('coordinates')
52
+ }
53
+ }
54
+
55
+ get quality() {
56
+ return this._option.quality
57
+ }
58
+
59
+ set quality(val) {
60
+ if (this._option.quality != val) {
61
+ this._option.quality = val
62
+ this._update('quality')
63
+ }
64
+ }
65
+
66
+
67
+
68
+ constructor(map: MapCombine, option: Partial<Tile3DOption> = {}) {
69
+ super(map, Object.assign({ ...Tile3D.option }, option))
70
+ }
71
+
72
+ static option: Tile3DOption = {
73
+ name: '3D瓦片',
74
+ show: true,
75
+ src: '',
76
+ quality: 0.5
77
+ }
78
+
79
+ private _needUpdate?: Set<string>
80
+ private _update(key: string) {
81
+ if (this._needUpdate) {
82
+ this._needUpdate.add(key)
83
+ } else {
84
+ this._needUpdate = new Set([key])
85
+ setTimeout(() => {
86
+ this.event.trigger('update', this._needUpdate)
87
+ this._needUpdate = undefined
88
+ });
89
+ }
90
+ }
91
+
92
+ protected _onDestroy(): void {
93
+ this.event.trigger('destroy')
94
+ }
95
+
96
+ focus() {
97
+ this.event.trigger('focus')
98
+ }
99
+ }
@@ -0,0 +1,86 @@
1
+ import { CesiumMap } from "./CesiumMap"
2
+
3
+ export function bindEvent(map: CesiumMap) {
4
+ const { event, viewer, container } = map
5
+ viewer.camera.percentageChanged = 0.0001;
6
+ viewer.camera.changed.addEventListener(() => {
7
+ event.trigger('view-change')
8
+ });
9
+ viewer.camera.moveEnd.addEventListener(() => {
10
+ event.trigger('view-moveEnd')
11
+ });
12
+ const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
13
+ let target: any;
14
+ handler.setInputAction((e: any) => {
15
+ event.canvas = [e.endPosition.x, e.endPosition.y];
16
+ event.geography = map.canvasTgeography(event.canvas);
17
+ let _target: any = undefined
18
+ const res = viewer.scene.pick(e.endPosition);
19
+ const a = res
20
+ ? res.id
21
+ ? res.id
22
+ : res.primitive
23
+ ? res.primitive
24
+ : undefined
25
+ : undefined;
26
+
27
+ if (a && !a.silent) {
28
+ _target = a;
29
+ }
30
+ if (_target !== target) {
31
+ target?.onPointerOut?.();
32
+ _target?.onPointerIn?.();
33
+ target = _target;
34
+ }
35
+
36
+ if (target) {
37
+ map.cursor = target.cursor;
38
+ } else {
39
+ map.cursor = "";
40
+ }
41
+ event.trigger('pointer-move')
42
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
43
+
44
+ handler.setInputAction(() => {
45
+ if (target) {
46
+ target.onPointerDown?.();
47
+ }
48
+ event.trigger('pointer-down')
49
+ }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
50
+
51
+
52
+ container.addEventListener('pointerup', () => {
53
+ if (target) {
54
+ target.onPointerUp?.();
55
+ }
56
+ event.trigger('pointer-up')
57
+ })
58
+
59
+
60
+ handler.setInputAction((e) => {
61
+ console.log('e', e);
62
+
63
+ if (target) {
64
+ target.onLClick?.();
65
+ }
66
+ event.trigger('left-click')
67
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
68
+ handler.setInputAction(() => {
69
+ if (target) {
70
+ target.onRClick?.();
71
+ }
72
+ event.trigger('right-click')
73
+ }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
74
+
75
+ handler.setInputAction(() => {
76
+ if (target) {
77
+ target.onDbClick?.();
78
+ }
79
+ event.trigger('double-click')
80
+ }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
81
+
82
+ event.on('destroy', () => {
83
+ viewer.destroy()
84
+ })
85
+
86
+ }
@@ -0,0 +1,167 @@
1
+
2
+ import { MapCombine } from "../basic/MapCombine";
3
+ import { PointOption, Point } from "../basic/Point";
4
+ import { PolygonOption, Polygon } from "../basic/Polygon";
5
+ import { PolylineOption, Polyline } from "../basic/Polyline";
6
+ import { Tile3DOption, Tile3D } from "../basic/Tile3D";
7
+ import { bindEvent } from "./CesiumEvent";
8
+ import { drawPoint } from "./CesiumPoint";
9
+ import { drawPolygon } from "./CesiumPolygon";
10
+ import { drawPolyline } from "./CesiumPolyline";
11
+ import { drawTile3D } from "./CesiumTile3D";
12
+
13
+ const $m = 20037508.34278924;
14
+
15
+ export class CesiumMap extends MapCombine {
16
+
17
+ viewer: any;
18
+ markers: any;
19
+
20
+ container: HTMLDivElement;
21
+
22
+
23
+
24
+ get cursor(): string {
25
+ return (this.container).style.cursor
26
+ }
27
+ set cursor(val: string) {
28
+ (this.container).style.cursor = val
29
+ }
30
+
31
+ get moveable(): boolean {
32
+ return this.viewer.scene.screenSpaceCameraController.enableRotate;
33
+ }
34
+ set moveable(val: boolean) {
35
+ this.viewer.scene.screenSpaceCameraController.enableRotate = val;
36
+ }
37
+ get center(): number[] {
38
+ const { viewer, container } = this;
39
+ const width = container.offsetWidth;
40
+ const height = container.offsetHeight;
41
+ const position = viewer.scene.camera.pickEllipsoid(
42
+ new Cesium.Cartesian2(width / 2, height / 2),
43
+ viewer.scene.globe.ellipsoid
44
+ );
45
+ const cartographic = Cesium.Cartographic.fromCartesian(position);
46
+ return [
47
+ Cesium.Math.toDegrees(cartographic.longitude),
48
+ Cesium.Math.toDegrees(cartographic.latitude),
49
+ ]
50
+ }
51
+ set center(val: number[]) {
52
+ const { viewer, container } = this;
53
+ const width = container.offsetWidth;
54
+ const height = container.offsetHeight;
55
+ const position = viewer.scene.camera.pickEllipsoid(
56
+ new Cesium.Cartesian2(width / 2, height / 2),
57
+ viewer.scene.globe.ellipsoid
58
+ );
59
+ const target = Cesium.Cartesian3.fromDegrees(...val)
60
+ Cesium.Cartesian3.subtract(target, position, target)
61
+ Cesium.Cartesian3.add(this.viewer.camera.position, target, this.viewer.camera.position)
62
+ }
63
+
64
+ get zoom(): number {
65
+ const cartographic = Cesium.Cartographic.fromCartesian(this.viewer.camera.position)
66
+ return this.distanceTzoom(cartographic.height)
67
+ }
68
+ set zoom(val: number) {
69
+
70
+ const cartographic = Cesium.Cartographic.fromCartesian(this.viewer.camera.position)
71
+ cartographic.height = this.zoomTdistance(val)
72
+ this.viewer.camera.position = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height)
73
+ }
74
+
75
+ fov = 0.9695385667699215;
76
+ distanceTzoom(distance: number) {
77
+ const height = this.container.offsetHeight;
78
+ return Math.log2(($m * height) / (256 * Math.tan(this.fov / 2) * distance));
79
+ }
80
+ zoomTdistance(zoom: number): number {
81
+ const height = this.container.offsetHeight;
82
+ return ($m * height) / (256 * Math.tan(this.fov / 2) * Math.pow(2, zoom));
83
+ }
84
+
85
+ constructor(viewer: any) {
86
+ super()
87
+ this.viewer = viewer
88
+ this.container = viewer.container
89
+ this.container.appendChild(this.htmllayer)
90
+ this.cursor = 'default'
91
+ this.markers = this.viewer.scene.primitives.add(
92
+ new Cesium.BillboardCollection()
93
+ );
94
+ bindEvent(this)
95
+
96
+ }
97
+
98
+ getView() {
99
+ const { camera } = this.viewer
100
+ return [
101
+ camera.position.x, camera.position.y, camera.position.z,
102
+ camera.heading, camera.pitch, camera.roll,
103
+ ]
104
+ }
105
+
106
+ setView(e: number[]) {
107
+ const { camera } = this.viewer
108
+ camera.setView({
109
+ destination: new Cesium.Cartesian3(e[0], e[1], e[2]),
110
+ orientation: new Cesium.HeadingPitchRoll(e[3], e[4], e[5])
111
+ });
112
+ }
113
+
114
+ createPoint<K>(option?: Partial<PointOption<K>>): Point<K> {
115
+ const e = new Point(this, option)
116
+ drawPoint(this, e)
117
+ return e
118
+ }
119
+
120
+ createPolyline<K>(option?: Partial<PolylineOption<K>>): Polyline<K> {
121
+ const e = new Polyline(this, option)
122
+ drawPolyline(this, e)
123
+ return e
124
+ }
125
+
126
+ createPolygon<K>(option?: Partial<PolygonOption<K>>): Polygon<K> {
127
+ const e = new Polygon(this, option)
128
+ drawPolygon(this, e)
129
+ return e
130
+ }
131
+
132
+ createTile3D(option?: Partial<Tile3DOption>): Tile3D {
133
+ const e = new Tile3D(this, option)
134
+ drawTile3D(this, e)
135
+ return e
136
+ }
137
+
138
+ canvasTgeography(p: number[]): number[] {
139
+ const { viewer } = this;
140
+ const cartesian2 = new Cesium.Cartesian2(...p);
141
+ const ray = viewer.camera.getPickRay(cartesian2);
142
+ const cartesian = viewer.scene.globe.pick(ray, viewer.scene);
143
+
144
+ if (cartesian) {
145
+ const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
146
+ return [
147
+ Cesium.Math.toDegrees(cartographic.longitude),
148
+ Cesium.Math.toDegrees(cartographic.latitude),
149
+ cartographic.height,
150
+ ];
151
+ } else {
152
+ return [0, 0, 0];
153
+ }
154
+ }
155
+ geographyTcanvas(p: number[]): number[] {
156
+ const res = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, Cesium.Cartesian3.fromDegrees(...p));
157
+ if (!res) {
158
+ return [-1, -1];
159
+ }
160
+ return [res.x, res.y];
161
+ }
162
+
163
+
164
+
165
+
166
+ }
167
+
@@ -0,0 +1,137 @@
1
+
2
+ import { Point } from "../basic/Point";
3
+ import { CesiumMap } from "./CesiumMap";
4
+
5
+
6
+ export function drawPoint(map: CesiumMap, point: Point<unknown>) {
7
+ const { markers, event } = map
8
+ const { size, center } = point
9
+ let status = 0
10
+ let skip = 0
11
+ const shape = markers.add({
12
+ show: false,
13
+ position: Cesium.Cartesian3.ZERO,
14
+ pixelOffset: new Cesium.Cartesian2(-size[0] * (center[0] - 0.5), -size[1] * (center[1] - 0.5)),
15
+ width: size[0],
16
+ height: size[1],
17
+ image: point.src,
18
+ rotation: point.rotation,
19
+ id: {
20
+ cursor: point.cursor,
21
+ silent: point.silent,
22
+ onPointerIn() {
23
+ status == 2 && point.event.trigger('pointer-in')
24
+ },
25
+ onPointerOut() {
26
+
27
+ status == 2 && point.event.trigger('pointer-out')
28
+ },
29
+ onLClick() {
30
+ status == 2 && point.event.trigger('left-click')
31
+ },
32
+ onRClick() {
33
+ status == 2 && point.event.trigger('right-click')
34
+ },
35
+ onPointerDown() {
36
+ if (point.editable && status == 2) {
37
+ status = 3
38
+ map.moveable = false
39
+ }
40
+
41
+ },
42
+ onPointerUp() {
43
+ if (point.editable && status == 3) {
44
+ status = 2
45
+ map.moveable = true
46
+ }
47
+ }
48
+ }
49
+ })
50
+
51
+ if (point.coordinates) {
52
+ status = 2
53
+ shape.position = Cesium.Cartesian3.fromDegrees(...point.coordinates)
54
+ shape.show = point.show
55
+ }
56
+
57
+ const onMouseMove = () => {
58
+ switch (status) {
59
+ case 0:
60
+ status = 1
61
+ shape.position = Cesium.Cartesian3.fromDegrees(...event.geography)
62
+ shape.show = point.show
63
+ break;
64
+ case 1:
65
+ case 3:
66
+ shape.position = Cesium.Cartesian3.fromDegrees(...event.geography)
67
+ break
68
+ }
69
+ }
70
+
71
+ const onClick = () => {
72
+ if (status == 1) {
73
+ status = 2
74
+ skip++
75
+ point.coordinates = event.geography
76
+ point.event.trigger('pointer-in')
77
+ }
78
+ }
79
+
80
+ const onUpdate = (e: Set<string>) => {
81
+ if (skip) {
82
+ skip--
83
+ return
84
+ }
85
+ const { size, center } = point
86
+ e.forEach(key => {
87
+ switch (key) {
88
+ case 'show':
89
+ shape.show = point.show
90
+ break;
91
+ case 'editable':
92
+ break;
93
+ case 'coordinates':
94
+ if (point.coordinates) {
95
+ shape.position = Cesium.Cartesian3.fromDegrees(...point.coordinates)
96
+ shape.show = point.show
97
+ status = 2;
98
+ } else {
99
+ shape.show = false
100
+ status = 0
101
+ }
102
+
103
+ break;
104
+ case 'src':
105
+ shape.image = point.src
106
+ break;
107
+ case 'size':
108
+ shape.width = point.size[0]
109
+ shape.height = point.size[1]
110
+ break;
111
+ case 'center':
112
+ shape.pixelOffset = new Cesium.Cartesian2(-size[0] * (center[0] - 0.5), -size[1] * (center[1] - 0.5))
113
+ break;
114
+ case 'rotation':
115
+ shape.rotation = Cesium.Math.toRadians(point.rotation)
116
+ break;
117
+ default:
118
+ throw new Error(`${key} 还不支持修改`)
119
+ }
120
+ })
121
+ }
122
+
123
+ const onDestroy = () => {
124
+ markers.remove(shape)
125
+ event.off('pointer-move', onMouseMove)
126
+ event.off('left-click', onClick)
127
+ point.event.off('update', onUpdate)
128
+ point.event.off('destroy', onDestroy)
129
+
130
+ }
131
+
132
+ event.on('pointer-move', onMouseMove)
133
+ event.on('left-click', onClick)
134
+ point.event.on('update', onUpdate)
135
+ point.event.on('destroy', onDestroy)
136
+
137
+ }