@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
@@ -0,0 +1,107 @@
1
+ import { Vector2 } from '@math.gl/core';
2
+ import { Position } from '../../geojson-types';
3
+ import { Color } from '../../types';
4
+
5
+ export interface PathMarker {
6
+ position: Position,
7
+ angle: number,
8
+ color: Color,
9
+ object: unknown
10
+ }
11
+
12
+ function getLineLength(vPoints) {
13
+ // calculate total length
14
+ let lineLength = 0;
15
+ for (let i = 0; i < vPoints.length - 1; i++) {
16
+ lineLength += vPoints[i].distance(vPoints[i + 1]);
17
+ }
18
+ return lineLength;
19
+ }
20
+
21
+ const DEFAULT_COLOR = [0, 0, 0, 255];
22
+ const DEFAULT_DIRECTION = { forward: true, backward: false };
23
+
24
+ export default function createPathMarkers({
25
+ data,
26
+ getPath = (x, context) => x.path,
27
+ getDirection = (x) => x.direction,
28
+ getColor = (x) => DEFAULT_COLOR,
29
+ getMarkerPercentages = (x, info) => [0.5],
30
+ projectFlat,
31
+ }): PathMarker[] {
32
+ const markers: PathMarker[] = [];
33
+
34
+ for (const object of data) {
35
+ const path = getPath(object, null);
36
+ const direction = getDirection(object) || DEFAULT_DIRECTION;
37
+ const color = getColor(object);
38
+
39
+ const vPoints = path.map((p) => new Vector2(p));
40
+ const vPointsReverse = vPoints.slice(0).reverse();
41
+
42
+ // calculate total length
43
+ const lineLength = getLineLength(vPoints);
44
+
45
+ // Ask for where to put markers
46
+ const percentages = getMarkerPercentages(object, { lineLength });
47
+
48
+ // Create the markers
49
+ for (const percentage of percentages) {
50
+ if (direction.forward) {
51
+ const marker = createMarkerAlongPath({
52
+ path: vPoints,
53
+ percentage,
54
+ lineLength,
55
+ color,
56
+ object,
57
+ projectFlat,
58
+ });
59
+ markers.push(marker);
60
+ }
61
+
62
+ if (direction.backward) {
63
+ const marker = createMarkerAlongPath({
64
+ path: vPointsReverse,
65
+ percentage,
66
+ lineLength,
67
+ color,
68
+ object,
69
+ projectFlat,
70
+ });
71
+ markers.push(marker);
72
+ }
73
+ }
74
+ }
75
+
76
+ return markers;
77
+ }
78
+
79
+ function createMarkerAlongPath({ path, percentage, lineLength, color, object, projectFlat }): PathMarker {
80
+ const distanceAlong = lineLength * percentage;
81
+ let currentDistance = 0;
82
+ let previousDistance = 0;
83
+ let i = 0;
84
+ for (i = 0; i < path.length - 1; i++) {
85
+ currentDistance += path[i].distance(path[i + 1]);
86
+ if (currentDistance > distanceAlong) {
87
+ break;
88
+ }
89
+ previousDistance = currentDistance;
90
+ }
91
+
92
+ // If reached the end of the loop without exiting early,
93
+ // undo the final increment to avoid a null-pointer exception
94
+ if (i === path.length - 1) {
95
+ i -= 1;
96
+ }
97
+
98
+ const vDirection = path[i + 1].clone().subtract(path[i]).normalize();
99
+ const along = distanceAlong - previousDistance;
100
+ const vCenter = vDirection.clone().multiply(new Vector2(along, along)).add(path[i]);
101
+
102
+ const vDirection2 = new Vector2(projectFlat(path[i + 1])).subtract(projectFlat(path[i]));
103
+
104
+ const angle = (vDirection2.verticalAngle() * 180) / Math.PI;
105
+
106
+ return { position: [vCenter.x, vCenter.y, 0], angle, color, object };
107
+ }
@@ -0,0 +1,179 @@
1
+ import {CompositeLayer, COORDINATE_SYSTEM, DefaultProps} from '@deck.gl/core';
2
+ import {ScatterplotLayer} from '@deck.gl/layers';
3
+ import {SimpleMeshLayer} from '@deck.gl/mesh-layers';
4
+ import PathOutlineLayer, {PathOutlineLayerProps} from '../path-outline-layer/path-outline-layer';
5
+ import Arrow2DGeometry from './arrow-2d-geometry';
6
+
7
+ import createPathMarkers from './create-path-markers';
8
+ import {getClosestPointOnPolyline} from './polyline';
9
+ import {Vector3} from '@math.gl/core';
10
+
11
+ const DISTANCE_FOR_MULTI_ARROWS = 0.1;
12
+ const ARROW_HEAD_SIZE = 0.2;
13
+ const ARROW_TAIL_WIDTH = 0.05;
14
+ // const ARROW_CENTER_ADJUST = -0.8;
15
+
16
+ const DEFAULT_MARKER_LAYER = SimpleMeshLayer;
17
+
18
+ export type PathMarkerLayerProps<DataT> = PathOutlineLayerProps<DataT> & {
19
+ getDirection?: (x) => any;
20
+ getMarkerColor?: (x) => number[];
21
+ getMarkerPercentages?: (x: any, info: any) => number[];
22
+ highlightPoint?: any;
23
+ highlightIndex?: number;
24
+ MarkerLayer?: any;
25
+ markerLayerProps?: any;
26
+ sizeScale?: number;
27
+ fp64?: boolean;
28
+ nebulaLayer?: any;
29
+ };
30
+
31
+ const DEFAULT_MARKER_LAYER_PROPS = {
32
+ mesh: new Arrow2DGeometry({headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH})
33
+ };
34
+
35
+ const defaultProps: DefaultProps<PathMarkerLayerProps<any>> = Object.assign(
36
+ {},
37
+ PathOutlineLayer.defaultProps,
38
+ {
39
+ MarkerLayer: DEFAULT_MARKER_LAYER,
40
+ markerLayerProps: DEFAULT_MARKER_LAYER_PROPS,
41
+
42
+ sizeScale: 100,
43
+ fp64: false,
44
+
45
+ highlightIndex: -1,
46
+ highlightPoint: null,
47
+
48
+ getPath: (x) => x.path,
49
+ getColor: (x) => x.color,
50
+ getMarkerColor: (x) => [0, 0, 0, 255],
51
+ getDirection: (x) => x.direction,
52
+ getMarkerPercentages: (object, {lineLength}) =>
53
+ lineLength > DISTANCE_FOR_MULTI_ARROWS ? [0.25, 0.5, 0.75] : [0.5]
54
+ }
55
+ );
56
+
57
+ export default class PathMarkerLayer<
58
+ DataT = any,
59
+ ExtraPropsT = Record<string, unknown>
60
+ > extends CompositeLayer<ExtraPropsT & Required<PathMarkerLayerProps<DataT>>> {
61
+ static layerName = 'PathMarkerLayer';
62
+ static defaultProps = defaultProps;
63
+
64
+ state: {
65
+ closestPoint: Vector3 | null;
66
+ closestPoints?: {position: Vector3}[];
67
+ markers: any[];
68
+ mesh: Arrow2DGeometry;
69
+ } = undefined!;
70
+
71
+ initializeState() {
72
+ this.state = {
73
+ markers: [],
74
+ mesh: new Arrow2DGeometry({headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH}),
75
+ closestPoint: null,
76
+ closestPoints: []
77
+ };
78
+ }
79
+
80
+ projectFlat(xyz, viewport, coordinateSystem, coordinateOrigin) {
81
+ if (coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS) {
82
+ const [dx, dy] = viewport.metersToLngLatDelta(xyz);
83
+ const [x, y] = coordinateOrigin;
84
+ return viewport.projectFlat([x + dx, dy + y]);
85
+ } else if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS) {
86
+ const [dx, dy] = xyz;
87
+ const [x, y] = coordinateOrigin;
88
+ return viewport.projectFlat([x + dx, dy + y]);
89
+ }
90
+
91
+ return viewport.projectFlat(xyz);
92
+ }
93
+
94
+ updateState({props, oldProps, changeFlags}) {
95
+ if (changeFlags.dataChanged || changeFlags.updateTriggersChanged) {
96
+ const {
97
+ data,
98
+ getPath,
99
+ getDirection,
100
+ getMarkerColor,
101
+ getMarkerPercentages,
102
+ coordinateSystem,
103
+ coordinateOrigin
104
+ } = this.props;
105
+
106
+ const {viewport} = this.context;
107
+ const projectFlat = (o) => this.projectFlat(o, viewport, coordinateSystem, coordinateOrigin);
108
+ this.state.markers = createPathMarkers({
109
+ data,
110
+ getPath,
111
+ getDirection,
112
+ getColor: getMarkerColor,
113
+ getMarkerPercentages,
114
+ projectFlat
115
+ });
116
+ this._recalculateClosestPoint();
117
+ }
118
+ if (changeFlags.propsChanged) {
119
+ if (props.point !== oldProps.point) {
120
+ this._recalculateClosestPoint();
121
+ }
122
+ }
123
+ }
124
+
125
+ _recalculateClosestPoint() {
126
+ const {highlightPoint, highlightIndex} = this.props;
127
+ if (highlightPoint && highlightIndex >= 0) {
128
+ const object = this.props.data![highlightIndex];
129
+ const points = this.props.getPath(object, null as any);
130
+ const {point} = getClosestPointOnPolyline({points, p: highlightPoint});
131
+ this.state.closestPoints = [{position: point}];
132
+ } else {
133
+ this.state.closestPoints = [];
134
+ }
135
+ }
136
+
137
+ getPickingInfo({info}) {
138
+ return Object.assign(info, {
139
+ // override object with picked feature
140
+ object: (info.object && info.object.path) || info.object
141
+ });
142
+ }
143
+
144
+ renderLayers() {
145
+ return [
146
+ new PathOutlineLayer(
147
+ this.props,
148
+ this.getSubLayerProps({
149
+ id: 'paths',
150
+ // Note: data has to be passed explicitly like this to avoid being empty
151
+ data: this.props.data
152
+ })
153
+ ),
154
+ new this.props.MarkerLayer(
155
+ this.getSubLayerProps(
156
+ Object.assign({}, this.props.markerLayerProps, {
157
+ id: 'markers',
158
+ data: this.state.markers,
159
+ getOrientation: (x) => [0, -x.angle, 0],
160
+ getColor: (x) => x.color,
161
+ sizeScale: this.props.sizeScale,
162
+ fp64: this.props.fp64,
163
+ pickable: false,
164
+ parameters: {
165
+ blend: false,
166
+ depthTest: false
167
+ }
168
+ })
169
+ )
170
+ ),
171
+ this.state.closestPoints &&
172
+ new ScatterplotLayer({
173
+ id: `${this.props.id}-highlight`,
174
+ data: this.state.closestPoints,
175
+ fp64: this.props.fp64
176
+ })
177
+ ];
178
+ }
179
+ }
@@ -0,0 +1,40 @@
1
+ import { Vector3, clamp } from '@math.gl/core';
2
+
3
+ // Return the closest point on a line segment
4
+ export function getClosestPointOnLine({ p, p1, p2, clampToLine = true }) {
5
+ const lineVector = new Vector3(p2).subtract(p1);
6
+ const pointVector = new Vector3(p).subtract(p1);
7
+ let dotProduct = lineVector.dot(pointVector);
8
+ if (clampToLine) {
9
+ dotProduct = clamp(dotProduct, 0, 1);
10
+ }
11
+
12
+ return lineVector.lerp(p1, p2, dotProduct);
13
+ }
14
+
15
+ // Return the closest point on a line segment
16
+ export function getClosestPointOnPolyline({ p, points }) {
17
+ p = new Vector3(p);
18
+ let pClosest: Vector3 | null = null;
19
+ let distanceSquared = Infinity;
20
+ let index = -1;
21
+ for (let i = 0; i < points.length - 1; ++i) {
22
+ const p1 = points[i];
23
+ const p2 = points[i + 1];
24
+ const pClosestOnLine = getClosestPointOnLine({ p, p1, p2 });
25
+ const distanceToLineSquared = p.distanceSquared(pClosestOnLine);
26
+ if (distanceToLineSquared < distanceSquared) {
27
+ distanceSquared = distanceToLineSquared;
28
+ pClosest = pClosestOnLine;
29
+ index = i;
30
+ }
31
+ }
32
+ return {
33
+ point: pClosest as Vector3,
34
+ index,
35
+ p1: points[index],
36
+ p2: points[index + 1],
37
+ distanceSquared,
38
+ distance: Math.sqrt(distanceSquared),
39
+ };
40
+ }
@@ -0,0 +1,147 @@
1
+ import { PathLayer, PathLayerProps } from '@deck.gl/layers';
2
+ import type { DefaultProps, LayerContext } from '@deck.gl/core';
3
+ import {GL} from '@luma.gl/constants';
4
+ import { Framebuffer, Texture } from '@luma.gl/core';
5
+ import outline from '../../shaderlib/outline/outline';
6
+ import { UNIT } from '../../constants';
7
+
8
+ // TODO - this should be built into assembleShaders
9
+ function injectShaderCode({ source, code = '' }) {
10
+ const INJECT_CODE = /}[^{}]*$/;
11
+ return source.replace(INJECT_CODE, code.concat('\n}\n'));
12
+ }
13
+
14
+ const VS_CODE = `\
15
+ outline_setUV(gl_Position);
16
+ outline_setZLevel(instanceZLevel);
17
+ `;
18
+
19
+ const FS_CODE = `\
20
+ fragColor = outline_filterColor(fragColor);
21
+ `;
22
+
23
+ export type PathOutlineLayerProps<DataT> = PathLayerProps<DataT> & {
24
+ dashJustified?: boolean;
25
+ getDashArray?: [number, number] | ((d: DataT) => [number, number] | null);
26
+ getZLevel?: (d: DataT, index: number) => number;
27
+ };
28
+
29
+ const defaultProps: DefaultProps<PathOutlineLayerProps<any>> = {
30
+ getZLevel: () => 0,
31
+ };
32
+
33
+ export default class PathOutlineLayer<
34
+ DataT = any,
35
+ ExtraPropsT = Record<string, unknown>
36
+ > extends PathLayer<DataT, ExtraPropsT & Required<PathOutlineLayerProps<DataT>>> {
37
+ static layerName = 'PathOutlineLayer';
38
+ static defaultProps = defaultProps;
39
+
40
+ state: {
41
+ model?: any;
42
+ pathTesselator: any;
43
+ outlineFramebuffer: Framebuffer;
44
+ dummyTexture: Texture;
45
+ } = undefined!;
46
+
47
+ // Override getShaders to inject the outline module
48
+ getShaders() {
49
+ const shaders = super.getShaders();
50
+ return Object.assign({}, shaders, {
51
+ modules: shaders.modules.concat([outline]),
52
+ vs: injectShaderCode({ source: shaders.vs, code: VS_CODE }),
53
+ fs: injectShaderCode({ source: shaders.fs, code: FS_CODE }),
54
+ });
55
+ }
56
+
57
+ // @ts-expect-error PathLayer is missing LayerContext arg
58
+ initializeState(context: LayerContext) {
59
+ super.initializeState();
60
+
61
+ // Create an outline "shadow" map
62
+ // TODO - we should create a single outlineMap for all layers
63
+ this.setState({
64
+ outlineFramebuffer: context.device.createFramebuffer({}),
65
+ dummyTexture: context.device.createTexture({}),
66
+ });
67
+
68
+ // Create an attribute manager
69
+ // @ts-expect-error check whether this.getAttributeManager works here
70
+ this.state.attributeManager.addInstanced({
71
+ instanceZLevel: {
72
+ size: 1,
73
+ type: GL.UNSIGNED_BYTE,
74
+ accessor: 'getZLevel',
75
+ },
76
+ });
77
+ }
78
+
79
+ // Override draw to add render module
80
+ draw({ moduleParameters = {}, parameters, uniforms, context }) {
81
+ // Need to calculate same uniforms as base layer
82
+ const {
83
+ jointRounded,
84
+ capRounded,
85
+ billboard,
86
+ miterLimit,
87
+ widthUnits,
88
+ widthScale,
89
+ widthMinPixels,
90
+ widthMaxPixels,
91
+ } = this.props;
92
+
93
+ uniforms = Object.assign({}, uniforms, {
94
+ jointType: Number(jointRounded),
95
+ capType: Number(capRounded),
96
+ billboard,
97
+ widthUnits: UNIT[widthUnits],
98
+ widthScale,
99
+ miterLimit,
100
+ widthMinPixels,
101
+ widthMaxPixels,
102
+ });
103
+
104
+ // Render the outline shadowmap (based on segment z orders)
105
+ const { outlineFramebuffer, dummyTexture } = this.state;
106
+ // TODO(v9): resize, see 'sf' example.
107
+ // outlineFramebuffer.resize();
108
+ // TODO(v9) clear FBO
109
+ // outlineFramebuffer.clear({ color: true, depth: true, stencil: true });
110
+
111
+ this.state.model.updateModuleSettings({
112
+ outlineEnabled: true,
113
+ outlineRenderShadowmap: true,
114
+ outlineShadowmap: dummyTexture,
115
+ });
116
+
117
+ this.state.model.draw({
118
+ uniforms: Object.assign({}, uniforms, {
119
+ jointType: 0,
120
+ widthScale: this.props.widthScale * 1.3,
121
+ }),
122
+ parameters: {
123
+ depthTest: false,
124
+ // Biggest value needs to go into buffer
125
+ blendEquation: GL.MAX,
126
+ },
127
+ framebuffer: outlineFramebuffer,
128
+ });
129
+
130
+ // Now use the outline shadowmap to render the lines (with outlines)
131
+ this.state.model.updateModuleSettings({
132
+ outlineEnabled: true,
133
+ outlineRenderShadowmap: false,
134
+ outlineShadowmap: outlineFramebuffer,
135
+ });
136
+ this.state.model.draw({
137
+ uniforms: Object.assign({}, uniforms, {
138
+ jointType: Number(jointRounded),
139
+ capType: Number(capRounded),
140
+ widthScale: this.props.widthScale,
141
+ }),
142
+ parameters: {
143
+ depthTest: false,
144
+ },
145
+ });
146
+ }
147
+ }
@@ -0,0 +1,209 @@
1
+ /* eslint-env browser */
2
+
3
+ import {CompositeLayer, CompositeLayerProps, DefaultProps} from '@deck.gl/core';
4
+ import {PolygonLayer} from '@deck.gl/layers';
5
+ import {polygon} from '@turf/helpers';
6
+ import turfBuffer from '@turf/buffer';
7
+ import turfDifference from '@turf/difference';
8
+
9
+ import EditableGeoJsonLayer from './editable-geojson-layer';
10
+ import {DrawRectangleMode} from '../edit-modes/draw-rectangle-mode';
11
+ import {DrawPolygonMode} from '../edit-modes/draw-polygon-mode';
12
+ import {ViewMode} from '../edit-modes/view-mode';
13
+
14
+ export const SELECTION_TYPE = {
15
+ NONE: null,
16
+ RECTANGLE: 'rectangle',
17
+ POLYGON: 'polygon'
18
+ };
19
+
20
+ const MODE_MAP = {
21
+ [SELECTION_TYPE.RECTANGLE]: DrawRectangleMode,
22
+ [SELECTION_TYPE.POLYGON]: DrawPolygonMode
23
+ };
24
+
25
+ const MODE_CONFIG_MAP = {
26
+ [SELECTION_TYPE.RECTANGLE]: {dragToDraw: true}
27
+ };
28
+
29
+ interface SelectionLayerProps<DataT> extends CompositeLayerProps {
30
+ layerIds: any[];
31
+ onSelect: (info: any) => any;
32
+ selectionType: string | null;
33
+ }
34
+
35
+ const defaultProps: DefaultProps<SelectionLayerProps<any>> = {
36
+ selectionType: SELECTION_TYPE.RECTANGLE,
37
+ layerIds: [],
38
+ onSelect: () => {}
39
+ };
40
+
41
+ const EMPTY_DATA = {
42
+ type: 'FeatureCollection',
43
+ features: []
44
+ };
45
+
46
+ const EXPANSION_KM = 50;
47
+ const LAYER_ID_GEOJSON = 'selection-geojson';
48
+ const LAYER_ID_BLOCKER = 'selection-blocker';
49
+
50
+ const PASS_THROUGH_PROPS = [
51
+ 'lineWidthScale',
52
+ 'lineWidthMinPixels',
53
+ 'lineWidthMaxPixels',
54
+ 'lineWidthUnits',
55
+ 'lineJointRounded',
56
+ 'lineCapRounded',
57
+ 'lineMiterLimit',
58
+ 'pointRadiusScale',
59
+ 'pointRadiusMinPixels',
60
+ 'pointRadiusMaxPixels',
61
+ 'lineDashJustified',
62
+ 'getLineColor',
63
+ 'getFillColor',
64
+ 'getRadius',
65
+ 'getLineWidth',
66
+ 'getLineDashArray',
67
+ 'getTentativeLineDashArray',
68
+ 'getTentativeLineColor',
69
+ 'getTentativeFillColor',
70
+ 'getTentativeLineWidth'
71
+ ];
72
+ export default class SelectionLayer<DataT, ExtraPropsT> extends CompositeLayer<
73
+ ExtraPropsT & Required<SelectionLayerProps<DataT>>
74
+ > {
75
+ static layerName = 'SelectionLayer';
76
+ static defaultProps = defaultProps;
77
+
78
+ state: {
79
+ pendingPolygonSelection: {
80
+ bigPolygon: ReturnType<typeof turfDifference>;
81
+ };
82
+ } = undefined!;
83
+
84
+ _selectRectangleObjects(coordinates: any) {
85
+ const {layerIds, onSelect} = this.props;
86
+ const [x1, y1] = this.context.viewport.project(coordinates[0][0]);
87
+ const [x2, y2] = this.context.viewport.project(coordinates[0][2]);
88
+ const pickingInfos = this.context.deck!.pickObjects({
89
+ x: Math.min(x1, x2),
90
+ y: Math.min(y1, y2),
91
+ width: Math.abs(x2 - x1),
92
+ height: Math.abs(y2 - y1),
93
+ layerIds
94
+ });
95
+
96
+ onSelect({pickingInfos});
97
+ }
98
+
99
+ _selectPolygonObjects(coordinates: any) {
100
+ const {layerIds, onSelect} = this.props;
101
+ const mousePoints = coordinates[0].map((c) => this.context.viewport.project(c));
102
+
103
+ const allX = mousePoints.map((mousePoint) => mousePoint[0]);
104
+ const allY = mousePoints.map((mousePoint) => mousePoint[1]);
105
+ const x = Math.min(...allX);
106
+ const y = Math.min(...allY);
107
+ const maxX = Math.max(...allX);
108
+ const maxY = Math.max(...allY);
109
+
110
+ // Use a polygon to hide the outside, because pickObjects()
111
+ // does not support polygons
112
+ const landPointsPoly = polygon(coordinates);
113
+ const bigBuffer = turfBuffer(landPointsPoly, EXPANSION_KM);
114
+ let bigPolygon;
115
+ try {
116
+ // turfDifference throws an exception if the polygon
117
+ // intersects with itself (TODO: check if true in all versions)
118
+ bigPolygon = turfDifference(bigBuffer, landPointsPoly);
119
+ } catch (e) {
120
+ // invalid selection polygon
121
+ console.log('turfDifference() error', e); // eslint-disable-line
122
+ return;
123
+ }
124
+
125
+ this.setState({
126
+ pendingPolygonSelection: {
127
+ bigPolygon
128
+ }
129
+ });
130
+
131
+ const blockerId = `${this.props.id}-${LAYER_ID_BLOCKER}`;
132
+
133
+ // HACK, find a better way
134
+ setTimeout(() => {
135
+ const pickingInfos = this.context.deck!.pickObjects({
136
+ x,
137
+ y,
138
+ width: maxX - x,
139
+ height: maxY - y,
140
+ layerIds: [blockerId, ...layerIds]
141
+ });
142
+
143
+ onSelect({
144
+ pickingInfos: pickingInfos.filter((item) => item.layer!.id !== this.props.id)
145
+ });
146
+ }, 250);
147
+ }
148
+
149
+ renderLayers() {
150
+ const {pendingPolygonSelection} = this.state;
151
+
152
+ const mode = MODE_MAP[this.props.selectionType!] || ViewMode;
153
+ const modeConfig = MODE_CONFIG_MAP[this.props.selectionType!];
154
+
155
+ const inheritedProps = {};
156
+ PASS_THROUGH_PROPS.forEach((p) => {
157
+ if (this.props[p] !== undefined) inheritedProps[p] = this.props[p];
158
+ });
159
+
160
+ const layers: any[] = [
161
+ new EditableGeoJsonLayer(
162
+ this.getSubLayerProps({
163
+ id: LAYER_ID_GEOJSON,
164
+ pickable: true,
165
+ mode,
166
+ modeConfig,
167
+ selectedFeatureIndexes: [],
168
+ data: EMPTY_DATA,
169
+ onEdit: ({updatedData, editType}) => {
170
+ if (editType === 'addFeature') {
171
+ const {coordinates} = updatedData.features[0].geometry;
172
+
173
+ if (this.props.selectionType === SELECTION_TYPE.RECTANGLE) {
174
+ this._selectRectangleObjects(coordinates);
175
+ } else if (this.props.selectionType === SELECTION_TYPE.POLYGON) {
176
+ this._selectPolygonObjects(coordinates);
177
+ }
178
+ }
179
+ },
180
+ ...inheritedProps
181
+ })
182
+ )
183
+ ];
184
+
185
+ if (pendingPolygonSelection) {
186
+ const {bigPolygon} = pendingPolygonSelection as any;
187
+ layers.push(
188
+ new PolygonLayer(
189
+ this.getSubLayerProps({
190
+ id: LAYER_ID_BLOCKER,
191
+ pickable: true,
192
+ stroked: false,
193
+ opacity: 1.0,
194
+ data: [bigPolygon],
195
+ getLineColor: (obj) => [0, 0, 0, 1],
196
+ getFillColor: (obj) => [0, 0, 0, 1],
197
+ getPolygon: (o) => o.geometry.coordinates
198
+ })
199
+ )
200
+ );
201
+ }
202
+
203
+ return layers;
204
+ }
205
+
206
+ shouldUpdateState({changeFlags: {stateChanged, propsOrDataChanged}}: Record<string, any>) {
207
+ return stateChanged || propsOrDataChanged;
208
+ }
209
+ }