@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,450 @@
|
|
|
1
|
+
/* eslint-env browser */
|
|
2
|
+
import { GeoJsonLayer, ScatterplotLayer, IconLayer, TextLayer } from '@deck.gl/layers';
|
|
3
|
+
import { ViewMode } from '../edit-modes/view-mode';
|
|
4
|
+
import { TranslateMode } from '../edit-modes/translate-mode';
|
|
5
|
+
import { ModifyMode } from '../edit-modes/modify-mode';
|
|
6
|
+
import { ScaleMode } from '../edit-modes/scale-mode';
|
|
7
|
+
import { RotateMode } from '../edit-modes/rotate-mode';
|
|
8
|
+
import { DuplicateMode } from '../edit-modes/duplicate-mode';
|
|
9
|
+
import { SplitPolygonMode } from '../edit-modes/split-polygon-mode';
|
|
10
|
+
import { ExtrudeMode } from '../edit-modes/extrude-mode';
|
|
11
|
+
import { ElevationMode } from '../edit-modes/elevation-mode';
|
|
12
|
+
import { DrawPointMode } from '../edit-modes/draw-point-mode';
|
|
13
|
+
import { DrawLineStringMode } from '../edit-modes/draw-line-string-mode';
|
|
14
|
+
import { DrawPolygonMode } from '../edit-modes/draw-polygon-mode';
|
|
15
|
+
import { DrawRectangleMode } from '../edit-modes/draw-rectangle-mode';
|
|
16
|
+
import { DrawSquareMode } from '../edit-modes/draw-square-mode';
|
|
17
|
+
import { DrawRectangleFromCenterMode } from '../edit-modes/draw-rectangle-from-center-mode';
|
|
18
|
+
import { DrawSquareFromCenterMode } from '../edit-modes/draw-square-from-center-mode';
|
|
19
|
+
import { DrawCircleFromCenterMode } from '../edit-modes/draw-circle-from-center-mode';
|
|
20
|
+
import { DrawCircleByDiameterMode } from '../edit-modes/draw-circle-by-diameter-mode';
|
|
21
|
+
import { DrawEllipseByBoundingBoxMode } from '../edit-modes/draw-ellipse-by-bounding-box-mode';
|
|
22
|
+
import { DrawRectangleUsingThreePointsMode } from '../edit-modes/draw-rectangle-using-three-points-mode';
|
|
23
|
+
import { DrawEllipseUsingThreePointsMode } from '../edit-modes/draw-ellipse-using-three-points-mode';
|
|
24
|
+
import { Draw90DegreePolygonMode } from '../edit-modes/draw-90degree-polygon-mode';
|
|
25
|
+
import { DrawPolygonByDraggingMode } from '../edit-modes/draw-polygon-by-dragging-mode';
|
|
26
|
+
import { SnappableMode } from '../edit-modes/snappable-mode';
|
|
27
|
+
import { TransformMode } from '../edit-modes/transform-mode';
|
|
28
|
+
import { PROJECTED_PIXEL_SIZE_MULTIPLIER } from '../constants';
|
|
29
|
+
import EditableLayer from './editable-layer';
|
|
30
|
+
import EditablePathLayer from './editable-path-layer';
|
|
31
|
+
const DEFAULT_LINE_COLOR = [0x0, 0x0, 0x0, 0x99];
|
|
32
|
+
const DEFAULT_FILL_COLOR = [0x0, 0x0, 0x0, 0x90];
|
|
33
|
+
const DEFAULT_SELECTED_LINE_COLOR = [0x0, 0x0, 0x0, 0xff];
|
|
34
|
+
const DEFAULT_SELECTED_FILL_COLOR = [0x0, 0x0, 0x90, 0x90];
|
|
35
|
+
const DEFAULT_TENTATIVE_LINE_COLOR = [0x90, 0x90, 0x90, 0xff];
|
|
36
|
+
const DEFAULT_TENTATIVE_FILL_COLOR = [0x90, 0x90, 0x90, 0x90];
|
|
37
|
+
const DEFAULT_EDITING_EXISTING_POINT_COLOR = [0xc0, 0x0, 0x0, 0xff];
|
|
38
|
+
const DEFAULT_EDITING_INTERMEDIATE_POINT_COLOR = [0x0, 0x0, 0x0, 0x80];
|
|
39
|
+
const DEFAULT_EDITING_SNAP_POINT_COLOR = [0x7c, 0x00, 0xc0, 0xff];
|
|
40
|
+
const DEFAULT_EDITING_POINT_OUTLINE_COLOR = [0xff, 0xff, 0xff, 0xff];
|
|
41
|
+
const DEFAULT_EDITING_EXISTING_POINT_RADIUS = 5;
|
|
42
|
+
const DEFAULT_EDITING_INTERMEDIATE_POINT_RADIUS = 3;
|
|
43
|
+
const DEFAULT_EDITING_SNAP_POINT_RADIUS = 7;
|
|
44
|
+
const DEFAULT_TOOLTIP_FONT_SIZE = 32 * PROJECTED_PIXEL_SIZE_MULTIPLIER;
|
|
45
|
+
const DEFAULT_EDIT_MODE = DrawPolygonMode;
|
|
46
|
+
function guideAccessor(accessor) {
|
|
47
|
+
if (!accessor || typeof accessor !== 'function') {
|
|
48
|
+
return accessor;
|
|
49
|
+
}
|
|
50
|
+
return (guideMaybeWrapped) => accessor(unwrapGuide(guideMaybeWrapped));
|
|
51
|
+
}
|
|
52
|
+
// The object handed to us from deck.gl is different depending on the version of deck.gl used, unwrap as necessary
|
|
53
|
+
function unwrapGuide(guideMaybeWrapped) {
|
|
54
|
+
if (guideMaybeWrapped.__source) {
|
|
55
|
+
return guideMaybeWrapped.__source.object;
|
|
56
|
+
}
|
|
57
|
+
else if (guideMaybeWrapped.sourceFeature) {
|
|
58
|
+
return guideMaybeWrapped.sourceFeature.feature;
|
|
59
|
+
}
|
|
60
|
+
// It is not wrapped, return as is
|
|
61
|
+
return guideMaybeWrapped;
|
|
62
|
+
}
|
|
63
|
+
function getEditHandleColor(handle) {
|
|
64
|
+
switch (handle.properties.editHandleType) {
|
|
65
|
+
case 'existing':
|
|
66
|
+
return DEFAULT_EDITING_EXISTING_POINT_COLOR;
|
|
67
|
+
case 'snap-source':
|
|
68
|
+
return DEFAULT_EDITING_SNAP_POINT_COLOR;
|
|
69
|
+
case 'intermediate':
|
|
70
|
+
default:
|
|
71
|
+
return DEFAULT_EDITING_INTERMEDIATE_POINT_COLOR;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function getEditHandleOutlineColor(handle) {
|
|
75
|
+
return DEFAULT_EDITING_POINT_OUTLINE_COLOR;
|
|
76
|
+
}
|
|
77
|
+
function getEditHandleRadius(handle) {
|
|
78
|
+
switch (handle.properties.editHandleType) {
|
|
79
|
+
case 'existing':
|
|
80
|
+
return DEFAULT_EDITING_EXISTING_POINT_RADIUS;
|
|
81
|
+
case 'snap':
|
|
82
|
+
return DEFAULT_EDITING_SNAP_POINT_RADIUS;
|
|
83
|
+
case 'intermediate':
|
|
84
|
+
default:
|
|
85
|
+
return DEFAULT_EDITING_INTERMEDIATE_POINT_RADIUS;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const defaultProps = {
|
|
89
|
+
mode: DEFAULT_EDIT_MODE,
|
|
90
|
+
// Edit and interaction events
|
|
91
|
+
onEdit: () => { },
|
|
92
|
+
pickable: true,
|
|
93
|
+
pickingRadius: 10,
|
|
94
|
+
pickingDepth: 5,
|
|
95
|
+
fp64: false,
|
|
96
|
+
filled: true,
|
|
97
|
+
stroked: true,
|
|
98
|
+
lineWidthScale: PROJECTED_PIXEL_SIZE_MULTIPLIER,
|
|
99
|
+
lineWidthMinPixels: 1,
|
|
100
|
+
lineWidthMaxPixels: Number.MAX_SAFE_INTEGER,
|
|
101
|
+
pickingLineWidthExtraPixels: 0,
|
|
102
|
+
lineWidthUnits: 'pixels',
|
|
103
|
+
lineJointRounded: false,
|
|
104
|
+
lineCapRounded: false,
|
|
105
|
+
lineMiterLimit: 4,
|
|
106
|
+
pointRadiusScale: 1,
|
|
107
|
+
pointRadiusMinPixels: 2,
|
|
108
|
+
pointRadiusMaxPixels: Number.MAX_SAFE_INTEGER,
|
|
109
|
+
getLineColor: (feature, isSelected, mode) => isSelected ? DEFAULT_SELECTED_LINE_COLOR : DEFAULT_LINE_COLOR,
|
|
110
|
+
getFillColor: (feature, isSelected, mode) => isSelected ? DEFAULT_SELECTED_FILL_COLOR : DEFAULT_FILL_COLOR,
|
|
111
|
+
getRadius: (f) => (f && f.properties && f.properties.radius) || (f && f.properties && f.properties.size) || 1,
|
|
112
|
+
getLineWidth: (f) => (f && f.properties && f.properties.lineWidth) || 3,
|
|
113
|
+
// Tentative feature rendering
|
|
114
|
+
getTentativeLineColor: (f) => DEFAULT_TENTATIVE_LINE_COLOR,
|
|
115
|
+
getTentativeFillColor: (f) => DEFAULT_TENTATIVE_FILL_COLOR,
|
|
116
|
+
getTentativeLineWidth: (f) => (f && f.properties && f.properties.lineWidth) || 3,
|
|
117
|
+
editHandleType: 'point',
|
|
118
|
+
// point handles
|
|
119
|
+
editHandlePointRadiusScale: 1,
|
|
120
|
+
editHandlePointOutline: true,
|
|
121
|
+
editHandlePointStrokeWidth: 2,
|
|
122
|
+
editHandlePointRadiusUnits: 'pixels',
|
|
123
|
+
editHandlePointRadiusMinPixels: 4,
|
|
124
|
+
editHandlePointRadiusMaxPixels: 8,
|
|
125
|
+
getEditHandlePointColor: getEditHandleColor,
|
|
126
|
+
getEditHandlePointOutlineColor: getEditHandleOutlineColor,
|
|
127
|
+
getEditHandlePointRadius: getEditHandleRadius,
|
|
128
|
+
// icon handles
|
|
129
|
+
editHandleIconAtlas: null,
|
|
130
|
+
editHandleIconMapping: null,
|
|
131
|
+
editHandleIconSizeScale: 1,
|
|
132
|
+
editHandleIconSizeUnits: 'pixels',
|
|
133
|
+
getEditHandleIcon: (handle) => handle.properties.editHandleType,
|
|
134
|
+
getEditHandleIconSize: 10,
|
|
135
|
+
getEditHandleIconColor: getEditHandleColor,
|
|
136
|
+
getEditHandleIconAngle: 0,
|
|
137
|
+
// misc
|
|
138
|
+
billboard: true,
|
|
139
|
+
};
|
|
140
|
+
// Mapping of mode name to mode class (for legacy purposes)
|
|
141
|
+
const modeNameMapping = {
|
|
142
|
+
view: ViewMode,
|
|
143
|
+
// Alter modes
|
|
144
|
+
modify: ModifyMode,
|
|
145
|
+
translate: new SnappableMode(new TranslateMode()),
|
|
146
|
+
transform: new SnappableMode(new TransformMode()),
|
|
147
|
+
scale: ScaleMode,
|
|
148
|
+
rotate: RotateMode,
|
|
149
|
+
duplicate: DuplicateMode,
|
|
150
|
+
split: SplitPolygonMode,
|
|
151
|
+
extrude: ExtrudeMode,
|
|
152
|
+
elevation: ElevationMode,
|
|
153
|
+
// Draw modes
|
|
154
|
+
drawPoint: DrawPointMode,
|
|
155
|
+
drawLineString: DrawLineStringMode,
|
|
156
|
+
drawPolygon: DrawPolygonMode,
|
|
157
|
+
drawRectangle: DrawRectangleMode,
|
|
158
|
+
drawSquare: DrawSquareMode,
|
|
159
|
+
drawRectangleFromCenter: DrawRectangleFromCenterMode,
|
|
160
|
+
drawSquareFromCenter: DrawSquareFromCenterMode,
|
|
161
|
+
drawCircleFromCenter: DrawCircleFromCenterMode,
|
|
162
|
+
drawCircleByBoundingBox: DrawCircleByDiameterMode,
|
|
163
|
+
drawEllipseByBoundingBox: DrawEllipseByBoundingBoxMode,
|
|
164
|
+
drawRectangleUsing3Points: DrawRectangleUsingThreePointsMode,
|
|
165
|
+
drawEllipseUsing3Points: DrawEllipseUsingThreePointsMode,
|
|
166
|
+
draw90DegreePolygon: Draw90DegreePolygonMode,
|
|
167
|
+
drawPolygonByDragging: DrawPolygonByDraggingMode,
|
|
168
|
+
};
|
|
169
|
+
export default class EditableGeoJsonLayer extends EditableLayer {
|
|
170
|
+
static layerName = 'EditableGeoJsonLayer';
|
|
171
|
+
static defaultProps = defaultProps;
|
|
172
|
+
state = undefined;
|
|
173
|
+
// setState: ($Shape<State>) => void;
|
|
174
|
+
renderLayers() {
|
|
175
|
+
const subLayerProps = this.getSubLayerProps({
|
|
176
|
+
id: 'geojson',
|
|
177
|
+
// Proxy most GeoJsonLayer props as-is
|
|
178
|
+
data: this.props.data,
|
|
179
|
+
fp64: this.props.fp64,
|
|
180
|
+
filled: this.props.filled,
|
|
181
|
+
stroked: this.props.stroked,
|
|
182
|
+
lineWidthScale: this.props.lineWidthScale,
|
|
183
|
+
lineWidthMinPixels: this.props.lineWidthMinPixels,
|
|
184
|
+
lineWidthMaxPixels: this.props.lineWidthMaxPixels,
|
|
185
|
+
lineWidthUnits: this.props.lineWidthUnits,
|
|
186
|
+
lineJointRounded: this.props.lineJointRounded,
|
|
187
|
+
lineCapRounded: this.props.lineCapRounded,
|
|
188
|
+
lineMiterLimit: this.props.lineMiterLimit,
|
|
189
|
+
pointRadiusScale: this.props.pointRadiusScale,
|
|
190
|
+
pointRadiusMinPixels: this.props.pointRadiusMinPixels,
|
|
191
|
+
pointRadiusMaxPixels: this.props.pointRadiusMaxPixels,
|
|
192
|
+
getLineColor: this.selectionAwareAccessor(this.props.getLineColor),
|
|
193
|
+
getFillColor: this.selectionAwareAccessor(this.props.getFillColor),
|
|
194
|
+
getPointRadius: this.selectionAwareAccessor(this.props.getRadius),
|
|
195
|
+
getLineWidth: this.selectionAwareAccessor(this.props.getLineWidth),
|
|
196
|
+
_subLayerProps: {
|
|
197
|
+
linestrings: {
|
|
198
|
+
billboard: this.props.billboard,
|
|
199
|
+
updateTriggers: {
|
|
200
|
+
// required to update dashed array attribute
|
|
201
|
+
all: [this.props.selectedFeatureIndexes, this.props.mode],
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
'polygons-stroke': {
|
|
205
|
+
billboard: this.props.billboard,
|
|
206
|
+
pickingLineWidthExtraPixels: this.props.pickingLineWidthExtraPixels,
|
|
207
|
+
type: EditablePathLayer,
|
|
208
|
+
updateTriggers: {
|
|
209
|
+
// required to update dashed array attribute
|
|
210
|
+
all: [this.props.selectedFeatureIndexes, this.props.mode],
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
updateTriggers: {
|
|
215
|
+
getLineColor: [this.props.selectedFeatureIndexes, this.props.mode],
|
|
216
|
+
getFillColor: [this.props.selectedFeatureIndexes, this.props.mode],
|
|
217
|
+
getPointRadius: [this.props.selectedFeatureIndexes, this.props.mode],
|
|
218
|
+
getLineWidth: [this.props.selectedFeatureIndexes, this.props.mode],
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
let layers = [new GeoJsonLayer(subLayerProps)];
|
|
222
|
+
layers = layers.concat(this.createGuidesLayers(), this.createTooltipsLayers());
|
|
223
|
+
return layers;
|
|
224
|
+
}
|
|
225
|
+
initializeState() {
|
|
226
|
+
super.initializeState();
|
|
227
|
+
this.setState({
|
|
228
|
+
selectedFeatures: [],
|
|
229
|
+
editHandles: [],
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
// TODO: is this the best way to properly update state from an outside event handler?
|
|
233
|
+
shouldUpdateState(opts) {
|
|
234
|
+
// console.log(
|
|
235
|
+
// 'shouldUpdateState',
|
|
236
|
+
// opts.changeFlags.propsOrDataChanged,
|
|
237
|
+
// opts.changeFlags.stateChanged
|
|
238
|
+
// );
|
|
239
|
+
return super.shouldUpdateState(opts) || opts.changeFlags.stateChanged;
|
|
240
|
+
}
|
|
241
|
+
updateState({ props, oldProps, changeFlags, context }) {
|
|
242
|
+
super.updateState({ oldProps, props, changeFlags, context });
|
|
243
|
+
if (changeFlags.propsOrDataChanged) {
|
|
244
|
+
const modePropChanged = Object.keys(oldProps).length === 0 || props.mode !== oldProps.mode;
|
|
245
|
+
if (modePropChanged) {
|
|
246
|
+
let mode;
|
|
247
|
+
if (typeof props.mode === 'function') {
|
|
248
|
+
// They passed a constructor/class, so new it up
|
|
249
|
+
const ModeConstructor = props.mode;
|
|
250
|
+
mode = new ModeConstructor();
|
|
251
|
+
}
|
|
252
|
+
else if (typeof props.mode === 'string') {
|
|
253
|
+
// Lookup the mode based on its name (for backwards compatibility)
|
|
254
|
+
mode = modeNameMapping[props.mode];
|
|
255
|
+
// eslint-disable-next-line no-console
|
|
256
|
+
console.warn('Deprecated use of passing `mode` as a string. Pass the mode\'s class constructor instead.');
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
// Should be an instance of EditMode in this case
|
|
260
|
+
mode = props.mode;
|
|
261
|
+
}
|
|
262
|
+
if (!mode) {
|
|
263
|
+
console.warn(`No mode configured for ${String(props.mode)}`); // eslint-disable-line no-console,no-undef
|
|
264
|
+
// Use default mode
|
|
265
|
+
mode = new DEFAULT_EDIT_MODE();
|
|
266
|
+
}
|
|
267
|
+
if (mode !== this.state.mode) {
|
|
268
|
+
this.setState({ mode, cursor: null });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
let selectedFeatures = [];
|
|
273
|
+
if (Array.isArray(props.selectedFeatureIndexes) &&
|
|
274
|
+
typeof props.data === 'object' &&
|
|
275
|
+
'features' in props.data) {
|
|
276
|
+
// TODO: needs improved testing, i.e. checking for duplicates, NaNs, out of range numbers, ...
|
|
277
|
+
const propsData = props.data;
|
|
278
|
+
// @ts-ignore error TS2339: Property 'features' does not exist on type 'never'
|
|
279
|
+
selectedFeatures = props.selectedFeatureIndexes.map((elem) => propsData.features[elem]);
|
|
280
|
+
}
|
|
281
|
+
this.setState({ selectedFeatures });
|
|
282
|
+
}
|
|
283
|
+
getModeProps(props) {
|
|
284
|
+
return {
|
|
285
|
+
modeConfig: props.modeConfig,
|
|
286
|
+
data: props.data,
|
|
287
|
+
selectedIndexes: props.selectedFeatureIndexes,
|
|
288
|
+
lastPointerMoveEvent: this.state.lastPointerMoveEvent,
|
|
289
|
+
cursor: this.state.cursor,
|
|
290
|
+
onEdit: (editAction) => {
|
|
291
|
+
// Force a re-render
|
|
292
|
+
// This supports double-click where we need to ensure that there's a re-render between the two clicks
|
|
293
|
+
// even though the data wasn't changed, just the internal tentative feature.
|
|
294
|
+
this.setNeedsUpdate();
|
|
295
|
+
props.onEdit(editAction);
|
|
296
|
+
},
|
|
297
|
+
onUpdateCursor: (cursor) => {
|
|
298
|
+
this.setState({ cursor });
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
selectionAwareAccessor(accessor) {
|
|
303
|
+
if (typeof accessor !== 'function') {
|
|
304
|
+
return accessor;
|
|
305
|
+
}
|
|
306
|
+
return (feature) => accessor(feature, this.isFeatureSelected(feature), this.props.mode);
|
|
307
|
+
}
|
|
308
|
+
isFeatureSelected(feature) {
|
|
309
|
+
if (!this.props.data || !this.props.selectedFeatureIndexes) {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
if (!this.props.selectedFeatureIndexes.length) {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
return this.state.selectedFeatures.includes(feature);
|
|
316
|
+
}
|
|
317
|
+
getPickingInfo({ info, sourceLayer }) {
|
|
318
|
+
if (sourceLayer.id.endsWith('guides')) {
|
|
319
|
+
// If user is picking an editing handle, add additional data to the info
|
|
320
|
+
info.isGuide = true;
|
|
321
|
+
}
|
|
322
|
+
return info;
|
|
323
|
+
}
|
|
324
|
+
_updateAutoHighlight(info) {
|
|
325
|
+
// Extra handling for guides
|
|
326
|
+
if (info?.sourceLayer) {
|
|
327
|
+
if (info.isGuide) {
|
|
328
|
+
for (const layer of info.sourceLayer.getSubLayers()) {
|
|
329
|
+
layer.updateAutoHighlight(info);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
info.sourceLayer.updateAutoHighlight(info);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
createGuidesLayers() {
|
|
338
|
+
const mode = this.getActiveMode();
|
|
339
|
+
const guides = mode.getGuides(this.getModeProps(this.props));
|
|
340
|
+
if (!guides || !guides.features.length) {
|
|
341
|
+
return [];
|
|
342
|
+
}
|
|
343
|
+
const subLayerProps = {
|
|
344
|
+
linestrings: {
|
|
345
|
+
billboard: this.props.billboard,
|
|
346
|
+
autoHighlight: false,
|
|
347
|
+
},
|
|
348
|
+
'polygons-fill': {
|
|
349
|
+
autoHighlight: false,
|
|
350
|
+
},
|
|
351
|
+
'polygons-stroke': {
|
|
352
|
+
billboard: this.props.billboard,
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
if (this.props.editHandleType === 'icon') {
|
|
356
|
+
subLayerProps['points-icon'] = {
|
|
357
|
+
type: IconLayer,
|
|
358
|
+
iconAtlas: this.props.editHandleIconAtlas,
|
|
359
|
+
iconMapping: this.props.editHandleIconMapping,
|
|
360
|
+
sizeUnits: this.props.editHandleIconSizeUnits,
|
|
361
|
+
sizeScale: this.props.editHandleIconSizeScale,
|
|
362
|
+
getIcon: guideAccessor(this.props.getEditHandleIcon),
|
|
363
|
+
getSize: guideAccessor(this.props.getEditHandleIconSize),
|
|
364
|
+
getColor: guideAccessor(this.props.getEditHandleIconColor),
|
|
365
|
+
getAngle: guideAccessor(this.props.getEditHandleIconAngle),
|
|
366
|
+
billboard: this.props.billboard,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
subLayerProps['points-circle'] = {
|
|
371
|
+
type: ScatterplotLayer,
|
|
372
|
+
radiusScale: this.props.editHandlePointRadiusScale,
|
|
373
|
+
stroked: this.props.editHandlePointOutline,
|
|
374
|
+
getLineWidth: this.props.editHandlePointStrokeWidth,
|
|
375
|
+
radiusUnits: this.props.editHandlePointRadiusUnits,
|
|
376
|
+
radiusMinPixels: this.props.editHandlePointRadiusMinPixels,
|
|
377
|
+
radiusMaxPixels: this.props.editHandlePointRadiusMaxPixels,
|
|
378
|
+
getRadius: guideAccessor(this.props.getEditHandlePointRadius),
|
|
379
|
+
getFillColor: guideAccessor(this.props.getEditHandlePointColor),
|
|
380
|
+
getLineColor: guideAccessor(this.props.getEditHandlePointOutlineColor),
|
|
381
|
+
billboard: this.props.billboard,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
const layer = new GeoJsonLayer(this.getSubLayerProps({
|
|
385
|
+
id: 'guides',
|
|
386
|
+
data: guides,
|
|
387
|
+
fp64: this.props.fp64,
|
|
388
|
+
_subLayerProps: subLayerProps,
|
|
389
|
+
lineWidthScale: this.props.lineWidthScale,
|
|
390
|
+
lineWidthMinPixels: this.props.lineWidthMinPixels,
|
|
391
|
+
lineWidthMaxPixels: this.props.lineWidthMaxPixels,
|
|
392
|
+
lineWidthUnits: this.props.lineWidthUnits,
|
|
393
|
+
lineJointRounded: this.props.lineJointRounded,
|
|
394
|
+
lineCapRounded: this.props.lineCapRounded,
|
|
395
|
+
lineMiterLimit: this.props.lineMiterLimit,
|
|
396
|
+
getLineColor: guideAccessor(this.props.getTentativeLineColor),
|
|
397
|
+
getLineWidth: guideAccessor(this.props.getTentativeLineWidth),
|
|
398
|
+
getFillColor: guideAccessor(this.props.getTentativeFillColor),
|
|
399
|
+
pointType: this.props.editHandleType === 'icon' ? 'icon' : 'circle',
|
|
400
|
+
iconAtlas: this.props.editHandleIconAtlas,
|
|
401
|
+
}));
|
|
402
|
+
return [layer];
|
|
403
|
+
}
|
|
404
|
+
createTooltipsLayers() {
|
|
405
|
+
const mode = this.getActiveMode();
|
|
406
|
+
const tooltips = mode.getTooltips(this.getModeProps(this.props));
|
|
407
|
+
const layer = new TextLayer({
|
|
408
|
+
getSize: DEFAULT_TOOLTIP_FONT_SIZE,
|
|
409
|
+
...this.getSubLayerProps({
|
|
410
|
+
id: 'tooltips',
|
|
411
|
+
data: tooltips,
|
|
412
|
+
}),
|
|
413
|
+
});
|
|
414
|
+
return [layer];
|
|
415
|
+
}
|
|
416
|
+
onLayerClick(event) {
|
|
417
|
+
this.getActiveMode().handleClick(event, this.getModeProps(this.props));
|
|
418
|
+
}
|
|
419
|
+
onLayerKeyUp(event) {
|
|
420
|
+
this.getActiveMode().handleKeyUp(event, this.getModeProps(this.props));
|
|
421
|
+
}
|
|
422
|
+
onStartDragging(event) {
|
|
423
|
+
this.getActiveMode().handleStartDragging(event, this.getModeProps(this.props));
|
|
424
|
+
}
|
|
425
|
+
onDragging(event) {
|
|
426
|
+
this.getActiveMode().handleDragging(event, this.getModeProps(this.props));
|
|
427
|
+
}
|
|
428
|
+
onStopDragging(event) {
|
|
429
|
+
this.getActiveMode().handleStopDragging(event, this.getModeProps(this.props));
|
|
430
|
+
}
|
|
431
|
+
onPointerMove(event) {
|
|
432
|
+
this.setState({ lastPointerMoveEvent: event });
|
|
433
|
+
this.getActiveMode().handlePointerMove(event, this.getModeProps(this.props));
|
|
434
|
+
}
|
|
435
|
+
getCursor({ isDragging }) {
|
|
436
|
+
if (this.state === null || this.state === undefined) {
|
|
437
|
+
// Layer in 'Awaiting state'
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
let { cursor } = this.state;
|
|
441
|
+
if (!cursor) {
|
|
442
|
+
// default cursor
|
|
443
|
+
cursor = isDragging ? 'grabbing' : 'grab';
|
|
444
|
+
}
|
|
445
|
+
return cursor;
|
|
446
|
+
}
|
|
447
|
+
getActiveMode() {
|
|
448
|
+
return this.state.mode;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { DefaultProps } from '@deck.gl/core';
|
|
2
|
+
import EditableLayer, { EditableLayerProps } from './editable-layer';
|
|
3
|
+
export type EditableH3ClusterLayerProps<DataT> = EditableLayerProps & {
|
|
4
|
+
data: DataT;
|
|
5
|
+
resolution?: number;
|
|
6
|
+
mode?: any;
|
|
7
|
+
modeConfig?: any;
|
|
8
|
+
selectedIndexes?: number[];
|
|
9
|
+
getEditedCluster?: (updatedHexagons: any[], existingCluster: any) => any;
|
|
10
|
+
getHexagons?: (d: any) => number[];
|
|
11
|
+
onEdit?: (updatedData?: any, editType?: string, featureIndexes?: number[], editContext?: any) => void;
|
|
12
|
+
filled?: boolean;
|
|
13
|
+
stroked?: boolean;
|
|
14
|
+
lineWidthScale?: number;
|
|
15
|
+
lineWidthMinPixels?: number;
|
|
16
|
+
lineWidthMaxPixels?: number;
|
|
17
|
+
lineWidthUnits?: string;
|
|
18
|
+
};
|
|
19
|
+
export default class EditableH3ClusterLayer extends EditableLayer<any, EditableH3ClusterLayerProps<any>> {
|
|
20
|
+
static layerName: string;
|
|
21
|
+
static defaultProps: DefaultProps<EditableH3ClusterLayerProps<any>>;
|
|
22
|
+
state: EditableLayer['state'] & {
|
|
23
|
+
cursor?: 'grabbing' | 'grab' | null;
|
|
24
|
+
tentativeHexagonIDs: string[];
|
|
25
|
+
};
|
|
26
|
+
initializeState(): void;
|
|
27
|
+
getDerivedHexagonIDs(coords: any): void;
|
|
28
|
+
getDerivedHexagonID(coords: any): void;
|
|
29
|
+
renderLayers(): any;
|
|
30
|
+
getSelectedHexIDs(): number[];
|
|
31
|
+
getCursor({ isDragging }: {
|
|
32
|
+
isDragging: boolean;
|
|
33
|
+
}): 'grabbing' | 'grab';
|
|
34
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/* eslint-env browser */
|
|
2
|
+
import { H3ClusterLayer } from '@deck.gl/geo-layers';
|
|
3
|
+
// TODO: Fix H3 support.
|
|
4
|
+
// import { polyfill, geoToH3 } from 'h3-js';
|
|
5
|
+
import { PROJECTED_PIXEL_SIZE_MULTIPLIER } from '../constants';
|
|
6
|
+
import EditableGeoJsonLayer from './editable-geojson-layer';
|
|
7
|
+
import EditableLayer from './editable-layer';
|
|
8
|
+
import { ViewMode } from '../edit-modes/view-mode';
|
|
9
|
+
const DEFAULT_EDIT_MODE = ViewMode;
|
|
10
|
+
const DEFAULT_H3_RESOLUTION = 9;
|
|
11
|
+
const EMPTY_FEATURE_COLLECTION = {
|
|
12
|
+
type: 'FeatureCollection',
|
|
13
|
+
features: []
|
|
14
|
+
};
|
|
15
|
+
const defaultProps = {
|
|
16
|
+
mode: DEFAULT_EDIT_MODE,
|
|
17
|
+
...EditableGeoJsonLayer.defaultProps,
|
|
18
|
+
// h3 layer
|
|
19
|
+
data: [],
|
|
20
|
+
selectedIndexes: [],
|
|
21
|
+
filled: false,
|
|
22
|
+
stroked: true,
|
|
23
|
+
lineWidthScale: PROJECTED_PIXEL_SIZE_MULTIPLIER,
|
|
24
|
+
lineWidthMinPixels: 1,
|
|
25
|
+
lineWidthMaxPixels: Number.MAX_SAFE_INTEGER,
|
|
26
|
+
lineWidthUnits: 'pixels',
|
|
27
|
+
getHexagons: (d) => d.hexIds,
|
|
28
|
+
getEditedCluster: (updatedHexagons, existingCluster) => {
|
|
29
|
+
if (existingCluster) {
|
|
30
|
+
return {
|
|
31
|
+
...existingCluster,
|
|
32
|
+
hexIds: updatedHexagons
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
hexIds: updatedHexagons
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
resolution: DEFAULT_H3_RESOLUTION
|
|
40
|
+
};
|
|
41
|
+
export default class EditableH3ClusterLayer extends EditableLayer {
|
|
42
|
+
static layerName = 'EditableH3ClusterLayer';
|
|
43
|
+
static defaultProps = defaultProps;
|
|
44
|
+
state = undefined;
|
|
45
|
+
initializeState() {
|
|
46
|
+
super.initializeState();
|
|
47
|
+
this.setState({
|
|
48
|
+
tentativeHexagonIDs: []
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// convert array of (lng, lat) coords to cluster of hexes
|
|
52
|
+
getDerivedHexagonIDs(coords) {
|
|
53
|
+
throw new Error('not implemented'); // TODO
|
|
54
|
+
// return polyfill(coords, this.props.resolution, true);
|
|
55
|
+
}
|
|
56
|
+
// convert pair of (lng, lat) coords into single hex
|
|
57
|
+
getDerivedHexagonID(coords) {
|
|
58
|
+
throw new Error('not implemented'); // TODO
|
|
59
|
+
// return geoToH3(coords[1], coords[0], this.props.resolution);
|
|
60
|
+
}
|
|
61
|
+
renderLayers() {
|
|
62
|
+
const layers = [
|
|
63
|
+
new EditableGeoJsonLayer(this.getSubLayerProps({
|
|
64
|
+
id: 'editable-geojson',
|
|
65
|
+
mode: this.props.mode,
|
|
66
|
+
data: EMPTY_FEATURE_COLLECTION,
|
|
67
|
+
selectedFeatureIndexes: [],
|
|
68
|
+
onEdit: (editAction) => {
|
|
69
|
+
const { editType, editContext } = editAction;
|
|
70
|
+
switch (editType) {
|
|
71
|
+
case 'updateTentativeFeature':
|
|
72
|
+
// tentative feature updates, updated on every pointer move
|
|
73
|
+
if (editContext.feature.geometry.type === 'Polygon') {
|
|
74
|
+
const coords = editContext.feature.geometry.coordinates;
|
|
75
|
+
const hexIDs = this.getDerivedHexagonIDs(coords);
|
|
76
|
+
this.setState({ tentativeHexagonIDs: hexIDs });
|
|
77
|
+
}
|
|
78
|
+
else if (editContext.feature.geometry.type === 'Point') {
|
|
79
|
+
const coords = editContext.feature.geometry.coordinates;
|
|
80
|
+
const hexID = this.getDerivedHexagonID(coords);
|
|
81
|
+
this.setState({ tentativeHexagonIDs: [hexID] });
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
case 'addFeature':
|
|
85
|
+
const updatedData = [...this.props.data];
|
|
86
|
+
const { modeConfig } = this.props;
|
|
87
|
+
if (!modeConfig || !modeConfig.booleanOperation) {
|
|
88
|
+
// add new h3 cluster
|
|
89
|
+
updatedData.push(this.props.getEditedCluster(this.state.tentativeHexagonIDs, null));
|
|
90
|
+
}
|
|
91
|
+
else if (this.props.selectedIndexes.length !== 1) {
|
|
92
|
+
// eslint-disable-next-line no-console,no-undef
|
|
93
|
+
console.warn('booleanOperation only supported for single cluster selection');
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// they're affecting a selected cluster
|
|
97
|
+
let finalHexagonIDs;
|
|
98
|
+
const committedHexagonIDs = new Set(this.getSelectedHexIDs());
|
|
99
|
+
const tentativeHexagonIDs = new Set(this.state.tentativeHexagonIDs);
|
|
100
|
+
switch (modeConfig.booleanOperation) {
|
|
101
|
+
case 'union':
|
|
102
|
+
default:
|
|
103
|
+
finalHexagonIDs = [
|
|
104
|
+
...new Set([...committedHexagonIDs, ...tentativeHexagonIDs])
|
|
105
|
+
];
|
|
106
|
+
break;
|
|
107
|
+
case 'intersection':
|
|
108
|
+
finalHexagonIDs = [...committedHexagonIDs].filter((hexID) => tentativeHexagonIDs.has(hexID));
|
|
109
|
+
break;
|
|
110
|
+
case 'difference':
|
|
111
|
+
finalHexagonIDs = [...committedHexagonIDs].filter((hexID) => !tentativeHexagonIDs.has(hexID));
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
const selectedIndex = this.props.selectedIndexes[0];
|
|
115
|
+
const existingCluster = this.props.data[selectedIndex];
|
|
116
|
+
updatedData[selectedIndex] = this.props.getEditedCluster(finalHexagonIDs, existingCluster);
|
|
117
|
+
}
|
|
118
|
+
this.setState({
|
|
119
|
+
tentativeHexagonIDs: []
|
|
120
|
+
});
|
|
121
|
+
this.props.onEdit({ updatedData });
|
|
122
|
+
break;
|
|
123
|
+
default:
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
})),
|
|
128
|
+
new H3ClusterLayer(this.getSubLayerProps({
|
|
129
|
+
id: 'hexagons',
|
|
130
|
+
data: this.props.data,
|
|
131
|
+
getHexagons: this.props.getHexagons
|
|
132
|
+
})),
|
|
133
|
+
new H3ClusterLayer(this.getSubLayerProps({
|
|
134
|
+
id: 'tentative-hexagons',
|
|
135
|
+
data: [
|
|
136
|
+
{
|
|
137
|
+
hexIds: this.state.tentativeHexagonIDs
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
getHexagons: (d) => d.hexIds
|
|
141
|
+
}))
|
|
142
|
+
];
|
|
143
|
+
return layers;
|
|
144
|
+
}
|
|
145
|
+
// because data is an array of hexagon data, we take the cumulative of all selected indexes,
|
|
146
|
+
// using props.getHexagons to support multiple data types
|
|
147
|
+
getSelectedHexIDs() {
|
|
148
|
+
let cumulativeHexIDs = [];
|
|
149
|
+
this.props.selectedIndexes.forEach((index) => {
|
|
150
|
+
const selectedCluster = this.props.data[index];
|
|
151
|
+
const hexIDs = this.props.getHexagons(selectedCluster);
|
|
152
|
+
cumulativeHexIDs = cumulativeHexIDs.concat(hexIDs);
|
|
153
|
+
});
|
|
154
|
+
return cumulativeHexIDs;
|
|
155
|
+
}
|
|
156
|
+
getCursor({ isDragging }) {
|
|
157
|
+
let { cursor } = this.state || {};
|
|
158
|
+
if (!cursor) {
|
|
159
|
+
// default cursor
|
|
160
|
+
cursor = isDragging ? 'grabbing' : 'grab';
|
|
161
|
+
}
|
|
162
|
+
return cursor;
|
|
163
|
+
}
|
|
164
|
+
}
|