@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
|
@@ -0,0 +1,201 @@
|
|
|
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 } from '@turf/helpers';
|
|
6
|
+
import { Polygon, Position } from '../geojson-types';
|
|
7
|
+
import { generatePointsParallelToLinePoints } from '../utils';
|
|
8
|
+
import { ClickEvent, PointerMoveEvent } from '../edit-modes/types';
|
|
9
|
+
import {
|
|
10
|
+
EditAction,
|
|
11
|
+
EditHandle,
|
|
12
|
+
ModeHandler,
|
|
13
|
+
getPickedEditHandle,
|
|
14
|
+
getEditHandlesForGeometry,
|
|
15
|
+
} from './mode-handler';
|
|
16
|
+
|
|
17
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
18
|
+
export class Draw90DegreePolygonHandler extends ModeHandler {
|
|
19
|
+
getEditHandles(picks?: Array<Record<string, any>>, mapCoords?: Position): EditHandle[] {
|
|
20
|
+
let handles = super.getEditHandles(picks, mapCoords);
|
|
21
|
+
|
|
22
|
+
const tentativeFeature = this.getTentativeFeature();
|
|
23
|
+
if (tentativeFeature) {
|
|
24
|
+
handles = handles.concat(getEditHandlesForGeometry(tentativeFeature.geometry, -1));
|
|
25
|
+
// Slice off the handles that are are next to the pointer
|
|
26
|
+
if (tentativeFeature && tentativeFeature.geometry.type === 'LineString') {
|
|
27
|
+
// Remove the last existing handle
|
|
28
|
+
handles = handles.slice(0, -1);
|
|
29
|
+
} else if (tentativeFeature && tentativeFeature.geometry.type === 'Polygon') {
|
|
30
|
+
// Remove the last existing handle
|
|
31
|
+
handles = handles.slice(0, -1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return handles;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
handlePointerMove({ mapCoords }: PointerMoveEvent): {
|
|
39
|
+
editAction: EditAction | null | undefined;
|
|
40
|
+
cancelMapPan: boolean;
|
|
41
|
+
} {
|
|
42
|
+
const clickSequence = this.getClickSequence();
|
|
43
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
44
|
+
|
|
45
|
+
if (clickSequence.length === 0) {
|
|
46
|
+
// nothing to do yet
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const tentativeFeature = this.getTentativeFeature();
|
|
51
|
+
if (tentativeFeature && tentativeFeature.geometry.type === 'Polygon') {
|
|
52
|
+
clickSequence[clickSequence.length - 1] =
|
|
53
|
+
tentativeFeature.geometry.coordinates[0][clickSequence.length - 1];
|
|
54
|
+
} else if (tentativeFeature && tentativeFeature.geometry.type === 'LineString') {
|
|
55
|
+
clickSequence[clickSequence.length - 1] =
|
|
56
|
+
tentativeFeature.geometry.coordinates[clickSequence.length - 1];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let p3;
|
|
60
|
+
if (clickSequence.length === 1) {
|
|
61
|
+
p3 = mapCoords;
|
|
62
|
+
} else {
|
|
63
|
+
const p1 = clickSequence[clickSequence.length - 2];
|
|
64
|
+
const p2 = clickSequence[clickSequence.length - 1];
|
|
65
|
+
[p3] = generatePointsParallelToLinePoints(p1, p2, mapCoords);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (clickSequence.length < 3) {
|
|
69
|
+
// Draw a LineString connecting all the clicked points with the hovered point
|
|
70
|
+
this._setTentativeFeature({
|
|
71
|
+
type: 'Feature',
|
|
72
|
+
geometry: {
|
|
73
|
+
type: 'LineString',
|
|
74
|
+
coordinates: [...clickSequence, p3],
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
// Draw a Polygon connecting all the clicked points with the hovered point
|
|
79
|
+
this._setTentativeFeature({
|
|
80
|
+
type: 'Feature',
|
|
81
|
+
geometry: {
|
|
82
|
+
type: 'Polygon',
|
|
83
|
+
coordinates: [[...clickSequence, p3, clickSequence[0]]],
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
handleClick(event: ClickEvent): EditAction | null | undefined {
|
|
92
|
+
super.handleClick(event);
|
|
93
|
+
|
|
94
|
+
const { picks } = event;
|
|
95
|
+
const tentativeFeature = this.getTentativeFeature();
|
|
96
|
+
|
|
97
|
+
let editAction: EditAction | null | undefined = null;
|
|
98
|
+
const clickedEditHandle = getPickedEditHandle(picks);
|
|
99
|
+
|
|
100
|
+
if (tentativeFeature && tentativeFeature.geometry.type === 'Polygon') {
|
|
101
|
+
const polygon: Polygon = tentativeFeature.geometry;
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
clickedEditHandle &&
|
|
105
|
+
clickedEditHandle.featureIndex === -1 &&
|
|
106
|
+
(clickedEditHandle.positionIndexes[1] === 0 ||
|
|
107
|
+
clickedEditHandle.positionIndexes[1] === polygon.coordinates[0].length - 3)
|
|
108
|
+
) {
|
|
109
|
+
// They clicked the first or last point (or double-clicked), so complete the polygon
|
|
110
|
+
const polygonToAdd: Polygon = {
|
|
111
|
+
type: 'Polygon',
|
|
112
|
+
coordinates: this.finalizedCoordinates([...polygon.coordinates[0]]),
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
this.resetClickSequence();
|
|
116
|
+
this._setTentativeFeature(null);
|
|
117
|
+
editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Trigger pointer move right away in order for it to update edit handles (to support double-click)
|
|
122
|
+
const fakePointerMoveEvent = {
|
|
123
|
+
screenCoords: [-1, -1] as Position,
|
|
124
|
+
mapCoords: event.mapCoords,
|
|
125
|
+
picks: [],
|
|
126
|
+
isDragging: false,
|
|
127
|
+
pointerDownPicks: null,
|
|
128
|
+
pointerDownScreenCoords: null,
|
|
129
|
+
pointerDownMapCoords: null,
|
|
130
|
+
sourceEvent: null,
|
|
131
|
+
} as unknown as PointerMoveEvent;
|
|
132
|
+
|
|
133
|
+
this.handlePointerMove(fakePointerMoveEvent);
|
|
134
|
+
|
|
135
|
+
return editAction;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
finalizedCoordinates(coords: Position[]) {
|
|
139
|
+
// Remove the hovered position
|
|
140
|
+
let coordinates = [[...coords.slice(0, -2), coords[0]]];
|
|
141
|
+
let pt = this.getIntermediatePoint([...coords]);
|
|
142
|
+
if (!pt) {
|
|
143
|
+
// if intermediate point with 90 degree not available
|
|
144
|
+
// try remove the last clicked point and get the intermediate point.
|
|
145
|
+
const tc = [...coords];
|
|
146
|
+
tc.splice(-3, 1);
|
|
147
|
+
pt = this.getIntermediatePoint([...tc]);
|
|
148
|
+
if (pt) {
|
|
149
|
+
coordinates = [[...coords.slice(0, -3), pt, coords[0]]];
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
coordinates = [[...coords.slice(0, -2), pt, coords[0]]];
|
|
153
|
+
}
|
|
154
|
+
return coordinates;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
getIntermediatePoint(coordinates: Position[]): Position | null {
|
|
158
|
+
let pt: Position | null = null;
|
|
159
|
+
|
|
160
|
+
if (coordinates.length > 4) {
|
|
161
|
+
const [p1, p2] = [...coordinates];
|
|
162
|
+
const angle1 = bearing(p1, p2);
|
|
163
|
+
const p3 = coordinates[coordinates.length - 3];
|
|
164
|
+
const p4 = coordinates[coordinates.length - 4];
|
|
165
|
+
const angle2 = bearing(p3, p4);
|
|
166
|
+
|
|
167
|
+
const angles = { first: [] as number[], second: [] as number[] };
|
|
168
|
+
// calculate 3 right angle points for first and last points in lineString
|
|
169
|
+
[1, 2, 3].forEach((factor) => {
|
|
170
|
+
const newAngle1 = angle1 + factor * 90;
|
|
171
|
+
// convert angles to 0 to -180 for anti-clock and 0 to 180 for clock wise
|
|
172
|
+
angles.first.push(newAngle1 > 180 ? newAngle1 - 360 : newAngle1);
|
|
173
|
+
const newAngle2 = angle2 + factor * 90;
|
|
174
|
+
angles.second.push(newAngle2 > 180 ? newAngle2 - 360 : newAngle2);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const distance = turfDistance(point(p1), point(p3));
|
|
178
|
+
// Draw imaginary right angle lines for both first and last points in lineString
|
|
179
|
+
// If there is intersection point for any 2 lines, will be the 90 degree point.
|
|
180
|
+
[0, 1, 2].forEach((indexFirst) => {
|
|
181
|
+
const line1 = lineString([
|
|
182
|
+
p1,
|
|
183
|
+
destination(p1, distance, angles.first[indexFirst]).geometry.coordinates,
|
|
184
|
+
]);
|
|
185
|
+
[0, 1, 2].forEach((indexSecond) => {
|
|
186
|
+
const line2 = lineString([
|
|
187
|
+
p3,
|
|
188
|
+
destination(p3, distance, angles.second[indexSecond]).geometry.coordinates,
|
|
189
|
+
]);
|
|
190
|
+
const fc = lineIntersect(line1, line2);
|
|
191
|
+
if (fc && fc.features.length) {
|
|
192
|
+
// found the intersect point
|
|
193
|
+
pt = fc.features[0].geometry.coordinates as Position;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return pt;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import circle from '@turf/circle';
|
|
2
|
+
import distance from '@turf/distance';
|
|
3
|
+
import { PointerMoveEvent } from '../edit-modes/types';
|
|
4
|
+
import { EditAction, getIntermediatePosition } from './mode-handler';
|
|
5
|
+
import { TwoClickPolygonHandler } from './two-click-polygon-handler';
|
|
6
|
+
|
|
7
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
8
|
+
export class DrawCircleByBoundingBoxHandler extends TwoClickPolygonHandler {
|
|
9
|
+
handlePointerMove(event: PointerMoveEvent): {
|
|
10
|
+
editAction: EditAction | null | undefined;
|
|
11
|
+
cancelMapPan: boolean;
|
|
12
|
+
} {
|
|
13
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
14
|
+
const clickSequence = this.getClickSequence();
|
|
15
|
+
|
|
16
|
+
if (clickSequence.length === 0) {
|
|
17
|
+
// nothing to do yet
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const modeConfig = this.getModeConfig() || {};
|
|
22
|
+
// Default turf value for circle is 64
|
|
23
|
+
const { steps = 64 } = modeConfig;
|
|
24
|
+
const options = { steps };
|
|
25
|
+
|
|
26
|
+
if (steps < 4) {
|
|
27
|
+
console.warn('Minimum steps to draw a circle is 4 '); // eslint-disable-line no-console,no-undef
|
|
28
|
+
options.steps = 4;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const firstClickedPoint = clickSequence[0];
|
|
32
|
+
const centerCoordinates = getIntermediatePosition(firstClickedPoint, event.mapCoords);
|
|
33
|
+
const radius = Math.max(distance(firstClickedPoint, centerCoordinates), 0.001);
|
|
34
|
+
// @ts-expect-error turf types diff
|
|
35
|
+
this._setTentativeFeature(circle(centerCoordinates, radius, options));
|
|
36
|
+
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import circle from '@turf/circle';
|
|
2
|
+
import distance from '@turf/distance';
|
|
3
|
+
import { PointerMoveEvent } from '../edit-modes/types';
|
|
4
|
+
import { EditAction } from './mode-handler';
|
|
5
|
+
import { TwoClickPolygonHandler } from './two-click-polygon-handler';
|
|
6
|
+
|
|
7
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
8
|
+
export class DrawCircleFromCenterHandler extends TwoClickPolygonHandler {
|
|
9
|
+
handlePointerMove(event: PointerMoveEvent): {
|
|
10
|
+
editAction: EditAction | null | undefined;
|
|
11
|
+
cancelMapPan: boolean;
|
|
12
|
+
} {
|
|
13
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
14
|
+
const clickSequence = this.getClickSequence();
|
|
15
|
+
|
|
16
|
+
if (clickSequence.length === 0) {
|
|
17
|
+
// nothing to do yet
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const modeConfig = this.getModeConfig() || {};
|
|
22
|
+
// Default turf value for circle is 64
|
|
23
|
+
const { steps = 64 } = modeConfig;
|
|
24
|
+
const options = { steps };
|
|
25
|
+
|
|
26
|
+
if (steps < 4) {
|
|
27
|
+
console.warn('Minimum steps to draw a circle is 4 '); // eslint-disable-line no-console,no-undef
|
|
28
|
+
options.steps = 4;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const centerCoordinates = clickSequence[0];
|
|
32
|
+
const radius = Math.max(distance(centerCoordinates, event.mapCoords), 0.001);
|
|
33
|
+
// @ts-expect-error turf types diff
|
|
34
|
+
this._setTentativeFeature(circle(centerCoordinates, radius, options));
|
|
35
|
+
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import bboxPolygon from '@turf/bbox-polygon';
|
|
2
|
+
import distance from '@turf/distance';
|
|
3
|
+
import ellipse from '@turf/ellipse';
|
|
4
|
+
import { point } from '@turf/helpers';
|
|
5
|
+
import { PointerMoveEvent } from '../edit-modes/types';
|
|
6
|
+
import { EditAction, getIntermediatePosition } from './mode-handler';
|
|
7
|
+
import { TwoClickPolygonHandler } from './two-click-polygon-handler';
|
|
8
|
+
|
|
9
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
10
|
+
export class DrawEllipseByBoundingBoxHandler extends TwoClickPolygonHandler {
|
|
11
|
+
handlePointerMove(event: PointerMoveEvent): {
|
|
12
|
+
editAction: EditAction | null | undefined;
|
|
13
|
+
cancelMapPan: boolean;
|
|
14
|
+
} {
|
|
15
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
16
|
+
const clickSequence = this.getClickSequence();
|
|
17
|
+
|
|
18
|
+
if (clickSequence.length === 0) {
|
|
19
|
+
// nothing to do yet
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const corner1 = clickSequence[0];
|
|
24
|
+
const corner2 = event.mapCoords;
|
|
25
|
+
|
|
26
|
+
const minX = Math.min(corner1[0], corner2[0]);
|
|
27
|
+
const minY = Math.min(corner1[1], corner2[1]);
|
|
28
|
+
const maxX = Math.max(corner1[0], corner2[0]);
|
|
29
|
+
const maxY = Math.max(corner1[1], corner2[1]);
|
|
30
|
+
|
|
31
|
+
const polygonPoints = bboxPolygon([minX, minY, maxX, maxY]).geometry.coordinates[0];
|
|
32
|
+
const centerCoordinates = getIntermediatePosition(corner1, corner2);
|
|
33
|
+
|
|
34
|
+
const xSemiAxis = Math.max(distance(point(polygonPoints[0]), point(polygonPoints[1])), 0.001);
|
|
35
|
+
const ySemiAxis = Math.max(distance(point(polygonPoints[0]), point(polygonPoints[3])), 0.001);
|
|
36
|
+
// @ts-expect-error turf types diff
|
|
37
|
+
this._setTentativeFeature(ellipse(centerCoordinates, xSemiAxis, ySemiAxis));
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import distance from '@turf/distance';
|
|
2
|
+
import ellipse from '@turf/ellipse';
|
|
3
|
+
import bearing from '@turf/bearing';
|
|
4
|
+
import { point } from '@turf/helpers';
|
|
5
|
+
import { PointerMoveEvent } from '../edit-modes/types';
|
|
6
|
+
import { EditAction, getIntermediatePosition } from './mode-handler';
|
|
7
|
+
import { ThreeClickPolygonHandler } from './three-click-polygon-handler';
|
|
8
|
+
|
|
9
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
10
|
+
export class DrawEllipseUsingThreePointsHandler extends ThreeClickPolygonHandler {
|
|
11
|
+
handlePointerMove(event: PointerMoveEvent): {
|
|
12
|
+
editAction: EditAction | null | undefined;
|
|
13
|
+
cancelMapPan: boolean;
|
|
14
|
+
} {
|
|
15
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
16
|
+
const clickSequence = this.getClickSequence();
|
|
17
|
+
|
|
18
|
+
if (clickSequence.length === 0) {
|
|
19
|
+
// nothing to do yet
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const mapCoords = event.mapCoords;
|
|
24
|
+
|
|
25
|
+
if (clickSequence.length === 1) {
|
|
26
|
+
this._setTentativeFeature({
|
|
27
|
+
type: 'Feature',
|
|
28
|
+
geometry: {
|
|
29
|
+
type: 'LineString',
|
|
30
|
+
coordinates: [clickSequence[0], mapCoords],
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
} else if (clickSequence.length === 2) {
|
|
34
|
+
const [p1, p2] = clickSequence;
|
|
35
|
+
|
|
36
|
+
const centerCoordinates = getIntermediatePosition(p1, p2);
|
|
37
|
+
const xSemiAxis = Math.max(distance(centerCoordinates, point(mapCoords)), 0.001);
|
|
38
|
+
const ySemiAxis = Math.max(distance(p1, p2), 0.001) / 2;
|
|
39
|
+
const options = { angle: bearing(p1, p2) };
|
|
40
|
+
// @ts-expect-error turf types diff
|
|
41
|
+
this._setTentativeFeature(ellipse(centerCoordinates, xSemiAxis, ySemiAxis, options));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Position, LineString } from '../geojson-types';
|
|
2
|
+
import { ClickEvent, PointerMoveEvent } from '../edit-modes/types';
|
|
3
|
+
import { EditAction, ModeHandler } from './mode-handler';
|
|
4
|
+
|
|
5
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
6
|
+
export class DrawLineStringHandler extends ModeHandler {
|
|
7
|
+
handleClick(event: ClickEvent): EditAction | null | undefined {
|
|
8
|
+
super.handleClick(event);
|
|
9
|
+
|
|
10
|
+
let editAction: EditAction | null | undefined = null;
|
|
11
|
+
const selectedFeatureIndexes = this.getSelectedFeatureIndexes();
|
|
12
|
+
const selectedGeometry = this.getSelectedGeometry();
|
|
13
|
+
const tentativeFeature = this.getTentativeFeature();
|
|
14
|
+
const clickSequence = this.getClickSequence();
|
|
15
|
+
|
|
16
|
+
if (
|
|
17
|
+
selectedFeatureIndexes.length > 1 ||
|
|
18
|
+
(selectedGeometry && selectedGeometry.type !== 'LineString')
|
|
19
|
+
) {
|
|
20
|
+
console.warn(`drawLineString mode only supported for single LineString selection`); // eslint-disable-line
|
|
21
|
+
this.resetClickSequence();
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (selectedGeometry && selectedGeometry.type === 'LineString') {
|
|
26
|
+
// Extend the LineString
|
|
27
|
+
const lineString: LineString = selectedGeometry;
|
|
28
|
+
|
|
29
|
+
let positionIndexes = [lineString.coordinates.length];
|
|
30
|
+
|
|
31
|
+
const modeConfig = this.getModeConfig();
|
|
32
|
+
if (modeConfig && modeConfig.drawAtFront) {
|
|
33
|
+
positionIndexes = [0];
|
|
34
|
+
}
|
|
35
|
+
const featureIndex = selectedFeatureIndexes[0];
|
|
36
|
+
const updatedData = this.getImmutableFeatureCollection()
|
|
37
|
+
.addPosition(featureIndex, positionIndexes, event.mapCoords)
|
|
38
|
+
.getObject();
|
|
39
|
+
|
|
40
|
+
editAction = {
|
|
41
|
+
updatedData,
|
|
42
|
+
editType: 'addPosition',
|
|
43
|
+
featureIndexes: [featureIndex],
|
|
44
|
+
editContext: {
|
|
45
|
+
positionIndexes,
|
|
46
|
+
position: event.mapCoords,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
this.resetClickSequence();
|
|
51
|
+
} else if (clickSequence.length === 2 && tentativeFeature) {
|
|
52
|
+
// Add a new LineString
|
|
53
|
+
const geometry: any = tentativeFeature.geometry;
|
|
54
|
+
editAction = this.getAddFeatureAction(geometry);
|
|
55
|
+
|
|
56
|
+
this.resetClickSequence();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return editAction;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
handlePointerMove(event: PointerMoveEvent): {
|
|
63
|
+
editAction: EditAction | null | undefined;
|
|
64
|
+
cancelMapPan: boolean;
|
|
65
|
+
} {
|
|
66
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
67
|
+
|
|
68
|
+
const clickSequence = this.getClickSequence();
|
|
69
|
+
const mapCoords = event.mapCoords;
|
|
70
|
+
|
|
71
|
+
let startPosition: Position | null | undefined = null;
|
|
72
|
+
const selectedFeatureIndexes = this.getSelectedFeatureIndexes();
|
|
73
|
+
const selectedGeometry = this.getSelectedGeometry();
|
|
74
|
+
|
|
75
|
+
if (
|
|
76
|
+
selectedFeatureIndexes.length > 1 ||
|
|
77
|
+
(selectedGeometry && selectedGeometry.type !== 'LineString')
|
|
78
|
+
) {
|
|
79
|
+
// unsupported
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (selectedGeometry && selectedGeometry.type === 'LineString') {
|
|
84
|
+
// Draw an extension line starting from one end of the selected LineString
|
|
85
|
+
startPosition = selectedGeometry.coordinates[selectedGeometry.coordinates.length - 1];
|
|
86
|
+
|
|
87
|
+
const modeConfig = this.getModeConfig();
|
|
88
|
+
if (modeConfig && modeConfig.drawAtFront) {
|
|
89
|
+
startPosition = selectedGeometry.coordinates[0];
|
|
90
|
+
}
|
|
91
|
+
} else if (clickSequence.length === 1) {
|
|
92
|
+
startPosition = clickSequence[0];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (startPosition) {
|
|
96
|
+
this._setTentativeFeature({
|
|
97
|
+
type: 'Feature',
|
|
98
|
+
properties: {},
|
|
99
|
+
geometry: {
|
|
100
|
+
type: 'LineString',
|
|
101
|
+
coordinates: [startPosition, mapCoords],
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Geometry } from '../geojson-types';
|
|
2
|
+
import { ClickEvent } from '../edit-modes/types';
|
|
3
|
+
import { EditAction, ModeHandler } from './mode-handler';
|
|
4
|
+
|
|
5
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
6
|
+
export class DrawPointHandler extends ModeHandler {
|
|
7
|
+
handleClick({ mapCoords }: ClickEvent): EditAction | null | undefined {
|
|
8
|
+
const geometry: Geometry = {
|
|
9
|
+
type: 'Point',
|
|
10
|
+
coordinates: mapCoords,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return this.getAddFeatureAction(geometry);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Polygon, Position } from '../geojson-types';
|
|
2
|
+
import { ClickEvent, PointerMoveEvent } from '../edit-modes/types';
|
|
3
|
+
import {
|
|
4
|
+
EditAction,
|
|
5
|
+
EditHandle,
|
|
6
|
+
ModeHandler,
|
|
7
|
+
getPickedEditHandle,
|
|
8
|
+
getEditHandlesForGeometry,
|
|
9
|
+
} from './mode-handler';
|
|
10
|
+
|
|
11
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
12
|
+
export class DrawPolygonHandler extends ModeHandler {
|
|
13
|
+
getEditHandles(picks?: Array<Record<string, any>>, mapCoords?: Position): EditHandle[] {
|
|
14
|
+
let handles = super.getEditHandles(picks, mapCoords);
|
|
15
|
+
|
|
16
|
+
if (this._tentativeFeature) {
|
|
17
|
+
handles = handles.concat(getEditHandlesForGeometry(this._tentativeFeature.geometry, -1));
|
|
18
|
+
// Slice off the handles that are are next to the pointer
|
|
19
|
+
if (this._tentativeFeature && this._tentativeFeature.geometry.type === 'LineString') {
|
|
20
|
+
// Remove the last existing handle
|
|
21
|
+
handles = handles.slice(0, -1);
|
|
22
|
+
} else if (this._tentativeFeature && this._tentativeFeature.geometry.type === 'Polygon') {
|
|
23
|
+
// Remove the last existing handle
|
|
24
|
+
handles = handles.slice(0, -1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return handles;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
handleClick(event: ClickEvent): EditAction | null | undefined {
|
|
32
|
+
super.handleClick(event);
|
|
33
|
+
|
|
34
|
+
const { picks } = event;
|
|
35
|
+
const tentativeFeature = this.getTentativeFeature();
|
|
36
|
+
|
|
37
|
+
let editAction: EditAction | null | undefined = null;
|
|
38
|
+
const clickedEditHandle = getPickedEditHandle(picks);
|
|
39
|
+
|
|
40
|
+
if (clickedEditHandle) {
|
|
41
|
+
// User clicked an edit handle.
|
|
42
|
+
// Remove it from the click sequence, so it isn't added as a new point.
|
|
43
|
+
const clickSequence = this.getClickSequence();
|
|
44
|
+
clickSequence.splice(clickSequence.length - 1, 1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (tentativeFeature && tentativeFeature.geometry.type === 'Polygon') {
|
|
48
|
+
const polygon: Polygon = tentativeFeature.geometry;
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
clickedEditHandle &&
|
|
52
|
+
clickedEditHandle.featureIndex === -1 &&
|
|
53
|
+
(clickedEditHandle.positionIndexes[1] === 0 ||
|
|
54
|
+
clickedEditHandle.positionIndexes[1] === polygon.coordinates[0].length - 3)
|
|
55
|
+
) {
|
|
56
|
+
// They clicked the first or last point (or double-clicked), so complete the polygon
|
|
57
|
+
|
|
58
|
+
// Remove the hovered position
|
|
59
|
+
const polygonToAdd: Polygon = {
|
|
60
|
+
type: 'Polygon',
|
|
61
|
+
coordinates: [[...polygon.coordinates[0].slice(0, -2), polygon.coordinates[0][0]]],
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
this.resetClickSequence();
|
|
65
|
+
this._setTentativeFeature(null);
|
|
66
|
+
editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Trigger pointer move right away in order for it to update edit handles (to support double-click)
|
|
71
|
+
const fakePointerMoveEvent = {
|
|
72
|
+
screenCoords: [-1, -1] as Position,
|
|
73
|
+
mapCoords: event.mapCoords,
|
|
74
|
+
picks: [],
|
|
75
|
+
isDragging: false,
|
|
76
|
+
pointerDownPicks: null,
|
|
77
|
+
pointerDownScreenCoords: null,
|
|
78
|
+
pointerDownMapCoords: null,
|
|
79
|
+
sourceEvent: null,
|
|
80
|
+
} as unknown as PointerMoveEvent;
|
|
81
|
+
|
|
82
|
+
this.handlePointerMove(fakePointerMoveEvent);
|
|
83
|
+
|
|
84
|
+
return editAction;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
handlePointerMove({ mapCoords }: PointerMoveEvent): {
|
|
88
|
+
editAction: EditAction | null | undefined;
|
|
89
|
+
cancelMapPan: boolean;
|
|
90
|
+
} {
|
|
91
|
+
const clickSequence = this.getClickSequence();
|
|
92
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
93
|
+
|
|
94
|
+
if (clickSequence.length === 0) {
|
|
95
|
+
// nothing to do yet
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (clickSequence.length < 3) {
|
|
100
|
+
// Draw a LineString connecting all the clicked points with the hovered point
|
|
101
|
+
this._setTentativeFeature({
|
|
102
|
+
type: 'Feature',
|
|
103
|
+
geometry: {
|
|
104
|
+
type: 'LineString',
|
|
105
|
+
coordinates: [...clickSequence, mapCoords],
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
// Draw a Polygon connecting all the clicked points with the hovered point
|
|
110
|
+
this._setTentativeFeature({
|
|
111
|
+
type: 'Feature',
|
|
112
|
+
geometry: {
|
|
113
|
+
type: 'Polygon',
|
|
114
|
+
coordinates: [[...clickSequence, mapCoords, clickSequence[0]]],
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import bboxPolygon from '@turf/bbox-polygon';
|
|
2
|
+
import { PointerMoveEvent } from '../edit-modes/types';
|
|
3
|
+
import { EditAction } from './mode-handler';
|
|
4
|
+
import { TwoClickPolygonHandler } from './two-click-polygon-handler';
|
|
5
|
+
|
|
6
|
+
// TODO edit-modes: delete handlers once EditMode fully implemented
|
|
7
|
+
export class DrawRectangleHandler extends TwoClickPolygonHandler {
|
|
8
|
+
handlePointerMove(event: PointerMoveEvent): {
|
|
9
|
+
editAction: EditAction | null | undefined;
|
|
10
|
+
cancelMapPan: boolean;
|
|
11
|
+
} {
|
|
12
|
+
const result = { editAction: null, cancelMapPan: false };
|
|
13
|
+
const clickSequence = this.getClickSequence();
|
|
14
|
+
|
|
15
|
+
if (clickSequence.length === 0) {
|
|
16
|
+
// nothing to do yet
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const corner1 = clickSequence[0];
|
|
21
|
+
const corner2 = event.mapCoords;
|
|
22
|
+
|
|
23
|
+
// @ts-expect-error turf type diff
|
|
24
|
+
this._setTentativeFeature(bboxPolygon([corner1[0], corner1[1], corner2[0], corner2[1]]));
|
|
25
|
+
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
}
|