@deck.gl-community/editable-layers 9.1.1 → 9.2.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/edit-modes/draw-line-string-mode.d.ts +3 -1
  2. package/dist/edit-modes/draw-line-string-mode.d.ts.map +1 -1
  3. package/dist/edit-modes/draw-line-string-mode.js +19 -21
  4. package/dist/edit-modes/draw-line-string-mode.js.map +1 -1
  5. package/dist/edit-modes/draw-polygon-mode.d.ts +3 -1
  6. package/dist/edit-modes/draw-polygon-mode.d.ts.map +1 -1
  7. package/dist/edit-modes/draw-polygon-mode.js +19 -22
  8. package/dist/edit-modes/draw-polygon-mode.js.map +1 -1
  9. package/dist/edit-modes/edit-mode.d.ts +2 -1
  10. package/dist/edit-modes/edit-mode.d.ts.map +1 -1
  11. package/dist/edit-modes/geojson-edit-mode.d.ts +1 -0
  12. package/dist/edit-modes/geojson-edit-mode.d.ts.map +1 -1
  13. package/dist/edit-modes/geojson-edit-mode.js +1 -0
  14. package/dist/edit-modes/geojson-edit-mode.js.map +1 -1
  15. package/dist/edit-modes/measure-distance-mode.d.ts.map +1 -1
  16. package/dist/edit-modes/rotate-mode.d.ts.map +1 -1
  17. package/dist/edit-modes/scale-mode.d.ts.map +1 -1
  18. package/dist/edit-modes/types.d.ts +1 -0
  19. package/dist/edit-modes/types.d.ts.map +1 -1
  20. package/dist/editable-layers/editable-geojson-layer.d.ts +2 -1
  21. package/dist/editable-layers/editable-geojson-layer.d.ts.map +1 -1
  22. package/dist/editable-layers/editable-geojson-layer.js +5 -0
  23. package/dist/editable-layers/editable-geojson-layer.js.map +1 -1
  24. package/dist/editable-layers/editable-layer.d.ts +3 -1
  25. package/dist/editable-layers/editable-layer.d.ts.map +1 -1
  26. package/dist/editable-layers/editable-layer.js +7 -1
  27. package/dist/editable-layers/editable-layer.js.map +1 -1
  28. package/dist/index.cjs +847 -79
  29. package/dist/index.cjs.map +4 -4
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/lib/layers/segments-layer.d.ts +1 -1
  35. package/dist/lib/layers/segments-layer.d.ts.map +1 -1
  36. package/dist/lib/layers/segments-layer.js +1 -1
  37. package/dist/lib/layers/segments-layer.js.map +1 -1
  38. package/dist/lib/nebula-core.d.ts.map +1 -1
  39. package/dist/utils/memoize.d.ts.map +1 -1
  40. package/dist/widgets/edit-mode-tray-widget.d.ts +71 -0
  41. package/dist/widgets/edit-mode-tray-widget.d.ts.map +1 -0
  42. package/dist/widgets/edit-mode-tray-widget.js +217 -0
  43. package/dist/widgets/edit-mode-tray-widget.js.map +1 -0
  44. package/package.json +12 -11
  45. package/src/edit-modes/draw-line-string-mode.ts +23 -24
  46. package/src/edit-modes/draw-polygon-mode.ts +24 -27
  47. package/src/edit-modes/edit-mode.ts +4 -1
  48. package/src/edit-modes/geojson-edit-mode.ts +2 -0
  49. package/src/edit-modes/types.ts +3 -0
  50. package/src/editable-layers/editable-geojson-layer.ts +8 -1
  51. package/src/editable-layers/editable-layer.ts +10 -2
  52. package/src/index.ts +8 -0
  53. package/src/lib/layers/segments-layer.ts +1 -1
  54. package/src/widgets/edit-mode-tray-widget.tsx +342 -0
package/dist/index.cjs CHANGED
@@ -52,6 +52,7 @@ __export(dist_exports, {
52
52
  DrawSquareFromCenterMode: () => DrawSquareFromCenterMode,
53
53
  DrawSquareMode: () => DrawSquareMode,
54
54
  DuplicateMode: () => DuplicateMode,
55
+ EditModeTrayWidget: () => EditModeTrayWidget,
55
56
  EditableGeoJsonLayer: () => EditableGeoJsonLayer,
56
57
  EditableH3ClusterLayer: () => EditableH3ClusterLayer,
57
58
  ElevatedEditHandleLayer: () => ElevatedEditHandleLayer,
@@ -660,8 +661,549 @@ var TextsLayer = class extends NebulaLayer {
660
661
  }
661
662
  };
662
663
 
664
+ // ../layers/src/path-marker-layer/path-marker-layer.ts
665
+ var import_core4 = require("@deck.gl/core");
666
+ var import_layers5 = require("@deck.gl/layers");
667
+ var import_mesh_layers = require("@deck.gl/mesh-layers");
668
+
669
+ // ../layers/src/path-outline-layer/path-outline-layer.ts
670
+ var import_layers4 = require("@deck.gl/layers");
671
+ var import_constants2 = require("@luma.gl/constants");
672
+
673
+ // ../layers/src/path-outline-layer/outline.ts
674
+ var INITIAL_STATE = {
675
+ outlineEnabled: false,
676
+ outlineRenderShadowmap: false,
677
+ outlineShadowmap: null
678
+ };
679
+ function getUniforms({ outlineEnabled, outlineRenderShadowmap, outlineShadowmap } = INITIAL_STATE) {
680
+ const uniforms = {};
681
+ if (outlineEnabled !== void 0) {
682
+ uniforms.outline_uEnabled = outlineEnabled;
683
+ }
684
+ if (outlineRenderShadowmap !== void 0) {
685
+ uniforms.outline_uRenderOutlines = outlineRenderShadowmap;
686
+ }
687
+ if (outlineShadowmap !== void 0) {
688
+ uniforms.outline_uShadowmap = outlineShadowmap;
689
+ }
690
+ return uniforms;
691
+ }
692
+ var vs = `#version 300 es
693
+ in float instanceZLevel;
694
+ out float outline_vzLevel;
695
+ out vec4 outline_vPosition;
696
+
697
+ // Set the z level for the outline shadowmap rendering
698
+ void outline_setZLevel(float zLevel) {
699
+ outline_vzLevel = zLevel;
700
+ }
701
+
702
+ // Store an adjusted position for texture2DProj
703
+ void outline_setUV(vec4 position) {
704
+ // mat4(
705
+ // 0.5, 0.0, 0.0, 0.0,
706
+ // 0.0, 0.5, 0.0, 0.0,
707
+ // 0.0, 0.0, 0.5, 0.0,
708
+ // 0.5, 0.5, 0.5, 1.0
709
+ // ) * position;
710
+ outline_vPosition = vec4(position.xyz * 0.5 + position.w * 0.5, position.w);
711
+ }
712
+ `;
713
+ var fs = `uniform bool outline_uEnabled;
714
+ uniform bool outline_uRenderOutlines;
715
+ uniform sampler2D outline_uShadowmap;
716
+
717
+ in float outline_vzLevel;
718
+ // in vec2 outline_vUV;
719
+ in vec4 outline_vPosition;
720
+
721
+ out vec4 fragColor;
722
+
723
+ const float OUTLINE_Z_LEVEL_ERROR = 0.01;
724
+
725
+ // Return a darker color in shadowmap
726
+ vec4 outline_filterShadowColor(vec4 color) {
727
+ return vec4(outline_vzLevel / 255., outline_vzLevel / 255., outline_vzLevel / 255., 1.);
728
+ }
729
+
730
+ // Return a darker color if in shadowmap
731
+ vec4 outline_filterDarkenColor(vec4 color) {
732
+ if (outline_uEnabled) {
733
+ float maxZLevel;
734
+ if (outline_vPosition.q > 0.0) {
735
+ maxZLevel = texture2DProj(outline_uShadowmap, outline_vPosition).r * 255.;
736
+ } else {
737
+ discard;
738
+ }
739
+ if (maxZLevel < outline_vzLevel + OUTLINE_Z_LEVEL_ERROR) {
740
+ vec4(color.rgb * 0.5, color.a);
741
+ } else {
742
+ discard;
743
+ }
744
+ }
745
+ return color;
746
+ }
747
+
748
+ // if enabled and rendering outlines - Render depth to shadowmap
749
+ // if enabled and rendering colors - Return a darker color if in shadowmap
750
+ // if disabled, just return color
751
+ vec4 outline_filterColor(vec4 color) {
752
+ if (outline_uEnabled) {
753
+ return outline_uRenderOutlines ?
754
+ outline_filterShadowColor(color) :
755
+ outline_filterDarkenColor(color);
756
+ }
757
+ return color;
758
+ }
759
+ `;
760
+ var outline = {
761
+ name: "outline",
762
+ vs,
763
+ fs,
764
+ getUniforms
765
+ };
766
+
767
+ // ../layers/src/path-outline-layer/path-outline-layer.ts
768
+ var UNIT = {
769
+ common: 0,
770
+ meters: 1,
771
+ pixels: 2
772
+ };
773
+ function injectShaderCode({ source, code = "" }) {
774
+ const INJECT_CODE = /}[^{}]*$/;
775
+ return source.replace(INJECT_CODE, code.concat("\n}\n"));
776
+ }
777
+ var VS_CODE = ` outline_setUV(gl_Position);
778
+ outline_setZLevel(instanceZLevel);
779
+ `;
780
+ var FS_CODE = ` fragColor = outline_filterColor(fragColor);
781
+ `;
782
+ var OUTLINE_SHADOWMAP_PARAMETERS = {
783
+ blend: true,
784
+ blendColorSrcFactor: "one",
785
+ blendColorDstFactor: "one",
786
+ blendColorOperation: "max",
787
+ blendAlphaSrcFactor: "one",
788
+ blendAlphaDstFactor: "one",
789
+ blendAlphaOperation: "max",
790
+ depthWriteEnabled: false,
791
+ depthCompare: "always"
792
+ };
793
+ var OUTLINE_RENDER_PARAMETERS = {
794
+ blend: false,
795
+ depthWriteEnabled: false,
796
+ depthCompare: "always"
797
+ };
798
+ var defaultProps = {
799
+ getZLevel: () => 0
800
+ };
801
+ var PathOutlineLayer = class extends import_layers4.PathLayer {
802
+ state = void 0;
803
+ // Override getShaders to inject the outline module
804
+ getShaders() {
805
+ const shaders = super.getShaders();
806
+ return Object.assign({}, shaders, {
807
+ modules: shaders.modules.concat([outline]),
808
+ vs: injectShaderCode({ source: shaders.vs, code: VS_CODE }),
809
+ fs: injectShaderCode({ source: shaders.fs, code: FS_CODE })
810
+ });
811
+ }
812
+ // @ts-expect-error PathLayer is missing LayerContext arg
813
+ initializeState(context) {
814
+ super.initializeState();
815
+ const outlineFramebuffer = context.device.createFramebuffer({
816
+ colorAttachments: ["rgba8unorm"]
817
+ });
818
+ this.setState({
819
+ outlineFramebuffer
820
+ });
821
+ this.state.attributeManager.addInstanced({
822
+ instanceZLevel: {
823
+ size: 1,
824
+ type: import_constants2.GL.UNSIGNED_BYTE,
825
+ accessor: "getZLevel"
826
+ }
827
+ });
828
+ }
829
+ // Override draw to add render module
830
+ draw({ moduleParameters = {}, parameters, uniforms, context }) {
831
+ var _a;
832
+ const {
833
+ jointRounded,
834
+ capRounded,
835
+ billboard,
836
+ miterLimit,
837
+ widthUnits,
838
+ widthScale,
839
+ widthMinPixels,
840
+ widthMaxPixels
841
+ } = this.props;
842
+ uniforms = Object.assign({}, uniforms, {
843
+ jointType: Number(jointRounded),
844
+ capType: Number(capRounded),
845
+ billboard,
846
+ widthUnits: UNIT[widthUnits],
847
+ widthScale,
848
+ miterLimit,
849
+ widthMinPixels,
850
+ widthMaxPixels
851
+ });
852
+ const { outlineFramebuffer } = this.state;
853
+ if (context == null ? void 0 : context.viewport) {
854
+ const viewportWidth = Math.max(1, Math.ceil(context.viewport.width));
855
+ const viewportHeight = Math.max(1, Math.ceil(context.viewport.height));
856
+ outlineFramebuffer.resize({ width: viewportWidth, height: viewportHeight });
857
+ } else {
858
+ outlineFramebuffer.resize();
859
+ }
860
+ const shadowmapTexture = (_a = outlineFramebuffer.colorAttachments[0]) == null ? void 0 : _a.texture;
861
+ if (!shadowmapTexture) {
862
+ return;
863
+ }
864
+ this.state.model.updateModuleSettings({
865
+ outlineEnabled: true,
866
+ outlineRenderShadowmap: true,
867
+ outlineShadowmap: shadowmapTexture
868
+ });
869
+ this.state.model.draw({
870
+ uniforms: Object.assign({}, uniforms, {
871
+ jointType: 0,
872
+ widthScale: this.props.widthScale * 1.3
873
+ }),
874
+ parameters: OUTLINE_SHADOWMAP_PARAMETERS,
875
+ framebuffer: outlineFramebuffer
876
+ });
877
+ this.state.model.updateModuleSettings({
878
+ outlineEnabled: true,
879
+ outlineRenderShadowmap: false,
880
+ outlineShadowmap: shadowmapTexture
881
+ });
882
+ this.state.model.draw({
883
+ uniforms: Object.assign({}, uniforms, {
884
+ jointType: Number(jointRounded),
885
+ capType: Number(capRounded),
886
+ widthScale: this.props.widthScale
887
+ }),
888
+ parameters: OUTLINE_RENDER_PARAMETERS
889
+ });
890
+ }
891
+ };
892
+ __publicField(PathOutlineLayer, "layerName", "PathOutlineLayer");
893
+ __publicField(PathOutlineLayer, "defaultProps", defaultProps);
894
+
895
+ // ../layers/src/path-marker-layer/arrow-2d-geometry.ts
896
+ var import_engine = require("@luma.gl/engine");
897
+ var Arrow2DGeometry = class extends import_engine.Geometry {
898
+ constructor(opts = {}) {
899
+ super(
900
+ Object.assign({}, opts, {
901
+ attributes: getArrowAttributes(opts),
902
+ topology: "triangle-list"
903
+ })
904
+ );
905
+ }
906
+ };
907
+ function getArrowAttributes({ length = 1, headSize = 0.2, tailWidth = 0.05, tailStart = 0.05 }) {
908
+ const texCoords = [
909
+ // HEAD
910
+ 0.5,
911
+ 1,
912
+ 0,
913
+ 0.5 - headSize / 2,
914
+ 1 - headSize,
915
+ 0,
916
+ 0.5 + headSize / 2,
917
+ 1 - headSize,
918
+ 0,
919
+ 0.5 - tailWidth / 2,
920
+ tailStart,
921
+ 0,
922
+ 0.5 + tailWidth / 2,
923
+ 1 - headSize,
924
+ 0,
925
+ 0.5 + tailWidth / 2,
926
+ tailStart,
927
+ 0,
928
+ 0.5 - tailWidth / 2,
929
+ tailStart,
930
+ 0,
931
+ 0.5 - tailWidth / 2,
932
+ 1 - headSize,
933
+ 0,
934
+ 0.5 + tailWidth / 2,
935
+ 1 - headSize,
936
+ 0
937
+ ];
938
+ const normals = [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1];
939
+ const positions = new Array(texCoords.length);
940
+ for (let i = 0; i < texCoords.length / 3; i++) {
941
+ const i3 = i * 3;
942
+ positions[i3 + 0] = (texCoords[i3 + 0] - 0.5) * length;
943
+ positions[i3 + 1] = (texCoords[i3 + 1] - 0.5) * length;
944
+ positions[i3 + 2] = 0;
945
+ }
946
+ return {
947
+ positions: { size: 3, value: new Float32Array(positions) },
948
+ normals: { size: 3, value: new Float32Array(normals) },
949
+ texCoords: { size: 2, value: new Float32Array(texCoords) }
950
+ };
951
+ }
952
+
953
+ // ../layers/src/path-marker-layer/create-path-markers.ts
954
+ var import_core2 = require("@math.gl/core");
955
+ function getLineLength(vPoints) {
956
+ let lineLength = 0;
957
+ for (let i = 0; i < vPoints.length - 1; i++) {
958
+ lineLength += vPoints[i].distance(vPoints[i + 1]);
959
+ }
960
+ return lineLength;
961
+ }
962
+ var DEFAULT_COLOR = [0, 0, 0, 255];
963
+ var DEFAULT_DIRECTION = { forward: true, backward: false };
964
+ function createPathMarkers({
965
+ data,
966
+ getPath = (x, context) => x.path,
967
+ getDirection = (x) => x.direction,
968
+ getColor = (x) => DEFAULT_COLOR,
969
+ getMarkerPercentages = (x, info) => [0.5],
970
+ projectFlat
971
+ }) {
972
+ const markers = [];
973
+ for (const object of data) {
974
+ const path = getPath(object, null);
975
+ const direction = getDirection(object) || DEFAULT_DIRECTION;
976
+ const color = getColor(object);
977
+ const vPoints = path.map((p) => new import_core2.Vector2(p));
978
+ const vPointsReverse = vPoints.slice(0).reverse();
979
+ const lineLength = getLineLength(vPoints);
980
+ const percentages = getMarkerPercentages(object, { lineLength });
981
+ for (const percentage of percentages) {
982
+ if (direction.forward) {
983
+ const marker = createMarkerAlongPath({
984
+ path: vPoints,
985
+ percentage,
986
+ lineLength,
987
+ color,
988
+ object,
989
+ projectFlat
990
+ });
991
+ markers.push(marker);
992
+ }
993
+ if (direction.backward) {
994
+ const marker = createMarkerAlongPath({
995
+ path: vPointsReverse,
996
+ percentage,
997
+ lineLength,
998
+ color,
999
+ object,
1000
+ projectFlat
1001
+ });
1002
+ markers.push(marker);
1003
+ }
1004
+ }
1005
+ }
1006
+ return markers;
1007
+ }
1008
+ function createMarkerAlongPath({
1009
+ path,
1010
+ percentage,
1011
+ lineLength,
1012
+ color,
1013
+ object,
1014
+ projectFlat
1015
+ }) {
1016
+ const distanceAlong = lineLength * percentage;
1017
+ let currentDistance = 0;
1018
+ let previousDistance = 0;
1019
+ let i = 0;
1020
+ for (i = 0; i < path.length - 1; i++) {
1021
+ currentDistance += path[i].distance(path[i + 1]);
1022
+ if (currentDistance > distanceAlong) {
1023
+ break;
1024
+ }
1025
+ previousDistance = currentDistance;
1026
+ }
1027
+ if (i === path.length - 1) {
1028
+ i -= 1;
1029
+ }
1030
+ const vDirection = path[i + 1].clone().subtract(path[i]).normalize();
1031
+ const along = distanceAlong - previousDistance;
1032
+ const vCenter = vDirection.clone().multiply(new import_core2.Vector2(along, along)).add(path[i]);
1033
+ const vDirection2 = new import_core2.Vector2(projectFlat(path[i + 1])).subtract(projectFlat(path[i]));
1034
+ const angle = vDirection2.verticalAngle() * 180 / Math.PI;
1035
+ return { position: [vCenter.x, vCenter.y, 0], angle, color, object };
1036
+ }
1037
+
1038
+ // ../layers/src/path-marker-layer/polyline.ts
1039
+ var import_core3 = require("@math.gl/core");
1040
+ function getClosestPointOnLine({ p, p1, p2, clampToLine = true }) {
1041
+ const lineVector = new import_core3.Vector3(p2).subtract(p1);
1042
+ const pointVector = new import_core3.Vector3(p).subtract(p1);
1043
+ let dotProduct = lineVector.dot(pointVector);
1044
+ if (clampToLine) {
1045
+ dotProduct = (0, import_core3.clamp)(dotProduct, 0, 1);
1046
+ }
1047
+ return lineVector.lerp(p1, p2, dotProduct);
1048
+ }
1049
+ function getClosestPointOnPolyline({ p, points }) {
1050
+ p = new import_core3.Vector3(p);
1051
+ let pClosest = null;
1052
+ let distanceSquared = Infinity;
1053
+ let index = -1;
1054
+ for (let i = 0; i < points.length - 1; ++i) {
1055
+ const p1 = points[i];
1056
+ const p2 = points[i + 1];
1057
+ const pClosestOnLine = getClosestPointOnLine({ p, p1, p2 });
1058
+ const distanceToLineSquared = p.distanceSquared(pClosestOnLine);
1059
+ if (distanceToLineSquared < distanceSquared) {
1060
+ distanceSquared = distanceToLineSquared;
1061
+ pClosest = pClosestOnLine;
1062
+ index = i;
1063
+ }
1064
+ }
1065
+ return {
1066
+ point: pClosest,
1067
+ index,
1068
+ p1: points[index],
1069
+ p2: points[index + 1],
1070
+ distanceSquared,
1071
+ distance: Math.sqrt(distanceSquared)
1072
+ };
1073
+ }
1074
+
1075
+ // ../layers/src/path-marker-layer/path-marker-layer.ts
1076
+ var DISTANCE_FOR_MULTI_ARROWS = 0.1;
1077
+ var ARROW_HEAD_SIZE = 0.2;
1078
+ var ARROW_TAIL_WIDTH = 0.05;
1079
+ var DEFAULT_MARKER_LAYER = import_mesh_layers.SimpleMeshLayer;
1080
+ var DEFAULT_MARKER_LAYER_PROPS = {
1081
+ mesh: new Arrow2DGeometry({ headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH })
1082
+ };
1083
+ var defaultProps2 = Object.assign(
1084
+ {},
1085
+ PathOutlineLayer.defaultProps,
1086
+ {
1087
+ MarkerLayer: DEFAULT_MARKER_LAYER,
1088
+ markerLayerProps: DEFAULT_MARKER_LAYER_PROPS,
1089
+ sizeScale: 100,
1090
+ fp64: false,
1091
+ highlightIndex: -1,
1092
+ highlightPoint: null,
1093
+ getPath: (x) => x.path,
1094
+ getColor: (x) => x.color,
1095
+ getMarkerColor: (x) => [0, 0, 0, 255],
1096
+ getDirection: (x) => x.direction,
1097
+ getMarkerPercentages: (object, { lineLength }) => lineLength > DISTANCE_FOR_MULTI_ARROWS ? [0.25, 0.5, 0.75] : [0.5]
1098
+ }
1099
+ );
1100
+ var PathMarkerLayer = class extends import_core4.CompositeLayer {
1101
+ state = void 0;
1102
+ initializeState() {
1103
+ this.state = {
1104
+ markers: [],
1105
+ mesh: new Arrow2DGeometry({ headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH }),
1106
+ closestPoint: null,
1107
+ closestPoints: []
1108
+ };
1109
+ }
1110
+ projectFlat(xyz, viewport, coordinateSystem, coordinateOrigin) {
1111
+ if (coordinateSystem === import_core4.COORDINATE_SYSTEM.METER_OFFSETS) {
1112
+ const [dx, dy] = viewport.metersToLngLatDelta(xyz);
1113
+ const [x, y] = coordinateOrigin;
1114
+ return viewport.projectFlat([x + dx, dy + y]);
1115
+ } else if (coordinateSystem === import_core4.COORDINATE_SYSTEM.LNGLAT_OFFSETS) {
1116
+ const [dx, dy] = xyz;
1117
+ const [x, y] = coordinateOrigin;
1118
+ return viewport.projectFlat([x + dx, dy + y]);
1119
+ }
1120
+ return viewport.projectFlat(xyz);
1121
+ }
1122
+ updateState({ props, oldProps, changeFlags }) {
1123
+ if (changeFlags.dataChanged || changeFlags.updateTriggersChanged) {
1124
+ const {
1125
+ data,
1126
+ getPath,
1127
+ getDirection,
1128
+ getMarkerColor,
1129
+ getMarkerPercentages,
1130
+ coordinateSystem,
1131
+ coordinateOrigin
1132
+ } = this.props;
1133
+ const { viewport } = this.context;
1134
+ const projectFlat = (o) => this.projectFlat(o, viewport, coordinateSystem, coordinateOrigin);
1135
+ this.state.markers = createPathMarkers({
1136
+ data,
1137
+ getPath,
1138
+ getDirection,
1139
+ getColor: getMarkerColor,
1140
+ getMarkerPercentages,
1141
+ projectFlat
1142
+ });
1143
+ this._recalculateClosestPoint();
1144
+ }
1145
+ if (changeFlags.propsChanged) {
1146
+ if (props.point !== oldProps.point) {
1147
+ this._recalculateClosestPoint();
1148
+ }
1149
+ }
1150
+ }
1151
+ _recalculateClosestPoint() {
1152
+ const { highlightPoint, highlightIndex } = this.props;
1153
+ if (highlightPoint && highlightIndex >= 0) {
1154
+ const object = this.props.data[highlightIndex];
1155
+ const points = this.props.getPath(object, null);
1156
+ const { point: point14 } = getClosestPointOnPolyline({ points, p: highlightPoint });
1157
+ this.state.closestPoints = [{ position: point14 }];
1158
+ } else {
1159
+ this.state.closestPoints = [];
1160
+ }
1161
+ }
1162
+ getPickingInfo({ info }) {
1163
+ return Object.assign(info, {
1164
+ // override object with picked feature
1165
+ object: info.object && info.object.path || info.object
1166
+ });
1167
+ }
1168
+ renderLayers() {
1169
+ return [
1170
+ new PathOutlineLayer(
1171
+ this.props,
1172
+ this.getSubLayerProps({
1173
+ id: "paths",
1174
+ // Note: data has to be passed explicitly like this to avoid being empty
1175
+ data: this.props.data
1176
+ })
1177
+ ),
1178
+ new this.props.MarkerLayer(
1179
+ this.getSubLayerProps(
1180
+ Object.assign({}, this.props.markerLayerProps, {
1181
+ id: "markers",
1182
+ data: this.state.markers,
1183
+ getOrientation: (x) => [0, -x.angle, 0],
1184
+ getColor: (x) => x.color,
1185
+ sizeScale: this.props.sizeScale,
1186
+ fp64: this.props.fp64,
1187
+ pickable: false,
1188
+ parameters: {
1189
+ blend: false,
1190
+ depthTest: false
1191
+ }
1192
+ })
1193
+ )
1194
+ ),
1195
+ this.state.closestPoints && new import_layers5.ScatterplotLayer({
1196
+ id: `${this.props.id}-highlight`,
1197
+ data: this.state.closestPoints,
1198
+ fp64: this.props.fp64
1199
+ })
1200
+ ];
1201
+ }
1202
+ };
1203
+ __publicField(PathMarkerLayer, "layerName", "PathMarkerLayer");
1204
+ __publicField(PathMarkerLayer, "defaultProps", defaultProps2);
1205
+
663
1206
  // dist/lib/layers/segments-layer.js
664
- var import_layers4 = require("@deck.gl-community/layers");
665
1207
  var NEBULA_TO_DECK_DIRECTIONS = {
666
1208
  [ArrowStyles.NONE]: { forward: false, backward: false },
667
1209
  [ArrowStyles.FORWARD]: { forward: true, backward: false },
@@ -717,7 +1259,7 @@ var SegmentsLayer = class extends NebulaLayer {
717
1259
  render({ nebula }) {
718
1260
  const defaultColor = [0, 0, 0, 255];
719
1261
  const { objects, updateTrigger } = this.deckCache;
720
- return new import_layers4.PathMarkerLayer({
1262
+ return new PathMarkerLayer({
721
1263
  id: `segments-${this.id}`,
722
1264
  data: objects,
723
1265
  opacity: 1,
@@ -743,7 +1285,7 @@ var SegmentsLayer = class extends NebulaLayer {
743
1285
  highlightColor: toDeckColor(this.highlightColor),
744
1286
  dashJustified: this.dashed,
745
1287
  getDashArray: this.dashed ? (nf) => nf.style.dashArray : void 0,
746
- markerLayerProps: this.markerLayerProps || import_layers4.PathMarkerLayer.defaultProps.markerLayerProps,
1288
+ markerLayerProps: this.markerLayerProps || PathMarkerLayer.defaultProps.markerLayerProps,
747
1289
  nebulaLayer: this
748
1290
  });
749
1291
  }
@@ -751,12 +1293,12 @@ var SegmentsLayer = class extends NebulaLayer {
751
1293
 
752
1294
  // dist/lib/nebula-core.js
753
1295
  var import_eventemitter32 = require("eventemitter3");
754
- var import_core2 = require("@deck.gl/core");
1296
+ var import_core5 = require("@deck.gl/core");
755
1297
  var LOGGER_PREFIX = "Nebula: ";
756
1298
  var NebulaCore = class {
757
1299
  init(props) {
758
1300
  this.props = props;
759
- this.wmViewport = new import_core2.WebMercatorViewport(this.props.viewport);
1301
+ this.wmViewport = new import_core5.WebMercatorViewport(this.props.viewport);
760
1302
  ["click", "mousemove", "mouseup", "mousedown"].forEach((name) => document.addEventListener(name, this._onMouseEvent, true));
761
1303
  }
762
1304
  detach() {
@@ -765,7 +1307,7 @@ var NebulaCore = class {
765
1307
  updateProps(newProps) {
766
1308
  this.props = newProps;
767
1309
  const { viewport } = this.props;
768
- this.wmViewport = new import_core2.WebMercatorViewport(viewport);
1310
+ this.wmViewport = new import_core5.WebMercatorViewport(viewport);
769
1311
  }
770
1312
  props = null;
771
1313
  deckgl = null;
@@ -966,7 +1508,7 @@ var NebulaCore = class {
966
1508
  };
967
1509
 
968
1510
  // dist/editable-layers/editable-geojson-layer.js
969
- var import_layers6 = require("@deck.gl/layers");
1511
+ var import_layers7 = require("@deck.gl/layers");
970
1512
 
971
1513
  // dist/edit-modes/geojson-edit-mode.js
972
1514
  var import_union = __toESM(require("@turf/union"), 1);
@@ -1697,6 +2239,8 @@ var GeoJsonEditMode = class {
1697
2239
  }
1698
2240
  handleClick(event, props) {
1699
2241
  }
2242
+ handleDoubleClick(event, props) {
2243
+ }
1700
2244
  handlePointerMove(event, props) {
1701
2245
  const tentativeFeature = this.createTentativeFeature(props);
1702
2246
  if (tentativeFeature) {
@@ -2802,15 +3346,7 @@ var DrawLineStringMode = class extends GeoJsonEditMode {
2802
3346
  }
2803
3347
  if (clickSequence.length > 1 && clickedEditHandle && Array.isArray(clickedEditHandle.properties.positionIndexes) && clickedEditHandle.properties.positionIndexes[0] === clickSequence.length - 1) {
2804
3348
  this.dist = 0;
2805
- const lineStringToAdd = {
2806
- type: "LineString",
2807
- coordinates: [...clickSequence]
2808
- };
2809
- this.resetClickSequence();
2810
- const editAction = this.getAddFeatureAction(lineStringToAdd, props.data);
2811
- if (editAction) {
2812
- props.onEdit(editAction);
2813
- }
3349
+ this.finishDrawing(props);
2814
3350
  } else if (positionAdded) {
2815
3351
  props.onEdit({
2816
3352
  // data is the same
@@ -2822,21 +3358,27 @@ var DrawLineStringMode = class extends GeoJsonEditMode {
2822
3358
  });
2823
3359
  }
2824
3360
  }
3361
+ handleDoubleClick(event, props) {
3362
+ this.finishDrawing(props);
3363
+ }
3364
+ finishDrawing(props) {
3365
+ const clickSequence = this.getClickSequence();
3366
+ if (clickSequence.length > 1) {
3367
+ const lineStringToAdd = {
3368
+ type: "LineString",
3369
+ coordinates: [...clickSequence]
3370
+ };
3371
+ this.resetClickSequence();
3372
+ const editAction = this.getAddFeatureAction(lineStringToAdd, props.data);
3373
+ if (editAction) {
3374
+ props.onEdit(editAction);
3375
+ }
3376
+ }
3377
+ }
2825
3378
  handleKeyUp(event, props) {
2826
3379
  const { key } = event;
2827
3380
  if (key === "Enter") {
2828
- const clickSequence = this.getClickSequence();
2829
- if (clickSequence.length > 1) {
2830
- const lineStringToAdd = {
2831
- type: "LineString",
2832
- coordinates: [...clickSequence]
2833
- };
2834
- this.resetClickSequence();
2835
- const editAction = this.getAddFeatureAction(lineStringToAdd, props.data);
2836
- if (editAction) {
2837
- props.onEdit(editAction);
2838
- }
2839
- }
3381
+ this.finishDrawing(props);
2840
3382
  } else if (key === "Escape") {
2841
3383
  this.resetClickSequence();
2842
3384
  props.onEdit({
@@ -2994,6 +3536,20 @@ var DrawPolygonMode = class extends GeoJsonEditMode {
2994
3536
  guides.features.push(...editHandles);
2995
3537
  return guides;
2996
3538
  }
3539
+ finishDrawing(props) {
3540
+ const clickSequence = this.getClickSequence();
3541
+ if (clickSequence.length > 2) {
3542
+ const polygonToAdd = {
3543
+ type: "Polygon",
3544
+ coordinates: [[...clickSequence, clickSequence[0]]]
3545
+ };
3546
+ this.resetClickSequence();
3547
+ const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props);
3548
+ if (editAction) {
3549
+ props.onEdit(editAction);
3550
+ }
3551
+ }
3552
+ }
2997
3553
  // eslint-disable-next-line complexity
2998
3554
  handleClick(event, props) {
2999
3555
  const { picks } = event;
@@ -3017,15 +3573,7 @@ var DrawPolygonMode = class extends GeoJsonEditMode {
3017
3573
  positionAdded = true;
3018
3574
  }
3019
3575
  if (clickSequence.length > 2 && clickedEditHandle && Array.isArray(clickedEditHandle.properties.positionIndexes) && (clickedEditHandle.properties.positionIndexes[0] === 0 || clickedEditHandle.properties.positionIndexes[0] === clickSequence.length - 1)) {
3020
- const polygonToAdd = {
3021
- type: "Polygon",
3022
- coordinates: [[...clickSequence, clickSequence[0]]]
3023
- };
3024
- this.resetClickSequence();
3025
- const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props);
3026
- if (editAction) {
3027
- props.onEdit(editAction);
3028
- }
3576
+ this.finishDrawing(props);
3029
3577
  } else if (positionAdded) {
3030
3578
  props.onEdit({
3031
3579
  // data is the same
@@ -3037,20 +3585,12 @@ var DrawPolygonMode = class extends GeoJsonEditMode {
3037
3585
  });
3038
3586
  }
3039
3587
  }
3588
+ handleDoubleClick(event, props) {
3589
+ this.finishDrawing(props);
3590
+ }
3040
3591
  handleKeyUp(event, props) {
3041
3592
  if (event.key === "Enter") {
3042
- const clickSequence = this.getClickSequence();
3043
- if (clickSequence.length > 2) {
3044
- const polygonToAdd = {
3045
- type: "Polygon",
3046
- coordinates: [[...clickSequence, clickSequence[0]]]
3047
- };
3048
- this.resetClickSequence();
3049
- const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props);
3050
- if (editAction) {
3051
- props.onEdit(editAction);
3052
- }
3053
- }
3593
+ this.finishDrawing(props);
3054
3594
  } else if (event.key === "Escape") {
3055
3595
  this.resetClickSequence();
3056
3596
  props.onEdit({
@@ -3987,13 +4527,15 @@ var DeleteMode = class extends GeoJsonEditMode {
3987
4527
  var PROJECTED_PIXEL_SIZE_MULTIPLIER2 = 2 / 3;
3988
4528
 
3989
4529
  // dist/editable-layers/editable-layer.js
3990
- var import_core3 = require("@deck.gl/core");
3991
- var EVENT_TYPES = ["click", "pointermove", "panstart", "panmove", "panend", "keyup"];
3992
- var EditableLayer = class extends import_core3.CompositeLayer {
4530
+ var import_core6 = require("@deck.gl/core");
4531
+ var EVENT_TYPES = ["click", "pointermove", "panstart", "panmove", "panend", "keyup", "dblclick"];
4532
+ var EditableLayer = class extends import_core6.CompositeLayer {
3993
4533
  state = void 0;
3994
4534
  // Overridable interaction event handlers
3995
4535
  onLayerClick(event) {
3996
4536
  }
4537
+ onLayerDoubleClick(event) {
4538
+ }
3997
4539
  onStartDragging(event) {
3998
4540
  }
3999
4541
  onStopDragging(event) {
@@ -4063,6 +4605,9 @@ var EditableLayer = class extends import_core3.CompositeLayer {
4063
4605
  sourceEvent: srcEvent
4064
4606
  });
4065
4607
  }
4608
+ _ondblclick({ srcEvent }) {
4609
+ this.onLayerDoubleClick(srcEvent);
4610
+ }
4066
4611
  _onkeyup({ srcEvent }) {
4067
4612
  this.onLayerKeyUp(srcEvent);
4068
4613
  }
@@ -4177,7 +4722,7 @@ var EditableLayer = class extends import_core3.CompositeLayer {
4177
4722
  __publicField(EditableLayer, "layerName", "EditableLayer");
4178
4723
 
4179
4724
  // dist/editable-layers/editable-path-layer.js
4180
- var import_layers5 = require("@deck.gl/layers");
4725
+ var import_layers6 = require("@deck.gl/layers");
4181
4726
  var uniformBlock = `uniform pickingLineWidthUniforms {
4182
4727
  float extraPixels;
4183
4728
  } pickingLineWidth;
@@ -4190,11 +4735,11 @@ var pickingUniforms = {
4190
4735
  extraPixels: "f32"
4191
4736
  }
4192
4737
  };
4193
- var defaultProps = {
4194
- ...import_layers5.PathLayer.defaultProps,
4738
+ var defaultProps3 = {
4739
+ ...import_layers6.PathLayer.defaultProps,
4195
4740
  pickingLineWidthExtraPixels: { type: "number", min: 0, value: Number.MAX_SAFE_INTEGER }
4196
4741
  };
4197
- var EditablePathLayer = class extends import_layers5.PathLayer {
4742
+ var EditablePathLayer = class extends import_layers6.PathLayer {
4198
4743
  getShaders() {
4199
4744
  const shaders = super.getShaders();
4200
4745
  shaders.vs = insertBefore(shaders.vs, "vec3 width;", `
@@ -4215,7 +4760,7 @@ var EditablePathLayer = class extends import_layers5.PathLayer {
4215
4760
  super.draw(props);
4216
4761
  }
4217
4762
  };
4218
- EditablePathLayer.defaultProps = defaultProps;
4763
+ EditablePathLayer.defaultProps = defaultProps3;
4219
4764
  EditablePathLayer.layerName = "EditablePathLayer";
4220
4765
 
4221
4766
  // dist/editable-layers/editable-geojson-layer.js
@@ -4273,7 +4818,7 @@ function getEditHandleRadius(handle) {
4273
4818
  return DEFAULT_EDITING_INTERMEDIATE_POINT_RADIUS;
4274
4819
  }
4275
4820
  }
4276
- var defaultProps2 = {
4821
+ var defaultProps4 = {
4277
4822
  mode: DEFAULT_EDIT_MODE,
4278
4823
  // Edit and interaction events
4279
4824
  onEdit: () => {
@@ -4405,7 +4950,7 @@ var EditableGeoJsonLayer = class extends EditableLayer {
4405
4950
  getLineWidth: [this.props.selectedFeatureIndexes, this.props.mode]
4406
4951
  }
4407
4952
  });
4408
- let layers = [new import_layers6.GeoJsonLayer(subLayerProps)];
4953
+ let layers = [new import_layers7.GeoJsonLayer(subLayerProps)];
4409
4954
  layers = layers.concat(this.createGuidesLayers(), this.createTooltipsLayers());
4410
4955
  return layers;
4411
4956
  }
@@ -4519,7 +5064,7 @@ var EditableGeoJsonLayer = class extends EditableLayer {
4519
5064
  };
4520
5065
  if (this.props.editHandleType === "icon") {
4521
5066
  subLayerProps["points-icon"] = {
4522
- type: import_layers6.IconLayer,
5067
+ type: import_layers7.IconLayer,
4523
5068
  iconAtlas: this.props.editHandleIconAtlas,
4524
5069
  iconMapping: this.props.editHandleIconMapping,
4525
5070
  sizeUnits: this.props.editHandleIconSizeUnits,
@@ -4532,7 +5077,7 @@ var EditableGeoJsonLayer = class extends EditableLayer {
4532
5077
  };
4533
5078
  } else {
4534
5079
  subLayerProps["points-circle"] = {
4535
- type: import_layers6.ScatterplotLayer,
5080
+ type: import_layers7.ScatterplotLayer,
4536
5081
  radiusScale: this.props.editHandlePointRadiusScale,
4537
5082
  stroked: this.props.editHandlePointOutline,
4538
5083
  getLineWidth: this.props.editHandlePointStrokeWidth,
@@ -4545,7 +5090,7 @@ var EditableGeoJsonLayer = class extends EditableLayer {
4545
5090
  billboard: this.props.billboard
4546
5091
  };
4547
5092
  }
4548
- const layer = new import_layers6.GeoJsonLayer(this.getSubLayerProps({
5093
+ const layer = new import_layers7.GeoJsonLayer(this.getSubLayerProps({
4549
5094
  id: "guides",
4550
5095
  data: guides,
4551
5096
  fp64: this.props.fp64,
@@ -4568,7 +5113,7 @@ var EditableGeoJsonLayer = class extends EditableLayer {
4568
5113
  createTooltipsLayers() {
4569
5114
  const mode = this.getActiveMode();
4570
5115
  const tooltips = mode.getTooltips(this.getModeProps(this.props));
4571
- const layer = new import_layers6.TextLayer({
5116
+ const layer = new import_layers7.TextLayer({
4572
5117
  getSize: DEFAULT_TOOLTIP_FONT_SIZE,
4573
5118
  ...this.getSubLayerProps({
4574
5119
  id: "tooltips",
@@ -4580,6 +5125,11 @@ var EditableGeoJsonLayer = class extends EditableLayer {
4580
5125
  onLayerClick(event) {
4581
5126
  this.getActiveMode().handleClick(event, this.getModeProps(this.props));
4582
5127
  }
5128
+ onLayerDoubleClick(event) {
5129
+ if (this.getActiveMode().handleDoubleClick) {
5130
+ this.getActiveMode().handleDoubleClick(event, this.getModeProps(this.props));
5131
+ }
5132
+ }
4583
5133
  onLayerKeyUp(event) {
4584
5134
  this.getActiveMode().handleKeyUp(event, this.getModeProps(this.props));
4585
5135
  }
@@ -4611,7 +5161,7 @@ var EditableGeoJsonLayer = class extends EditableLayer {
4611
5161
  }
4612
5162
  };
4613
5163
  __publicField(EditableGeoJsonLayer, "layerName", "EditableGeoJsonLayer");
4614
- __publicField(EditableGeoJsonLayer, "defaultProps", defaultProps2);
5164
+ __publicField(EditableGeoJsonLayer, "defaultProps", defaultProps4);
4615
5165
 
4616
5166
  // dist/editable-layers/editable-h3-cluster-layer.js
4617
5167
  var import_geo_layers = require("@deck.gl/geo-layers");
@@ -4621,7 +5171,7 @@ var EMPTY_FEATURE_COLLECTION = {
4621
5171
  type: "FeatureCollection",
4622
5172
  features: []
4623
5173
  };
4624
- var defaultProps3 = {
5174
+ var defaultProps5 = {
4625
5175
  mode: DEFAULT_EDIT_MODE2,
4626
5176
  ...EditableGeoJsonLayer.defaultProps,
4627
5177
  // h3 layer
@@ -4760,11 +5310,11 @@ var EditableH3ClusterLayer = class extends EditableLayer {
4760
5310
  }
4761
5311
  };
4762
5312
  __publicField(EditableH3ClusterLayer, "layerName", "EditableH3ClusterLayer");
4763
- __publicField(EditableH3ClusterLayer, "defaultProps", defaultProps3);
5313
+ __publicField(EditableH3ClusterLayer, "defaultProps", defaultProps5);
4764
5314
 
4765
5315
  // dist/editable-layers/selection-layer.js
4766
- var import_core4 = require("@deck.gl/core");
4767
- var import_layers7 = require("@deck.gl/layers");
5316
+ var import_core7 = require("@deck.gl/core");
5317
+ var import_layers8 = require("@deck.gl/layers");
4768
5318
  var import_helpers16 = require("@turf/helpers");
4769
5319
  var import_buffer3 = __toESM(require("@turf/buffer"), 1);
4770
5320
  var import_difference4 = __toESM(require("@turf/difference"), 1);
@@ -4780,7 +5330,7 @@ var MODE_MAP = {
4780
5330
  var MODE_CONFIG_MAP = {
4781
5331
  [SELECTION_TYPE2.RECTANGLE]: { dragToDraw: true }
4782
5332
  };
4783
- var defaultProps4 = {
5333
+ var defaultProps6 = {
4784
5334
  selectionType: SELECTION_TYPE2.RECTANGLE,
4785
5335
  layerIds: [],
4786
5336
  onSelect: () => {
@@ -4815,7 +5365,7 @@ var PASS_THROUGH_PROPS = [
4815
5365
  "getTentativeFillColor",
4816
5366
  "getTentativeLineWidth"
4817
5367
  ];
4818
- var SelectionLayer = class extends import_core4.CompositeLayer {
5368
+ var SelectionLayer = class extends import_core7.CompositeLayer {
4819
5369
  state = void 0;
4820
5370
  _selectRectangleObjects(coordinates) {
4821
5371
  const { layerIds, onSelect } = this.props;
@@ -4899,7 +5449,7 @@ var SelectionLayer = class extends import_core4.CompositeLayer {
4899
5449
  ];
4900
5450
  if (pendingPolygonSelection) {
4901
5451
  const { bigPolygon } = pendingPolygonSelection;
4902
- layers.push(new import_layers7.PolygonLayer(this.getSubLayerProps({
5452
+ layers.push(new import_layers8.PolygonLayer(this.getSubLayerProps({
4903
5453
  id: LAYER_ID_BLOCKER,
4904
5454
  pickable: true,
4905
5455
  stroked: false,
@@ -4917,19 +5467,19 @@ var SelectionLayer = class extends import_core4.CompositeLayer {
4917
5467
  }
4918
5468
  };
4919
5469
  __publicField(SelectionLayer, "layerName", "SelectionLayer");
4920
- __publicField(SelectionLayer, "defaultProps", defaultProps4);
5470
+ __publicField(SelectionLayer, "defaultProps", defaultProps6);
4921
5471
 
4922
5472
  // dist/editable-layers/elevated-edit-handle-layer.js
4923
- var import_core5 = require("@deck.gl/core");
4924
- var import_layers8 = require("@deck.gl/layers");
4925
- var defaultProps5 = {};
4926
- var ElevatedEditHandleLayer = class extends import_core5.CompositeLayer {
5473
+ var import_core8 = require("@deck.gl/core");
5474
+ var import_layers9 = require("@deck.gl/layers");
5475
+ var defaultProps7 = {};
5476
+ var ElevatedEditHandleLayer = class extends import_core8.CompositeLayer {
4927
5477
  renderLayers() {
4928
- const handles = new import_layers8.ScatterplotLayer(Object.assign({}, this.props, {
5478
+ const handles = new import_layers9.ScatterplotLayer(Object.assign({}, this.props, {
4929
5479
  id: `${this.props.id}-ScatterplotLayer`,
4930
5480
  data: this.props.data
4931
5481
  }));
4932
- const lines = new import_layers8.LineLayer(Object.assign({}, this.props, {
5482
+ const lines = new import_layers9.LineLayer(Object.assign({}, this.props, {
4933
5483
  id: `${this.props.id}-LineLayer`,
4934
5484
  data: this.props.data,
4935
5485
  pickable: false,
@@ -4942,7 +5492,225 @@ var ElevatedEditHandleLayer = class extends import_core5.CompositeLayer {
4942
5492
  }
4943
5493
  };
4944
5494
  __publicField(ElevatedEditHandleLayer, "layerName", "ElevatedEditHandleLayer");
4945
- __publicField(ElevatedEditHandleLayer, "defaultProps", defaultProps5);
5495
+ __publicField(ElevatedEditHandleLayer, "defaultProps", defaultProps7);
5496
+
5497
+ // dist/widgets/edit-mode-tray-widget.js
5498
+ var import_jsx_runtime = require("preact/jsx-runtime");
5499
+ var import_preact = require("preact");
5500
+ var import_core9 = require("@deck.gl/core");
5501
+ var ROOT_STYLE = {
5502
+ position: "absolute",
5503
+ display: "flex",
5504
+ pointerEvents: "auto",
5505
+ userSelect: "none",
5506
+ zIndex: "99"
5507
+ };
5508
+ var TRAY_BASE_STYLE = {
5509
+ display: "flex",
5510
+ gap: "6px",
5511
+ background: "rgba(36, 40, 41, 0.88)",
5512
+ borderRadius: "999px",
5513
+ padding: "6px",
5514
+ alignItems: "center",
5515
+ justifyContent: "center",
5516
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.25)"
5517
+ };
5518
+ var BUTTON_BASE_STYLE = {
5519
+ appearance: "none",
5520
+ background: "transparent",
5521
+ border: "none",
5522
+ color: "#f0f0f0",
5523
+ width: "34px",
5524
+ height: "34px",
5525
+ display: "flex",
5526
+ flexDirection: "column",
5527
+ alignItems: "center",
5528
+ justifyContent: "center",
5529
+ borderRadius: "50%",
5530
+ cursor: "pointer",
5531
+ padding: "0",
5532
+ transition: "background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease"
5533
+ };
5534
+ var BUTTON_ACTIVE_STYLE = {
5535
+ background: "#0071e3",
5536
+ color: "#ffffff",
5537
+ boxShadow: "0 0 0 2px rgba(255, 255, 255, 0.35)"
5538
+ };
5539
+ var BUTTON_LABEL_STYLE = {
5540
+ fontSize: "10px",
5541
+ marginTop: "2px",
5542
+ lineHeight: "12px"
5543
+ };
5544
+ var _EditModeTrayWidget = class extends import_core9.Widget {
5545
+ placement = "top-left";
5546
+ className = "deck-widget-edit-mode-tray";
5547
+ layout = "vertical";
5548
+ selectedModeId = null;
5549
+ deck = null;
5550
+ appliedCustomClassName = null;
5551
+ constructor(props = {}) {
5552
+ super({ ..._EditModeTrayWidget.defaultProps, ...props });
5553
+ this.placement = props.placement ?? _EditModeTrayWidget.defaultProps.placement;
5554
+ this.layout = props.layout ?? _EditModeTrayWidget.defaultProps.layout;
5555
+ this.selectedModeId = this.resolveSelectedModeId(props.modes ?? [], props);
5556
+ }
5557
+ setProps(props) {
5558
+ if (props.placement !== void 0) {
5559
+ this.placement = props.placement;
5560
+ }
5561
+ if (props.layout !== void 0) {
5562
+ this.layout = props.layout;
5563
+ }
5564
+ const modes = props.modes ?? this.props.modes ?? [];
5565
+ this.selectedModeId = this.resolveSelectedModeId(modes, props);
5566
+ super.setProps(props);
5567
+ this.renderTray();
5568
+ }
5569
+ onAdd({ deck }) {
5570
+ this.deck = deck;
5571
+ }
5572
+ onRemove() {
5573
+ this.deck = null;
5574
+ const root = this.rootElement;
5575
+ if (root) {
5576
+ (0, import_preact.render)(null, root);
5577
+ }
5578
+ this.rootElement = null;
5579
+ }
5580
+ onRenderHTML(rootElement) {
5581
+ const style = { ...ROOT_STYLE, ...this.props.style };
5582
+ Object.assign(rootElement.style, style);
5583
+ if (this.appliedCustomClassName && this.appliedCustomClassName !== this.props.className) {
5584
+ rootElement.classList.remove(this.appliedCustomClassName);
5585
+ this.appliedCustomClassName = null;
5586
+ }
5587
+ if (this.props.className) {
5588
+ rootElement.classList.add(this.props.className);
5589
+ this.appliedCustomClassName = this.props.className;
5590
+ }
5591
+ rootElement.classList.add(this.className);
5592
+ this.renderTray();
5593
+ }
5594
+ renderTray() {
5595
+ const root = this.rootElement;
5596
+ if (!root) {
5597
+ return;
5598
+ }
5599
+ const modes = this.props.modes ?? [];
5600
+ const selectedId = this.selectedModeId;
5601
+ const direction = this.layout === "horizontal" ? "row" : "column";
5602
+ const trayStyle = {
5603
+ ...TRAY_BASE_STYLE,
5604
+ flexDirection: direction
5605
+ };
5606
+ const stopEvent = (event) => {
5607
+ event.stopPropagation();
5608
+ if (typeof event.stopImmediatePropagation === "function") {
5609
+ event.stopImmediatePropagation();
5610
+ }
5611
+ };
5612
+ const ui = (0, import_jsx_runtime.jsx)("div", { style: trayStyle, onPointerDown: stopEvent, onPointerMove: stopEvent, onPointerUp: stopEvent, onMouseDown: stopEvent, onMouseMove: stopEvent, onMouseUp: stopEvent, onTouchStart: stopEvent, onTouchMove: stopEvent, onTouchEnd: stopEvent, children: modes.map((option, index) => {
5613
+ const id = this.getModeId(option, index);
5614
+ const active = id === selectedId;
5615
+ const label = option.label ?? "";
5616
+ const title = option.title ?? label;
5617
+ const buttonStyle = {
5618
+ ...BUTTON_BASE_STYLE,
5619
+ ...active ? BUTTON_ACTIVE_STYLE : {}
5620
+ };
5621
+ return (0, import_jsx_runtime.jsxs)("button", { type: "button", title: title || void 0, "aria-pressed": active, style: buttonStyle, onClick: (event) => {
5622
+ stopEvent(event);
5623
+ this.handleSelect(option, id);
5624
+ }, children: [option.icon, label ? (0, import_jsx_runtime.jsx)("span", { style: BUTTON_LABEL_STYLE, children: label }) : null] }, id);
5625
+ }) });
5626
+ (0, import_preact.render)(ui, root);
5627
+ }
5628
+ handleSelect(option, id) {
5629
+ var _a, _b;
5630
+ if (this.selectedModeId !== id) {
5631
+ this.selectedModeId = id;
5632
+ this.renderTray();
5633
+ }
5634
+ (_b = (_a = this.props).onSelectMode) == null ? void 0 : _b.call(_a, {
5635
+ id,
5636
+ mode: option.mode,
5637
+ option
5638
+ });
5639
+ }
5640
+ resolveSelectedModeId(modes, props) {
5641
+ var _a;
5642
+ if (props.selectedModeId !== void 0) {
5643
+ return props.selectedModeId;
5644
+ }
5645
+ const activeMode = props.activeMode ?? ((_a = this.props) == null ? void 0 : _a.activeMode) ?? null;
5646
+ if (activeMode) {
5647
+ const match = this.findOptionByMode(modes, activeMode);
5648
+ if (match) {
5649
+ return this.getModeId(match.option, match.index);
5650
+ }
5651
+ }
5652
+ if (this.selectedModeId) {
5653
+ const existing = this.findOptionById(modes, this.selectedModeId);
5654
+ if (existing) {
5655
+ return this.selectedModeId;
5656
+ }
5657
+ }
5658
+ const first = modes[0];
5659
+ return first ? this.getModeId(first, 0) : null;
5660
+ }
5661
+ findOptionByMode(modes, activeMode) {
5662
+ for (let index = 0; index < modes.length; index++) {
5663
+ const option = modes[index];
5664
+ if (option.mode === activeMode) {
5665
+ return { option, index };
5666
+ }
5667
+ if (this.isSameMode(option.mode, activeMode)) {
5668
+ return { option, index };
5669
+ }
5670
+ }
5671
+ return null;
5672
+ }
5673
+ findOptionById(modes, id) {
5674
+ for (let index = 0; index < modes.length; index++) {
5675
+ if (this.getModeId(modes[index], index) === id) {
5676
+ return { option: modes[index], index };
5677
+ }
5678
+ }
5679
+ return null;
5680
+ }
5681
+ getModeId(option, index) {
5682
+ if (option.id) {
5683
+ return option.id;
5684
+ }
5685
+ const mode = option.mode;
5686
+ if (mode) {
5687
+ if (typeof mode === "function" && mode.name) {
5688
+ return mode.name;
5689
+ }
5690
+ if (mode && mode.constructor && mode.constructor.name) {
5691
+ return mode.constructor.name;
5692
+ }
5693
+ }
5694
+ return `mode-${index}`;
5695
+ }
5696
+ isSameMode(modeA, modeB) {
5697
+ if (modeA === modeB) {
5698
+ return true;
5699
+ }
5700
+ const constructorA = modeA == null ? void 0 : modeA.constructor;
5701
+ const constructorB = modeB == null ? void 0 : modeB.constructor;
5702
+ return Boolean(constructorA && constructorB && constructorA === constructorB);
5703
+ }
5704
+ };
5705
+ var EditModeTrayWidget = _EditModeTrayWidget;
5706
+ __publicField(EditModeTrayWidget, "defaultProps", {
5707
+ id: "edit-mode-tray",
5708
+ placement: "top-left",
5709
+ layout: "vertical",
5710
+ modes: [],
5711
+ style: {},
5712
+ className: ""
5713
+ });
4946
5714
 
4947
5715
  // dist/edit-modes/resize-circle-mode.js
4948
5716
  var import_nearest_point_on_line2 = __toESM(require("@turf/nearest-point-on-line"), 1);