@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.
- package/README.md +82 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.js +14 -0
- package/dist/curve-utils.d.ts +2 -0
- package/dist/curve-utils.js +61 -0
- package/dist/edit-modes/composite-mode.d.ts +14 -0
- package/dist/edit-modes/composite-mode.js +47 -0
- package/dist/edit-modes/draw-90degree-polygon-mode.d.ts +11 -0
- package/dist/edit-modes/draw-90degree-polygon-mode.js +179 -0
- package/dist/edit-modes/draw-circle-by-diameter-mode.d.ts +24 -0
- package/dist/edit-modes/draw-circle-by-diameter-mode.js +78 -0
- package/dist/edit-modes/draw-circle-from-center-mode.d.ts +22 -0
- package/dist/edit-modes/draw-circle-from-center-mode.js +70 -0
- package/dist/edit-modes/draw-ellipse-by-bounding-box-mode.d.ts +5 -0
- package/dist/edit-modes/draw-ellipse-by-bounding-box-mode.js +20 -0
- package/dist/edit-modes/draw-ellipse-using-three-points-mode.d.ts +5 -0
- package/dist/edit-modes/draw-ellipse-using-three-points-mode.js +16 -0
- package/dist/edit-modes/draw-line-string-mode.d.ts +25 -0
- package/dist/edit-modes/draw-line-string-mode.js +170 -0
- package/dist/edit-modes/draw-point-mode.d.ts +8 -0
- package/dist/edit-modes/draw-point-mode.js +28 -0
- package/dist/edit-modes/draw-polygon-by-dragging-mode.d.ts +14 -0
- package/dist/edit-modes/draw-polygon-by-dragging-mode.js +87 -0
- package/dist/edit-modes/draw-polygon-mode.d.ts +10 -0
- package/dist/edit-modes/draw-polygon-mode.js +143 -0
- package/dist/edit-modes/draw-rectangle-from-center-mode.d.ts +5 -0
- package/dist/edit-modes/draw-rectangle-from-center-mode.js +17 -0
- package/dist/edit-modes/draw-rectangle-mode.d.ts +5 -0
- package/dist/edit-modes/draw-rectangle-mode.js +11 -0
- package/dist/edit-modes/draw-rectangle-using-three-points-mode.d.ts +5 -0
- package/dist/edit-modes/draw-rectangle-using-three-points-mode.js +28 -0
- package/dist/edit-modes/draw-square-from-center-mode.d.ts +5 -0
- package/dist/edit-modes/draw-square-from-center-mode.js +35 -0
- package/dist/edit-modes/draw-square-mode.d.ts +5 -0
- package/dist/edit-modes/draw-square-mode.js +28 -0
- package/dist/edit-modes/duplicate-mode.d.ts +7 -0
- package/dist/edit-modes/duplicate-mode.js +17 -0
- package/dist/edit-modes/edit-mode.d.ts +11 -0
- package/dist/edit-modes/edit-mode.js +2 -0
- package/dist/edit-modes/elevation-mode.d.ts +13 -0
- package/dist/edit-modes/elevation-mode.js +49 -0
- package/dist/edit-modes/extend-line-string-mode.d.ts +9 -0
- package/dist/edit-modes/extend-line-string-mode.js +72 -0
- package/dist/edit-modes/extrude-mode.d.ts +15 -0
- package/dist/edit-modes/extrude-mode.js +186 -0
- package/dist/edit-modes/geojson-edit-mode.d.ts +33 -0
- package/dist/edit-modes/geojson-edit-mode.js +208 -0
- package/dist/edit-modes/immutable-feature-collection.d.ts +43 -0
- package/dist/edit-modes/immutable-feature-collection.js +300 -0
- package/dist/edit-modes/measure-angle-mode.d.ts +11 -0
- package/dist/edit-modes/measure-angle-mode.js +99 -0
- package/dist/edit-modes/measure-area-mode.d.ts +8 -0
- package/dist/edit-modes/measure-area-mode.js +50 -0
- package/dist/edit-modes/measure-distance-mode.d.ts +19 -0
- package/dist/edit-modes/measure-distance-mode.js +171 -0
- package/dist/edit-modes/modify-mode.d.ts +15 -0
- package/dist/edit-modes/modify-mode.js +203 -0
- package/dist/edit-modes/resize-circle-mode.d.ts +16 -0
- package/dist/edit-modes/resize-circle-mode.js +142 -0
- package/dist/edit-modes/rotate-mode.d.ts +17 -0
- package/dist/edit-modes/rotate-mode.js +151 -0
- package/dist/edit-modes/scale-mode.d.ts +27 -0
- package/dist/edit-modes/scale-mode.js +173 -0
- package/dist/edit-modes/snappable-mode.d.ts +21 -0
- package/dist/edit-modes/snappable-mode.js +109 -0
- package/dist/edit-modes/split-polygon-mode.d.ts +10 -0
- package/dist/edit-modes/split-polygon-mode.js +164 -0
- package/dist/edit-modes/three-click-polygon-mode.d.ts +10 -0
- package/dist/edit-modes/three-click-polygon-mode.js +72 -0
- package/dist/edit-modes/transform-mode.d.ts +9 -0
- package/dist/edit-modes/transform-mode.js +63 -0
- package/dist/edit-modes/translate-mode.d.ts +13 -0
- package/dist/edit-modes/translate-mode.js +113 -0
- package/dist/edit-modes/two-click-polygon-mode.d.ts +13 -0
- package/dist/edit-modes/two-click-polygon-mode.js +93 -0
- package/dist/edit-modes/types.d.ts +86 -0
- package/dist/edit-modes/types.js +1 -0
- package/dist/edit-modes/utils.d.ts +36 -0
- package/dist/edit-modes/utils.js +381 -0
- package/dist/edit-modes/view-mode.d.ts +3 -0
- package/dist/edit-modes/view-mode.js +3 -0
- package/dist/editable-layers/editable-geojson-layer.d.ts +98 -0
- package/dist/editable-layers/editable-geojson-layer.js +450 -0
- package/dist/editable-layers/editable-h3-cluster-layer.d.ts +34 -0
- package/dist/editable-layers/editable-h3-cluster-layer.js +164 -0
- package/dist/editable-layers/editable-layer.d.ts +49 -0
- package/dist/editable-layers/editable-layer.js +195 -0
- package/dist/editable-layers/editable-path-layer.d.ts +9 -0
- package/dist/editable-layers/editable-path-layer.js +34 -0
- package/dist/editable-layers/elevated-edit-handle-layer.d.ts +7 -0
- package/dist/editable-layers/elevated-edit-handle-layer.js +24 -0
- package/dist/editable-layers/junction-scatterplot-layer.d.ts +14 -0
- package/dist/editable-layers/junction-scatterplot-layer.js +41 -0
- package/dist/editable-layers/path-marker-layer/arrow-2d-geometry.d.ts +4 -0
- package/dist/editable-layers/path-marker-layer/arrow-2d-geometry.js +55 -0
- package/dist/editable-layers/path-marker-layer/create-path-markers.d.ts +16 -0
- package/dist/editable-layers/path-marker-layer/create-path-markers.js +75 -0
- package/dist/editable-layers/path-marker-layer/path-marker-layer.d.ts +40 -0
- package/dist/editable-layers/path-marker-layer/path-marker-layer.js +121 -0
- package/dist/editable-layers/path-marker-layer/polyline.d.ts +18 -0
- package/dist/editable-layers/path-marker-layer/polyline.js +37 -0
- package/dist/editable-layers/path-outline-layer/path-outline-layer.d.ts +26 -0
- package/dist/editable-layers/path-outline-layer/path-outline-layer.js +106 -0
- package/dist/editable-layers/selection-layer.d.ts +26 -0
- package/dist/editable-layers/selection-layer.js +167 -0
- package/dist/geojson-types.d.ts +58 -0
- package/dist/geojson-types.js +2 -0
- package/dist/index.cjs +5825 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +62 -0
- package/dist/lib/constants.d.ts +6 -0
- package/dist/lib/constants.js +6 -0
- package/dist/lib/deck-renderer/deck-cache.d.ts +14 -0
- package/dist/lib/deck-renderer/deck-cache.js +51 -0
- package/dist/lib/deck-renderer/deck-drawer.d.ts +63 -0
- package/dist/lib/deck-renderer/deck-drawer.js +232 -0
- package/dist/lib/feature.d.ts +10 -0
- package/dist/lib/feature.js +16 -0
- package/dist/lib/layer-mouse-event.d.ts +11 -0
- package/dist/lib/layer-mouse-event.js +24 -0
- package/dist/lib/layers/junctions-layer.d.ts +8 -0
- package/dist/lib/layers/junctions-layer.js +33 -0
- package/dist/lib/layers/segments-layer.d.ts +18 -0
- package/dist/lib/layers/segments-layer.js +94 -0
- package/dist/lib/layers/texts-layer.d.ts +8 -0
- package/dist/lib/layers/texts-layer.js +32 -0
- package/dist/lib/math.d.ts +11 -0
- package/dist/lib/math.js +22 -0
- package/dist/lib/nebula-layer.d.ts +13 -0
- package/dist/lib/nebula-layer.js +26 -0
- package/dist/lib/nebula.d.ts +34 -0
- package/dist/lib/nebula.js +254 -0
- package/dist/lib/style.d.ts +19 -0
- package/dist/lib/style.js +20 -0
- package/dist/memoize.d.ts +6 -0
- package/dist/memoize.js +40 -0
- package/dist/mode-handlers/composite-mode-handler.d.ts +24 -0
- package/dist/mode-handlers/composite-mode-handler.js +55 -0
- package/dist/mode-handlers/draw-90degree-polygon-handler.d.ts +13 -0
- package/dist/mode-handlers/draw-90degree-polygon-handler.js +169 -0
- package/dist/mode-handlers/draw-circle-by-bounding-box-handler.d.ts +9 -0
- package/dist/mode-handlers/draw-circle-by-bounding-box-handler.js +29 -0
- package/dist/mode-handlers/draw-circle-from-center-handler.d.ts +9 -0
- package/dist/mode-handlers/draw-circle-from-center-handler.js +27 -0
- package/dist/mode-handlers/draw-ellipse-by-bounding-box-handler.d.ts +9 -0
- package/dist/mode-handlers/draw-ellipse-by-bounding-box-handler.js +30 -0
- package/dist/mode-handlers/draw-ellipse-using-three-points-handler.d.ts +9 -0
- package/dist/mode-handlers/draw-ellipse-using-three-points-handler.js +37 -0
- package/dist/mode-handlers/draw-line-string-handler.d.ts +9 -0
- package/dist/mode-handlers/draw-line-string-handler.js +83 -0
- package/dist/mode-handlers/draw-point-handler.d.ts +5 -0
- package/dist/mode-handlers/draw-point-handler.js +11 -0
- package/dist/mode-handlers/draw-polygon-handler.d.ts +11 -0
- package/dist/mode-handlers/draw-polygon-handler.js +92 -0
- package/dist/mode-handlers/draw-rectangle-handler.d.ts +9 -0
- package/dist/mode-handlers/draw-rectangle-handler.js +18 -0
- package/dist/mode-handlers/draw-rectangle-using-three-points-handler.d.ts +9 -0
- package/dist/mode-handlers/draw-rectangle-using-three-points-handler.js +49 -0
- package/dist/mode-handlers/duplicate-handler.d.ts +9 -0
- package/dist/mode-handlers/duplicate-handler.js +19 -0
- package/dist/mode-handlers/elevation-handler.d.ts +19 -0
- package/dist/mode-handlers/elevation-handler.js +48 -0
- package/dist/mode-handlers/extrude-handler.d.ts +18 -0
- package/dist/mode-handlers/extrude-handler.js +176 -0
- package/dist/mode-handlers/mode-handler.d.ts +61 -0
- package/dist/mode-handlers/mode-handler.js +286 -0
- package/dist/mode-handlers/modify-handler.d.ts +19 -0
- package/dist/mode-handlers/modify-handler.js +193 -0
- package/dist/mode-handlers/rotate-handler.d.ts +17 -0
- package/dist/mode-handlers/rotate-handler.js +74 -0
- package/dist/mode-handlers/scale-handler.d.ts +17 -0
- package/dist/mode-handlers/scale-handler.js +76 -0
- package/dist/mode-handlers/snappable-handler.d.ts +33 -0
- package/dist/mode-handlers/snappable-handler.js +133 -0
- package/dist/mode-handlers/split-polygon-handler.d.ts +11 -0
- package/dist/mode-handlers/split-polygon-handler.js +154 -0
- package/dist/mode-handlers/three-click-polygon-handler.d.ts +5 -0
- package/dist/mode-handlers/three-click-polygon-handler.js +18 -0
- package/dist/mode-handlers/translate-handler.d.ts +17 -0
- package/dist/mode-handlers/translate-handler.js +72 -0
- package/dist/mode-handlers/two-click-polygon-handler.d.ts +5 -0
- package/dist/mode-handlers/two-click-polygon-handler.js +18 -0
- package/dist/mode-handlers/view-handler.d.ts +8 -0
- package/dist/mode-handlers/view-handler.js +10 -0
- package/dist/shaderlib/color/color.d.ts +8 -0
- package/dist/shaderlib/color/color.js +51 -0
- package/dist/shaderlib/outline/outline.d.ts +8 -0
- package/dist/shaderlib/outline/outline.js +97 -0
- package/dist/shaderlib/utils/utils.d.ts +8 -0
- package/dist/shaderlib/utils/utils.js +28 -0
- package/dist/translateFromCenter.d.ts +4 -0
- package/dist/translateFromCenter.js +19 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +20 -0
- package/dist/utils.js +144 -0
- package/package.json +84 -0
- package/src/constants.ts +15 -0
- package/src/curve-utils.ts +77 -0
- package/src/edit-modes/composite-mode.ts +74 -0
- package/src/edit-modes/draw-90degree-polygon-mode.ts +220 -0
- package/src/edit-modes/draw-circle-by-diameter-mode.ts +88 -0
- package/src/edit-modes/draw-circle-from-center-mode.ts +79 -0
- package/src/edit-modes/draw-ellipse-by-bounding-box-mode.ts +25 -0
- package/src/edit-modes/draw-ellipse-using-three-points-mode.ts +23 -0
- package/src/edit-modes/draw-line-string-mode.ts +200 -0
- package/src/edit-modes/draw-point-mode.ts +35 -0
- package/src/edit-modes/draw-polygon-by-dragging-mode.ts +106 -0
- package/src/edit-modes/draw-polygon-mode.ts +171 -0
- package/src/edit-modes/draw-rectangle-from-center-mode.ts +23 -0
- package/src/edit-modes/draw-rectangle-mode.ts +14 -0
- package/src/edit-modes/draw-rectangle-using-three-points-mode.ts +36 -0
- package/src/edit-modes/draw-square-from-center-mode.ts +46 -0
- package/src/edit-modes/draw-square-mode.ts +36 -0
- package/src/edit-modes/duplicate-mode.ts +21 -0
- package/src/edit-modes/edit-mode.ts +30 -0
- package/src/edit-modes/elevation-mode.ts +86 -0
- package/src/edit-modes/extend-line-string-mode.ts +87 -0
- package/src/edit-modes/extrude-mode.ts +254 -0
- package/src/edit-modes/geojson-edit-mode.ts +283 -0
- package/src/edit-modes/immutable-feature-collection.ts +417 -0
- package/src/edit-modes/measure-angle-mode.ts +127 -0
- package/src/edit-modes/measure-area-mode.ts +62 -0
- package/src/edit-modes/measure-distance-mode.ts +215 -0
- package/src/edit-modes/modify-mode.ts +293 -0
- package/src/edit-modes/resize-circle-mode.ts +202 -0
- package/src/edit-modes/rotate-mode.ts +208 -0
- package/src/edit-modes/scale-mode.ts +231 -0
- package/src/edit-modes/snappable-mode.ts +174 -0
- package/src/edit-modes/split-polygon-mode.ts +201 -0
- package/src/edit-modes/three-click-polygon-mode.ts +111 -0
- package/src/edit-modes/transform-mode.ts +75 -0
- package/src/edit-modes/translate-mode.ts +161 -0
- package/src/edit-modes/two-click-polygon-mode.ts +132 -0
- package/src/edit-modes/types.ts +135 -0
- package/src/edit-modes/utils.ts +513 -0
- package/src/edit-modes/view-mode.ts +3 -0
- package/src/editable-layers/editable-geojson-layer.ts +603 -0
- package/src/editable-layers/editable-h3-cluster-layer.ts +226 -0
- package/src/editable-layers/editable-layer.ts +252 -0
- package/src/editable-layers/editable-path-layer.ts +51 -0
- package/src/editable-layers/elevated-edit-handle-layer.ts +33 -0
- package/src/editable-layers/junction-scatterplot-layer.ts +53 -0
- package/src/editable-layers/path-marker-layer/arrow-2d-geometry.ts +61 -0
- package/src/editable-layers/path-marker-layer/create-path-markers.ts +107 -0
- package/src/editable-layers/path-marker-layer/path-marker-layer.ts +179 -0
- package/src/editable-layers/path-marker-layer/polyline.ts +40 -0
- package/src/editable-layers/path-outline-layer/path-outline-layer.ts +147 -0
- package/src/editable-layers/selection-layer.ts +209 -0
- package/src/geojson-types.ts +89 -0
- package/src/index.ts +125 -0
- package/src/lib/constants.ts +6 -0
- package/src/lib/deck-renderer/deck-cache.ts +61 -0
- package/src/lib/deck-renderer/deck-drawer.ts +263 -0
- package/src/lib/feature.ts +27 -0
- package/src/lib/layer-mouse-event.ts +32 -0
- package/src/lib/layers/junctions-layer.ts +40 -0
- package/src/lib/layers/segments-layer.ts +108 -0
- package/src/lib/layers/texts-layer.ts +43 -0
- package/src/lib/math.ts +26 -0
- package/src/lib/nebula-layer.ts +33 -0
- package/src/lib/nebula.ts +323 -0
- package/src/lib/style.ts +22 -0
- package/src/memoize.ts +43 -0
- package/src/mode-handlers/composite-mode-handler.ts +89 -0
- package/src/mode-handlers/draw-90degree-polygon-handler.ts +201 -0
- package/src/mode-handlers/draw-circle-by-bounding-box-handler.ts +39 -0
- package/src/mode-handlers/draw-circle-from-center-handler.ts +38 -0
- package/src/mode-handlers/draw-ellipse-by-bounding-box-handler.ts +41 -0
- package/src/mode-handlers/draw-ellipse-using-three-points-handler.ts +46 -0
- package/src/mode-handlers/draw-line-string-handler.ts +108 -0
- package/src/mode-handlers/draw-point-handler.ts +15 -0
- package/src/mode-handlers/draw-polygon-handler.ts +121 -0
- package/src/mode-handlers/draw-rectangle-handler.ts +28 -0
- package/src/mode-handlers/draw-rectangle-using-three-points-handler.ts +60 -0
- package/src/mode-handlers/duplicate-handler.ts +25 -0
- package/src/mode-handlers/elevation-handler.ts +88 -0
- package/src/mode-handlers/extrude-handler.ts +245 -0
- package/src/mode-handlers/mode-handler.ts +394 -0
- package/src/mode-handlers/modify-handler.ts +263 -0
- package/src/mode-handlers/rotate-handler.ts +107 -0
- package/src/mode-handlers/scale-handler.ts +105 -0
- package/src/mode-handlers/snappable-handler.ts +184 -0
- package/src/mode-handlers/split-polygon-handler.ts +177 -0
- package/src/mode-handlers/three-click-polygon-handler.ts +25 -0
- package/src/mode-handlers/translate-handler.ts +110 -0
- package/src/mode-handlers/two-click-polygon-handler.ts +25 -0
- package/src/mode-handlers/view-handler.ts +13 -0
- package/src/shaderlib/color/color.ts +56 -0
- package/src/shaderlib/outline/outline.ts +101 -0
- package/src/shaderlib/utils/utils.ts +33 -0
- package/src/translateFromCenter.ts +48 -0
- package/src/types.ts +39 -0
- 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
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -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
|
+
}
|