@sakuzu/maplibre-gl-draw 1.0.0
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/CHANGELOG.md +43 -0
- package/LICENSE +661 -0
- package/README.ja.md +248 -0
- package/README.md +255 -0
- package/THIRD_PARTY_NOTICES.md +275 -0
- package/dist/api/api.d.ts +1259 -0
- package/dist/api/api.js +86 -0
- package/dist/api/context.d.ts +173 -0
- package/dist/api/context.js +193 -0
- package/dist/api/display-api.d.ts +1 -0
- package/dist/api/display-api.js +23 -0
- package/dist/api/event-api.d.ts +13 -0
- package/dist/api/event-api.js +17 -0
- package/dist/api/extension-api.d.ts +46 -0
- package/dist/api/extension-api.js +85 -0
- package/dist/api/feature-api.d.ts +11 -0
- package/dist/api/feature-api.js +101 -0
- package/dist/api/geometry/apply.d.ts +51 -0
- package/dist/api/geometry/apply.js +114 -0
- package/dist/api/geometry/boolean.d.ts +28 -0
- package/dist/api/geometry/boolean.js +65 -0
- package/dist/api/geometry/buffer.d.ts +11 -0
- package/dist/api/geometry/buffer.js +105 -0
- package/dist/api/geometry/split.d.ts +16 -0
- package/dist/api/geometry/split.js +75 -0
- package/dist/api/geometry/targets.d.ts +76 -0
- package/dist/api/geometry/targets.js +158 -0
- package/dist/api/geometry/types.d.ts +31 -0
- package/dist/api/geometry/types.js +3 -0
- package/dist/api/geometry-operations.d.ts +162 -0
- package/dist/api/geometry-operations.js +94 -0
- package/dist/api/group-api.d.ts +10 -0
- package/dist/api/group-api.js +78 -0
- package/dist/api/import-export/constants.d.ts +29 -0
- package/dist/api/import-export/constants.js +40 -0
- package/dist/api/import-export/embedded-file.d.ts +13 -0
- package/dist/api/import-export/embedded-file.js +31 -0
- package/dist/api/import-export/file-name.d.ts +10 -0
- package/dist/api/import-export/file-name.js +20 -0
- package/dist/api/import-export/format-detection.d.ts +12 -0
- package/dist/api/import-export/format-detection.js +29 -0
- package/dist/api/import-export/geojson-export.d.ts +19 -0
- package/dist/api/import-export/geojson-export.js +262 -0
- package/dist/api/import-export/geojson-import.d.ts +34 -0
- package/dist/api/import-export/geojson-import.js +538 -0
- package/dist/api/import-export/geometry-validation.d.ts +20 -0
- package/dist/api/import-export/geometry-validation.js +107 -0
- package/dist/api/import-export/image-import.d.ts +12 -0
- package/dist/api/import-export/image-import.js +53 -0
- package/dist/api/import-export/index.d.ts +9 -0
- package/dist/api/import-export/index.js +107 -0
- package/dist/api/import-export/native-format.d.ts +15 -0
- package/dist/api/import-export/native-format.js +126 -0
- package/dist/api/import-export/native-validation.d.ts +28 -0
- package/dist/api/import-export/native-validation.js +212 -0
- package/dist/api/import-export/own-property.d.ts +10 -0
- package/dist/api/import-export/own-property.js +19 -0
- package/dist/api/import-export/style-validation.d.ts +27 -0
- package/dist/api/import-export/style-validation.js +49 -0
- package/dist/api/import-export/types.d.ts +26 -0
- package/dist/api/import-export/types.js +3 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.js +3 -0
- package/dist/api/input-api.d.ts +158 -0
- package/dist/api/input-api.js +144 -0
- package/dist/api/instance-api.d.ts +38 -0
- package/dist/api/instance-api.js +136 -0
- package/dist/api/layer-api.d.ts +12 -0
- package/dist/api/layer-api.js +62 -0
- package/dist/api/selection-api.d.ts +7 -0
- package/dist/api/selection-api.js +78 -0
- package/dist/api/snapping-api.d.ts +125 -0
- package/dist/api/snapping-api.js +50 -0
- package/dist/api/topology-api.d.ts +30 -0
- package/dist/api/topology-api.js +16 -0
- package/dist/api/tracing-api.d.ts +31 -0
- package/dist/api/tracing-api.js +16 -0
- package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
- package/dist/dispatcher/hit-test/box-strategies.js +275 -0
- package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
- package/dist/dispatcher/hit-test/box-strategy.js +37 -0
- package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
- package/dist/dispatcher/hit-test/globe-shape.js +70 -0
- package/dist/dispatcher/hit-test/index.d.ts +14 -0
- package/dist/dispatcher/hit-test/index.js +9 -0
- package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
- package/dist/dispatcher/hit-test/local-frame.js +112 -0
- package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
- package/dist/dispatcher/hit-test/segment-grid.js +79 -0
- package/dist/dispatcher/hit-test/service.d.ts +120 -0
- package/dist/dispatcher/hit-test/service.js +333 -0
- package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
- package/dist/dispatcher/hit-test/strategies/base.js +66 -0
- package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
- package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
- package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
- package/dist/dispatcher/hit-test/strategies/image.js +115 -0
- package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
- package/dist/dispatcher/hit-test/strategies/index.js +10 -0
- package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
- package/dist/dispatcher/hit-test/strategies/line.js +30 -0
- package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
- package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
- package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
- package/dist/dispatcher/hit-test/strategies/point.js +29 -0
- package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
- package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
- package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
- package/dist/dispatcher/hit-test/topmost.js +157 -0
- package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
- package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
- package/dist/dispatcher/index.d.ts +15 -0
- package/dist/dispatcher/index.js +3 -0
- package/dist/dispatcher/input-router.d.ts +1 -0
- package/dist/dispatcher/input-router.js +288 -0
- package/dist/dispatcher/normalizer.d.ts +1 -0
- package/dist/dispatcher/normalizer.js +513 -0
- package/dist/dispatcher/types.d.ts +144 -0
- package/dist/dispatcher/types.js +15 -0
- package/dist/display/chunk-set.d.ts +24 -0
- package/dist/display/chunk-set.js +533 -0
- package/dist/display/chunk.d.ts +1 -0
- package/dist/display/chunk.js +104 -0
- package/dist/display/columnar/index.d.ts +12 -0
- package/dist/display/columnar/index.js +13 -0
- package/dist/display/columnar/prepare.d.ts +42 -0
- package/dist/display/columnar/prepare.js +116 -0
- package/dist/display/columnar/source.d.ts +1 -0
- package/dist/display/columnar/source.js +531 -0
- package/dist/display/columnar/table.d.ts +1 -0
- package/dist/display/columnar/table.js +471 -0
- package/dist/display/columnar/types.d.ts +223 -0
- package/dist/display/columnar/types.js +3 -0
- package/dist/display/dataset.d.ts +2 -0
- package/dist/display/dataset.js +891 -0
- package/dist/display/index.d.ts +13 -0
- package/dist/display/index.js +3 -0
- package/dist/display/interaction.d.ts +1 -0
- package/dist/display/interaction.js +90 -0
- package/dist/display/manager.d.ts +1 -0
- package/dist/display/manager.js +440 -0
- package/dist/display/packed-rtree.d.ts +1 -0
- package/dist/display/packed-rtree.js +244 -0
- package/dist/display/partition.d.ts +1 -0
- package/dist/display/partition.js +226 -0
- package/dist/display/provider.d.ts +1 -0
- package/dist/display/provider.js +342 -0
- package/dist/display/retained.d.ts +40 -0
- package/dist/display/retained.js +898 -0
- package/dist/display/selection.d.ts +13 -0
- package/dist/display/selection.js +226 -0
- package/dist/display/source.d.ts +1 -0
- package/dist/display/source.js +119 -0
- package/dist/display/spatial.d.ts +1 -0
- package/dist/display/spatial.js +71 -0
- package/dist/display/style.d.ts +1 -0
- package/dist/display/style.js +126 -0
- package/dist/display/thinning.d.ts +65 -0
- package/dist/display/thinning.js +910 -0
- package/dist/display/triangulation.d.ts +1 -0
- package/dist/display/triangulation.js +0 -0
- package/dist/display/types.d.ts +561 -0
- package/dist/display/types.js +43 -0
- package/dist/extension/feature-handler.d.ts +182 -0
- package/dist/extension/feature-handler.js +3 -0
- package/dist/extension/index.d.ts +9 -0
- package/dist/extension/index.js +3 -0
- package/dist/extension/renderers.d.ts +208 -0
- package/dist/extension/renderers.js +3 -0
- package/dist/geometry/angle.d.ts +47 -0
- package/dist/geometry/angle.js +44 -0
- package/dist/geometry/bbox.d.ts +48 -0
- package/dist/geometry/bbox.js +83 -0
- package/dist/geometry/boolean.d.ts +162 -0
- package/dist/geometry/boolean.js +331 -0
- package/dist/geometry/buffer.d.ts +72 -0
- package/dist/geometry/buffer.js +218 -0
- package/dist/geometry/circle.d.ts +55 -0
- package/dist/geometry/circle.js +107 -0
- package/dist/geometry/coords.d.ts +97 -0
- package/dist/geometry/coords.js +149 -0
- package/dist/geometry/distance.d.ts +79 -0
- package/dist/geometry/distance.js +111 -0
- package/dist/geometry/errors.d.ts +74 -0
- package/dist/geometry/errors.js +104 -0
- package/dist/geometry/index.d.ts +28 -0
- package/dist/geometry/index.js +38 -0
- package/dist/geometry/measure.d.ts +81 -0
- package/dist/geometry/measure.js +236 -0
- package/dist/geometry/predicates.d.ts +62 -0
- package/dist/geometry/predicates.js +132 -0
- package/dist/geometry/simplify.d.ts +74 -0
- package/dist/geometry/simplify.js +159 -0
- package/dist/geometry/split.d.ts +68 -0
- package/dist/geometry/split.js +430 -0
- package/dist/geometry/types.d.ts +95 -0
- package/dist/geometry/types.js +3 -0
- package/dist/geometry/units.d.ts +35 -0
- package/dist/geometry/units.js +41 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +20 -0
- package/dist/maplibre-gl-draw.d.ts +47 -0
- package/dist/maplibre-gl-draw.js +407 -0
- package/dist/messages.d.ts +64 -0
- package/dist/messages.js +36 -0
- package/dist/modes/cursor.d.ts +1 -0
- package/dist/modes/cursor.js +72 -0
- package/dist/modes/draw/circle.d.ts +1 -0
- package/dist/modes/draw/circle.js +222 -0
- package/dist/modes/draw/commit-layer.d.ts +26 -0
- package/dist/modes/draw/commit-layer.js +31 -0
- package/dist/modes/draw/freehand.d.ts +1 -0
- package/dist/modes/draw/freehand.js +264 -0
- package/dist/modes/draw/image.d.ts +1 -0
- package/dist/modes/draw/image.js +60 -0
- package/dist/modes/draw/index.d.ts +9 -0
- package/dist/modes/draw/index.js +11 -0
- package/dist/modes/draw/line.d.ts +1 -0
- package/dist/modes/draw/line.js +363 -0
- package/dist/modes/draw/point.d.ts +1 -0
- package/dist/modes/draw/point.js +87 -0
- package/dist/modes/draw/polygon.d.ts +1 -0
- package/dist/modes/draw/polygon.js +378 -0
- package/dist/modes/draw/trace-support.d.ts +79 -0
- package/dist/modes/draw/trace-support.js +161 -0
- package/dist/modes/handler.d.ts +285 -0
- package/dist/modes/handler.js +3 -0
- package/dist/modes/index.d.ts +7 -0
- package/dist/modes/index.js +3 -0
- package/dist/modes/manager.d.ts +15 -0
- package/dist/modes/manager.js +196 -0
- package/dist/modes/select/box-selection.d.ts +52 -0
- package/dist/modes/select/box-selection.js +140 -0
- package/dist/modes/select/click-handler.d.ts +32 -0
- package/dist/modes/select/click-handler.js +166 -0
- package/dist/modes/select/cursor-handler.d.ts +15 -0
- package/dist/modes/select/cursor-handler.js +59 -0
- package/dist/modes/select/drag/auxiliary.d.ts +26 -0
- package/dist/modes/select/drag/auxiliary.js +56 -0
- package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
- package/dist/modes/select/drag/intermediate-writes.js +171 -0
- package/dist/modes/select/drag/move.d.ts +24 -0
- package/dist/modes/select/drag/move.js +59 -0
- package/dist/modes/select/drag/operation.d.ts +30 -0
- package/dist/modes/select/drag/operation.js +18 -0
- package/dist/modes/select/drag/radius.d.ts +15 -0
- package/dist/modes/select/drag/radius.js +49 -0
- package/dist/modes/select/drag/transform.d.ts +17 -0
- package/dist/modes/select/drag/transform.js +155 -0
- package/dist/modes/select/drag/vertex.d.ts +17 -0
- package/dist/modes/select/drag/vertex.js +163 -0
- package/dist/modes/select/drag-handler.d.ts +1 -0
- package/dist/modes/select/drag-handler.js +254 -0
- package/dist/modes/select/hit-helpers.d.ts +40 -0
- package/dist/modes/select/hit-helpers.js +51 -0
- package/dist/modes/select/mode.d.ts +1 -0
- package/dist/modes/select/mode.js +397 -0
- package/dist/modes/select/shortcut-handler.d.ts +40 -0
- package/dist/modes/select/shortcut-handler.js +128 -0
- package/dist/operations/index.d.ts +9 -0
- package/dist/operations/index.js +3 -0
- package/dist/operations/layer-operations.d.ts +1 -0
- package/dist/operations/layer-operations.js +350 -0
- package/dist/operations/resize.d.ts +71 -0
- package/dist/operations/resize.js +252 -0
- package/dist/operations/rotate.d.ts +17 -0
- package/dist/operations/rotate.js +166 -0
- package/dist/operations/selection-operations.d.ts +20 -0
- package/dist/operations/selection-operations.js +159 -0
- package/dist/operations/shared-vertex.d.ts +1 -0
- package/dist/operations/shared-vertex.js +210 -0
- package/dist/operations/trace-graph.d.ts +96 -0
- package/dist/operations/trace-graph.js +283 -0
- package/dist/operations/vertex.d.ts +1 -0
- package/dist/operations/vertex.js +538 -0
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/mutation-hooks.d.ts +28 -0
- package/dist/plugins/mutation-hooks.js +84 -0
- package/dist/plugins/plugin-context.d.ts +1 -0
- package/dist/plugins/plugin-context.js +367 -0
- package/dist/plugins/plugin-manager.d.ts +103 -0
- package/dist/plugins/plugin-manager.js +316 -0
- package/dist/plugins/plugin.d.ts +529 -0
- package/dist/plugins/plugin.js +3 -0
- package/dist/shared/config/constants.d.ts +66 -0
- package/dist/shared/config/constants.js +60 -0
- package/dist/shared/config/feature-style.d.ts +155 -0
- package/dist/shared/config/feature-style.js +154 -0
- package/dist/shared/config/index.d.ts +17 -0
- package/dist/shared/config/index.js +8 -0
- package/dist/shared/config/rendering.d.ts +107 -0
- package/dist/shared/config/rendering.js +33 -0
- package/dist/shared/config/selection-highlight.d.ts +29 -0
- package/dist/shared/config/selection-highlight.js +35 -0
- package/dist/shared/config/selection.d.ts +273 -0
- package/dist/shared/config/selection.js +266 -0
- package/dist/shared/config/topology.d.ts +33 -0
- package/dist/shared/config/topology.js +17 -0
- package/dist/shared/config/trace.d.ts +40 -0
- package/dist/shared/config/trace.js +17 -0
- package/dist/shared/math/angle.d.ts +21 -0
- package/dist/shared/math/angle.js +34 -0
- package/dist/shared/math/circle.d.ts +6 -0
- package/dist/shared/math/circle.js +10 -0
- package/dist/shared/math/constants.d.ts +48 -0
- package/dist/shared/math/constants.js +59 -0
- package/dist/shared/math/distance.d.ts +78 -0
- package/dist/shared/math/distance.js +147 -0
- package/dist/shared/math/globe-subdivision.d.ts +62 -0
- package/dist/shared/math/globe-subdivision.js +99 -0
- package/dist/shared/math/index.d.ts +17 -0
- package/dist/shared/math/index.js +21 -0
- package/dist/shared/math/intersection.d.ts +63 -0
- package/dist/shared/math/intersection.js +236 -0
- package/dist/shared/math/longitude.d.ts +20 -0
- package/dist/shared/math/longitude.js +31 -0
- package/dist/shared/math/mercator-plane.d.ts +27 -0
- package/dist/shared/math/mercator-plane.js +26 -0
- package/dist/shared/math/obb.d.ts +65 -0
- package/dist/shared/math/obb.js +107 -0
- package/dist/shared/math/rotation.d.ts +93 -0
- package/dist/shared/math/rotation.js +186 -0
- package/dist/shared/math/segment-grid.d.ts +69 -0
- package/dist/shared/math/segment-grid.js +159 -0
- package/dist/shared/math/transform.d.ts +140 -0
- package/dist/shared/math/transform.js +189 -0
- package/dist/shared/types/events.d.ts +128 -0
- package/dist/shared/types/events.js +3 -0
- package/dist/shared/types/model.d.ts +950 -0
- package/dist/shared/types/model.js +3 -0
- package/dist/shared/types/selection-box.d.ts +23 -0
- package/dist/shared/types/selection-box.js +3 -0
- package/dist/shared/types/style.d.ts +68 -0
- package/dist/shared/types/style.js +3 -0
- package/dist/shared/utils/color.d.ts +49 -0
- package/dist/shared/utils/color.js +180 -0
- package/dist/shared/utils/coordinates.d.ts +52 -0
- package/dist/shared/utils/coordinates.js +75 -0
- package/dist/shared/utils/embedded-image.d.ts +34 -0
- package/dist/shared/utils/embedded-image.js +161 -0
- package/dist/shared/utils/event-emitter.d.ts +262 -0
- package/dist/shared/utils/event-emitter.js +44 -0
- package/dist/shared/utils/feature-bbox.d.ts +8 -0
- package/dist/shared/utils/feature-bbox.js +207 -0
- package/dist/shared/utils/feature-segments.d.ts +23 -0
- package/dist/shared/utils/feature-segments.js +179 -0
- package/dist/shared/utils/id.d.ts +1 -0
- package/dist/shared/utils/id.js +35 -0
- package/dist/shared/utils/image.d.ts +34 -0
- package/dist/shared/utils/image.js +106 -0
- package/dist/shared/utils/index.d.ts +15 -0
- package/dist/shared/utils/index.js +24 -0
- package/dist/shared/utils/map.d.ts +26 -0
- package/dist/shared/utils/map.js +35 -0
- package/dist/shared/utils/name-generator.d.ts +197 -0
- package/dist/shared/utils/name-generator.js +337 -0
- package/dist/shared/utils/pixel-ratio.d.ts +111 -0
- package/dist/shared/utils/pixel-ratio.js +85 -0
- package/dist/shared/utils/property.d.ts +88 -0
- package/dist/shared/utils/property.js +140 -0
- package/dist/shared/utils/vertex-ref.d.ts +23 -0
- package/dist/shared/utils/vertex-ref.js +20 -0
- package/dist/snapping/custom-targets.d.ts +1 -0
- package/dist/snapping/custom-targets.js +21 -0
- package/dist/snapping/geometry.d.ts +1 -0
- package/dist/snapping/geometry.js +61 -0
- package/dist/snapping/index.d.ts +14 -0
- package/dist/snapping/index.js +4 -0
- package/dist/snapping/indicator.d.ts +19 -0
- package/dist/snapping/indicator.js +145 -0
- package/dist/snapping/providers/display.d.ts +72 -0
- package/dist/snapping/providers/display.js +268 -0
- package/dist/snapping/providers/guide.d.ts +69 -0
- package/dist/snapping/providers/guide.js +187 -0
- package/dist/snapping/providers/intersection.d.ts +1 -0
- package/dist/snapping/providers/intersection.js +92 -0
- package/dist/snapping/providers/shared.d.ts +39 -0
- package/dist/snapping/providers/shared.js +146 -0
- package/dist/snapping/providers/store.d.ts +1 -0
- package/dist/snapping/providers/store.js +132 -0
- package/dist/snapping/service.d.ts +1 -0
- package/dist/snapping/service.js +272 -0
- package/dist/snapping/types.d.ts +267 -0
- package/dist/snapping/types.js +66 -0
- package/dist/store/change-merger.d.ts +1 -0
- package/dist/store/change-merger.js +102 -0
- package/dist/store/draw-store.d.ts +1 -0
- package/dist/store/draw-store.js +396 -0
- package/dist/store/event-bridge.d.ts +1 -0
- package/dist/store/event-bridge.js +161 -0
- package/dist/store/index.d.ts +12 -0
- package/dist/store/index.js +4 -0
- package/dist/store/local-visibility.d.ts +21 -0
- package/dist/store/local-visibility.js +27 -0
- package/dist/store/lock.d.ts +67 -0
- package/dist/store/lock.js +54 -0
- package/dist/store/memory/change-bus.d.ts +60 -0
- package/dist/store/memory/change-bus.js +232 -0
- package/dist/store/memory/file-store.d.ts +15 -0
- package/dist/store/memory/file-store.js +33 -0
- package/dist/store/memory/frozen.d.ts +21 -0
- package/dist/store/memory/frozen.js +51 -0
- package/dist/store/memory/ui-state.d.ts +51 -0
- package/dist/store/memory/ui-state.js +223 -0
- package/dist/store/memory.d.ts +26 -0
- package/dist/store/memory.js +708 -0
- package/dist/store/spatial/index.d.ts +6 -0
- package/dist/store/spatial/index.js +4 -0
- package/dist/store/spatial/spatial-index.d.ts +90 -0
- package/dist/store/spatial/spatial-index.js +148 -0
- package/dist/store/spatial/store-spatial-index.d.ts +60 -0
- package/dist/store/spatial/store-spatial-index.js +125 -0
- package/dist/store/store.d.ts +417 -0
- package/dist/store/store.js +3 -0
- package/dist/store/types.d.ts +8 -0
- package/dist/store/types.js +3 -0
- package/dist/store/writable-layer.d.ts +35 -0
- package/dist/store/writable-layer.js +20 -0
- package/dist/view/cache/buffer.d.ts +28 -0
- package/dist/view/cache/buffer.js +176 -0
- package/dist/view/cache/earcut.d.ts +1 -0
- package/dist/view/cache/earcut.js +122 -0
- package/dist/view/cache/style-rule.d.ts +1 -0
- package/dist/view/cache/style-rule.js +97 -0
- package/dist/view/cache/terrain-fill.d.ts +30 -0
- package/dist/view/cache/terrain-fill.js +60 -0
- package/dist/view/cache/texture.d.ts +14 -0
- package/dist/view/cache/texture.js +292 -0
- package/dist/view/coordinator.d.ts +27 -0
- package/dist/view/coordinator.js +72 -0
- package/dist/view/feature-companion.d.ts +173 -0
- package/dist/view/feature-companion.js +108 -0
- package/dist/view/globe-subdivision.d.ts +78 -0
- package/dist/view/globe-subdivision.js +128 -0
- package/dist/view/index.d.ts +47 -0
- package/dist/view/index.js +20 -0
- package/dist/view/layer/attach.d.ts +20 -0
- package/dist/view/layer/attach.js +47 -0
- package/dist/view/layer/blend.d.ts +57 -0
- package/dist/view/layer/blend.js +14 -0
- package/dist/view/layer/custom-layer.d.ts +1 -0
- package/dist/view/layer/custom-layer.js +509 -0
- package/dist/view/layer/depth-state.d.ts +14 -0
- package/dist/view/layer/depth-state.js +44 -0
- package/dist/view/layer/display-list.d.ts +1 -0
- package/dist/view/layer/display-list.js +111 -0
- package/dist/view/layer/drape-planner.d.ts +139 -0
- package/dist/view/layer/drape-planner.js +726 -0
- package/dist/view/layer/frame-render.d.ts +57 -0
- package/dist/view/layer/frame-render.js +209 -0
- package/dist/view/layer/frame-state.d.ts +147 -0
- package/dist/view/layer/frame-state.js +484 -0
- package/dist/view/layer/gl-state.d.ts +77 -0
- package/dist/view/layer/gl-state.js +132 -0
- package/dist/view/layer/index.d.ts +6 -0
- package/dist/view/layer/index.js +5 -0
- package/dist/view/layer/render-scope.d.ts +30 -0
- package/dist/view/layer/render-scope.js +28 -0
- package/dist/view/layer/render.d.ts +87 -0
- package/dist/view/layer/render.js +187 -0
- package/dist/view/layer/renderers.d.ts +81 -0
- package/dist/view/layer/renderers.js +142 -0
- package/dist/view/layer/slot-manager.d.ts +26 -0
- package/dist/view/layer/slot-manager.js +133 -0
- package/dist/view/layer/slots.d.ts +33 -0
- package/dist/view/layer/slots.js +50 -0
- package/dist/view/layer/store-retained-bbox.d.ts +36 -0
- package/dist/view/layer/store-retained-bbox.js +188 -0
- package/dist/view/layer/store-retained-chunk.d.ts +97 -0
- package/dist/view/layer/store-retained-chunk.js +94 -0
- package/dist/view/layer/store-retained-classify.d.ts +34 -0
- package/dist/view/layer/store-retained-classify.js +88 -0
- package/dist/view/layer/store-retained-collect.d.ts +24 -0
- package/dist/view/layer/store-retained-collect.js +121 -0
- package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
- package/dist/view/layer/store-retained-coord-patch.js +168 -0
- package/dist/view/layer/store-retained-immediate.d.ts +63 -0
- package/dist/view/layer/store-retained-immediate.js +49 -0
- package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
- package/dist/view/layer/store-retained-invalidation.js +192 -0
- package/dist/view/layer/store-retained.d.ts +198 -0
- package/dist/view/layer/store-retained.js +430 -0
- package/dist/view/layer/terrain-resolver.d.ts +1 -0
- package/dist/view/layer/terrain-resolver.js +174 -0
- package/dist/view/renderers/batch-manager.d.ts +61 -0
- package/dist/view/renderers/batch-manager.js +718 -0
- package/dist/view/renderers/draw-factors.d.ts +60 -0
- package/dist/view/renderers/draw-factors.js +35 -0
- package/dist/view/renderers/drawer.d.ts +1 -0
- package/dist/view/renderers/drawer.js +346 -0
- package/dist/view/renderers/image.d.ts +1 -0
- package/dist/view/renderers/image.js +255 -0
- package/dist/view/renderers/line/dash.d.ts +31 -0
- package/dist/view/renderers/line/dash.js +152 -0
- package/dist/view/renderers/line/line-geometry.d.ts +39 -0
- package/dist/view/renderers/line/line-geometry.js +460 -0
- package/dist/view/renderers/line/line-gl.d.ts +1 -0
- package/dist/view/renderers/line/line-gl.js +236 -0
- package/dist/view/renderers/line/line-shader.d.ts +1 -0
- package/dist/view/renderers/line/line-shader.js +364 -0
- package/dist/view/renderers/line/line-types.d.ts +43 -0
- package/dist/view/renderers/line/line-types.js +3 -0
- package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
- package/dist/view/renderers/line/line-uniforms.js +390 -0
- package/dist/view/renderers/line/sdf-line.d.ts +92 -0
- package/dist/view/renderers/line/sdf-line.js +567 -0
- package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
- package/dist/view/renderers/point/billboard-depth.js +56 -0
- package/dist/view/renderers/point/point-instance.d.ts +124 -0
- package/dist/view/renderers/point/point-instance.js +738 -0
- package/dist/view/renderers/point/point-sdf.d.ts +58 -0
- package/dist/view/renderers/point/point-sdf.js +170 -0
- package/dist/view/renderers/point/point-shape.d.ts +99 -0
- package/dist/view/renderers/point/point-shape.js +504 -0
- package/dist/view/renderers/point/point-style.d.ts +1 -0
- package/dist/view/renderers/point/point-style.js +46 -0
- package/dist/view/renderers/polygon/batch.d.ts +26 -0
- package/dist/view/renderers/polygon/batch.js +336 -0
- package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
- package/dist/view/renderers/polygon/earcut-input.js +55 -0
- package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
- package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
- package/dist/view/renderers/polygon/fill.d.ts +74 -0
- package/dist/view/renderers/polygon/fill.js +251 -0
- package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
- package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
- package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
- package/dist/view/renderers/polygon/terrain-cull.js +14 -0
- package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
- package/dist/view/renderers/polygon/triangulator.js +3 -0
- package/dist/view/renderers/retained.d.ts +43 -0
- package/dist/view/renderers/retained.js +3 -0
- package/dist/view/renderers/stroke.d.ts +121 -0
- package/dist/view/renderers/stroke.js +621 -0
- package/dist/view/shaders/frame.d.ts +8 -0
- package/dist/view/shaders/frame.js +37 -0
- package/dist/view/shaders/helpers.d.ts +238 -0
- package/dist/view/shaders/helpers.js +611 -0
- package/dist/view/shaders/initializer.d.ts +27 -0
- package/dist/view/shaders/initializer.js +125 -0
- package/dist/view/shaders/projection.d.ts +123 -0
- package/dist/view/shaders/projection.js +299 -0
- package/dist/view/shaders/quad-grid.d.ts +77 -0
- package/dist/view/shaders/quad-grid.js +128 -0
- package/dist/view/shaders/quad.d.ts +189 -0
- package/dist/view/shaders/quad.js +582 -0
- package/dist/view/shaders/retained-origin.d.ts +50 -0
- package/dist/view/shaders/retained-origin.js +67 -0
- package/dist/view/shaders/terrain-shade.d.ts +23 -0
- package/dist/view/shaders/terrain-shade.js +93 -0
- package/dist/view/style-rule.d.ts +166 -0
- package/dist/view/style-rule.js +300 -0
- package/dist/view/terrain/anchor.d.ts +135 -0
- package/dist/view/terrain/anchor.js +226 -0
- package/dist/view/terrain/context.d.ts +132 -0
- package/dist/view/terrain/context.js +437 -0
- package/dist/view/terrain/dem-atlas.d.ts +97 -0
- package/dist/view/terrain/dem-atlas.js +534 -0
- package/dist/view/terrain/detect.d.ts +126 -0
- package/dist/view/terrain/detect.js +198 -0
- package/dist/view/terrain/drape/bin-store.d.ts +179 -0
- package/dist/view/terrain/drape/bin-store.js +529 -0
- package/dist/view/terrain/drape/binning.d.ts +259 -0
- package/dist/view/terrain/drape/binning.js +604 -0
- package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
- package/dist/view/terrain/drape/edge-constrain.js +175 -0
- package/dist/view/terrain/drape/geometry.d.ts +95 -0
- package/dist/view/terrain/drape/geometry.js +260 -0
- package/dist/view/terrain/drape/mesh.d.ts +50 -0
- package/dist/view/terrain/drape/mesh.js +86 -0
- package/dist/view/terrain/drape/pass.d.ts +122 -0
- package/dist/view/terrain/drape/pass.js +379 -0
- package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
- package/dist/view/terrain/drape/quad-glyphs.js +117 -0
- package/dist/view/terrain/drape/quad.d.ts +249 -0
- package/dist/view/terrain/drape/quad.js +835 -0
- package/dist/view/terrain/drape/renderer.d.ts +184 -0
- package/dist/view/terrain/drape/renderer.js +706 -0
- package/dist/view/terrain/drape/shared.d.ts +80 -0
- package/dist/view/terrain/drape/shared.js +173 -0
- package/dist/view/terrain/drape/stitch.d.ts +155 -0
- package/dist/view/terrain/drape/stitch.js +228 -0
- package/dist/view/terrain/ground.d.ts +72 -0
- package/dist/view/terrain/ground.js +151 -0
- package/dist/view/terrain/metrics.d.ts +180 -0
- package/dist/view/terrain/metrics.js +231 -0
- package/dist/view/terrain/occlusion.d.ts +11 -0
- package/dist/view/terrain/occlusion.js +129 -0
- package/dist/view/terrain/polygon.d.ts +86 -0
- package/dist/view/terrain/polygon.js +301 -0
- package/dist/view/terrain/shade.d.ts +48 -0
- package/dist/view/terrain/shade.js +45 -0
- package/dist/view/terrain/state.d.ts +99 -0
- package/dist/view/terrain/state.js +186 -0
- package/dist/view/terrain/tessellation.d.ts +265 -0
- package/dist/view/terrain/tessellation.js +924 -0
- package/dist/view/terrain/tiling.d.ts +56 -0
- package/dist/view/terrain/tiling.js +155 -0
- package/dist/view/terrain/upstream-terrain.d.ts +82 -0
- package/dist/view/terrain/upstream-terrain.js +116 -0
- package/dist/view/ui/auxiliary-handles.d.ts +151 -0
- package/dist/view/ui/auxiliary-handles.js +22 -0
- package/dist/view/ui/bounds.d.ts +53 -0
- package/dist/view/ui/bounds.js +149 -0
- package/dist/view/ui/box-selection.d.ts +1 -0
- package/dist/view/ui/box-selection.js +83 -0
- package/dist/view/ui/handle-test.d.ts +1 -0
- package/dist/view/ui/handle-test.js +437 -0
- package/dist/view/ui/handle-thinning.d.ts +122 -0
- package/dist/view/ui/handle-thinning.js +430 -0
- package/dist/view/ui/handles.d.ts +25 -0
- package/dist/view/ui/handles.js +673 -0
- package/dist/view/ui/helper.d.ts +19 -0
- package/dist/view/ui/helper.js +76 -0
- package/dist/view/ui/index.d.ts +15 -0
- package/dist/view/ui/index.js +15 -0
- package/dist/view/ui/selection-scope.d.ts +25 -0
- package/dist/view/ui/selection-scope.js +34 -0
- package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
- package/dist/view/ui/selection-ui/bounding-box.js +240 -0
- package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
- package/dist/view/ui/selection-ui/extension-registry.js +78 -0
- package/dist/view/ui/selection-ui/index.d.ts +12 -0
- package/dist/view/ui/selection-ui/index.js +12 -0
- package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
- package/dist/view/ui/selection-ui/renderer.js +227 -0
- package/dist/view/ui/selection-ui/types.d.ts +55 -0
- package/dist/view/ui/selection-ui/types.js +3 -0
- package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
- package/dist/view/ui/selection-ui-drawer.js +329 -0
- package/dist/view/ui/tentative.d.ts +1 -0
- package/dist/view/ui/tentative.js +320 -0
- package/dist/view/viewport.d.ts +119 -0
- package/dist/view/viewport.js +254 -0
- package/package.json +113 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Conversion from GeoJSON to the internal Feature format + load of a
|
|
5
|
+
* GeoJSON FeatureCollection
|
|
6
|
+
*/
|
|
7
|
+
import { createId } from '../../shared/utils/id.js';
|
|
8
|
+
import { GEOJSON_PREFIX, LIBRARY_PROPERTIES } from './constants.js';
|
|
9
|
+
import { normalizeEmbeddedFile } from './embedded-file.js';
|
|
10
|
+
import { COORDINATE_DEPTH, describeCoordinateProblem } from './geometry-validation.js';
|
|
11
|
+
import { setOwnProperty } from './own-property.js';
|
|
12
|
+
import { isHexColor, sanitizeFeatureStyle } from './style-validation.js';
|
|
13
|
+
/**
|
|
14
|
+
* Converts a single geometry (Point/LineString/Polygon) into the Feature format
|
|
15
|
+
*/
|
|
16
|
+
function convertSingleGeometry(geometry, meta, userProperties, featureType, fileData) {
|
|
17
|
+
// The fields shared besides geometry (id/layerId/groupId/style/visible/locked)
|
|
18
|
+
const base = {
|
|
19
|
+
id: meta.id,
|
|
20
|
+
layerId: meta.layerId,
|
|
21
|
+
groupId: meta.groupId,
|
|
22
|
+
properties: userProperties,
|
|
23
|
+
style: meta.style,
|
|
24
|
+
locked: meta.locked,
|
|
25
|
+
visible: meta.visible,
|
|
26
|
+
};
|
|
27
|
+
switch (geometry.type) {
|
|
28
|
+
case 'Point': {
|
|
29
|
+
const type = resolveFeatureType('Point', featureType);
|
|
30
|
+
return {
|
|
31
|
+
feature: { ...base, type, coordinates: geometry.coordinates },
|
|
32
|
+
// The embedded image belongs only to a feature that really is an Image
|
|
33
|
+
fileData: type === 'Image' ? fileData : undefined,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
case 'LineString': {
|
|
37
|
+
// A custom type with a sequence of points (such as an arrow) is written out as a
|
|
38
|
+
// LineString, so restore the original type when the featureType marker is present
|
|
39
|
+
// (this pairs with the default branch on export).
|
|
40
|
+
const type = resolveFeatureType('LineString', featureType);
|
|
41
|
+
return {
|
|
42
|
+
feature: {
|
|
43
|
+
...base,
|
|
44
|
+
type,
|
|
45
|
+
coordinates: geometry.coordinates,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
case 'Polygon':
|
|
50
|
+
return {
|
|
51
|
+
feature: {
|
|
52
|
+
...base,
|
|
53
|
+
type: 'Polygon',
|
|
54
|
+
coordinates: geometry.coordinates,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
default:
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Converts a Multi* geometry into a single Multi feature (the default behavior)
|
|
63
|
+
*
|
|
64
|
+
* The parts are kept as they are instead of being split, so that properties are not
|
|
65
|
+
* duplicated.
|
|
66
|
+
*/
|
|
67
|
+
function convertMultiGeometry(geometry, meta, userProperties) {
|
|
68
|
+
if (geometry.coordinates.length === 0)
|
|
69
|
+
return null;
|
|
70
|
+
return [
|
|
71
|
+
{
|
|
72
|
+
feature: {
|
|
73
|
+
id: meta.id,
|
|
74
|
+
layerId: meta.layerId,
|
|
75
|
+
groupId: meta.groupId,
|
|
76
|
+
properties: userProperties,
|
|
77
|
+
style: meta.style,
|
|
78
|
+
locked: meta.locked,
|
|
79
|
+
visible: meta.visible,
|
|
80
|
+
type: geometry.type,
|
|
81
|
+
coordinates: geometry.coordinates,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Flattens the coordinates of a Multi* geometry into individual features
|
|
88
|
+
*
|
|
89
|
+
* A compatibility behavior used only when `flattenMulti: true` is given.
|
|
90
|
+
*/
|
|
91
|
+
function flattenMultiGeometry(coordsArray, toGeometry, generateFeatureId, meta, userProperties, featureType, fileData) {
|
|
92
|
+
const results = [];
|
|
93
|
+
for (const coords of coordsArray) {
|
|
94
|
+
// Each part of the Multi becomes an individual Feature, so assign it a new ID
|
|
95
|
+
const result = convertSingleGeometry(toGeometry(coords), { ...meta, id: generateFeatureId() }, { ...userProperties }, featureType, fileData);
|
|
96
|
+
if (result)
|
|
97
|
+
results.push(result);
|
|
98
|
+
}
|
|
99
|
+
return results.length > 0 ? results : null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Folds the sub-geometries of a GeometryCollection by type
|
|
103
|
+
*
|
|
104
|
+
* A GeometryCollection is not made a first-class feature type; it is gathered into one
|
|
105
|
+
* geometry per type. Sub-geometries of the same kind become a single Multi
|
|
106
|
+
* (a GC of three Polygons becomes one MultiPolygon feature), and even when they are
|
|
107
|
+
* mixed, they grow to at most three features, one per type
|
|
108
|
+
* (MultiPoint / MultiLineString / MultiPolygon). Duplication of the properties is thus
|
|
109
|
+
* held down to those three.
|
|
110
|
+
*
|
|
111
|
+
* A nested GeometryCollection is expanded recursively into the same buckets.
|
|
112
|
+
*/
|
|
113
|
+
function collectGeometryCollectionParts(geometry, buckets) {
|
|
114
|
+
for (const sub of geometry.geometries) {
|
|
115
|
+
switch (sub.type) {
|
|
116
|
+
case 'Point':
|
|
117
|
+
buckets.points.push(sub.coordinates);
|
|
118
|
+
break;
|
|
119
|
+
case 'MultiPoint':
|
|
120
|
+
buckets.points.push(...sub.coordinates);
|
|
121
|
+
break;
|
|
122
|
+
case 'LineString':
|
|
123
|
+
buckets.lines.push(sub.coordinates);
|
|
124
|
+
break;
|
|
125
|
+
case 'MultiLineString':
|
|
126
|
+
buckets.lines.push(...sub.coordinates);
|
|
127
|
+
break;
|
|
128
|
+
case 'Polygon':
|
|
129
|
+
buckets.polygons.push(sub.coordinates);
|
|
130
|
+
break;
|
|
131
|
+
case 'MultiPolygon':
|
|
132
|
+
buckets.polygons.push(...sub.coordinates);
|
|
133
|
+
break;
|
|
134
|
+
case 'GeometryCollection':
|
|
135
|
+
collectGeometryCollectionParts(sub, buckets);
|
|
136
|
+
break;
|
|
137
|
+
default:
|
|
138
|
+
// Unreachable: normalizeGeometry rejects every other type before conversion
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Converts a GeometryCollection into a set of Features folded by type
|
|
145
|
+
*/
|
|
146
|
+
function convertGeometryCollection(geometry, meta, userProperties, generateFeatureId) {
|
|
147
|
+
const buckets = {
|
|
148
|
+
points: [],
|
|
149
|
+
lines: [],
|
|
150
|
+
polygons: [],
|
|
151
|
+
};
|
|
152
|
+
collectGeometryCollectionParts(geometry, buckets);
|
|
153
|
+
const results = [];
|
|
154
|
+
// The folded features multiply out of the original single feature, so a new id is
|
|
155
|
+
// assigned and the properties are copied for each folded feature.
|
|
156
|
+
const push = (type, coordinates) => {
|
|
157
|
+
results.push({
|
|
158
|
+
feature: {
|
|
159
|
+
id: generateFeatureId(),
|
|
160
|
+
layerId: meta.layerId,
|
|
161
|
+
groupId: meta.groupId,
|
|
162
|
+
properties: { ...userProperties },
|
|
163
|
+
style: meta.style,
|
|
164
|
+
locked: meta.locked,
|
|
165
|
+
visible: meta.visible,
|
|
166
|
+
type,
|
|
167
|
+
coordinates,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
if (buckets.points.length > 0)
|
|
172
|
+
push('MultiPoint', buckets.points);
|
|
173
|
+
if (buckets.lines.length > 0)
|
|
174
|
+
push('MultiLineString', buckets.lines);
|
|
175
|
+
if (buckets.polygons.length > 0)
|
|
176
|
+
push('MultiPolygon', buckets.polygons);
|
|
177
|
+
return results.length > 0 ? results : null;
|
|
178
|
+
}
|
|
179
|
+
/** The names of the GeoJSON geometry types, lower-cased */
|
|
180
|
+
const GEOMETRY_TYPE_NAMES = new Set([
|
|
181
|
+
'point',
|
|
182
|
+
'linestring',
|
|
183
|
+
'polygon',
|
|
184
|
+
'multipoint',
|
|
185
|
+
'multilinestring',
|
|
186
|
+
'multipolygon',
|
|
187
|
+
'geometrycollection',
|
|
188
|
+
]);
|
|
189
|
+
/**
|
|
190
|
+
* Resolves the feature type of a Point or LineString from the featureType marker
|
|
191
|
+
*
|
|
192
|
+
* The marker restores a type that GeoJSON has no geometry for (Image, Circle, Freehand and
|
|
193
|
+
* custom types). The export writes the type name as it is, and the marker is read as that exact
|
|
194
|
+
* name. It is used only when it is a non-empty string, does not name a GeoJSON geometry type
|
|
195
|
+
* (in any letter case), and names a type whose coordinates have the shape of the geometry.
|
|
196
|
+
* Anything else is ignored and the geometry type is kept, so the marker can never pair a type
|
|
197
|
+
* with coordinates of another shape.
|
|
198
|
+
*/
|
|
199
|
+
function resolveFeatureType(geometryType, marker) {
|
|
200
|
+
if (typeof marker !== 'string' || marker === '')
|
|
201
|
+
return geometryType;
|
|
202
|
+
if (GEOMETRY_TYPE_NAMES.has(marker.toLowerCase()))
|
|
203
|
+
return geometryType;
|
|
204
|
+
const expectedDepth = COORDINATE_DEPTH[marker];
|
|
205
|
+
const actualDepth = geometryType === 'Point' ? 0 : 1;
|
|
206
|
+
return expectedDepth === undefined || expectedDepth === actualDepth ? marker : geometryType;
|
|
207
|
+
}
|
|
208
|
+
/** The geometry types the import converts */
|
|
209
|
+
const SUPPORTED_GEOMETRY_TYPES = new Set([
|
|
210
|
+
'Point',
|
|
211
|
+
'LineString',
|
|
212
|
+
'Polygon',
|
|
213
|
+
'MultiPoint',
|
|
214
|
+
'MultiLineString',
|
|
215
|
+
'MultiPolygon',
|
|
216
|
+
]);
|
|
217
|
+
function isRecord(value) {
|
|
218
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Truncates every GeoJSON position to the two elements [longitude, latitude]
|
|
222
|
+
*
|
|
223
|
+
* GeoJSON allows a third element and beyond (elevation and so on), but the Coordinate
|
|
224
|
+
* of core has two elements. Letting a three-element position through misaligns the
|
|
225
|
+
* coordinate packing of the rendering so that nothing can be drawn, so it is normalized
|
|
226
|
+
* at the import boundary. A value that is not an array is returned as it is (the
|
|
227
|
+
* validation that follows rejects it).
|
|
228
|
+
*/
|
|
229
|
+
function truncatePositions(value) {
|
|
230
|
+
if (!Array.isArray(value))
|
|
231
|
+
return value;
|
|
232
|
+
if (typeof value[0] === 'number')
|
|
233
|
+
return value.length > 2 ? value.slice(0, 2) : value;
|
|
234
|
+
return value.map(truncatePositions);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Returns a copy of the geometry with every position truncated to two elements, or the
|
|
238
|
+
* reason it cannot be imported
|
|
239
|
+
*
|
|
240
|
+
* Every geometry of a GeometryCollection must be valid for the GeometryCollection to be imported.
|
|
241
|
+
*/
|
|
242
|
+
function normalizeGeometry(geometry) {
|
|
243
|
+
if (geometry === null || geometry === undefined)
|
|
244
|
+
return 'the feature has no geometry';
|
|
245
|
+
if (!isRecord(geometry))
|
|
246
|
+
return 'the geometry is not an object';
|
|
247
|
+
const { type } = geometry;
|
|
248
|
+
if (type === 'GeometryCollection') {
|
|
249
|
+
if (!Array.isArray(geometry.geometries)) {
|
|
250
|
+
return 'the GeometryCollection has no geometries array';
|
|
251
|
+
}
|
|
252
|
+
const geometries = [];
|
|
253
|
+
for (const sub of geometry.geometries) {
|
|
254
|
+
const normalized = normalizeGeometry(sub);
|
|
255
|
+
if (typeof normalized === 'string') {
|
|
256
|
+
return `a geometry of the GeometryCollection: ${normalized}`;
|
|
257
|
+
}
|
|
258
|
+
geometries.push(normalized);
|
|
259
|
+
}
|
|
260
|
+
return { type, geometries };
|
|
261
|
+
}
|
|
262
|
+
if (typeof type !== 'string' || !SUPPORTED_GEOMETRY_TYPES.has(type)) {
|
|
263
|
+
return `unsupported geometry type "${String(type)}"`;
|
|
264
|
+
}
|
|
265
|
+
const coordinates = truncatePositions(geometry.coordinates);
|
|
266
|
+
const problem = describeCoordinateProblem(type, coordinates);
|
|
267
|
+
if (problem)
|
|
268
|
+
return `the ${type} has ${problem}`;
|
|
269
|
+
return { type, coordinates };
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Copies the properties of simplestyle-spec into a FeatureStyle (an import fallback)
|
|
273
|
+
*
|
|
274
|
+
* Plain GeoJSON (the output of a GPS logger or of another tool) does not carry a style
|
|
275
|
+
* with the maplibre-gl-draw: prefix, but it may express colors and line widths through the
|
|
276
|
+
* keys of simplestyle-spec. Only when the round-trip key is absent are these read as the
|
|
277
|
+
* internal style. Keys whose type or form does not match (a color that is not #rgb or
|
|
278
|
+
* #rrggbb, an opacity outside 0-1, a negative width) are silently ignored, and undefined is
|
|
279
|
+
* returned if not a single one could be copied. The original properties are not rewritten,
|
|
280
|
+
* so the simplestyle keys remain as user-defined properties.
|
|
281
|
+
*/
|
|
282
|
+
function simplestyleToFeatureStyle(properties) {
|
|
283
|
+
if (!properties)
|
|
284
|
+
return undefined;
|
|
285
|
+
const style = {};
|
|
286
|
+
let found = false;
|
|
287
|
+
const copyString = (key, target) => {
|
|
288
|
+
const value = properties[key];
|
|
289
|
+
if (isHexColor(value)) {
|
|
290
|
+
style[target] = value;
|
|
291
|
+
found = true;
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
const copyNumber = (key, target) => {
|
|
295
|
+
const value = properties[key];
|
|
296
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
297
|
+
style[target] = value;
|
|
298
|
+
found = true;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
copyString('stroke', 'strokeColor');
|
|
302
|
+
copyNumber('stroke-width', 'strokeWidth');
|
|
303
|
+
copyNumber('stroke-opacity', 'strokeOpacity');
|
|
304
|
+
copyString('fill', 'fillColor');
|
|
305
|
+
copyNumber('fill-opacity', 'fillOpacity');
|
|
306
|
+
copyString('marker-color', 'pointColor');
|
|
307
|
+
// The numbers are checked against the ranges of FeatureStyle by the same rules as the
|
|
308
|
+
// round-trip style
|
|
309
|
+
return found ? sanitizeFeatureStyle(style) : undefined;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Converts a GeoJSON Feature into the internal Feature format
|
|
313
|
+
*
|
|
314
|
+
* The geometry is validated and normalized first, and a feature that cannot be imported is
|
|
315
|
+
* returned as a reason instead of throwing. A Multi* geometry is kept as a Multi feature by
|
|
316
|
+
* default (it is expanded into individual features only when `flattenMulti: true`). A
|
|
317
|
+
* GeometryCollection is folded by type into at most three features. visible/locked/groupId
|
|
318
|
+
* are restored from the properties with the maplibre-gl-draw: prefix. Nothing is written.
|
|
319
|
+
*/
|
|
320
|
+
export function convertGeoJSONToFeature(geoFeature, layerId, generateFeatureId, generateFileId, options) {
|
|
321
|
+
if (!isRecord(geoFeature))
|
|
322
|
+
return { reason: 'the entry is not a GeoJSON Feature object' };
|
|
323
|
+
const rawProperties = geoFeature.properties;
|
|
324
|
+
if (rawProperties !== null && rawProperties !== undefined && !isRecord(rawProperties)) {
|
|
325
|
+
return { reason: 'the properties are not an object' };
|
|
326
|
+
}
|
|
327
|
+
const properties = (rawProperties ?? null);
|
|
328
|
+
const geometry = normalizeGeometry(geoFeature.geometry);
|
|
329
|
+
if (typeof geometry === 'string')
|
|
330
|
+
return { reason: geometry };
|
|
331
|
+
const flattenMulti = options?.flattenMulti === true;
|
|
332
|
+
// An id is a string; a number (allowed for a GeoJSON id) is normalized into its string
|
|
333
|
+
// form, and anything else gets a new id. The prefixed property takes precedence, then the
|
|
334
|
+
// standard id member of the Feature. Whether it collides with existing data is resolved by
|
|
335
|
+
// the caller, which knows the store.
|
|
336
|
+
const prefixedId = properties?.[`${GEOJSON_PREFIX}id`];
|
|
337
|
+
const rawId = prefixedId === undefined || prefixedId === null || prefixedId === ''
|
|
338
|
+
? geoFeature.id
|
|
339
|
+
: prefixedId;
|
|
340
|
+
const id = typeof rawId === 'string' && rawId !== ''
|
|
341
|
+
? rawId
|
|
342
|
+
: typeof rawId === 'number' && Number.isFinite(rawId)
|
|
343
|
+
? String(rawId)
|
|
344
|
+
: generateFeatureId();
|
|
345
|
+
const rawLayerId = properties?.[`${GEOJSON_PREFIX}layerId`];
|
|
346
|
+
const featureLayerId = typeof rawLayerId === 'string' && rawLayerId !== '' ? rawLayerId : layerId;
|
|
347
|
+
const rawGroupId = properties?.[`${GEOJSON_PREFIX}groupId`];
|
|
348
|
+
const groupId = typeof rawGroupId === 'string' && rawGroupId !== '' ? rawGroupId : undefined;
|
|
349
|
+
// The round-trip style key takes precedence; only when it is absent is the style built
|
|
350
|
+
// from simplestyle-spec (they are not merged). Either way the keys are validated.
|
|
351
|
+
const roundTripStyle = properties?.[`${GEOJSON_PREFIX}style`];
|
|
352
|
+
const style = roundTripStyle !== undefined && roundTripStyle !== null
|
|
353
|
+
? sanitizeFeatureStyle(roundTripStyle)
|
|
354
|
+
: simplestyleToFeatureStyle(properties);
|
|
355
|
+
const featureType = properties?.[`${GEOJSON_PREFIX}featureType`];
|
|
356
|
+
// visible is hidden only when it is explicitly false, and locked is treated as locked
|
|
357
|
+
// only when it is explicitly true
|
|
358
|
+
const visible = properties?.[`${GEOJSON_PREFIX}visible`] !== false;
|
|
359
|
+
const locked = properties?.[`${GEOJSON_PREFIX}locked`] === true;
|
|
360
|
+
// Extract the embedded image data. It is taken only for a single point that really is an
|
|
361
|
+
// Image.
|
|
362
|
+
const imageData = properties?.[`${GEOJSON_PREFIX}imageData`];
|
|
363
|
+
const imageMimeType = properties?.[`${GEOJSON_PREFIX}imageMimeType`];
|
|
364
|
+
const embedsImage = Boolean(imageData && imageMimeType) &&
|
|
365
|
+
geometry.type === 'Point' &&
|
|
366
|
+
resolveFeatureType('Point', featureType) === 'Image';
|
|
367
|
+
// Extract the properties
|
|
368
|
+
// - without a prefix: added as is as a user-defined property
|
|
369
|
+
// - with a prefix and one of this library's own properties: added with the prefix stripped
|
|
370
|
+
// - any other prefixed key (id, layerId, style, visible, locked and so on): excluded
|
|
371
|
+
// (they are handled separately)
|
|
372
|
+
// Keys are defined as own properties so that a `__proto__` key stays an ordinary key.
|
|
373
|
+
const userProperties = {};
|
|
374
|
+
if (properties) {
|
|
375
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
376
|
+
if (key.startsWith(GEOJSON_PREFIX)) {
|
|
377
|
+
const keyWithoutPrefix = key.slice(GEOJSON_PREFIX.length);
|
|
378
|
+
if (LIBRARY_PROPERTIES.has(keyWithoutPrefix)) {
|
|
379
|
+
// When there is image data, imageFileId is replaced with a new ID, so it is
|
|
380
|
+
// not added here
|
|
381
|
+
if (keyWithoutPrefix !== 'imageFileId' || !embedsImage) {
|
|
382
|
+
setOwnProperty(userProperties, keyWithoutPrefix, value);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Anything else (id, layerId, style, featureType, visible, locked, imageData and
|
|
386
|
+
// so on) is excluded
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
setOwnProperty(userProperties, key, value);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// When there is image data on a single Image point, create the FileData and set a new
|
|
394
|
+
// imageFileId
|
|
395
|
+
let fileData;
|
|
396
|
+
if (embedsImage) {
|
|
397
|
+
const newFileId = generateFileId();
|
|
398
|
+
fileData = {
|
|
399
|
+
id: newFileId,
|
|
400
|
+
mimeType: imageMimeType,
|
|
401
|
+
dataURL: imageData,
|
|
402
|
+
};
|
|
403
|
+
userProperties.imageFileId = newFileId;
|
|
404
|
+
}
|
|
405
|
+
const meta = {
|
|
406
|
+
id,
|
|
407
|
+
layerId: featureLayerId,
|
|
408
|
+
groupId,
|
|
409
|
+
style,
|
|
410
|
+
visible,
|
|
411
|
+
locked,
|
|
412
|
+
};
|
|
413
|
+
const convert = () => {
|
|
414
|
+
switch (geometry.type) {
|
|
415
|
+
case 'Point':
|
|
416
|
+
case 'LineString':
|
|
417
|
+
case 'Polygon': {
|
|
418
|
+
const result = convertSingleGeometry(geometry, meta, userProperties, featureType, fileData);
|
|
419
|
+
return result ? [result] : null;
|
|
420
|
+
}
|
|
421
|
+
case 'MultiPoint':
|
|
422
|
+
if (!flattenMulti) {
|
|
423
|
+
return convertMultiGeometry(geometry, meta, userProperties);
|
|
424
|
+
}
|
|
425
|
+
return flattenMultiGeometry(geometry.coordinates, (coords) => ({ type: 'Point', coordinates: coords }), generateFeatureId, meta, userProperties, featureType, fileData);
|
|
426
|
+
case 'MultiLineString':
|
|
427
|
+
if (!flattenMulti) {
|
|
428
|
+
return convertMultiGeometry(geometry, meta, userProperties);
|
|
429
|
+
}
|
|
430
|
+
return flattenMultiGeometry(geometry.coordinates, (coords) => ({ type: 'LineString', coordinates: coords }), generateFeatureId, meta, userProperties, undefined, undefined);
|
|
431
|
+
case 'MultiPolygon':
|
|
432
|
+
if (!flattenMulti) {
|
|
433
|
+
return convertMultiGeometry(geometry, meta, userProperties);
|
|
434
|
+
}
|
|
435
|
+
return flattenMultiGeometry(geometry.coordinates, (coords) => ({ type: 'Polygon', coordinates: coords }), generateFeatureId, meta, userProperties, undefined, undefined);
|
|
436
|
+
case 'GeometryCollection':
|
|
437
|
+
return convertGeometryCollection(geometry, meta, userProperties, generateFeatureId);
|
|
438
|
+
default:
|
|
439
|
+
// Unreachable: normalizeGeometry rejects every other type
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
const results = convert();
|
|
444
|
+
// Only a GeometryCollection without any member produces nothing
|
|
445
|
+
return results ? { results } : { reason: 'the geometry has no parts' };
|
|
446
|
+
}
|
|
447
|
+
/** How many times a colliding feature id is regenerated before the import gives up */
|
|
448
|
+
const MAX_ID_ATTEMPTS = 1000;
|
|
449
|
+
/**
|
|
450
|
+
* Imports a GeoJSON FeatureCollection (adds to the existing data)
|
|
451
|
+
*/
|
|
452
|
+
export async function loadGeoJSON(data, deps, options) {
|
|
453
|
+
const { store, autoNameGenerator, generateFeatureId, getCurrentLayerId } = deps;
|
|
454
|
+
const layerId = getCurrentLayerId();
|
|
455
|
+
const generateFileId = () => createId();
|
|
456
|
+
// 1. Validate, convert and resolve everything before writing. store.transact does not roll
|
|
457
|
+
// back, so nothing may throw once the writing has started. A feature that cannot be
|
|
458
|
+
// imported is skipped with its reason instead of rejecting the whole load.
|
|
459
|
+
const results = [];
|
|
460
|
+
const skipped = [];
|
|
461
|
+
data.features.forEach((geoFeature, index) => {
|
|
462
|
+
const converted = convertGeoJSONToFeature(geoFeature, layerId, generateFeatureId, generateFileId, options);
|
|
463
|
+
if ('reason' in converted) {
|
|
464
|
+
skipped.push({ index, reason: converted.reason });
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
results.push(...converted.results);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
// Feature and group IDs share the entries of layer.order, so an id taken by either (or by
|
|
471
|
+
// an earlier feature of this import) is replaced with a new one. This is what makes a
|
|
472
|
+
// GeoJSON exported from a store loadable into the same store again.
|
|
473
|
+
const takenIds = new Set();
|
|
474
|
+
const isTaken = (id) => takenIds.has(id) || store.getFeature(id) !== undefined || store.getGroup(id) !== undefined;
|
|
475
|
+
const resolveId = (id) => {
|
|
476
|
+
let resolved = id;
|
|
477
|
+
for (let attempt = 0; isTaken(resolved); attempt++) {
|
|
478
|
+
if (attempt >= MAX_ID_ATTEMPTS) {
|
|
479
|
+
throw new Error('Failed to generate a unique feature id for the GeoJSON import');
|
|
480
|
+
}
|
|
481
|
+
resolved = generateFeatureId();
|
|
482
|
+
}
|
|
483
|
+
takenIds.add(resolved);
|
|
484
|
+
return resolved;
|
|
485
|
+
};
|
|
486
|
+
for (const { feature } of results) {
|
|
487
|
+
feature.id = resolveId(feature.id);
|
|
488
|
+
// References are resolved against this store: a layer it does not have falls back to
|
|
489
|
+
// the current layer, and a group it does not have is dropped (a feature pointing at a
|
|
490
|
+
// missing group would belong to no layer order and never be drawn).
|
|
491
|
+
if (!store.getLayer(feature.layerId))
|
|
492
|
+
feature.layerId = layerId;
|
|
493
|
+
if (feature.groupId !== undefined && !store.getGroup(feature.groupId)) {
|
|
494
|
+
delete feature.groupId;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// Embedded images are accepted only as PNG / JPEG / WebP / GIF data URLs, and an oversized
|
|
498
|
+
// one is scaled down. Unlike a malformed geometry, a bad image rejects the whole load: the
|
|
499
|
+
// image fields are written only by this library's export, so a bad one means the file was
|
|
500
|
+
// altered, and the load is refused rather than trusted in part.
|
|
501
|
+
for (const result of results) {
|
|
502
|
+
if (!result.fileData)
|
|
503
|
+
continue;
|
|
504
|
+
const content = await normalizeEmbeddedFile(result.fileData.dataURL, result.fileData.mimeType);
|
|
505
|
+
if (!content) {
|
|
506
|
+
throw new Error(`Invalid GeoJSON: the image data of feature "${result.feature.id}" is not an embedded ` +
|
|
507
|
+
'PNG / JPEG / WebP / GIF data URL of its declared type');
|
|
508
|
+
}
|
|
509
|
+
result.fileData = { ...result.fileData, ...content };
|
|
510
|
+
}
|
|
511
|
+
// 2. Write. Written with batch: the whole import is one notification, one step for a
|
|
512
|
+
// subscriber that records changes. Hosts that rebuild a view should subscribe to the
|
|
513
|
+
// per-flush `features.change` event rather than the per-feature events.
|
|
514
|
+
const featureIds = [];
|
|
515
|
+
store.transact(() => {
|
|
516
|
+
for (const result of results) {
|
|
517
|
+
// When there is image data, add the file first
|
|
518
|
+
if (result.fileData) {
|
|
519
|
+
store.createFile(result.fileData);
|
|
520
|
+
}
|
|
521
|
+
// When name is not set, generate an automatic name
|
|
522
|
+
if (result.feature.properties.name === undefined) {
|
|
523
|
+
const autoName = autoNameGenerator.generateName(result.feature.type);
|
|
524
|
+
if (autoName !== undefined) {
|
|
525
|
+
result.feature.properties.name = autoName;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
store.createFeature(result.feature);
|
|
529
|
+
featureIds.push(result.feature.id);
|
|
530
|
+
}
|
|
531
|
+
}, 'batch');
|
|
532
|
+
return {
|
|
533
|
+
format: 'geojson',
|
|
534
|
+
featureIds,
|
|
535
|
+
replaced: false,
|
|
536
|
+
skipped,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The nesting depth of the coordinates of each built-in feature type
|
|
3
|
+
* (0 = a single position, 1 = a sequence of positions, and so on).
|
|
4
|
+
* Custom types are accepted at any depth as long as the nesting is regular.
|
|
5
|
+
*/
|
|
6
|
+
export declare const COORDINATE_DEPTH: Readonly<Record<string, number>>;
|
|
7
|
+
/**
|
|
8
|
+
* Returns why the coordinates cannot be used for a feature of the type, or null when they
|
|
9
|
+
* can
|
|
10
|
+
*
|
|
11
|
+
* Every position must be two finite numbers, and no array may be empty. A built-in type
|
|
12
|
+
* must have its nesting depth, a line has at least two positions, and a ring at least four
|
|
13
|
+
* with the first and the last equal. A custom type may use any regular depth.
|
|
14
|
+
*
|
|
15
|
+
* @param type - the feature type
|
|
16
|
+
* @param coordinates - the coordinates to check
|
|
17
|
+
* @returns a short phrase that reads after "has" (for example "malformed coordinates"), or
|
|
18
|
+
* null
|
|
19
|
+
*/
|
|
20
|
+
export declare function describeCoordinateProblem(type: string, coordinates: unknown): string | null;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* The nesting depth of the coordinates of each built-in feature type
|
|
5
|
+
* (0 = a single position, 1 = a sequence of positions, and so on).
|
|
6
|
+
* Custom types are accepted at any depth as long as the nesting is regular.
|
|
7
|
+
*/
|
|
8
|
+
export const COORDINATE_DEPTH = {
|
|
9
|
+
Point: 0,
|
|
10
|
+
Image: 0,
|
|
11
|
+
Circle: 0,
|
|
12
|
+
LineString: 1,
|
|
13
|
+
Freehand: 1,
|
|
14
|
+
MultiPoint: 1,
|
|
15
|
+
Polygon: 2,
|
|
16
|
+
MultiLineString: 2,
|
|
17
|
+
MultiPolygon: 3,
|
|
18
|
+
};
|
|
19
|
+
/** Whether the value is a position of two finite numbers */
|
|
20
|
+
function isPosition(value) {
|
|
21
|
+
return (Array.isArray(value) &&
|
|
22
|
+
value.length === 2 &&
|
|
23
|
+
typeof value[0] === 'number' &&
|
|
24
|
+
Number.isFinite(value[0]) &&
|
|
25
|
+
typeof value[1] === 'number' &&
|
|
26
|
+
Number.isFinite(value[1]));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the nesting depth of well-formed coordinates, or -1 when they are malformed
|
|
30
|
+
* (a non-finite number, an empty array or irregular nesting)
|
|
31
|
+
*/
|
|
32
|
+
function coordinateDepth(value) {
|
|
33
|
+
if (isPosition(value))
|
|
34
|
+
return 0;
|
|
35
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
36
|
+
return -1;
|
|
37
|
+
const depth = coordinateDepth(value[0]);
|
|
38
|
+
if (depth < 0)
|
|
39
|
+
return -1;
|
|
40
|
+
for (let i = 1; i < value.length; i++) {
|
|
41
|
+
if (coordinateDepth(value[i]) !== depth)
|
|
42
|
+
return -1;
|
|
43
|
+
}
|
|
44
|
+
return depth + 1;
|
|
45
|
+
}
|
|
46
|
+
/** Why a line (a sequence of positions of depth 1) is unusable, or null */
|
|
47
|
+
function lineProblem(line) {
|
|
48
|
+
return line.length < 2 ? 'a line with fewer than two positions' : null;
|
|
49
|
+
}
|
|
50
|
+
/** Why a ring (a sequence of positions of depth 1) is unusable, or null */
|
|
51
|
+
function ringProblem(ring) {
|
|
52
|
+
if (ring.length < 4)
|
|
53
|
+
return 'a ring with fewer than four positions';
|
|
54
|
+
const first = ring[0];
|
|
55
|
+
const last = ring[ring.length - 1];
|
|
56
|
+
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
57
|
+
return 'a ring whose first and last positions differ';
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
function firstProblem(parts, check) {
|
|
62
|
+
for (const part of parts) {
|
|
63
|
+
const problem = check(part);
|
|
64
|
+
if (problem)
|
|
65
|
+
return problem;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/** Why a polygon (a list of rings) is unusable, or null */
|
|
70
|
+
function polygonProblem(rings) {
|
|
71
|
+
return firstProblem(rings, ringProblem);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns why the coordinates cannot be used for a feature of the type, or null when they
|
|
75
|
+
* can
|
|
76
|
+
*
|
|
77
|
+
* Every position must be two finite numbers, and no array may be empty. A built-in type
|
|
78
|
+
* must have its nesting depth, a line has at least two positions, and a ring at least four
|
|
79
|
+
* with the first and the last equal. A custom type may use any regular depth.
|
|
80
|
+
*
|
|
81
|
+
* @param type - the feature type
|
|
82
|
+
* @param coordinates - the coordinates to check
|
|
83
|
+
* @returns a short phrase that reads after "has" (for example "malformed coordinates"), or
|
|
84
|
+
* null
|
|
85
|
+
*/
|
|
86
|
+
export function describeCoordinateProblem(type, coordinates) {
|
|
87
|
+
const depth = coordinateDepth(coordinates);
|
|
88
|
+
if (depth < 0)
|
|
89
|
+
return 'malformed coordinates';
|
|
90
|
+
const expected = COORDINATE_DEPTH[type];
|
|
91
|
+
if (expected !== undefined && depth !== expected) {
|
|
92
|
+
return `coordinates that do not match the type ${type}`;
|
|
93
|
+
}
|
|
94
|
+
switch (type) {
|
|
95
|
+
case 'LineString':
|
|
96
|
+
case 'Freehand':
|
|
97
|
+
return lineProblem(coordinates);
|
|
98
|
+
case 'MultiLineString':
|
|
99
|
+
return firstProblem(coordinates, lineProblem);
|
|
100
|
+
case 'Polygon':
|
|
101
|
+
return polygonProblem(coordinates);
|
|
102
|
+
case 'MultiPolygon':
|
|
103
|
+
return firstProblem(coordinates, polygonProblem);
|
|
104
|
+
default:
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AutoNameGenerator } from '../../shared/utils/name-generator.js';
|
|
2
|
+
import type { Store } from '../../store/store.js';
|
|
3
|
+
import type { LoadOptions, LoadResult } from '../../store/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Imports an image file and creates an Image feature
|
|
6
|
+
*/
|
|
7
|
+
export declare function loadImage(file: File, options: LoadOptions, deps: {
|
|
8
|
+
store: Store;
|
|
9
|
+
autoNameGenerator: AutoNameGenerator;
|
|
10
|
+
generateFeatureId: () => string;
|
|
11
|
+
getCurrentLayerId: () => string;
|
|
12
|
+
}): Promise<LoadResult>;
|