@deck.gl-community/editable-layers 9.0.0-alpha.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 (295) hide show
  1. package/README.md +82 -0
  2. package/dist/constants.d.ts +14 -0
  3. package/dist/constants.js +14 -0
  4. package/dist/curve-utils.d.ts +2 -0
  5. package/dist/curve-utils.js +61 -0
  6. package/dist/edit-modes/composite-mode.d.ts +14 -0
  7. package/dist/edit-modes/composite-mode.js +47 -0
  8. package/dist/edit-modes/draw-90degree-polygon-mode.d.ts +11 -0
  9. package/dist/edit-modes/draw-90degree-polygon-mode.js +179 -0
  10. package/dist/edit-modes/draw-circle-by-diameter-mode.d.ts +24 -0
  11. package/dist/edit-modes/draw-circle-by-diameter-mode.js +78 -0
  12. package/dist/edit-modes/draw-circle-from-center-mode.d.ts +22 -0
  13. package/dist/edit-modes/draw-circle-from-center-mode.js +70 -0
  14. package/dist/edit-modes/draw-ellipse-by-bounding-box-mode.d.ts +5 -0
  15. package/dist/edit-modes/draw-ellipse-by-bounding-box-mode.js +20 -0
  16. package/dist/edit-modes/draw-ellipse-using-three-points-mode.d.ts +5 -0
  17. package/dist/edit-modes/draw-ellipse-using-three-points-mode.js +16 -0
  18. package/dist/edit-modes/draw-line-string-mode.d.ts +25 -0
  19. package/dist/edit-modes/draw-line-string-mode.js +170 -0
  20. package/dist/edit-modes/draw-point-mode.d.ts +8 -0
  21. package/dist/edit-modes/draw-point-mode.js +28 -0
  22. package/dist/edit-modes/draw-polygon-by-dragging-mode.d.ts +14 -0
  23. package/dist/edit-modes/draw-polygon-by-dragging-mode.js +87 -0
  24. package/dist/edit-modes/draw-polygon-mode.d.ts +10 -0
  25. package/dist/edit-modes/draw-polygon-mode.js +143 -0
  26. package/dist/edit-modes/draw-rectangle-from-center-mode.d.ts +5 -0
  27. package/dist/edit-modes/draw-rectangle-from-center-mode.js +17 -0
  28. package/dist/edit-modes/draw-rectangle-mode.d.ts +5 -0
  29. package/dist/edit-modes/draw-rectangle-mode.js +11 -0
  30. package/dist/edit-modes/draw-rectangle-using-three-points-mode.d.ts +5 -0
  31. package/dist/edit-modes/draw-rectangle-using-three-points-mode.js +28 -0
  32. package/dist/edit-modes/draw-square-from-center-mode.d.ts +5 -0
  33. package/dist/edit-modes/draw-square-from-center-mode.js +35 -0
  34. package/dist/edit-modes/draw-square-mode.d.ts +5 -0
  35. package/dist/edit-modes/draw-square-mode.js +28 -0
  36. package/dist/edit-modes/duplicate-mode.d.ts +7 -0
  37. package/dist/edit-modes/duplicate-mode.js +17 -0
  38. package/dist/edit-modes/edit-mode.d.ts +11 -0
  39. package/dist/edit-modes/edit-mode.js +2 -0
  40. package/dist/edit-modes/elevation-mode.d.ts +13 -0
  41. package/dist/edit-modes/elevation-mode.js +49 -0
  42. package/dist/edit-modes/extend-line-string-mode.d.ts +9 -0
  43. package/dist/edit-modes/extend-line-string-mode.js +72 -0
  44. package/dist/edit-modes/extrude-mode.d.ts +15 -0
  45. package/dist/edit-modes/extrude-mode.js +186 -0
  46. package/dist/edit-modes/geojson-edit-mode.d.ts +33 -0
  47. package/dist/edit-modes/geojson-edit-mode.js +208 -0
  48. package/dist/edit-modes/immutable-feature-collection.d.ts +43 -0
  49. package/dist/edit-modes/immutable-feature-collection.js +300 -0
  50. package/dist/edit-modes/measure-angle-mode.d.ts +11 -0
  51. package/dist/edit-modes/measure-angle-mode.js +99 -0
  52. package/dist/edit-modes/measure-area-mode.d.ts +8 -0
  53. package/dist/edit-modes/measure-area-mode.js +50 -0
  54. package/dist/edit-modes/measure-distance-mode.d.ts +19 -0
  55. package/dist/edit-modes/measure-distance-mode.js +171 -0
  56. package/dist/edit-modes/modify-mode.d.ts +15 -0
  57. package/dist/edit-modes/modify-mode.js +203 -0
  58. package/dist/edit-modes/resize-circle-mode.d.ts +16 -0
  59. package/dist/edit-modes/resize-circle-mode.js +142 -0
  60. package/dist/edit-modes/rotate-mode.d.ts +17 -0
  61. package/dist/edit-modes/rotate-mode.js +151 -0
  62. package/dist/edit-modes/scale-mode.d.ts +27 -0
  63. package/dist/edit-modes/scale-mode.js +173 -0
  64. package/dist/edit-modes/snappable-mode.d.ts +21 -0
  65. package/dist/edit-modes/snappable-mode.js +109 -0
  66. package/dist/edit-modes/split-polygon-mode.d.ts +10 -0
  67. package/dist/edit-modes/split-polygon-mode.js +164 -0
  68. package/dist/edit-modes/three-click-polygon-mode.d.ts +10 -0
  69. package/dist/edit-modes/three-click-polygon-mode.js +72 -0
  70. package/dist/edit-modes/transform-mode.d.ts +9 -0
  71. package/dist/edit-modes/transform-mode.js +63 -0
  72. package/dist/edit-modes/translate-mode.d.ts +13 -0
  73. package/dist/edit-modes/translate-mode.js +113 -0
  74. package/dist/edit-modes/two-click-polygon-mode.d.ts +13 -0
  75. package/dist/edit-modes/two-click-polygon-mode.js +93 -0
  76. package/dist/edit-modes/types.d.ts +86 -0
  77. package/dist/edit-modes/types.js +1 -0
  78. package/dist/edit-modes/utils.d.ts +36 -0
  79. package/dist/edit-modes/utils.js +381 -0
  80. package/dist/edit-modes/view-mode.d.ts +3 -0
  81. package/dist/edit-modes/view-mode.js +3 -0
  82. package/dist/editable-layers/editable-geojson-layer.d.ts +98 -0
  83. package/dist/editable-layers/editable-geojson-layer.js +450 -0
  84. package/dist/editable-layers/editable-h3-cluster-layer.d.ts +34 -0
  85. package/dist/editable-layers/editable-h3-cluster-layer.js +164 -0
  86. package/dist/editable-layers/editable-layer.d.ts +49 -0
  87. package/dist/editable-layers/editable-layer.js +195 -0
  88. package/dist/editable-layers/editable-path-layer.d.ts +9 -0
  89. package/dist/editable-layers/editable-path-layer.js +34 -0
  90. package/dist/editable-layers/elevated-edit-handle-layer.d.ts +7 -0
  91. package/dist/editable-layers/elevated-edit-handle-layer.js +24 -0
  92. package/dist/editable-layers/junction-scatterplot-layer.d.ts +14 -0
  93. package/dist/editable-layers/junction-scatterplot-layer.js +41 -0
  94. package/dist/editable-layers/path-marker-layer/arrow-2d-geometry.d.ts +4 -0
  95. package/dist/editable-layers/path-marker-layer/arrow-2d-geometry.js +55 -0
  96. package/dist/editable-layers/path-marker-layer/create-path-markers.d.ts +16 -0
  97. package/dist/editable-layers/path-marker-layer/create-path-markers.js +75 -0
  98. package/dist/editable-layers/path-marker-layer/path-marker-layer.d.ts +40 -0
  99. package/dist/editable-layers/path-marker-layer/path-marker-layer.js +121 -0
  100. package/dist/editable-layers/path-marker-layer/polyline.d.ts +18 -0
  101. package/dist/editable-layers/path-marker-layer/polyline.js +37 -0
  102. package/dist/editable-layers/path-outline-layer/path-outline-layer.d.ts +26 -0
  103. package/dist/editable-layers/path-outline-layer/path-outline-layer.js +106 -0
  104. package/dist/editable-layers/selection-layer.d.ts +26 -0
  105. package/dist/editable-layers/selection-layer.js +167 -0
  106. package/dist/geojson-types.d.ts +58 -0
  107. package/dist/geojson-types.js +2 -0
  108. package/dist/index.cjs +5825 -0
  109. package/dist/index.cjs.map +7 -0
  110. package/dist/index.d.ts +60 -0
  111. package/dist/index.js +62 -0
  112. package/dist/lib/constants.d.ts +6 -0
  113. package/dist/lib/constants.js +6 -0
  114. package/dist/lib/deck-renderer/deck-cache.d.ts +14 -0
  115. package/dist/lib/deck-renderer/deck-cache.js +51 -0
  116. package/dist/lib/deck-renderer/deck-drawer.d.ts +63 -0
  117. package/dist/lib/deck-renderer/deck-drawer.js +232 -0
  118. package/dist/lib/feature.d.ts +10 -0
  119. package/dist/lib/feature.js +16 -0
  120. package/dist/lib/layer-mouse-event.d.ts +11 -0
  121. package/dist/lib/layer-mouse-event.js +24 -0
  122. package/dist/lib/layers/junctions-layer.d.ts +8 -0
  123. package/dist/lib/layers/junctions-layer.js +33 -0
  124. package/dist/lib/layers/segments-layer.d.ts +18 -0
  125. package/dist/lib/layers/segments-layer.js +94 -0
  126. package/dist/lib/layers/texts-layer.d.ts +8 -0
  127. package/dist/lib/layers/texts-layer.js +32 -0
  128. package/dist/lib/math.d.ts +11 -0
  129. package/dist/lib/math.js +22 -0
  130. package/dist/lib/nebula-layer.d.ts +13 -0
  131. package/dist/lib/nebula-layer.js +26 -0
  132. package/dist/lib/nebula.d.ts +34 -0
  133. package/dist/lib/nebula.js +254 -0
  134. package/dist/lib/style.d.ts +19 -0
  135. package/dist/lib/style.js +20 -0
  136. package/dist/memoize.d.ts +6 -0
  137. package/dist/memoize.js +40 -0
  138. package/dist/mode-handlers/composite-mode-handler.d.ts +24 -0
  139. package/dist/mode-handlers/composite-mode-handler.js +55 -0
  140. package/dist/mode-handlers/draw-90degree-polygon-handler.d.ts +13 -0
  141. package/dist/mode-handlers/draw-90degree-polygon-handler.js +169 -0
  142. package/dist/mode-handlers/draw-circle-by-bounding-box-handler.d.ts +9 -0
  143. package/dist/mode-handlers/draw-circle-by-bounding-box-handler.js +29 -0
  144. package/dist/mode-handlers/draw-circle-from-center-handler.d.ts +9 -0
  145. package/dist/mode-handlers/draw-circle-from-center-handler.js +27 -0
  146. package/dist/mode-handlers/draw-ellipse-by-bounding-box-handler.d.ts +9 -0
  147. package/dist/mode-handlers/draw-ellipse-by-bounding-box-handler.js +30 -0
  148. package/dist/mode-handlers/draw-ellipse-using-three-points-handler.d.ts +9 -0
  149. package/dist/mode-handlers/draw-ellipse-using-three-points-handler.js +37 -0
  150. package/dist/mode-handlers/draw-line-string-handler.d.ts +9 -0
  151. package/dist/mode-handlers/draw-line-string-handler.js +83 -0
  152. package/dist/mode-handlers/draw-point-handler.d.ts +5 -0
  153. package/dist/mode-handlers/draw-point-handler.js +11 -0
  154. package/dist/mode-handlers/draw-polygon-handler.d.ts +11 -0
  155. package/dist/mode-handlers/draw-polygon-handler.js +92 -0
  156. package/dist/mode-handlers/draw-rectangle-handler.d.ts +9 -0
  157. package/dist/mode-handlers/draw-rectangle-handler.js +18 -0
  158. package/dist/mode-handlers/draw-rectangle-using-three-points-handler.d.ts +9 -0
  159. package/dist/mode-handlers/draw-rectangle-using-three-points-handler.js +49 -0
  160. package/dist/mode-handlers/duplicate-handler.d.ts +9 -0
  161. package/dist/mode-handlers/duplicate-handler.js +19 -0
  162. package/dist/mode-handlers/elevation-handler.d.ts +19 -0
  163. package/dist/mode-handlers/elevation-handler.js +48 -0
  164. package/dist/mode-handlers/extrude-handler.d.ts +18 -0
  165. package/dist/mode-handlers/extrude-handler.js +176 -0
  166. package/dist/mode-handlers/mode-handler.d.ts +61 -0
  167. package/dist/mode-handlers/mode-handler.js +286 -0
  168. package/dist/mode-handlers/modify-handler.d.ts +19 -0
  169. package/dist/mode-handlers/modify-handler.js +193 -0
  170. package/dist/mode-handlers/rotate-handler.d.ts +17 -0
  171. package/dist/mode-handlers/rotate-handler.js +74 -0
  172. package/dist/mode-handlers/scale-handler.d.ts +17 -0
  173. package/dist/mode-handlers/scale-handler.js +76 -0
  174. package/dist/mode-handlers/snappable-handler.d.ts +33 -0
  175. package/dist/mode-handlers/snappable-handler.js +133 -0
  176. package/dist/mode-handlers/split-polygon-handler.d.ts +11 -0
  177. package/dist/mode-handlers/split-polygon-handler.js +154 -0
  178. package/dist/mode-handlers/three-click-polygon-handler.d.ts +5 -0
  179. package/dist/mode-handlers/three-click-polygon-handler.js +18 -0
  180. package/dist/mode-handlers/translate-handler.d.ts +17 -0
  181. package/dist/mode-handlers/translate-handler.js +72 -0
  182. package/dist/mode-handlers/two-click-polygon-handler.d.ts +5 -0
  183. package/dist/mode-handlers/two-click-polygon-handler.js +18 -0
  184. package/dist/mode-handlers/view-handler.d.ts +8 -0
  185. package/dist/mode-handlers/view-handler.js +10 -0
  186. package/dist/shaderlib/color/color.d.ts +8 -0
  187. package/dist/shaderlib/color/color.js +51 -0
  188. package/dist/shaderlib/outline/outline.d.ts +8 -0
  189. package/dist/shaderlib/outline/outline.js +97 -0
  190. package/dist/shaderlib/utils/utils.d.ts +8 -0
  191. package/dist/shaderlib/utils/utils.js +28 -0
  192. package/dist/translateFromCenter.d.ts +4 -0
  193. package/dist/translateFromCenter.js +19 -0
  194. package/dist/types.d.ts +35 -0
  195. package/dist/types.js +1 -0
  196. package/dist/utils.d.ts +20 -0
  197. package/dist/utils.js +144 -0
  198. package/package.json +84 -0
  199. package/src/constants.ts +15 -0
  200. package/src/curve-utils.ts +77 -0
  201. package/src/edit-modes/composite-mode.ts +74 -0
  202. package/src/edit-modes/draw-90degree-polygon-mode.ts +220 -0
  203. package/src/edit-modes/draw-circle-by-diameter-mode.ts +88 -0
  204. package/src/edit-modes/draw-circle-from-center-mode.ts +79 -0
  205. package/src/edit-modes/draw-ellipse-by-bounding-box-mode.ts +25 -0
  206. package/src/edit-modes/draw-ellipse-using-three-points-mode.ts +23 -0
  207. package/src/edit-modes/draw-line-string-mode.ts +200 -0
  208. package/src/edit-modes/draw-point-mode.ts +35 -0
  209. package/src/edit-modes/draw-polygon-by-dragging-mode.ts +106 -0
  210. package/src/edit-modes/draw-polygon-mode.ts +171 -0
  211. package/src/edit-modes/draw-rectangle-from-center-mode.ts +23 -0
  212. package/src/edit-modes/draw-rectangle-mode.ts +14 -0
  213. package/src/edit-modes/draw-rectangle-using-three-points-mode.ts +36 -0
  214. package/src/edit-modes/draw-square-from-center-mode.ts +46 -0
  215. package/src/edit-modes/draw-square-mode.ts +36 -0
  216. package/src/edit-modes/duplicate-mode.ts +21 -0
  217. package/src/edit-modes/edit-mode.ts +30 -0
  218. package/src/edit-modes/elevation-mode.ts +86 -0
  219. package/src/edit-modes/extend-line-string-mode.ts +87 -0
  220. package/src/edit-modes/extrude-mode.ts +254 -0
  221. package/src/edit-modes/geojson-edit-mode.ts +283 -0
  222. package/src/edit-modes/immutable-feature-collection.ts +417 -0
  223. package/src/edit-modes/measure-angle-mode.ts +127 -0
  224. package/src/edit-modes/measure-area-mode.ts +62 -0
  225. package/src/edit-modes/measure-distance-mode.ts +215 -0
  226. package/src/edit-modes/modify-mode.ts +293 -0
  227. package/src/edit-modes/resize-circle-mode.ts +202 -0
  228. package/src/edit-modes/rotate-mode.ts +208 -0
  229. package/src/edit-modes/scale-mode.ts +231 -0
  230. package/src/edit-modes/snappable-mode.ts +174 -0
  231. package/src/edit-modes/split-polygon-mode.ts +201 -0
  232. package/src/edit-modes/three-click-polygon-mode.ts +111 -0
  233. package/src/edit-modes/transform-mode.ts +75 -0
  234. package/src/edit-modes/translate-mode.ts +161 -0
  235. package/src/edit-modes/two-click-polygon-mode.ts +132 -0
  236. package/src/edit-modes/types.ts +135 -0
  237. package/src/edit-modes/utils.ts +513 -0
  238. package/src/edit-modes/view-mode.ts +3 -0
  239. package/src/editable-layers/editable-geojson-layer.ts +603 -0
  240. package/src/editable-layers/editable-h3-cluster-layer.ts +226 -0
  241. package/src/editable-layers/editable-layer.ts +252 -0
  242. package/src/editable-layers/editable-path-layer.ts +51 -0
  243. package/src/editable-layers/elevated-edit-handle-layer.ts +33 -0
  244. package/src/editable-layers/junction-scatterplot-layer.ts +53 -0
  245. package/src/editable-layers/path-marker-layer/arrow-2d-geometry.ts +61 -0
  246. package/src/editable-layers/path-marker-layer/create-path-markers.ts +107 -0
  247. package/src/editable-layers/path-marker-layer/path-marker-layer.ts +179 -0
  248. package/src/editable-layers/path-marker-layer/polyline.ts +40 -0
  249. package/src/editable-layers/path-outline-layer/path-outline-layer.ts +147 -0
  250. package/src/editable-layers/selection-layer.ts +209 -0
  251. package/src/geojson-types.ts +89 -0
  252. package/src/index.ts +125 -0
  253. package/src/lib/constants.ts +6 -0
  254. package/src/lib/deck-renderer/deck-cache.ts +61 -0
  255. package/src/lib/deck-renderer/deck-drawer.ts +263 -0
  256. package/src/lib/feature.ts +27 -0
  257. package/src/lib/layer-mouse-event.ts +32 -0
  258. package/src/lib/layers/junctions-layer.ts +40 -0
  259. package/src/lib/layers/segments-layer.ts +108 -0
  260. package/src/lib/layers/texts-layer.ts +43 -0
  261. package/src/lib/math.ts +26 -0
  262. package/src/lib/nebula-layer.ts +33 -0
  263. package/src/lib/nebula.ts +323 -0
  264. package/src/lib/style.ts +22 -0
  265. package/src/memoize.ts +43 -0
  266. package/src/mode-handlers/composite-mode-handler.ts +89 -0
  267. package/src/mode-handlers/draw-90degree-polygon-handler.ts +201 -0
  268. package/src/mode-handlers/draw-circle-by-bounding-box-handler.ts +39 -0
  269. package/src/mode-handlers/draw-circle-from-center-handler.ts +38 -0
  270. package/src/mode-handlers/draw-ellipse-by-bounding-box-handler.ts +41 -0
  271. package/src/mode-handlers/draw-ellipse-using-three-points-handler.ts +46 -0
  272. package/src/mode-handlers/draw-line-string-handler.ts +108 -0
  273. package/src/mode-handlers/draw-point-handler.ts +15 -0
  274. package/src/mode-handlers/draw-polygon-handler.ts +121 -0
  275. package/src/mode-handlers/draw-rectangle-handler.ts +28 -0
  276. package/src/mode-handlers/draw-rectangle-using-three-points-handler.ts +60 -0
  277. package/src/mode-handlers/duplicate-handler.ts +25 -0
  278. package/src/mode-handlers/elevation-handler.ts +88 -0
  279. package/src/mode-handlers/extrude-handler.ts +245 -0
  280. package/src/mode-handlers/mode-handler.ts +394 -0
  281. package/src/mode-handlers/modify-handler.ts +263 -0
  282. package/src/mode-handlers/rotate-handler.ts +107 -0
  283. package/src/mode-handlers/scale-handler.ts +105 -0
  284. package/src/mode-handlers/snappable-handler.ts +184 -0
  285. package/src/mode-handlers/split-polygon-handler.ts +177 -0
  286. package/src/mode-handlers/three-click-polygon-handler.ts +25 -0
  287. package/src/mode-handlers/translate-handler.ts +110 -0
  288. package/src/mode-handlers/two-click-polygon-handler.ts +25 -0
  289. package/src/mode-handlers/view-handler.ts +13 -0
  290. package/src/shaderlib/color/color.ts +56 -0
  291. package/src/shaderlib/outline/outline.ts +101 -0
  292. package/src/shaderlib/utils/utils.ts +33 -0
  293. package/src/translateFromCenter.ts +48 -0
  294. package/src/types.ts +39 -0
  295. package/src/utils.ts +185 -0
package/dist/utils.js ADDED
@@ -0,0 +1,144 @@
1
+ import destination from '@turf/destination';
2
+ import bearing from '@turf/bearing';
3
+ import pointToLineDistance from '@turf/point-to-line-distance';
4
+ import { point } from '@turf/helpers';
5
+ import WebMercatorViewport from 'viewport-mercator-project';
6
+ export function toDeckColor(color, defaultColor = [255, 0, 0, 255]) {
7
+ if (!Array.isArray(color)) {
8
+ return defaultColor;
9
+ }
10
+ return [color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255];
11
+ }
12
+ //
13
+ // a GeoJSON helper function that calls the provided function with
14
+ // an argument that is the most deeply-nested array having elements
15
+ // that are arrays of primitives as an argument, e.g.
16
+ //
17
+ // {
18
+ // "type": "MultiPolygon",
19
+ // "coordinates": [
20
+ // [
21
+ // [[30, 20], [45, 40], [10, 40], [30, 20]]
22
+ // ],
23
+ // [
24
+ // [[15, 5], [40, 10], [10, 20], [5, 10], [15, 5]]
25
+ // ]
26
+ // ]
27
+ // }
28
+ //
29
+ // the function would be called on:
30
+ //
31
+ // [[30, 20], [45, 40], [10, 40], [30, 20]]
32
+ //
33
+ // and
34
+ //
35
+ // [[15, 5], [40, 10], [10, 20], [5, 10], [15, 5]]
36
+ //
37
+ export function recursivelyTraverseNestedArrays(array, prefix, fn) {
38
+ if (!Array.isArray(array[0])) {
39
+ return true;
40
+ }
41
+ for (let i = 0; i < array.length; i++) {
42
+ if (recursivelyTraverseNestedArrays(array[i], [...prefix, i], fn)) {
43
+ fn(array, prefix);
44
+ break;
45
+ }
46
+ }
47
+ return false;
48
+ }
49
+ export function generatePointsParallelToLinePoints(p1, p2, mapCoords) {
50
+ const lineString = {
51
+ type: 'LineString',
52
+ coordinates: [p1, p2],
53
+ };
54
+ const pt = point(mapCoords);
55
+ const ddistance = pointToLineDistance(pt, lineString);
56
+ const lineBearing = bearing(p1, p2);
57
+ // Check if current point is to the left or right of line
58
+ // Line from A=(x1,y1) to B=(x2,y2) a point P=(x,y)
59
+ // then (x−x1)(y2−y1)−(y−y1)(x2−x1)
60
+ const isPointToLeftOfLine = (mapCoords[0] - p1[0]) * (p2[1] - p1[1]) - (mapCoords[1] - p1[1]) * (p2[0] - p1[0]);
61
+ // Bearing to draw perpendicular to the line string
62
+ const orthogonalBearing = isPointToLeftOfLine < 0 ? lineBearing - 90 : lineBearing - 270;
63
+ // Get coordinates for the point p3 and p4 which are perpendicular to the lineString
64
+ // Add the distance as the current position moves away from the lineString
65
+ const p3 = destination(p2, ddistance, orthogonalBearing);
66
+ const p4 = destination(p1, ddistance, orthogonalBearing);
67
+ return [p3.geometry.coordinates, p4.geometry.coordinates];
68
+ }
69
+ export function distance2d(x1, y1, x2, y2) {
70
+ const dx = x1 - x2;
71
+ const dy = y1 - y2;
72
+ return Math.sqrt(dx * dx + dy * dy);
73
+ }
74
+ export function mix(a, b, ratio) {
75
+ return b * ratio + a * (1 - ratio);
76
+ }
77
+ export function nearestPointOnProjectedLine(line, inPoint, viewport) {
78
+ const wmViewport = new WebMercatorViewport(viewport);
79
+ // Project the line to viewport, then find the nearest point
80
+ const coordinates = line.geometry.coordinates;
81
+ const projectedCoords = coordinates.map(([x, y, z = 0]) => wmViewport.project([x, y, z]));
82
+ const [x, y] = wmViewport.project(inPoint.geometry.coordinates);
83
+ // console.log('projectedCoords', JSON.stringify(projectedCoords));
84
+ let minDistance = Infinity;
85
+ let minPointInfo = {};
86
+ projectedCoords.forEach(([x2, y2], index) => {
87
+ if (index === 0) {
88
+ return;
89
+ }
90
+ const [x1, y1] = projectedCoords[index - 1];
91
+ // line from projectedCoords[index - 1] to projectedCoords[index]
92
+ // convert to Ax + By + C = 0
93
+ const A = y1 - y2;
94
+ const B = x2 - x1;
95
+ const C = x1 * y2 - x2 * y1;
96
+ // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
97
+ const div = A * A + B * B;
98
+ const distance = Math.abs(A * x + B * y + C) / Math.sqrt(div);
99
+ // TODO: Check if inside bounds
100
+ if (distance < minDistance) {
101
+ minDistance = distance;
102
+ minPointInfo = {
103
+ index,
104
+ x0: (B * (B * x - A * y) - A * C) / div,
105
+ y0: (A * (-B * x + A * y) - B * C) / div,
106
+ };
107
+ }
108
+ });
109
+ const { index, x0, y0 } = minPointInfo;
110
+ const [x1, y1, z1 = 0] = projectedCoords[index - 1];
111
+ const [x2, y2, z2 = 0] = projectedCoords[index];
112
+ // calculate what ratio of the line we are on to find the proper z
113
+ const lineLength = distance2d(x1, y1, x2, y2);
114
+ const startToPointLength = distance2d(x1, y1, x0, y0);
115
+ const ratio = startToPointLength / lineLength;
116
+ const z0 = mix(z1, z2, ratio);
117
+ return {
118
+ type: 'Feature',
119
+ geometry: {
120
+ type: 'Point',
121
+ // @ts-expect-error Position type diff
122
+ coordinates: wmViewport.unproject([x0, y0, z0]),
123
+ },
124
+ properties: {
125
+ // TODO: calculate the distance in proper units
126
+ dist: minDistance,
127
+ index: index - 1,
128
+ },
129
+ };
130
+ }
131
+ /**
132
+ * Inserts toInsert string into base string before insertBefore string.
133
+ * @param base A string to insert into.
134
+ * @param insertBefore A sub string in `base` string to insert before.
135
+ * @param toInsert A string to insert.
136
+ * @returns Combined string. `base` string if `insertBefore` string isn't found.
137
+ */
138
+ export function insertBefore(base, insertBefore, toInsert) {
139
+ const at = base.indexOf(insertBefore);
140
+ if (at < 0) {
141
+ return base;
142
+ }
143
+ return base.slice(0, at) + toInsert + base.slice(at);
144
+ }
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@deck.gl-community/editable-layers",
3
+ "description": "A suite of 3D-enabled data editing overlays, suitable for deck.gl",
4
+ "license": "MIT",
5
+ "version": "9.0.0-alpha.1",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/visgl/deck.gl-community"
9
+ },
10
+ "scripts": {
11
+ "test": "vitest run",
12
+ "test-watch": "vitest"
13
+ },
14
+ "keywords": [
15
+ "webgl",
16
+ "visualization",
17
+ "overlay",
18
+ "layer"
19
+ ],
20
+ "type": "module",
21
+ "types": "dist/index.d.ts",
22
+ "main": "dist/index.cjs",
23
+ "module": "dist/index.js",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "require": "./dist/index.cjs",
28
+ "import": "./dist/index.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "src"
34
+ ],
35
+ "dependencies": {
36
+ "@turf/along": "^6.5.0",
37
+ "@turf/area": "^6.5.0",
38
+ "@turf/bbox": "^6.5.0",
39
+ "@turf/bbox-polygon": "^6.5.0",
40
+ "@turf/bearing": "^6.5.0",
41
+ "@turf/boolean-point-in-polygon": "^6.5.0",
42
+ "@turf/buffer": "^6.5.0",
43
+ "@turf/center": "^6.5.0",
44
+ "@turf/centroid": "^6.5.0",
45
+ "@turf/circle": "^6.5.0",
46
+ "@turf/clone": "^6.5.0",
47
+ "@turf/destination": "^6.5.0",
48
+ "@turf/difference": "^6.5.0",
49
+ "@turf/distance": "^6.5.0",
50
+ "@turf/ellipse": "^6.5.0",
51
+ "@turf/helpers": "^6.5.0",
52
+ "@turf/intersect": "^6.5.0",
53
+ "@turf/invariant": "^6.5.0",
54
+ "@turf/line-intersect": "^6.5.0",
55
+ "@turf/meta": "^6.5.0",
56
+ "@turf/midpoint": "^6.5.0",
57
+ "@turf/nearest-point-on-line": "^6.5.0",
58
+ "@turf/point-to-line-distance": "^6.5.0",
59
+ "@turf/polygon-to-line": "^6.5.0",
60
+ "@turf/rewind": "^6.5.0",
61
+ "@turf/transform-rotate": "^6.5.0",
62
+ "@turf/transform-scale": "^6.5.0",
63
+ "@turf/transform-translate": "^6.5.0",
64
+ "@turf/union": "^6.5.0",
65
+ "cubic-hermite-spline": "^1.0.1",
66
+ "eventemitter3": "^5.0.0",
67
+ "geojson-types": "^2.0.1",
68
+ "lodash.throttle": "^4.1.1",
69
+ "uuid": "9.0.0",
70
+ "viewport-mercator-project": ">=6.2.3"
71
+ },
72
+ "peerDependencies": {
73
+ "@deck.gl/core": ">=9.0.5",
74
+ "@deck.gl/extensions": ">=9.0.5",
75
+ "@deck.gl/geo-layers": ">=9.0.5",
76
+ "@deck.gl/layers": ">=9.0.5",
77
+ "@deck.gl/mesh-layers": ">=9.0.6",
78
+ "@luma.gl/constants": ">=9.0.9",
79
+ "@luma.gl/core": ">=9.0.9",
80
+ "@luma.gl/engine": ">=9.0.9",
81
+ "@math.gl/core": ">=4.0.1"
82
+ },
83
+ "gitHead": "8374ab0ac62a52ae8a6b14276694cabced43de35"
84
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * A multiplier for screen-space width/scale for Arc, Line, Icon and Text layers.
3
+ * Required in order to maintain the same appearance after upgrading to deck.gl v8.5.
4
+ * https://github.com/visgl/deck.gl/blob/master/docs/upgrade-guide.md
5
+ */
6
+ export const PROJECTED_PIXEL_SIZE_MULTIPLIER = 2 / 3;
7
+
8
+ /**
9
+ * Unit literal to shader unit number conversion.
10
+ */
11
+ export const UNIT = {
12
+ common: 0,
13
+ meters: 1,
14
+ pixels: 2,
15
+ };
@@ -0,0 +1,77 @@
1
+ import hermite from 'cubic-hermite-spline';
2
+ import turfDistance from '@turf/distance';
3
+ import { lineString } from '@turf/helpers';
4
+ import type { Feature, MultiLineString, LineString, Position } from '@turf/helpers';
5
+
6
+ const INTERPOLATION_INTERVAL = 0.005;
7
+ const INTERPOLATION_THRESHOLD = 0.001;
8
+
9
+ function calculateSingleTangent(p0: [number, number], p1: [number, number], d: number): number[] {
10
+ const x = (p1[0] - p0[0]) / d;
11
+ const y = (p1[1] - p0[1]) / d;
12
+ return [x, y];
13
+ }
14
+
15
+ // eslint-disable-next-line max-statements
16
+ export function generateCurveFromControlPoints(
17
+ line: Feature<MultiLineString>
18
+ ): Feature<LineString> {
19
+ // calculate knots
20
+ const knots = [0];
21
+ let prev: Position[] | null = null;
22
+ let totalDistance = 0;
23
+
24
+ const { coordinates: coords } = line.geometry;
25
+
26
+ for (let i = 0; i < coords.length; i++) {
27
+ const cur = coords[i];
28
+ if (prev !== null) {
29
+ // @ts-expect-error turf types diff
30
+ totalDistance += turfDistance(prev, cur);
31
+ knots.push(totalDistance);
32
+ }
33
+ prev = cur;
34
+ }
35
+
36
+ // calculate tangents
37
+ const tangents: number[][] = [];
38
+
39
+ // first tangent
40
+ // @ts-ignore
41
+ tangents.push(calculateSingleTangent(coords[0], coords[1], knots[1] - knots[0]));
42
+
43
+ // second to before last
44
+ for (let i = 1; i < coords.length - 1; i++) {
45
+ // @ts-ignore
46
+ const A = calculateSingleTangent(coords[i], coords[i + 1], knots[i + 1] - knots[i]);
47
+ // @ts-ignore
48
+ const B = calculateSingleTangent(coords[i - 1], coords[i], knots[i] - knots[i - 1]);
49
+ const x = (A[0] + B[0]) / 2.0;
50
+ const y = (A[1] + B[1]) / 2.0;
51
+ tangents.push([x, y]);
52
+ }
53
+
54
+ // last tangent
55
+ const last = coords.length - 1;
56
+ tangents.push(
57
+ // @ts-ignore
58
+ calculateSingleTangent(coords[last - 1], coords[last], knots[last] - knots[last - 1])
59
+ );
60
+
61
+ // generate curve
62
+ const result: any[] = [];
63
+ for (let i = 0; i < coords.length; i++) {
64
+ // add control point
65
+ result.push(coords[i]);
66
+
67
+ // add interpolated values
68
+ for (let t = knots[i] + INTERPOLATION_INTERVAL; t < knots[i + 1]; t += INTERPOLATION_INTERVAL) {
69
+ if (knots[i + 1] - t > INTERPOLATION_THRESHOLD) {
70
+ // Only add if not too close to a control point (knot = control point)
71
+ result.push(hermite(t, coords, tangents, knots));
72
+ }
73
+ }
74
+ }
75
+
76
+ return lineString(result);
77
+ }
@@ -0,0 +1,74 @@
1
+ import { FeatureCollection } from '../geojson-types';
2
+ import {
3
+ ModeProps,
4
+ ClickEvent,
5
+ PointerMoveEvent,
6
+ StartDraggingEvent,
7
+ StopDraggingEvent,
8
+ DraggingEvent,
9
+ GuideFeatureCollection,
10
+ GuideFeature,
11
+ } from './types';
12
+ import { GeoJsonEditMode } from './geojson-edit-mode';
13
+
14
+ export class CompositeMode extends GeoJsonEditMode {
15
+ _modes: Array<GeoJsonEditMode>;
16
+
17
+ constructor(modes: Array<GeoJsonEditMode>) {
18
+ super();
19
+ this._modes = modes;
20
+ }
21
+
22
+ _coalesce<T>(
23
+ callback: (arg0: GeoJsonEditMode) => T,
24
+ resultEval: ((arg0: T) => boolean | null | undefined) | null = null
25
+ ): T {
26
+ let result: T | null = null;
27
+
28
+ for (let i = 0; i < this._modes.length; i++) {
29
+ // eslint-disable-next-line callback-return
30
+ result = callback(this._modes[i]);
31
+ if (resultEval ? resultEval(result) : result) {
32
+ break;
33
+ }
34
+ }
35
+
36
+ return result!;
37
+ }
38
+
39
+ handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>): void {
40
+ this._coalesce((handler) => handler.handleClick(event, props));
41
+ }
42
+
43
+ handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>): void {
44
+ return this._coalesce((handler) => handler.handlePointerMove(event, props));
45
+ }
46
+
47
+ handleStartDragging(event: StartDraggingEvent, props: ModeProps<FeatureCollection>): void {
48
+ return this._coalesce((handler) => handler.handleStartDragging(event, props));
49
+ }
50
+
51
+ handleStopDragging(event: StopDraggingEvent, props: ModeProps<FeatureCollection>): void {
52
+ return this._coalesce((handler) => handler.handleStopDragging(event, props));
53
+ }
54
+
55
+ handleDragging(event: DraggingEvent, props: ModeProps<FeatureCollection>): void {
56
+ return this._coalesce((handler) => handler.handleDragging(event, props));
57
+ }
58
+
59
+ getGuides(props: ModeProps<FeatureCollection>): GuideFeatureCollection {
60
+ // TODO: Combine the guides *BUT* make sure if none of the results have
61
+ // changed to return the same object so that "guides !== this.state.guides"
62
+ // in editable-geojson-layer works.
63
+
64
+ const allGuides: GuideFeature[] = [];
65
+ for (const mode of this._modes) {
66
+ allGuides.push(...mode.getGuides(props).features);
67
+ }
68
+
69
+ return {
70
+ type: 'FeatureCollection',
71
+ features: allGuides,
72
+ };
73
+ }
74
+ }
@@ -0,0 +1,220 @@
1
+ import destination from '@turf/destination';
2
+ import bearing from '@turf/bearing';
3
+ import lineIntersect from '@turf/line-intersect';
4
+ import turfDistance from '@turf/distance';
5
+ import { point, lineString as turfLineString } from '@turf/helpers';
6
+ import {
7
+ generatePointsParallelToLinePoints,
8
+ getPickedEditHandle,
9
+ getEditHandlesForGeometry,
10
+ } from './utils';
11
+ import {
12
+ ClickEvent,
13
+ PointerMoveEvent,
14
+ ModeProps,
15
+ GuideFeatureCollection,
16
+ TentativeFeature,
17
+ } from './types';
18
+ import { Polygon, LineString, Position, FeatureCollection } from '../geojson-types';
19
+ import { GeoJsonEditMode } from './geojson-edit-mode';
20
+
21
+ export class Draw90DegreePolygonMode extends GeoJsonEditMode {
22
+ createTentativeFeature(props: ModeProps<FeatureCollection>): TentativeFeature {
23
+ const clickSequence = this.getClickSequence();
24
+
25
+ const { mapCoords } = props.lastPointerMoveEvent;
26
+
27
+ let p3;
28
+ if (clickSequence.length === 1) {
29
+ p3 = mapCoords;
30
+ } else {
31
+ const p1 = clickSequence[clickSequence.length - 2];
32
+ const p2 = clickSequence[clickSequence.length - 1];
33
+ [p3] = generatePointsParallelToLinePoints(p1, p2, mapCoords);
34
+ }
35
+
36
+ let tentativeFeature;
37
+
38
+ if (clickSequence.length < 3) {
39
+ // Draw a LineString connecting all the clicked points with the hovered point
40
+ tentativeFeature = {
41
+ type: 'Feature',
42
+ properties: {
43
+ guideType: 'tentative',
44
+ },
45
+ geometry: {
46
+ type: 'LineString',
47
+ coordinates: [...clickSequence, p3],
48
+ },
49
+ };
50
+ } else {
51
+ // Draw a Polygon connecting all the clicked points with the hovered point
52
+ tentativeFeature = {
53
+ type: 'Feature',
54
+ properties: {
55
+ guideType: 'tentative',
56
+ },
57
+ geometry: {
58
+ type: 'Polygon',
59
+ coordinates: [[...clickSequence, p3, clickSequence[0]]],
60
+ },
61
+ };
62
+ }
63
+
64
+ return tentativeFeature;
65
+ }
66
+
67
+ getGuides(props: ModeProps<FeatureCollection>): GuideFeatureCollection {
68
+ const guides: GuideFeatureCollection = {
69
+ type: 'FeatureCollection',
70
+ features: [],
71
+ };
72
+
73
+ const clickSequence = this.getClickSequence();
74
+
75
+ if (clickSequence.length === 0 || !props.lastPointerMoveEvent) {
76
+ return guides;
77
+ }
78
+ const tentativeFeature = this.createTentativeFeature(props);
79
+
80
+ guides.features.push(tentativeFeature);
81
+
82
+ guides.features = guides.features.concat(
83
+ getEditHandlesForGeometry(tentativeFeature.geometry, -1)
84
+ );
85
+
86
+ // Slice off the handles that are are next to the pointer
87
+ guides.features = guides.features.slice(0, -1);
88
+
89
+ return guides;
90
+ }
91
+
92
+ handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
93
+ props.onUpdateCursor('cell');
94
+ super.handlePointerMove(event, props);
95
+ }
96
+
97
+ handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
98
+ const { picks } = event;
99
+ const tentativeFeature = this.getTentativeGuide(props);
100
+ this.addClickSequence(event);
101
+ const clickSequence = this.getClickSequence();
102
+
103
+ if (!tentativeFeature) {
104
+ // nothing else to do
105
+ return;
106
+ }
107
+
108
+ if (clickSequence.length === 3 && tentativeFeature.geometry.type === 'LineString') {
109
+ const lineString: LineString = tentativeFeature.geometry;
110
+
111
+ // Tweak the clicked position to be the snapped 90 degree point along the polygon
112
+ clickSequence[clickSequence.length - 1] =
113
+ lineString.coordinates[lineString.coordinates.length - 1];
114
+ } else if (clickSequence.length > 3 && tentativeFeature.geometry.type === 'Polygon') {
115
+ const polygon: Polygon = tentativeFeature.geometry;
116
+
117
+ // Tweak the clicked position to be the snapped 90 degree point along the polygon
118
+ clickSequence[clickSequence.length - 1] =
119
+ polygon.coordinates[0][polygon.coordinates[0].length - 2];
120
+
121
+ const clickedEditHandle = getPickedEditHandle(picks);
122
+
123
+ if (
124
+ clickedEditHandle &&
125
+ Array.isArray(clickedEditHandle.properties.positionIndexes) &&
126
+ (clickedEditHandle.properties.positionIndexes[1] === 0 ||
127
+ clickedEditHandle.properties.positionIndexes[1] === polygon.coordinates[0].length - 3)
128
+ ) {
129
+ // They clicked the first or last point (or double-clicked), so complete the polygon
130
+ const polygonToAdd: Polygon = {
131
+ type: 'Polygon',
132
+ coordinates: this.finalizedCoordinates([...polygon.coordinates[0]]),
133
+ };
134
+
135
+ this.resetClickSequence();
136
+
137
+ const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props);
138
+ if (editAction) {
139
+ props.onEdit(editAction);
140
+ }
141
+ }
142
+ }
143
+
144
+ // Trigger pointer move right away in order for it to update edit handles (to support double-click)
145
+ const fakePointerMoveEvent: PointerMoveEvent = {
146
+ screenCoords: [-1, -1],
147
+ mapCoords: event.mapCoords,
148
+ picks: [],
149
+ pointerDownPicks: null,
150
+ pointerDownScreenCoords: null,
151
+ pointerDownMapCoords: null,
152
+ cancelPan: () => {},
153
+ sourceEvent: null,
154
+ };
155
+
156
+ this.handlePointerMove(fakePointerMoveEvent, props);
157
+ }
158
+
159
+ finalizedCoordinates(coords: Position[]) {
160
+ // Remove the hovered position
161
+ let coordinates = [[...coords.slice(0, -2), coords[0]]];
162
+ let pt = this.getIntermediatePoint([...coords]);
163
+ if (!pt) {
164
+ // if intermediate point with 90 degree not available
165
+ // try remove the last clicked point and get the intermediate point.
166
+ const tc = [...coords];
167
+ tc.splice(-3, 1);
168
+ pt = this.getIntermediatePoint([...tc]);
169
+ if (pt) {
170
+ coordinates = [[...coords.slice(0, -3), pt, coords[0]]];
171
+ }
172
+ } else {
173
+ coordinates = [[...coords.slice(0, -2), pt, coords[0]]];
174
+ }
175
+ return coordinates;
176
+ }
177
+
178
+ getIntermediatePoint(coordinates: Position[]): Position | null {
179
+ let pt: Position | null = null;
180
+ if (coordinates.length > 4) {
181
+ const [p1, p2] = [...coordinates];
182
+ const angle1 = bearing(p1, p2);
183
+ const p3 = coordinates[coordinates.length - 3];
184
+ const p4 = coordinates[coordinates.length - 4];
185
+ const angle2 = bearing(p3, p4);
186
+
187
+ const angles = { first: [] as number[], second: [] as number[] };
188
+ // calculate 3 right angle points for first and last points in lineString
189
+ [1, 2, 3].forEach((factor) => {
190
+ const newAngle1 = angle1 + factor * 90;
191
+ // convert angles to 0 to -180 for anti-clock and 0 to 180 for clock wise
192
+ angles.first.push(newAngle1 > 180 ? newAngle1 - 360 : newAngle1);
193
+ const newAngle2 = angle2 + factor * 90;
194
+ angles.second.push(newAngle2 > 180 ? newAngle2 - 360 : newAngle2);
195
+ });
196
+
197
+ const distance = turfDistance(point(p1), point(p3));
198
+ // Draw imaginary right angle lines for both first and last points in lineString
199
+ // If there is intersection point for any 2 lines, will be the 90 degree point.
200
+ [0, 1, 2].forEach((indexFirst) => {
201
+ const line1 = turfLineString([
202
+ p1,
203
+ destination(p1, distance, angles.first[indexFirst]).geometry.coordinates,
204
+ ]);
205
+ [0, 1, 2].forEach((indexSecond) => {
206
+ const line2 = turfLineString([
207
+ p3,
208
+ destination(p3, distance, angles.second[indexSecond]).geometry.coordinates,
209
+ ]);
210
+ const fc = lineIntersect(line1, line2);
211
+ if (fc && fc.features.length) {
212
+ // found the intersect point
213
+ pt = fc.features[0].geometry.coordinates as Position;
214
+ }
215
+ });
216
+ });
217
+ }
218
+ return pt;
219
+ }
220
+ }