@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 booleanPointInPolygon from '@turf/boolean-point-in-polygon';
|
|
2
|
+
import turfDifference from '@turf/difference';
|
|
3
|
+
import turfBuffer from '@turf/buffer';
|
|
4
|
+
import lineIntersect from '@turf/line-intersect';
|
|
5
|
+
import { lineString, Point } from '@turf/helpers';
|
|
6
|
+
import turfBearing from '@turf/bearing';
|
|
7
|
+
import turfDistance from '@turf/distance';
|
|
8
|
+
import turfDestination from '@turf/destination';
|
|
9
|
+
import turfPolygonToLine from '@turf/polygon-to-line';
|
|
10
|
+
import nearestPointOnLine, { NearestPointOnLine } from '@turf/nearest-point-on-line';
|
|
11
|
+
import { generatePointsParallelToLinePoints } from './utils';
|
|
12
|
+
import { FeatureCollection } from '../geojson-types';
|
|
13
|
+
import {
|
|
14
|
+
ClickEvent,
|
|
15
|
+
PointerMoveEvent,
|
|
16
|
+
ModeProps,
|
|
17
|
+
GuideFeatureCollection,
|
|
18
|
+
TentativeFeature,
|
|
19
|
+
} from './types';
|
|
20
|
+
import { GeoJsonEditMode, GeoJsonEditAction } from './geojson-edit-mode';
|
|
21
|
+
import { ImmutableFeatureCollection } from './immutable-feature-collection';
|
|
22
|
+
|
|
23
|
+
export class SplitPolygonMode extends GeoJsonEditMode {
|
|
24
|
+
calculateMapCoords(clickSequence: any, mapCoords: any, props: ModeProps<FeatureCollection>) {
|
|
25
|
+
const modeConfig = props.modeConfig;
|
|
26
|
+
if (!modeConfig || !modeConfig.lock90Degree || !clickSequence.length) {
|
|
27
|
+
return mapCoords;
|
|
28
|
+
}
|
|
29
|
+
if (clickSequence.length === 1) {
|
|
30
|
+
// if first point is clicked, then find closest polygon point and build ~90deg vector
|
|
31
|
+
const firstPoint = clickSequence[0];
|
|
32
|
+
const selectedGeometry = this.getSelectedGeometry(props);
|
|
33
|
+
// @ts-expect-error turf types diff
|
|
34
|
+
const feature = turfPolygonToLine(selectedGeometry);
|
|
35
|
+
|
|
36
|
+
const lines = feature.type === 'FeatureCollection' ? feature.features : [feature];
|
|
37
|
+
let minDistance = Number.MAX_SAFE_INTEGER;
|
|
38
|
+
let closestPoint: NearestPointOnLine | null = null;
|
|
39
|
+
// If Multipolygon, then we should find nearest polygon line and stick split to it.
|
|
40
|
+
lines.forEach((line) => {
|
|
41
|
+
const snapPoint = nearestPointOnLine(line, firstPoint);
|
|
42
|
+
const distanceFromOrigin = turfDistance(snapPoint, firstPoint);
|
|
43
|
+
if (minDistance > distanceFromOrigin) {
|
|
44
|
+
minDistance = distanceFromOrigin;
|
|
45
|
+
closestPoint = snapPoint;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (closestPoint) {
|
|
50
|
+
// closest point is used as 90degree entry to the polygon
|
|
51
|
+
const lastBearing = turfBearing(firstPoint, closestPoint);
|
|
52
|
+
const currentDistance = turfDistance(firstPoint, mapCoords, { units: 'meters' });
|
|
53
|
+
return turfDestination(firstPoint, currentDistance, lastBearing, {
|
|
54
|
+
units: 'meters',
|
|
55
|
+
}).geometry.coordinates;
|
|
56
|
+
}
|
|
57
|
+
return mapCoords;
|
|
58
|
+
}
|
|
59
|
+
// Allow only 90 degree turns
|
|
60
|
+
const lastPoint = clickSequence[clickSequence.length - 1];
|
|
61
|
+
const [approximatePoint] = generatePointsParallelToLinePoints(
|
|
62
|
+
clickSequence[clickSequence.length - 2],
|
|
63
|
+
lastPoint,
|
|
64
|
+
mapCoords
|
|
65
|
+
);
|
|
66
|
+
// align point with current ground
|
|
67
|
+
const nearestPt = nearestPointOnLine(lineString([lastPoint, approximatePoint]), mapCoords)
|
|
68
|
+
.geometry.coordinates;
|
|
69
|
+
return nearestPt;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getGuides(props: ModeProps<FeatureCollection>): GuideFeatureCollection {
|
|
73
|
+
const clickSequence = this.getClickSequence();
|
|
74
|
+
|
|
75
|
+
const guides: GuideFeatureCollection = {
|
|
76
|
+
type: 'FeatureCollection',
|
|
77
|
+
features: [],
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
if (clickSequence.length === 0 || !props.lastPointerMoveEvent) {
|
|
81
|
+
// nothing to do yet
|
|
82
|
+
return guides;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const { mapCoords } = props.lastPointerMoveEvent;
|
|
86
|
+
|
|
87
|
+
guides.features.push({
|
|
88
|
+
type: 'Feature',
|
|
89
|
+
properties: {
|
|
90
|
+
guideType: 'tentative',
|
|
91
|
+
},
|
|
92
|
+
geometry: {
|
|
93
|
+
type: 'LineString',
|
|
94
|
+
coordinates: [...clickSequence, this.calculateMapCoords(clickSequence, mapCoords, props)],
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return guides;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
|
|
102
|
+
const tentativeFeature = this.getTentativeGuide(props);
|
|
103
|
+
|
|
104
|
+
const selectedGeometry = this.getSelectedGeometry(props);
|
|
105
|
+
|
|
106
|
+
if (!selectedGeometry) {
|
|
107
|
+
// eslint-disable-next-line no-console,no-undef
|
|
108
|
+
console.warn('A polygon must be selected for splitting');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const clickSequence = this.getClickSequence();
|
|
113
|
+
if (tentativeFeature && tentativeFeature.geometry.type === 'LineString') {
|
|
114
|
+
clickSequence.push(
|
|
115
|
+
tentativeFeature.geometry.coordinates[tentativeFeature.geometry.coordinates.length - 1]
|
|
116
|
+
);
|
|
117
|
+
} else {
|
|
118
|
+
this.addClickSequence(event);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const pt: Point = {
|
|
122
|
+
type: 'Point',
|
|
123
|
+
coordinates: clickSequence[clickSequence.length - 1],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// @ts-expect-error turf types diff
|
|
127
|
+
const isPointInPolygon = booleanPointInPolygon(pt, selectedGeometry);
|
|
128
|
+
if (clickSequence.length > 1 && tentativeFeature && !isPointInPolygon) {
|
|
129
|
+
this.resetClickSequence();
|
|
130
|
+
// @ts-expect-error narrow type
|
|
131
|
+
const isLineInterectingWithPolygon = lineIntersect(tentativeFeature, selectedGeometry);
|
|
132
|
+
if (isLineInterectingWithPolygon.features.length === 0) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const editAction = this.splitPolygon(tentativeFeature, props);
|
|
137
|
+
|
|
138
|
+
if (editAction) {
|
|
139
|
+
props.onEdit(editAction);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
|
|
145
|
+
props.onUpdateCursor('cell');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
splitPolygon(tentativeFeature: TentativeFeature, props: ModeProps<FeatureCollection>) {
|
|
149
|
+
const selectedGeometry = this.getSelectedGeometry(props);
|
|
150
|
+
const featureIndex = props.selectedIndexes[0];
|
|
151
|
+
const modeConfig = props.modeConfig || {};
|
|
152
|
+
|
|
153
|
+
// Default gap in between the polygon
|
|
154
|
+
let { gap = 0.1, units = 'centimeters' } = modeConfig;
|
|
155
|
+
if (gap === 0) {
|
|
156
|
+
gap = 0.1;
|
|
157
|
+
units = 'centimeters';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const buffer = turfBuffer(tentativeFeature, gap, { units });
|
|
161
|
+
// @ts-expect-error turf types diff
|
|
162
|
+
const updatedGeometry = turfDifference(selectedGeometry, buffer);
|
|
163
|
+
if (!updatedGeometry) {
|
|
164
|
+
// eslint-disable-next-line no-console,no-undef
|
|
165
|
+
console.warn('Canceling edit. Split Polygon erased');
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const { type, coordinates } = updatedGeometry.geometry;
|
|
170
|
+
let updatedCoordinates: any[] = []; // TODO
|
|
171
|
+
if (type === 'Polygon') {
|
|
172
|
+
// Update the coordinates as per Multipolygon
|
|
173
|
+
updatedCoordinates = coordinates.map((c) => [c]);
|
|
174
|
+
} else {
|
|
175
|
+
// Handle Case when Multipolygon has holes
|
|
176
|
+
updatedCoordinates = coordinates.reduce((agg, prev) => {
|
|
177
|
+
prev.forEach((p) => {
|
|
178
|
+
// @ts-expect-error revisit coordinates type here
|
|
179
|
+
agg.push([p]);
|
|
180
|
+
});
|
|
181
|
+
return agg;
|
|
182
|
+
}, []);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Update the type to Mulitpolygon
|
|
186
|
+
const updatedData = new ImmutableFeatureCollection(props.data).replaceGeometry(featureIndex, {
|
|
187
|
+
type: 'MultiPolygon',
|
|
188
|
+
coordinates: updatedCoordinates,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const editAction: GeoJsonEditAction = {
|
|
192
|
+
updatedData: updatedData.getObject(),
|
|
193
|
+
editType: 'split',
|
|
194
|
+
editContext: {
|
|
195
|
+
featureIndexes: [featureIndex],
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
return editAction;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ClickEvent,
|
|
3
|
+
PointerMoveEvent,
|
|
4
|
+
ModeProps,
|
|
5
|
+
GuideFeatureCollection,
|
|
6
|
+
TentativeFeature,
|
|
7
|
+
} from './types';
|
|
8
|
+
import { Position, Polygon, FeatureOf, FeatureCollection } from '../geojson-types';
|
|
9
|
+
import { GeoJsonEditMode } from './geojson-edit-mode';
|
|
10
|
+
|
|
11
|
+
export class ThreeClickPolygonMode extends GeoJsonEditMode {
|
|
12
|
+
handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
|
|
13
|
+
this.addClickSequence(event);
|
|
14
|
+
const clickSequence = this.getClickSequence();
|
|
15
|
+
const tentativeFeature = this.getTentativeGuide(props);
|
|
16
|
+
|
|
17
|
+
if (
|
|
18
|
+
clickSequence.length > 2 &&
|
|
19
|
+
tentativeFeature &&
|
|
20
|
+
tentativeFeature.geometry.type === 'Polygon'
|
|
21
|
+
) {
|
|
22
|
+
const editAction = this.getAddFeatureOrBooleanPolygonAction(tentativeFeature.geometry, props);
|
|
23
|
+
this.resetClickSequence();
|
|
24
|
+
|
|
25
|
+
if (editAction) {
|
|
26
|
+
props.onEdit(editAction);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getGuides(props: ModeProps<FeatureCollection>): GuideFeatureCollection {
|
|
32
|
+
const { lastPointerMoveEvent, modeConfig } = props;
|
|
33
|
+
const clickSequence = this.getClickSequence();
|
|
34
|
+
|
|
35
|
+
const guides: GuideFeatureCollection = {
|
|
36
|
+
type: 'FeatureCollection',
|
|
37
|
+
features: [],
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (clickSequence.length === 0) {
|
|
41
|
+
// nothing to do yet
|
|
42
|
+
return guides;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const hoveredCoord = lastPointerMoveEvent.mapCoords;
|
|
46
|
+
|
|
47
|
+
if (clickSequence.length === 1) {
|
|
48
|
+
guides.features.push({
|
|
49
|
+
type: 'Feature',
|
|
50
|
+
properties: {
|
|
51
|
+
guideType: 'tentative',
|
|
52
|
+
},
|
|
53
|
+
geometry: {
|
|
54
|
+
type: 'LineString',
|
|
55
|
+
coordinates: [clickSequence[0], hoveredCoord],
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
const polygon = this.getThreeClickPolygon(
|
|
60
|
+
clickSequence[0],
|
|
61
|
+
clickSequence[1],
|
|
62
|
+
hoveredCoord,
|
|
63
|
+
modeConfig
|
|
64
|
+
);
|
|
65
|
+
if (polygon) {
|
|
66
|
+
guides.features.push({
|
|
67
|
+
type: 'Feature',
|
|
68
|
+
properties: {
|
|
69
|
+
guideType: 'tentative',
|
|
70
|
+
},
|
|
71
|
+
geometry: polygon.geometry,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return guides;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getThreeClickPolygon(
|
|
80
|
+
coord1: Position,
|
|
81
|
+
coord2: Position,
|
|
82
|
+
coord3: Position,
|
|
83
|
+
modeConfig: any
|
|
84
|
+
): FeatureOf<Polygon> | null | undefined {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
|
|
89
|
+
props.onUpdateCursor('cell');
|
|
90
|
+
super.handlePointerMove(event, props);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
createTentativeFeature(props: ModeProps<FeatureCollection>): TentativeFeature {
|
|
94
|
+
const { lastPointerMoveEvent } = props;
|
|
95
|
+
const clickSequence = this.getClickSequence();
|
|
96
|
+
|
|
97
|
+
const lastCoords = lastPointerMoveEvent ? [lastPointerMoveEvent.mapCoords] : [];
|
|
98
|
+
|
|
99
|
+
let tentativeFeature;
|
|
100
|
+
if (clickSequence.length === 2) {
|
|
101
|
+
tentativeFeature = this.getThreeClickPolygon(
|
|
102
|
+
clickSequence[0],
|
|
103
|
+
clickSequence[1],
|
|
104
|
+
lastCoords[0],
|
|
105
|
+
props.modeConfig
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return tentativeFeature;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { featureCollection } from '@turf/helpers';
|
|
2
|
+
import { PointerMoveEvent, ModeProps, StartDraggingEvent } from './types';
|
|
3
|
+
import { FeatureCollection } from '../geojson-types';
|
|
4
|
+
import { TranslateMode } from './translate-mode';
|
|
5
|
+
import { ScaleMode } from './scale-mode';
|
|
6
|
+
import { RotateMode } from './rotate-mode';
|
|
7
|
+
|
|
8
|
+
import { CompositeMode } from './composite-mode';
|
|
9
|
+
import { GeoJsonEditMode } from './geojson-edit-mode';
|
|
10
|
+
|
|
11
|
+
export class TransformMode extends CompositeMode {
|
|
12
|
+
constructor() {
|
|
13
|
+
super([new TranslateMode(), new ScaleMode(), new RotateMode()]);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
|
|
17
|
+
let updatedCursor: string | null = null;
|
|
18
|
+
super.handlePointerMove(event, {
|
|
19
|
+
...props,
|
|
20
|
+
onUpdateCursor: (cursor) => {
|
|
21
|
+
updatedCursor = cursor || updatedCursor;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
props.onUpdateCursor(updatedCursor);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
handleStartDragging(event: StartDraggingEvent, props: ModeProps<FeatureCollection>) {
|
|
28
|
+
let scaleMode: ScaleMode | null = null;
|
|
29
|
+
let translateMode: TranslateMode | null = null;
|
|
30
|
+
const filteredModes: GeoJsonEditMode[] = [];
|
|
31
|
+
|
|
32
|
+
// If the user selects a scaling edit handle that overlaps with part of the selected feature,
|
|
33
|
+
// it is possible for both scale and translate actions to be triggered. This logic prevents
|
|
34
|
+
// this simultaneous action trigger from happening by putting a higher priority on scaling
|
|
35
|
+
// since the user needs to be more precise to hover over a scaling edit handle.
|
|
36
|
+
this._modes.forEach((mode) => {
|
|
37
|
+
if (mode instanceof TranslateMode) {
|
|
38
|
+
translateMode = mode;
|
|
39
|
+
} else {
|
|
40
|
+
if (mode instanceof ScaleMode) {
|
|
41
|
+
scaleMode = mode;
|
|
42
|
+
}
|
|
43
|
+
filteredModes.push(mode);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (scaleMode instanceof ScaleMode && !scaleMode.isEditHandleSelected()) {
|
|
48
|
+
filteredModes.push(translateMode!);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
filteredModes.filter(Boolean).forEach((mode) => mode.handleStartDragging(event, props));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
getGuides(props: ModeProps<FeatureCollection>) {
|
|
55
|
+
let compositeGuides = super.getGuides(props);
|
|
56
|
+
const rotateMode = (this._modes || []).find((mode) => mode instanceof RotateMode);
|
|
57
|
+
|
|
58
|
+
if (rotateMode instanceof RotateMode) {
|
|
59
|
+
const nonEnvelopeGuides = compositeGuides.features.filter((guide) => {
|
|
60
|
+
const { editHandleType, mode } = (guide.properties as any) || {};
|
|
61
|
+
// Both scale and rotate modes have the same enveloping box as a guide - only need one
|
|
62
|
+
const guidesToFilterOut = [mode];
|
|
63
|
+
// Do not render scaling edit handles if rotating
|
|
64
|
+
if (rotateMode.getIsRotating()) {
|
|
65
|
+
guidesToFilterOut.push(editHandleType);
|
|
66
|
+
}
|
|
67
|
+
return !guidesToFilterOut.includes('scale');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// @ts-expect-error turf types
|
|
71
|
+
compositeGuides = featureCollection(nonEnvelopeGuides);
|
|
72
|
+
}
|
|
73
|
+
return compositeGuides;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import turfBearing from '@turf/bearing';
|
|
2
|
+
import turfDistance from '@turf/distance';
|
|
3
|
+
import clone from '@turf/clone';
|
|
4
|
+
import { point, Feature as TurfFeature, Geometry as TurfGeometry } from '@turf/helpers';
|
|
5
|
+
import WebMercatorViewport from 'viewport-mercator-project';
|
|
6
|
+
import { FeatureCollection, Position, Geometry } from '../geojson-types';
|
|
7
|
+
import {
|
|
8
|
+
PointerMoveEvent,
|
|
9
|
+
StartDraggingEvent,
|
|
10
|
+
StopDraggingEvent,
|
|
11
|
+
DraggingEvent,
|
|
12
|
+
ModeProps,
|
|
13
|
+
} from './types';
|
|
14
|
+
import { mapCoords } from './utils';
|
|
15
|
+
import { translateFromCenter } from '../translateFromCenter';
|
|
16
|
+
import { GeoJsonEditMode, GeoJsonEditAction } from './geojson-edit-mode';
|
|
17
|
+
import { ImmutableFeatureCollection } from './immutable-feature-collection';
|
|
18
|
+
|
|
19
|
+
export class TranslateMode extends GeoJsonEditMode {
|
|
20
|
+
_geometryBeforeTranslate: FeatureCollection | null | undefined;
|
|
21
|
+
_isTranslatable: boolean = undefined!;
|
|
22
|
+
|
|
23
|
+
handleDragging(event: DraggingEvent, props: ModeProps<FeatureCollection>) {
|
|
24
|
+
if (!this._isTranslatable) {
|
|
25
|
+
// Nothing to do
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (this._geometryBeforeTranslate) {
|
|
30
|
+
// Translate the geometry
|
|
31
|
+
const editAction = this.getTranslateAction(
|
|
32
|
+
event.pointerDownMapCoords,
|
|
33
|
+
event.mapCoords,
|
|
34
|
+
'translating',
|
|
35
|
+
props
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (editAction) {
|
|
39
|
+
props.onEdit(editAction);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// cancel map panning
|
|
44
|
+
event.cancelPan();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
|
|
48
|
+
this._isTranslatable = this.isSelectionPicked(event.pointerDownPicks || event.picks, props);
|
|
49
|
+
|
|
50
|
+
this.updateCursor(props);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
handleStartDragging(event: StartDraggingEvent, props: ModeProps<FeatureCollection>) {
|
|
54
|
+
if (!this._isTranslatable) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this._geometryBeforeTranslate = this.getSelectedFeaturesAsFeatureCollection(props);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
handleStopDragging(event: StopDraggingEvent, props: ModeProps<FeatureCollection>) {
|
|
62
|
+
if (this._geometryBeforeTranslate) {
|
|
63
|
+
// Translate the geometry
|
|
64
|
+
const editAction = this.getTranslateAction(
|
|
65
|
+
event.pointerDownMapCoords,
|
|
66
|
+
event.mapCoords,
|
|
67
|
+
'translated',
|
|
68
|
+
props
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (editAction) {
|
|
72
|
+
props.onEdit(editAction);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this._geometryBeforeTranslate = null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
updateCursor(props: ModeProps<FeatureCollection>) {
|
|
80
|
+
if (this._isTranslatable) {
|
|
81
|
+
props.onUpdateCursor('move');
|
|
82
|
+
} else {
|
|
83
|
+
props.onUpdateCursor(null);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// eslint-disable-next-line max-statements
|
|
88
|
+
getTranslateAction(
|
|
89
|
+
startDragPoint: Position,
|
|
90
|
+
currentPoint: Position,
|
|
91
|
+
editType: string,
|
|
92
|
+
props: ModeProps<FeatureCollection>
|
|
93
|
+
): GeoJsonEditAction | null | undefined {
|
|
94
|
+
if (!this._geometryBeforeTranslate) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let updatedData = new ImmutableFeatureCollection(props.data);
|
|
99
|
+
const selectedIndexes = props.selectedIndexes;
|
|
100
|
+
|
|
101
|
+
const { viewport: viewportDesc, screenSpace } = props.modeConfig || {};
|
|
102
|
+
|
|
103
|
+
// move features without adapting to mercator projection
|
|
104
|
+
if (viewportDesc && screenSpace) {
|
|
105
|
+
const viewport = viewportDesc.project ? viewportDesc : new WebMercatorViewport(viewportDesc);
|
|
106
|
+
|
|
107
|
+
const from = viewport.project(startDragPoint);
|
|
108
|
+
const to = viewport.project(currentPoint);
|
|
109
|
+
const dx = to[0] - from[0];
|
|
110
|
+
const dy = to[1] - from[1];
|
|
111
|
+
|
|
112
|
+
for (let i = 0; i < selectedIndexes.length; i++) {
|
|
113
|
+
const selectedIndex = selectedIndexes[i];
|
|
114
|
+
const feature = this._geometryBeforeTranslate.features[i];
|
|
115
|
+
|
|
116
|
+
let coordinates = feature.geometry.coordinates;
|
|
117
|
+
if (coordinates) {
|
|
118
|
+
coordinates = mapCoords(coordinates, (coord) => {
|
|
119
|
+
const pixels = viewport.project(coord);
|
|
120
|
+
if (pixels) {
|
|
121
|
+
pixels[0] += dx;
|
|
122
|
+
pixels[1] += dy;
|
|
123
|
+
return viewport.unproject(pixels);
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// @ts-expect-error turf types
|
|
129
|
+
updatedData = updatedData.replaceGeometry(selectedIndex, {
|
|
130
|
+
type: feature.geometry.type,
|
|
131
|
+
coordinates,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
const p1 = point(startDragPoint);
|
|
137
|
+
const p2 = point(currentPoint);
|
|
138
|
+
|
|
139
|
+
const distanceMoved = turfDistance(p1, p2);
|
|
140
|
+
const direction = turfBearing(p1, p2);
|
|
141
|
+
|
|
142
|
+
const movedFeatures = this._geometryBeforeTranslate.features.map((feature) =>
|
|
143
|
+
translateFromCenter(clone(feature as TurfFeature<TurfGeometry>), distanceMoved, direction)
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
for (let i = 0; i < selectedIndexes.length; i++) {
|
|
147
|
+
const selectedIndex = selectedIndexes[i];
|
|
148
|
+
const movedFeature = movedFeatures[i];
|
|
149
|
+
updatedData = updatedData.replaceGeometry(selectedIndex, movedFeature.geometry as Geometry);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
updatedData: updatedData.getObject(),
|
|
155
|
+
editType,
|
|
156
|
+
editContext: {
|
|
157
|
+
featureIndexes: selectedIndexes,
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ClickEvent,
|
|
3
|
+
StartDraggingEvent,
|
|
4
|
+
StopDraggingEvent,
|
|
5
|
+
PointerMoveEvent,
|
|
6
|
+
ModeProps,
|
|
7
|
+
GuideFeatureCollection,
|
|
8
|
+
TentativeFeature,
|
|
9
|
+
} from './types';
|
|
10
|
+
import { Polygon, FeatureCollection, FeatureOf, Position } from '../geojson-types';
|
|
11
|
+
import { GeoJsonEditMode } from './geojson-edit-mode';
|
|
12
|
+
|
|
13
|
+
export class TwoClickPolygonMode extends GeoJsonEditMode {
|
|
14
|
+
handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
|
|
15
|
+
if (props.modeConfig && props.modeConfig.dragToDraw) {
|
|
16
|
+
// handled in drag handlers
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.addClickSequence(event);
|
|
21
|
+
|
|
22
|
+
this.checkAndFinishPolygon(props);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
handleStartDragging(event: StartDraggingEvent, props: ModeProps<FeatureCollection>): void {
|
|
26
|
+
if (!props.modeConfig || !props.modeConfig.dragToDraw) {
|
|
27
|
+
// handled in click handlers
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.addClickSequence(event);
|
|
32
|
+
event.cancelPan();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
handleStopDragging(event: StopDraggingEvent, props: ModeProps<FeatureCollection>): void {
|
|
36
|
+
if (!props.modeConfig || !props.modeConfig.dragToDraw) {
|
|
37
|
+
// handled in click handlers
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.addClickSequence(event);
|
|
41
|
+
|
|
42
|
+
this.checkAndFinishPolygon(props);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
checkAndFinishPolygon(props: ModeProps<FeatureCollection>) {
|
|
46
|
+
const clickSequence = this.getClickSequence();
|
|
47
|
+
const tentativeFeature = this.getTentativeGuide(props);
|
|
48
|
+
|
|
49
|
+
if (
|
|
50
|
+
clickSequence.length > 1 &&
|
|
51
|
+
tentativeFeature &&
|
|
52
|
+
tentativeFeature.geometry.type === 'Polygon'
|
|
53
|
+
) {
|
|
54
|
+
const feature: FeatureOf<Polygon> = {
|
|
55
|
+
type: 'Feature',
|
|
56
|
+
properties: {
|
|
57
|
+
shape: tentativeFeature.properties.shape,
|
|
58
|
+
},
|
|
59
|
+
geometry: {
|
|
60
|
+
type: 'Polygon',
|
|
61
|
+
coordinates: tentativeFeature.geometry.coordinates,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
const editAction = this.getAddFeatureOrBooleanPolygonAction(feature, props);
|
|
65
|
+
|
|
66
|
+
this.resetClickSequence();
|
|
67
|
+
|
|
68
|
+
if (editAction) {
|
|
69
|
+
props.onEdit(editAction);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getGuides(props: ModeProps<FeatureCollection>): GuideFeatureCollection {
|
|
75
|
+
const { lastPointerMoveEvent, modeConfig } = props;
|
|
76
|
+
const clickSequence = this.getClickSequence();
|
|
77
|
+
|
|
78
|
+
const guides: GuideFeatureCollection = {
|
|
79
|
+
type: 'FeatureCollection',
|
|
80
|
+
features: [],
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
if (clickSequence.length === 0 || !lastPointerMoveEvent) {
|
|
84
|
+
// nothing to do yet
|
|
85
|
+
return guides;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const corner1 = clickSequence[0];
|
|
89
|
+
const corner2 = lastPointerMoveEvent.mapCoords;
|
|
90
|
+
|
|
91
|
+
const polygon = this.getTwoClickPolygon(corner1, corner2, modeConfig);
|
|
92
|
+
if (polygon) {
|
|
93
|
+
guides.features.push({
|
|
94
|
+
type: 'Feature',
|
|
95
|
+
properties: {
|
|
96
|
+
shape: polygon.properties && polygon.properties.shape,
|
|
97
|
+
guideType: 'tentative',
|
|
98
|
+
},
|
|
99
|
+
geometry: polygon.geometry,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return guides;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
getTwoClickPolygon(
|
|
107
|
+
coord1: Position,
|
|
108
|
+
coord2: Position,
|
|
109
|
+
modeConfig: any
|
|
110
|
+
): FeatureOf<Polygon> | null | undefined {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
|
|
115
|
+
props.onUpdateCursor('cell');
|
|
116
|
+
super.handlePointerMove(event, props);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
createTentativeFeature(props: ModeProps<FeatureCollection>): TentativeFeature {
|
|
120
|
+
const { lastPointerMoveEvent } = props;
|
|
121
|
+
const clickSequence = this.getClickSequence();
|
|
122
|
+
|
|
123
|
+
const lastCoords = lastPointerMoveEvent ? [lastPointerMoveEvent.mapCoords] : [];
|
|
124
|
+
|
|
125
|
+
let tentativeFeature;
|
|
126
|
+
if (clickSequence.length === 1) {
|
|
127
|
+
tentativeFeature = this.getTwoClickPolygon(clickSequence[0], lastCoords[0], props.modeConfig);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return tentativeFeature;
|
|
131
|
+
}
|
|
132
|
+
}
|