@mapcomponents/react-maplibre 0.1.61 → 0.1.63

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 (197) hide show
  1. package/.babelrc +21 -2
  2. package/.eslintrc.js +8 -1
  3. package/.storybook/main.js +0 -1
  4. package/.storybook/preview.js +0 -2
  5. package/CHANGELOG.md +23 -0
  6. package/coverage/clover.xml +265 -89
  7. package/coverage/coverage-final.json +14 -6
  8. package/coverage/lcov-report/favicon.png +0 -0
  9. package/coverage/lcov-report/index.html +84 -39
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/src/components/MapLibreMap/MapLibreMap.tsx.html +1 -1
  12. package/coverage/lcov-report/src/components/MapLibreMap/index.html +1 -1
  13. package/coverage/lcov-report/src/components/MlCenterPosition/MlCenterPosition.tsx.html +1 -1
  14. package/coverage/lcov-report/src/components/MlCenterPosition/index.html +1 -1
  15. package/coverage/lcov-report/src/components/MlCreatePdfButton/MlCreatePdfButton.tsx.html +1 -1
  16. package/coverage/lcov-report/src/components/MlCreatePdfButton/index.html +1 -1
  17. package/coverage/lcov-report/src/components/MlCreatePdfForm/MlCreatePdfForm.cy.tsx.html +148 -0
  18. package/coverage/lcov-report/src/components/MlCreatePdfForm/MlCreatePdfForm.tsx.html +2 -8
  19. package/coverage/lcov-report/src/components/MlCreatePdfForm/index.html +22 -7
  20. package/coverage/lcov-report/src/components/MlFeatureEditor/MlFeatureEditor.tsx.html +73 -40
  21. package/coverage/lcov-report/src/components/MlFeatureEditor/index.html +15 -15
  22. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/MlFillExtrusionLayer.tsx.html +1 -1
  23. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/index.html +1 -1
  24. package/coverage/lcov-report/src/components/MlFollowGps/MlFollowGps.tsx.html +1 -1
  25. package/coverage/lcov-report/src/components/MlFollowGps/index.html +1 -1
  26. package/coverage/lcov-report/src/components/MlGPXViewer/MlGPXViewer.tsx.html +9 -3
  27. package/coverage/lcov-report/src/components/MlGPXViewer/gpxConverter.js.html +1 -1
  28. package/coverage/lcov-report/src/components/MlGPXViewer/index.html +1 -1
  29. package/coverage/lcov-report/src/components/MlGeoJsonLayer/MlGeoJsonLayer.tsx.html +59 -29
  30. package/coverage/lcov-report/src/components/MlGeoJsonLayer/index.html +1 -1
  31. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.lineStyler.js.html +652 -0
  32. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.polygonStyler.js.html +649 -0
  33. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/index.html +131 -0
  34. package/coverage/lcov-report/src/components/MlGeojsonLayerWithSource/MlGeojsonLayerWithSource.tsx.html +1 -1
  35. package/coverage/lcov-report/src/components/MlGeojsonLayerWithSource/index.html +1 -1
  36. package/coverage/lcov-report/src/components/MlImageMarkerLayer/MlImageMarkerLayer.tsx.html +1 -1
  37. package/coverage/lcov-report/src/components/MlImageMarkerLayer/index.html +1 -1
  38. package/coverage/lcov-report/src/components/MlLayer/MlLayer.tsx.html +1 -1
  39. package/coverage/lcov-report/src/components/MlLayer/index.html +1 -1
  40. package/coverage/lcov-report/src/components/MlLayerMagnify/MlLayerMagnify.tsx.html +1 -1
  41. package/coverage/lcov-report/src/components/MlLayerMagnify/index.html +1 -1
  42. package/coverage/lcov-report/src/components/MlLayerSwipe/MlLayerSwipe.tsx.html +1 -1
  43. package/coverage/lcov-report/src/components/MlLayerSwipe/index.html +1 -1
  44. package/coverage/lcov-report/src/components/MlLayerSwitcher/MlLayerSwitcher.js.html +1 -1
  45. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/LayerBox.js.html +1 -1
  46. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/index.html +1 -1
  47. package/coverage/lcov-report/src/components/MlLayerSwitcher/index.html +1 -1
  48. package/coverage/lcov-report/src/components/MlMarker/MlMarker.tsx.html +1 -1
  49. package/coverage/lcov-report/src/components/MlMarker/index.html +1 -1
  50. package/coverage/lcov-report/src/components/MlMeasureTool/MlMeasureTool.tsx.html +1 -1
  51. package/coverage/lcov-report/src/components/MlMeasureTool/index.html +1 -1
  52. package/coverage/lcov-report/src/components/MlNavigationCompass/MlNavigationCompass.tsx.html +1 -1
  53. package/coverage/lcov-report/src/components/MlNavigationCompass/index.html +1 -1
  54. package/coverage/lcov-report/src/components/MlNavigationTools/MlNavigationTools.tsx.html +1 -1
  55. package/coverage/lcov-report/src/components/MlNavigationTools/index.html +1 -1
  56. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.js.html +1 -1
  57. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.stories_.js.html +1 -1
  58. package/coverage/lcov-report/src/components/MlOsmLayer/index.html +1 -1
  59. package/coverage/lcov-report/src/components/MlScaleReference/MlScaleReference.js.html +1 -1
  60. package/coverage/lcov-report/src/components/MlScaleReference/index.html +1 -1
  61. package/coverage/lcov-report/src/components/MlShareMapState/MlShareMapState.js.html +1 -1
  62. package/coverage/lcov-report/src/components/MlShareMapState/index.html +1 -1
  63. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/ColorPicker.tsx.html +214 -0
  64. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/LayerList.tsx.html +121 -0
  65. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/LayerListItem.tsx.html +412 -0
  66. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/LayerPropertyForm.tsx.html +463 -0
  67. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/index.html +161 -0
  68. package/coverage/lcov-report/src/components/MlSketchTool/MlSketchTool.tsx.html +898 -0
  69. package/coverage/lcov-report/src/components/MlSketchTool/index.html +116 -0
  70. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.js.html +1 -1
  71. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/index.html +1 -1
  72. package/coverage/lcov-report/src/components/MlThreeJsLayer/MlThreeJsLayer.js.html +1 -1
  73. package/coverage/lcov-report/src/components/MlThreeJsLayer/index.html +1 -1
  74. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/MlTransitionGeoJsonLayer.tsx.html +1 -1
  75. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/index.html +1 -1
  76. package/coverage/lcov-report/src/components/MlUseMapDebugger/MlUseMapDebugger.js.html +1 -1
  77. package/coverage/lcov-report/src/components/MlUseMapDebugger/index.html +1 -1
  78. package/coverage/lcov-report/src/components/MlVectorTileLayer/MlVectorTileLayer.tsx.html +1 -1
  79. package/coverage/lcov-report/src/components/MlVectorTileLayer/index.html +1 -1
  80. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js.html +1 -1
  81. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/index.html +1 -1
  82. package/coverage/lcov-report/src/components/MlWmsLayer/MlWmsLayer.tsx.html +1 -1
  83. package/coverage/lcov-report/src/components/MlWmsLayer/index.html +1 -1
  84. package/coverage/lcov-report/src/components/MlWmsLoader/MlWmsLoader.tsx.html +1 -1
  85. package/coverage/lcov-report/src/components/MlWmsLoader/index.html +1 -1
  86. package/coverage/lcov-report/src/contexts/MapContext.tsx.html +1 -1
  87. package/coverage/lcov-report/src/contexts/SimpleDataContext.js.html +1 -1
  88. package/coverage/lcov-report/src/contexts/SimpleDataProvider.js.html +1 -1
  89. package/coverage/lcov-report/src/contexts/index.html +1 -1
  90. package/coverage/lcov-report/src/hooks/index.html +11 -11
  91. package/coverage/lcov-report/src/hooks/useCameraFollowPath/index.html +1 -1
  92. package/coverage/lcov-report/src/hooks/useCameraFollowPath/useCameraFollowPath.tsx.html +1 -1
  93. package/coverage/lcov-report/src/hooks/useExportMap/index.html +14 -14
  94. package/coverage/lcov-report/src/hooks/useExportMap/index.ts.html +1 -1
  95. package/coverage/lcov-report/src/hooks/useExportMap/lib.ts.html +21 -108
  96. package/coverage/lcov-report/src/hooks/useLayer.ts.html +1 -1
  97. package/coverage/lcov-report/src/hooks/useLayerEvent.js.html +9 -9
  98. package/coverage/lcov-report/src/hooks/useMap.ts.html +1 -1
  99. package/coverage/lcov-report/src/hooks/useMapState.ts.html +1 -1
  100. package/coverage/lcov-report/src/hooks/useSource.ts.html +1 -1
  101. package/coverage/lcov-report/src/hooks/useWms.js.html +1 -1
  102. package/coverage/lcov-report/src/index.html +1 -1
  103. package/coverage/lcov-report/src/index.ts.html +5 -2
  104. package/coverage/lcov.info +564 -161
  105. package/cypress/support/commands.ts +37 -0
  106. package/cypress/support/component-index.html +12 -0
  107. package/cypress/support/component.ts +46 -0
  108. package/cypress.config.ts +101 -0
  109. package/dist/components/MapLibreMap/MapLibreMap.d.ts +1 -1
  110. package/dist/components/MapLibreMap/lib/MapLibreGlWrapper.d.ts +3 -3
  111. package/dist/components/MlCreatePdfForm/MlCreatePdfForm.cy.d.ts +1 -0
  112. package/dist/components/MlCreatePdfForm/MlCreatePdfForm.stories.d.ts +1 -0
  113. package/dist/components/MlCreatePdfForm/lib/PdfContext.d.ts +3 -16
  114. package/dist/components/MlCreatePdfForm/lib/PdfPreview.d.ts +19 -6
  115. package/dist/components/MlCreatePdfForm/lib/_PdfPreview.d.ts +13 -0
  116. package/dist/components/MlFeatureEditor/MlFeatureEditor.d.ts +10 -4
  117. package/dist/components/MlFeatureEditor/lib/double_click_zoom.d.ts +0 -2
  118. package/dist/components/MlFeatureEditor/lib/theme.d.ts +1 -1
  119. package/dist/components/MlGPXViewer/util/GeoJsonContext.d.ts +1 -1
  120. package/dist/components/MlGPXViewer/util/MlGPXViewerInstructions.d.ts +1 -0
  121. package/dist/components/MlGPXViewer/util/SampleLayer.d.ts +0 -0
  122. package/dist/components/MlGPXViewer/util/demoViewer.d.ts +5 -0
  123. package/dist/components/MlGeoJsonLayer/MlGeoJsonLayer.d.ts +4 -4
  124. package/dist/components/MlGeoJsonLayer/MlGeoJsonLayer.stories.d.ts +103 -11
  125. package/dist/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.lineStyler.d.ts +2 -0
  126. package/dist/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.polygonStyler.d.ts +2 -0
  127. package/dist/components/MlSketchTool/LayerList/ColorPicker.d.ts +9 -0
  128. package/dist/components/MlSketchTool/LayerList/LayerList.d.ts +5 -0
  129. package/dist/components/MlSketchTool/LayerList/LayerListItem.d.ts +11 -0
  130. package/dist/components/MlSketchTool/LayerList/LayerPropertyForm.d.ts +9 -0
  131. package/dist/components/MlSketchTool/MlSketchTool.d.ts +29 -0
  132. package/dist/components/MlSketchTool/MlSketchTool.stories.d.ts +10 -0
  133. package/dist/contexts/SimpleDataProvider.d.ts +1 -1
  134. package/dist/custom.d.d.ts +1 -1
  135. package/dist/hooks/useLayer.d.ts +1 -1
  136. package/dist/hooks/useMap.d.ts +1 -1
  137. package/dist/hooks/useMapState.d.ts +3 -3
  138. package/dist/hooks/useSource.d.ts +1 -1
  139. package/dist/index.d.ts +1 -0
  140. package/dist/index.esm.css +1 -1
  141. package/dist/index.esm.js +3473 -4386
  142. package/dist/index.esm.js.map +1 -1
  143. package/dist/ui_components/LoadingOverlayContext.d.ts +1 -1
  144. package/dist/ui_components/Sidebar.d.ts +9 -1
  145. package/dist/ui_components/TopToolbar.d.ts +6 -1
  146. package/package.json +22 -15
  147. package/public/assets/sample1.gpx +3003 -0
  148. package/public/assets/sample2.gpx +1264 -0
  149. package/public/assets/sample3.gpx +912 -0
  150. package/public/index.html +0 -4
  151. package/public/thumbnails/MlSketchTool.png +0 -0
  152. package/public/thumbnails/useCameraFollowPath.png +0 -0
  153. package/src/components/MlCreatePdfForm/MlCreatePdfForm.cy.tsx +21 -0
  154. package/src/components/MlCreatePdfForm/MlCreatePdfForm.stories.tsx +14 -1
  155. package/src/components/MlCreatePdfForm/MlCreatePdfForm.tsx +0 -2
  156. package/src/components/MlCreatePdfForm/lib/PdfContext.tsx +16 -18
  157. package/src/components/MlCreatePdfForm/lib/PdfForm.tsx +79 -6
  158. package/src/components/MlCreatePdfForm/lib/PdfPreview.tsx +285 -357
  159. package/src/components/MlCreatePdfForm/lib/_PdfPreview.tsx +399 -0
  160. package/src/components/MlCreatePdfForm/lib/pdfContext.d.ts +24 -0
  161. package/src/components/MlCreatePdfForm/lib/preview.css +114 -0
  162. package/src/components/MlFeatureEditor/MlFeatureEditor.meta.json +1 -1
  163. package/src/components/MlFeatureEditor/MlFeatureEditor.tsx +39 -28
  164. package/src/components/MlGPXViewer/MlGPXViewer.stories.js +75 -15
  165. package/src/components/MlGPXViewer/MlGPXViewer.tsx +3 -1
  166. package/src/components/MlGPXViewer/util/MlGPXViewerInstructions.js +145 -0
  167. package/src/components/MlGPXViewer/util/SampleLayer.js +2 -0
  168. package/src/components/MlGPXViewer/util/demoViewer.js +254 -0
  169. package/src/components/MlGeoJsonLayer/MlGeoJsonLayer.stories.tsx +102 -0
  170. package/src/components/MlGeoJsonLayer/MlGeoJsonLayer.tsx +33 -23
  171. package/src/components/MlGeoJsonLayer/assets/sample_1.json +138 -24
  172. package/src/components/MlGeoJsonLayer/assets/sample_2.json +140 -20
  173. package/src/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.lineStyler.js +189 -0
  174. package/src/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.polygonStyler.js +188 -0
  175. package/src/components/MlSketchTool/LayerList/ColorPicker.tsx +43 -0
  176. package/src/components/MlSketchTool/LayerList/LayerList.tsx +12 -0
  177. package/src/components/MlSketchTool/LayerList/LayerListItem.tsx +109 -0
  178. package/src/components/MlSketchTool/LayerList/LayerPropertyForm.tsx +126 -0
  179. package/src/components/MlSketchTool/MlSketchTool.doc.de.md +3 -0
  180. package/src/components/MlSketchTool/MlSketchTool.meta.json +15 -0
  181. package/src/components/MlSketchTool/MlSketchTool.stories.js +26 -0
  182. package/src/components/MlSketchTool/MlSketchTool.tsx +271 -0
  183. package/src/components/MlTransitionGeoJsonLayer/MlTransitionGeoJsonLayer.meta.json +2 -2
  184. package/src/hooks/useExportMap/lib.ts +14 -43
  185. package/src/index.ts +1 -0
  186. package/src/ui_components/Sidebar.tsx +80 -0
  187. package/src/ui_components/TopToolbar.tsx +24 -0
  188. package/tsconfig.json +39 -58
  189. package/config/getHttpsConfig.js +0 -66
  190. package/config/modules.js +0 -134
  191. package/config/pnpTs.js +0 -35
  192. package/config/webpack.config.js +0 -757
  193. package/config/webpackDevServer.config.js +0 -130
  194. package/scripts/start.js +0 -166
  195. package/src/components/MlGeoJsonLayer/MlGeoJsonLayer.stories.js +0 -66
  196. package/src/ui_components/Sidebar.js +0 -100
  197. package/src/ui_components/TopToolbar.js +0 -29
@@ -0,0 +1,399 @@
1
+ import React, { useContext, useRef, useState, useEffect } from 'react';
2
+ import MlGeoJsonLayer from '../../MlGeoJsonLayer/MlGeoJsonLayer';
3
+ import * as turf from '@turf/turf';
4
+ import useMap from '../../../hooks/useMap';
5
+ import useLayerEvent from '../../../hooks/useLayerEvent';
6
+ import { BBox, Feature, Polygon } from '@turf/turf';
7
+ import PdfContext from './PdfContext';
8
+ import { MapMouseEvent, MapTouchEvent, MapLayerMouseEvent, LngLat } from 'maplibre-gl';
9
+
10
+ const createPreviewGeojson = (
11
+ geojsonProps: { center: LngLat; distance: number; bearing: number },
12
+ orientation: string
13
+ ) => {
14
+ const topLeftAngle = orientation === 'portrait' ? -35.3 : -54.7;
15
+ const bottomRightAngle = orientation === 'portrait' ? 144.7 : 125.3;
16
+ const topLeft = turf.destination(
17
+ [geojsonProps.center.lng, geojsonProps.center.lat],
18
+ geojsonProps.distance,
19
+ topLeftAngle
20
+ );
21
+ const bottomRight = turf.destination(
22
+ [geojsonProps.center.lng, geojsonProps.center.lat],
23
+ geojsonProps.distance,
24
+ bottomRightAngle
25
+ );
26
+ const bbox = [
27
+ topLeft.geometry.coordinates[0],
28
+ topLeft.geometry.coordinates[1],
29
+ bottomRight.geometry.coordinates[0],
30
+ bottomRight.geometry.coordinates[1],
31
+ ];
32
+
33
+ let _previewGeojson = turf.bboxPolygon(bbox as BBox);
34
+ _previewGeojson = turf.transformRotate(_previewGeojson, geojsonProps.bearing);
35
+ if (!_previewGeojson?.properties) {
36
+ _previewGeojson.properties = {};
37
+ }
38
+ _previewGeojson.properties.bearing = geojsonProps.bearing;
39
+ return _previewGeojson;
40
+ };
41
+
42
+ interface PdfPreviewProps {
43
+ /**
44
+ * Id of the target MapLibre instance in mapContext
45
+ */
46
+ mapId?: string;
47
+ /**
48
+ * Id of an existing layer in the mapLibre instance to help specify the layer order
49
+ * This layer will be visually beneath the layer with the "insertBeforeLayer" id.
50
+ */
51
+ insertBeforeLayer?: string;
52
+ }
53
+
54
+ interface geojsonProps {
55
+ center: { lng: number; lat: number };
56
+ distance: number;
57
+ bearing: number;
58
+ geojson: Feature<Polygon> | undefined;
59
+ }
60
+
61
+ export default function PdfPreview(props: PdfPreviewProps) {
62
+ const pdfContext = useContext(PdfContext);
63
+ const initializedRef = useRef(false);
64
+ const activeFeature = useRef();
65
+
66
+ const dragging = useRef(false);
67
+
68
+ const draggingResizeHandle = useRef(false);
69
+
70
+ const draggingRotationHandle = useRef(false);
71
+
72
+ const [geojsonProps, setGeojsonProps] = useState<geojsonProps>({
73
+ center: { lng: 0, lat: 0 },
74
+ distance: 10,
75
+ bearing: 0,
76
+ geojson: undefined,
77
+ });
78
+
79
+ const mapHook = useMap({
80
+ mapId: props.mapId,
81
+ waitForLayer: props.insertBeforeLayer,
82
+ });
83
+
84
+ useEffect(() => {
85
+ if (
86
+ !mapHook.map ||
87
+ !pdfContext.geojsonRef ||
88
+ !pdfContext.orientation ||
89
+ !pdfContext.template ||
90
+ initializedRef.current
91
+ )
92
+ return;
93
+
94
+ initializedRef.current = true;
95
+
96
+ const center = mapHook.map.map.getCenter();
97
+ const canvasHeight = mapHook.map.map._canvas.height;
98
+ const canvasWidth = mapHook.map.map._canvas.width;
99
+ const bboxPixelHeight = Math.ceil(canvasHeight / 2);
100
+ const bboxPixelWidth = Math.ceil(
101
+ (pdfContext.template.width / pdfContext.template.height) * bboxPixelHeight
102
+ );
103
+
104
+ const topLeft = mapHook.map.map.unproject([
105
+ Math.floor(canvasWidth / 2 - bboxPixelWidth / 2),
106
+ Math.floor(canvasHeight / 2 - bboxPixelHeight / 2),
107
+ ]);
108
+
109
+ const distance = turf.distance([center.lng, center.lat], [topLeft.lng, topLeft.lat]);
110
+
111
+ const tmpGeojsonProps = {
112
+ center,
113
+ distance,
114
+ bearing: 0,
115
+ geojson: createPreviewGeojson({ center, distance, bearing: 0 }, pdfContext.orientation),
116
+ };
117
+ setGeojsonProps(tmpGeojsonProps);
118
+ pdfContext.geojsonRef.current = tmpGeojsonProps.geojson;
119
+ }, [mapHook.map]);
120
+
121
+ useEffect(() => {
122
+ if (!pdfContext.orientation || !pdfContext.geojsonRef) return;
123
+
124
+ const tmpGeojsonProps = JSON.parse(JSON.stringify(geojsonProps));
125
+ tmpGeojsonProps.geojson = createPreviewGeojson(tmpGeojsonProps, pdfContext.orientation);
126
+ setGeojsonProps(tmpGeojsonProps);
127
+ pdfContext.geojsonRef.current = tmpGeojsonProps.geojson;
128
+ }, [pdfContext.orientation]);
129
+
130
+ // Resize handle events
131
+ useLayerEvent({
132
+ event: 'mouseenter',
133
+ layerId: 'pdfPreviewGeojsonResizeHandle',
134
+ eventHandler: function () {
135
+ if (!mapHook.map) return;
136
+
137
+ mapHook.map.map._canvas.style.cursor = 'nwse-resize';
138
+ mapHook.map.map.dragPan.disable();
139
+ },
140
+ });
141
+ useLayerEvent({
142
+ event: 'mouseleave',
143
+ layerId: 'pdfPreviewGeojsonResizeHandle',
144
+ eventHandler: function () {
145
+ if (!mapHook.map) return;
146
+
147
+ mapHook.map.map._canvas.style.cursor = '';
148
+ mapHook.map.map.dragPan.enable();
149
+ },
150
+ });
151
+ useLayerEvent({
152
+ event: 'mousedown',
153
+ layerId: 'pdfPreviewGeojsonResizeHandle',
154
+ addTouchEvents: true,
155
+ eventHandler: function (e: MapMouseEvent | MapTouchEvent) {
156
+ e.preventDefault();
157
+ if (!mapHook.map) return;
158
+
159
+ dragging.current = false;
160
+ draggingRotationHandle.current = false;
161
+ draggingResizeHandle.current = true;
162
+ mapHook.map.map._canvas.style.cursor = 'move';
163
+
164
+ function onMove(e: MapMouseEvent | MapTouchEvent) {
165
+ if (!pdfContext.geojsonRef || !draggingResizeHandle.current || !pdfContext.orientation)
166
+ return;
167
+
168
+ const tmpGeojsonProps = JSON.parse(JSON.stringify(geojsonProps));
169
+ let _distance = turf.distance(
170
+ [tmpGeojsonProps.center.lng, tmpGeojsonProps.center.lat],
171
+ [e.lngLat.lng, e.lngLat.lat]
172
+ );
173
+ // limit max diagonal distance of PDF area to 120km as larger area lead to distortions for northern and southern areas
174
+ if (_distance > 60) {
175
+ _distance = 60;
176
+ }
177
+ tmpGeojsonProps.distance = _distance;
178
+ tmpGeojsonProps.geojson = createPreviewGeojson(tmpGeojsonProps, pdfContext.orientation);
179
+ pdfContext.geojsonRef.current = tmpGeojsonProps.geojson;
180
+ setGeojsonProps(tmpGeojsonProps);
181
+ }
182
+ function onUp() {
183
+ if (!draggingResizeHandle.current || !mapHook.map) return;
184
+
185
+ mapHook.map.map._canvas.style.cursor = '';
186
+ draggingResizeHandle.current = false;
187
+
188
+ mapHook.map.map.dragPan.enable();
189
+ // Unbind mouse events
190
+ mapHook.map.map.off('mousemove', onMove);
191
+ mapHook.map.map.off('touchmove', onMove);
192
+ }
193
+
194
+ // Mouse events
195
+ mapHook.map.map.on('mousemove', onMove);
196
+ mapHook.map.map.on('touchmove', onMove);
197
+ mapHook.map.map.once('mouseup', onUp);
198
+ mapHook.map.map.once('touchend', onUp);
199
+ },
200
+ });
201
+
202
+ // Rotation handle events
203
+ useLayerEvent({
204
+ event: 'mouseenter',
205
+ layerId: 'pdfPreviewGeojsonRotationHandle',
206
+ eventHandler: function () {
207
+ if (!mapHook.map) return;
208
+
209
+ mapHook.map.map._canvas.style.cursor = 'nwse-resize';
210
+ mapHook.map.map.dragPan.disable();
211
+ },
212
+ });
213
+ useLayerEvent({
214
+ event: 'mouseleave',
215
+ layerId: 'pdfPreviewGeojsonRotationHandle',
216
+ eventHandler: function () {
217
+ if (!mapHook.map) return;
218
+
219
+ mapHook.map.map._canvas.style.cursor = '';
220
+ mapHook.map.map.dragPan.enable();
221
+ },
222
+ });
223
+ useLayerEvent({
224
+ event: 'mousedown',
225
+ layerId: 'pdfPreviewGeojsonRotationHandle',
226
+ addTouchEvents: true,
227
+ eventHandler: function (e: MapMouseEvent | MapTouchEvent) {
228
+ e.preventDefault();
229
+ if (!mapHook.map || !pdfContext.orientation) return;
230
+
231
+ dragging.current = false;
232
+ draggingResizeHandle.current = false;
233
+ draggingRotationHandle.current = true;
234
+ mapHook.map.map._canvas.style.cursor = 'move';
235
+
236
+ function onMove(e: MapMouseEvent | MapTouchEvent) {
237
+ e.preventDefault();
238
+ if (!draggingRotationHandle.current || !pdfContext.orientation || !pdfContext.geojsonRef)
239
+ return;
240
+
241
+ const tmpGeojsonProps = JSON.parse(JSON.stringify(geojsonProps));
242
+ const _bearing = turf.bearing(
243
+ [tmpGeojsonProps.center.lng, tmpGeojsonProps.center.lat],
244
+ [e.lngLat.lng, e.lngLat.lat]
245
+ );
246
+ tmpGeojsonProps.bearing = 144.7 + _bearing;
247
+ tmpGeojsonProps.geojson = createPreviewGeojson(tmpGeojsonProps, pdfContext.orientation);
248
+ pdfContext.geojsonRef.current = tmpGeojsonProps.geojson;
249
+ setGeojsonProps(tmpGeojsonProps);
250
+ }
251
+ function onUp() {
252
+ if (!draggingRotationHandle.current || !mapHook.map) return;
253
+
254
+ mapHook.map.map._canvas.style.cursor = '';
255
+ draggingRotationHandle.current = false;
256
+
257
+ mapHook.map.map.dragPan.enable();
258
+ // Unbind mouse events
259
+ mapHook.map.map.off('mousemove', onMove);
260
+ mapHook.map.map.off('touchmove', onMove);
261
+ }
262
+
263
+ // Mouse events
264
+ mapHook.map.map.on('mousemove', onMove);
265
+ mapHook.map.map.on('touchmove', onMove);
266
+ mapHook.map.map.once('mouseup', onUp);
267
+ mapHook.map.map.once('touchend', onUp);
268
+ },
269
+ });
270
+
271
+ // drag & drop events
272
+ useLayerEvent({
273
+ event: 'mouseenter',
274
+ layerId: 'pdfPreviewGeojson',
275
+ eventHandler: function (e: MapLayerMouseEvent) {
276
+ if (!mapHook.map || !e?.features?.length) return;
277
+ mapHook.map.map._canvas.style.cursor = 'move';
278
+ activeFeature.current = e.features[0];
279
+ },
280
+ });
281
+ useLayerEvent({
282
+ event: 'mouseleave',
283
+ layerId: 'pdfPreviewGeojson',
284
+ eventHandler: function () {
285
+ if (!mapHook.map) return;
286
+
287
+ mapHook.map.map._canvas.style.cursor = '';
288
+ mapHook.map.map.dragPan.enable();
289
+ activeFeature.current = undefined;
290
+ },
291
+ });
292
+ useLayerEvent({
293
+ event: 'mousedown',
294
+ addTouchEvents: true,
295
+ layerId: 'pdfPreviewGeojson',
296
+ eventHandler: function (e: MapMouseEvent | MapTouchEvent) {
297
+ e.preventDefault();
298
+ console.log('mousedown');
299
+ if (!mapHook.map) return;
300
+
301
+ draggingResizeHandle.current = false;
302
+ draggingRotationHandle.current = false;
303
+ dragging.current = true;
304
+ mapHook.map.map._canvas.style.cursor = 'move';
305
+
306
+ function onMove(e: MapMouseEvent | MapTouchEvent) {
307
+ e.preventDefault();
308
+ if (!dragging.current || !pdfContext.geojsonRef || !pdfContext.orientation) return;
309
+
310
+ const tmpGeojsonProps = JSON.parse(JSON.stringify(geojsonProps));
311
+ tmpGeojsonProps.center = e.lngLat;
312
+ tmpGeojsonProps.geojson = createPreviewGeojson(tmpGeojsonProps, pdfContext.orientation);
313
+ pdfContext.geojsonRef.current = tmpGeojsonProps.geojson;
314
+ setGeojsonProps(tmpGeojsonProps);
315
+ }
316
+ function onUp() {
317
+ if (!dragging.current || !mapHook.map) return;
318
+
319
+ mapHook.map.map._canvas.style.cursor = '';
320
+ dragging.current = false;
321
+
322
+ mapHook.map.map.dragPan.enable();
323
+ // Unbind mouse events
324
+ mapHook.map.map.off('mousemove', onMove);
325
+ mapHook.map.map.off('touchmove', onMove);
326
+ }
327
+
328
+ // Mouse events
329
+ mapHook.map.map.on('mousemove', onMove);
330
+ mapHook.map.map.on('touchmove', onMove);
331
+ mapHook.map.map.once('mouseup', onUp);
332
+ mapHook.map.map.once('touchend', onUp);
333
+ },
334
+ });
335
+
336
+ //map.on('mouseleave', 'point', function() {
337
+ // map.setPaintProperty('point', 'circle-color', '#3887be');
338
+ // canvas.style.cursor = '';
339
+ // isCursorOverPoint = false;
340
+ // map.dragPan.enable();
341
+ //});
342
+
343
+ return (
344
+ <>
345
+ {geojsonProps?.geojson?.bbox && (
346
+ <>
347
+ <MlGeoJsonLayer
348
+ paint={{ 'line-color': '#616161', 'line-width': 4 }}
349
+ type="line"
350
+ layerId="pdfPreviewGeojsonOutline"
351
+ geojson={geojsonProps.geojson}
352
+ />
353
+ <MlGeoJsonLayer
354
+ paint={{ 'fill-opacity': 0 }}
355
+ type="fill"
356
+ layerId="pdfPreviewGeojson"
357
+ geojson={geojsonProps.geojson}
358
+ />
359
+ <MlGeoJsonLayer
360
+ layerId="pdfPreviewGeojsonResizeHandle"
361
+ paint={{
362
+ 'circle-radius': 10,
363
+ 'circle-color': '#1976d2',
364
+ 'circle-stroke-width': 2,
365
+ 'circle-stroke-color': '#ffffff',
366
+ }}
367
+ geojson={{
368
+ type: 'Feature',
369
+ geometry: {
370
+ type: 'Point',
371
+ //coordinates: [geojsonProps.geojson.bbox[2], geojsonProps.geojson.bbox[3]],
372
+ coordinates: geojsonProps.geojson.geometry.coordinates[0][2],
373
+ },
374
+ properties: {},
375
+ }}
376
+ />
377
+ <MlGeoJsonLayer
378
+ layerId="pdfPreviewGeojsonRotationHandle"
379
+ paint={{
380
+ 'circle-radius': 10,
381
+ 'circle-color': '#86dd71',
382
+ 'circle-stroke-width': 2,
383
+ 'circle-stroke-color': '#ffffff',
384
+ }}
385
+ geojson={{
386
+ type: 'Feature',
387
+ geometry: {
388
+ type: 'Point',
389
+ //coordinates: [geojsonProps.geojson.bbox[0], geojsonProps.geojson.bbox[3]],
390
+ coordinates: geojsonProps.geojson.geometry.coordinates[0][3],
391
+ },
392
+ properties: {},
393
+ }}
394
+ />
395
+ </>
396
+ )}
397
+ </>
398
+ );
399
+ }
@@ -0,0 +1,24 @@
1
+ import { Feature } from '@turf/turf';
2
+ export interface PdfPreviewOptions {
3
+ center: [number, number] | undefined;
4
+ scale: [number, number] | undefined;
5
+ rotate: number;
6
+ width: number;
7
+ height: number;
8
+ fixedScale?: number | false;
9
+ orientation: 'portrait' | 'landscape';
10
+ }
11
+
12
+ export interface PdfContextInterface {
13
+ options: PdfPreviewOptions;
14
+ setOptions: (arg1: (val: PdfPreviewOptions) => PdfPreviewOptions) => void;
15
+ format: string;
16
+ setFormat: (format: string) => void;
17
+ quality: string;
18
+ setQuality: (quality: string) => void;
19
+ geojsonRef: MutableRefObject<
20
+ | Feature
21
+ | undefined
22
+ >;
23
+ template: { width: number; height: number };
24
+ }
@@ -0,0 +1,114 @@
1
+ .root {
2
+ position: relative;
3
+ }
4
+ .mapContainer {
5
+ position: relative;
6
+ }
7
+ .will-change-container {
8
+ padding-left: 100px;
9
+ padding-top: 100px;
10
+ will-change: transform;
11
+ }
12
+ .will-change-target {
13
+ position: relative;
14
+ width: 100px;
15
+ height: 100px;
16
+ line-height: 100px;
17
+ text-align: center;
18
+ background: #ee8;
19
+ color: #333;
20
+ font-weight: bold;
21
+ border: 1px solid #333;
22
+ box-sizing: border-box;
23
+ }
24
+ .moveable-control-box{
25
+ z-index:255;
26
+ cursor: pointer;
27
+ }
28
+ .moveable-rotation .moveable-rotation-control {
29
+ cursor:pointer !important;
30
+ }
31
+ .target {
32
+ position: fixed;
33
+ top: 0;
34
+ left: 0;
35
+ line-height: 100px;
36
+ text-align: center;
37
+ background: rgba(120,210,210,0.1);
38
+ border: 3px solid #3a3;
39
+ box-sizing: border-box;
40
+ z-index:250;
41
+ cursor: pointer;
42
+ }
43
+
44
+ .nested {
45
+ position: absolute;
46
+ border: 4px solid #ccc;
47
+ width: 100px;
48
+ height: 100px;
49
+ top: 50px;
50
+ left: 70px;
51
+ color: #333;
52
+ /* box-sizing: border-box; */
53
+ }
54
+
55
+ .nested.first {
56
+ top: 150px;
57
+ }
58
+
59
+ .nested.rotate {
60
+ transform-origin: 0 0;
61
+ transform: rotate(-30deg);
62
+ }
63
+
64
+ .nested.scale {
65
+ transform: scale(1.5, 1.5);
66
+ }
67
+
68
+ .nested .target {
69
+ top: 50px;
70
+ left: 50px
71
+ }
72
+
73
+
74
+ /* pos guidelines */
75
+ .moveable-normal.red {
76
+ background: red!important;
77
+ }
78
+ /* gap guidelines */
79
+ .moveable-gap.red {
80
+ background: red!important;
81
+ }
82
+ /* When snapped to an element in elementGuidelines */
83
+ .moveable-bold.red {
84
+ background: red!important;
85
+ }
86
+ /* A dashed line between target and element */
87
+ .moveable-dashed.red {
88
+ border-top-color: red!important;
89
+ border-left-color: red!important;
90
+ }
91
+
92
+ /* pos guidelines */
93
+ .moveable-normal.green {
94
+ background: green!important;
95
+ }
96
+ /* gap guidelines */
97
+ .moveable-gap.green {
98
+ background: green!important;
99
+ }
100
+ /* When snapped to an element in elementGuidelines */
101
+ .moveable-bold.green {
102
+ background: green!important;
103
+ }
104
+ /* A dashed line between target and element */
105
+ .moveable-dashed.green {
106
+ border-top-color: green!important;
107
+ border-left-color: green!important;
108
+ }
109
+ .MuiDialog-root{
110
+ pointer-events: none;
111
+ }
112
+ .MuiDialog-root .react-draggable{
113
+ pointer-events: all;
114
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "MlFeatureEditor",
3
- "title": "Sketch tools",
3
+ "title": "Feature editor",
4
4
  "description": "Enables the editing of Point, Linestring and Polygon GeoJSON Files.",
5
5
  "i18n": {
6
6
  "de": {
@@ -1,13 +1,14 @@
1
- import React, { useState, useEffect, useRef } from "react";
2
- import "./MlFeatureEditor.css";
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import './MlFeatureEditor.css';
3
3
 
4
- import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
5
- import MapboxDraw from "@mapbox/mapbox-gl-draw";
6
- import CustomPolygonMode from "./custom-polygon-mode.js";
7
- import CustomSelectMode from "./custom-select-mode.js";
8
- import CustomDirectSelectMode from "./custom-direct-select-mode.js";
4
+ import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
5
+ import MapboxDraw from '@mapbox/mapbox-gl-draw';
6
+ import CustomPolygonMode from './custom-polygon-mode.js';
7
+ import CustomSelectMode from './custom-select-mode.js';
8
+ import CustomDirectSelectMode from './custom-direct-select-mode.js';
9
9
 
10
- import useMap from "../../hooks/useMap";
10
+ import useMap from '../../hooks/useMap';
11
+ import { GeoJSONObject, Feature } from '@turf/turf';
11
12
 
12
13
  interface MlFeatureEditorProps {
13
14
  /**
@@ -22,12 +23,17 @@ interface MlFeatureEditorProps {
22
23
  /**
23
24
  * Input GeoJson data at initialization
24
25
  */
25
- geojson?: any;
26
+ geojson?: Feature;
26
27
  /**
27
28
  * Callback function that is called each time the GeoJson data within has changed within MlFeatureEditor.
28
29
  * First parameter is the new GeoJson feature.
29
30
  */
30
- onChange?: Function;
31
+ onChange?: (para: GeoJSONObject[]) => void;
32
+ /**
33
+ * Callback function that is called each time the GeoJson data within has been finished within MlFeatureEditor.
34
+ * First parameter is the new GeoJson feature.
35
+ */
36
+ onFinish?: () => void;
31
37
  /**
32
38
  * Feature editor mode:
33
39
  * - "custom_select" edit features
@@ -51,10 +57,15 @@ const MlFeatureEditor = (props: MlFeatureEditorProps) => {
51
57
  const drawToolsInitialized = useRef(false);
52
58
  const [drawToolsReady, setDrawToolsReady] = useState(false);
53
59
 
54
-
55
60
  const modeChangeHandler = (e: any) => {
56
- console.log("MlFeatureEditor mode change to " + e.mode);
61
+ console.log('MlFeatureEditor mode change to ' + e.mode);
57
62
  //setDrawMode(e.mode);
63
+ if (
64
+ typeof props.onFinish === 'function' &&
65
+ (e.mode === 'custom_select' || e.mode === 'simple_select')
66
+ ) {
67
+ props.onFinish();
68
+ }
58
69
  };
59
70
 
60
71
  useEffect(() => {
@@ -63,17 +74,19 @@ const MlFeatureEditor = (props: MlFeatureEditorProps) => {
63
74
 
64
75
  if (
65
76
  mapHook.map.map.style &&
66
- mapHook.map.map.getSource("mapbox-gl-draw-cold") &&
77
+ mapHook.map.map.getSource('mapbox-gl-draw-cold') &&
67
78
  draw.current
68
79
  ) {
69
80
  // remove old Mapbox-gl-Draw from Mapbox instance when hot-reloading this component during development
81
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
70
82
  // @ts-ignore
71
83
  draw.current?.remove();
72
84
  }
73
85
 
74
86
  draw.current = new MapboxDraw({
75
87
  displayControlsDefault: false,
76
- defaultMode: props.mode || "custom_select",
88
+ defaultMode: props.mode || 'custom_select',
89
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
77
90
  // @ts-ignore
78
91
  modes: Object.assign(
79
92
  {
@@ -85,10 +98,9 @@ const MlFeatureEditor = (props: MlFeatureEditorProps) => {
85
98
  ),
86
99
  });
87
100
 
88
- mapHook.map.addControl(draw.current, "top-left", mapHook.componentId);
101
+ mapHook.map.addControl(draw.current, 'top-left', mapHook.componentId);
89
102
 
90
-
91
- mapHook.map.on("draw.modechange", modeChangeHandler, mapHook.componentId);
103
+ mapHook.map.on('draw.modechange', modeChangeHandler, mapHook.componentId);
92
104
 
93
105
  setDrawToolsReady(true);
94
106
  }
@@ -100,35 +112,34 @@ const MlFeatureEditor = (props: MlFeatureEditorProps) => {
100
112
  const changeHandler = () => {
101
113
  if (draw.current) {
102
114
  // update drawnFeatures state object
103
- if (typeof props.onChange === "function") {
104
- let currentFeatureCollection = draw.current.getAll?.();
115
+ if (typeof props.onChange === 'function') {
116
+ const currentFeatureCollection = draw.current.getAll?.();
105
117
  props.onChange(currentFeatureCollection?.features);
106
118
  }
107
119
  }
108
120
  };
109
121
 
110
- mapHook.map.on("mouseup", changeHandler);
122
+ mapHook.map.on('mouseup', changeHandler);
111
123
 
112
- mapHook.map.on("touchend", changeHandler);
124
+ mapHook.map.on('touchend', changeHandler);
113
125
 
114
126
  return () => {
115
127
  if (!mapHook.map) return;
116
128
 
117
- mapHook.map.map.off("mouseup", changeHandler);
118
-
119
- mapHook.map.map.off("touchend", changeHandler);
120
- }
121
-
122
- }, [drawToolsReady, mapHook.map])
129
+ mapHook.map.map.off('mouseup', changeHandler);
130
+ mapHook.map.map.off('touchend', changeHandler);
131
+ };
132
+ }, [drawToolsReady, mapHook.map]);
123
133
 
124
134
  useEffect(() => {
125
135
  if (draw.current && props.geojson?.geometry) {
126
- draw.current.set({ type: "FeatureCollection", features: [props.geojson] });
136
+ draw.current.set({ type: 'FeatureCollection', features: [props.geojson as any] });
127
137
  }
128
138
  }, [props.geojson, drawToolsReady]);
129
139
 
130
140
  useEffect(() => {
131
141
  if (props.mode && draw.current) {
142
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
132
143
  // @ts-ignore
133
144
  draw.current.changeMode(props.mode);
134
145
  }