@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,218 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Buffer
|
|
5
|
+
*
|
|
6
|
+
* Generated in meters without interposing a map projection. A point becomes a circle; a
|
|
7
|
+
* line becomes the union of the circle of each vertex and the band of each edge (a
|
|
8
|
+
* quadrilateral offset by the distance ±90 degrees from the bearing of the edge); a
|
|
9
|
+
* polygon becomes the union (positive value) or the difference (negative value) of the
|
|
10
|
+
* line buffer of its outer and inner rings and the original polygon.
|
|
11
|
+
*
|
|
12
|
+
* The offsets are points reached along great circles (destinationPoint, the direct problem
|
|
13
|
+
* on the sphere), so the distances hold at any latitude; the edges between the generated
|
|
14
|
+
* points are straight in longitude and latitude. An input out of scope gives null: a
|
|
15
|
+
* coordinate that is not finite, a vertex whose buffer distance reaches a pole (the parts
|
|
16
|
+
* would wrap the pole, which a ring in longitude and latitude cannot express), or an edge
|
|
17
|
+
* that spans more than 180 degrees of longitude (the planar edge then runs the other way
|
|
18
|
+
* round the globe from its bearing).
|
|
19
|
+
*/
|
|
20
|
+
import { difference, union, unionAll } from './boolean.js';
|
|
21
|
+
import { generateCirclePolygon, normalizeCircleSegments } from './circle.js';
|
|
22
|
+
import { closeRing, isFiniteCoordinate, toMultiPolygonCoordinates } from './coords.js';
|
|
23
|
+
import { destinationPoint, initialBearingDegrees } from './distance.js';
|
|
24
|
+
import { EARTH_RADIUS_METERS, toDegrees } from './units.js';
|
|
25
|
+
/** The default number of segments per circle of {@link buffer}: 64. */
|
|
26
|
+
export const DEFAULT_BUFFER_SEGMENTS = 64;
|
|
27
|
+
/**
|
|
28
|
+
* The buffer of a point (a geodesic circle)
|
|
29
|
+
*/
|
|
30
|
+
function circlePolygon(center, radius, segments) {
|
|
31
|
+
return [generateCirclePolygon(center, radius, segments)];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Drops the duplicates of identical coordinates (the order is preserved)
|
|
35
|
+
*/
|
|
36
|
+
function dedupeVertices(line) {
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const result = [];
|
|
39
|
+
for (const vertex of line) {
|
|
40
|
+
const key = `${vertex[0]},${vertex[1]}`;
|
|
41
|
+
if (seen.has(key)) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
seen.add(key);
|
|
45
|
+
result.push(vertex);
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generates the parts that make up the buffer of a line
|
|
51
|
+
*
|
|
52
|
+
* Returns the geodesic circle of each vertex and the band of each edge lined up. Taking
|
|
53
|
+
* the union is up to the caller.
|
|
54
|
+
*/
|
|
55
|
+
function lineBufferParts(line, radius, segments) {
|
|
56
|
+
// Vertices at identical coordinates produce the same circle twice. The end of a
|
|
57
|
+
// closed ring is the typical case; drop them for the robustness of polygon-clipping
|
|
58
|
+
const vertices = dedupeVertices(line);
|
|
59
|
+
const parts = [];
|
|
60
|
+
for (const vertex of vertices) {
|
|
61
|
+
parts.push(circlePolygon(vertex, radius, segments));
|
|
62
|
+
}
|
|
63
|
+
for (let i = 0; i < line.length - 1; i++) {
|
|
64
|
+
const start = line[i];
|
|
65
|
+
const end = line[i + 1];
|
|
66
|
+
// An edge of length 0 has no determined bearing. It is covered by the vertex
|
|
67
|
+
// circles alone
|
|
68
|
+
if (start[0] === end[0] && start[1] === end[1]) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// A quadrilateral offset by the distance ±90 degrees from the direction of the great
|
|
72
|
+
// circle of the edge at each end: the initial bearing at the start and the final bearing
|
|
73
|
+
// (the reverse bearing turned by 180 degrees) at the end
|
|
74
|
+
const startBearing = initialBearingDegrees(start, end);
|
|
75
|
+
const endBearing = initialBearingDegrees(end, start) + 180;
|
|
76
|
+
parts.push([
|
|
77
|
+
closeRing([
|
|
78
|
+
destinationPoint(start, radius, startBearing - 90),
|
|
79
|
+
destinationPoint(end, radius, endBearing - 90),
|
|
80
|
+
destinationPoint(end, radius, endBearing + 90),
|
|
81
|
+
destinationPoint(start, radius, startBearing + 90),
|
|
82
|
+
]),
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
return parts;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Takes out the lines that make up a geometry (each ring in the case of a polygon)
|
|
89
|
+
*/
|
|
90
|
+
function collectLines(geometry) {
|
|
91
|
+
switch (geometry.type) {
|
|
92
|
+
case 'Point':
|
|
93
|
+
return [[geometry.coordinates]];
|
|
94
|
+
case 'MultiPoint':
|
|
95
|
+
return geometry.coordinates.map((coordinate) => [coordinate]);
|
|
96
|
+
case 'LineString':
|
|
97
|
+
return [geometry.coordinates];
|
|
98
|
+
case 'MultiLineString':
|
|
99
|
+
return geometry.coordinates;
|
|
100
|
+
default:
|
|
101
|
+
return toMultiPolygonCoordinates(geometry.coordinates).flat();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Determines whether the buffer of the lines at the given radius is out of scope
|
|
106
|
+
*
|
|
107
|
+
* Out of scope are a coordinate that is not finite, a vertex whose circle reaches a pole
|
|
108
|
+
* (the parts would wrap the pole, which a ring in longitude and latitude cannot express) and an edge that spans more
|
|
109
|
+
* than 180 degrees of longitude (its bearing points the other way round the globe from the
|
|
110
|
+
* planar edge, so the band would wrap the whole world).
|
|
111
|
+
*/
|
|
112
|
+
function isOutOfScope(lines, radius) {
|
|
113
|
+
const radiusDegrees = toDegrees(radius / EARTH_RADIUS_METERS);
|
|
114
|
+
for (const line of lines) {
|
|
115
|
+
for (let i = 0; i < line.length; i++) {
|
|
116
|
+
const vertex = line[i];
|
|
117
|
+
if (!isFiniteCoordinate(vertex) || Math.abs(vertex[1]) + radiusDegrees >= 90) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
if (i > 0 && Math.abs(vertex[0] - line[i - 1][0]) > 180) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Determines whether the geometry is a polygon-family geometry
|
|
129
|
+
*/
|
|
130
|
+
function isAreaGeometry(geometry) {
|
|
131
|
+
return geometry.type === 'Polygon' || geometry.type === 'MultiPolygon';
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Builds the area within a distance in meters of a geometry.
|
|
135
|
+
*
|
|
136
|
+
* The distances are laid out without a map projection, through {@link destinationPoint},
|
|
137
|
+
* the direct problem on the sphere. Every generated vertex lies at the buffer distance from
|
|
138
|
+
* its source vertex at any latitude, up to floating-point rounding; the edges between the
|
|
139
|
+
* generated vertices are straight in longitude and latitude. A point becomes a circle (the
|
|
140
|
+
* same as {@link generateCirclePolygon}); a line becomes the union of a circle at each
|
|
141
|
+
* vertex and a band along each edge, offset ±90 degrees from the great-circle bearing of
|
|
142
|
+
* the edge; a polygon becomes the union (positive distance) or the difference (negative
|
|
143
|
+
* distance) of the original polygon and the band along its rings.
|
|
144
|
+
*
|
|
145
|
+
* | Input | Positive | 0 | Negative |
|
|
146
|
+
* | --- | --- | --- | --- |
|
|
147
|
+
* | Point / MultiPoint | circle | `null` | `null` |
|
|
148
|
+
* | LineString / MultiLineString | band | `null` | `null` |
|
|
149
|
+
* | Polygon / MultiPolygon | expansion | normalized original | contraction |
|
|
150
|
+
*
|
|
151
|
+
* With a negative distance, parts narrower than `2 * |meters|` disappear, and an empty array
|
|
152
|
+
* is returned when the whole polygon disappears. `null` means the operation is not defined
|
|
153
|
+
* for the input: the table above, a distance that is not finite, a coordinate that is not
|
|
154
|
+
* finite, a vertex whose distance reaches a pole (`|lat|` plus the distance in degrees of
|
|
155
|
+
* latitude is 90 or more), and an edge that spans more than 180 degrees of longitude.
|
|
156
|
+
*
|
|
157
|
+
* @param geometry The geometry to buffer, coordinates in degrees
|
|
158
|
+
* @param meters The buffer distance in meters. A negative value shrinks a polygon
|
|
159
|
+
* @param options The number of segments per circle
|
|
160
|
+
* @returns The normalized MultiPolygon coordinates of the area. An empty array when a
|
|
161
|
+
* shrunk polygon vanishes. `null` when the operation is not defined for the input
|
|
162
|
+
* @throws {@link GeometryError} when the boolean operation engine fails even after the
|
|
163
|
+
* retry on the 1e-9 degree grid
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* import { buffer } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
168
|
+
*
|
|
169
|
+
* // The area within 100 m of a line
|
|
170
|
+
* const corridor = buffer(
|
|
171
|
+
* { type: 'LineString', coordinates: [[139.76, 35.68], [139.77, 35.69]] },
|
|
172
|
+
* 100,
|
|
173
|
+
* { segments: 32 },
|
|
174
|
+
* );
|
|
175
|
+
*
|
|
176
|
+
* // Shrink a polygon by 50 m
|
|
177
|
+
* const shrunk = buffer(
|
|
178
|
+
* {
|
|
179
|
+
* type: 'Polygon',
|
|
180
|
+
* coordinates: [[[139.76, 35.68], [139.77, 35.68], [139.77, 35.69], [139.76, 35.68]]],
|
|
181
|
+
* },
|
|
182
|
+
* -50,
|
|
183
|
+
* );
|
|
184
|
+
* if (shrunk === null) {
|
|
185
|
+
* // Not defined for the input
|
|
186
|
+
* } else if (shrunk.length === 0) {
|
|
187
|
+
* // The whole area vanished
|
|
188
|
+
* }
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export function buffer(geometry, meters, options) {
|
|
192
|
+
if (!Number.isFinite(meters)) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
const segments = normalizeCircleSegments(options?.segments, DEFAULT_BUFFER_SEGMENTS);
|
|
196
|
+
const radius = Math.abs(meters);
|
|
197
|
+
const area = isAreaGeometry(geometry);
|
|
198
|
+
// The erosion of a point or a line is not defined
|
|
199
|
+
if (!area && meters <= 0) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
// A zero distance on a polygon is its normalized form, which needs no offset
|
|
203
|
+
if (area && meters === 0) {
|
|
204
|
+
return unionAll([geometry.coordinates]);
|
|
205
|
+
}
|
|
206
|
+
const lines = collectLines(geometry);
|
|
207
|
+
if (isOutOfScope(lines, radius)) {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
if (!area) {
|
|
211
|
+
return unionAll(lines.flatMap((line) => lineBufferParts(line, radius, segments)));
|
|
212
|
+
}
|
|
213
|
+
const areaCoordinates = geometry.coordinates;
|
|
214
|
+
// The line buffer of the outer and inner rings (a band of distance |meters| from the
|
|
215
|
+
// boundary)
|
|
216
|
+
const boundary = unionAll(lines.flatMap((ring) => lineBufferParts(ring, radius, segments)));
|
|
217
|
+
return meters > 0 ? union(areaCoordinates, boundary) : difference(areaCoordinates, boundary);
|
|
218
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BBox, Coordinate } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a requested number of vertices of a circle
|
|
4
|
+
*
|
|
5
|
+
* The value is rounded down to an integer and clamped to 3-1024. An omitted value and NaN
|
|
6
|
+
* give the default, so no input makes the generation loop run forever or return a ring
|
|
7
|
+
* without positions.
|
|
8
|
+
*
|
|
9
|
+
* @param segments The requested number of vertices
|
|
10
|
+
* @param fallback The number used when it is omitted or NaN
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeCircleSegments(segments: number | undefined, fallback?: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* Approximates a geodesic circle with a closed ring.
|
|
15
|
+
*
|
|
16
|
+
* The vertices come from {@link destinationPoint}, so each lies at the radius from the
|
|
17
|
+
* center at any latitude, up to floating-point rounding; only the straight edges between
|
|
18
|
+
* them fall slightly inside the circle. The first vertex is due north of the center and the
|
|
19
|
+
* ring runs clockwise. The number of vertices is rounded down and clamped to 3-1024; NaN
|
|
20
|
+
* gives 64. A circle that reaches a pole cannot be expressed as a ring in longitude and
|
|
21
|
+
* latitude and is out of scope.
|
|
22
|
+
*
|
|
23
|
+
* @param center The center `[lng, lat]` in degrees
|
|
24
|
+
* @param radiusMeters The radius in meters. 0 gives a ring of identical positions
|
|
25
|
+
* @param segments The number of vertices (64 by default)
|
|
26
|
+
* @returns The ring, `segments + 1` positions `[lng, lat]` with the first repeated at the
|
|
27
|
+
* end. An empty array for a center that is not finite and for a radius that is negative
|
|
28
|
+
* or not finite
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { generateCirclePolygon } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
33
|
+
*
|
|
34
|
+
* const ring = generateCirclePolygon([139.767, 35.681], 500, 32);
|
|
35
|
+
* ring.length; // 33
|
|
36
|
+
* const polygon = [ring]; // Polygon coordinates
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function generateCirclePolygon(center: Coordinate, radiusMeters: number, segments?: number): Coordinate[];
|
|
40
|
+
/**
|
|
41
|
+
* The bounding box of a geodesic circle
|
|
42
|
+
*
|
|
43
|
+
* The north and south extremes lie on the meridian of the center. The east and west extremes
|
|
44
|
+
* are where the circle touches a meridian, at the bearing `acos(tan δ · tan φ)` from the
|
|
45
|
+
* center (δ the angular radius, φ the latitude of the center), which is poleward of due east
|
|
46
|
+
* and west. The box is taken from the points reached at those bearings, so it contains the
|
|
47
|
+
* polygon of {@link generateCirclePolygon} for any number of vertices. A circle that
|
|
48
|
+
* contains a pole spans 360 degrees of longitude from the center and reaches the pole.
|
|
49
|
+
*
|
|
50
|
+
* @param center Center coordinate [lng, lat]
|
|
51
|
+
* @param radiusMeters Radius (meters)
|
|
52
|
+
* @returns [minLng, minLat, maxLng, maxLat]. null for a center that is not finite or a
|
|
53
|
+
* radius that is negative or not finite
|
|
54
|
+
*/
|
|
55
|
+
export declare function circleBoundingBox(center: Coordinate, radiusMeters: number): BBox | null;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Circle generation
|
|
5
|
+
*
|
|
6
|
+
* Approximates a geodesic circle with a polygon (64 vertices by default). Rendering of the
|
|
7
|
+
* Circle feature and the buffer of a point share this implementation. The vertices come
|
|
8
|
+
* from {@link destinationPoint}, the direct problem on the sphere, so every vertex lies at
|
|
9
|
+
* the radius from the center in haversine distance at any latitude; only the straight
|
|
10
|
+
* edges between the vertices fall inside the circle.
|
|
11
|
+
*/
|
|
12
|
+
import { isFiniteCoordinate } from './coords.js';
|
|
13
|
+
import { destinationPoint } from './distance.js';
|
|
14
|
+
import { EARTH_RADIUS_METERS, toDegrees } from './units.js';
|
|
15
|
+
/** The default number of vertices of a circle */
|
|
16
|
+
const DEFAULT_CIRCLE_SEGMENTS = 64;
|
|
17
|
+
/** The lower bound of the number of vertices (fewer than a triangle is not a polygon) */
|
|
18
|
+
const MIN_CIRCLE_SEGMENTS = 3;
|
|
19
|
+
/** The upper bound of the number of vertices */
|
|
20
|
+
const MAX_CIRCLE_SEGMENTS = 1024;
|
|
21
|
+
/**
|
|
22
|
+
* Normalizes a requested number of vertices of a circle
|
|
23
|
+
*
|
|
24
|
+
* The value is rounded down to an integer and clamped to 3-1024. An omitted value and NaN
|
|
25
|
+
* give the default, so no input makes the generation loop run forever or return a ring
|
|
26
|
+
* without positions.
|
|
27
|
+
*
|
|
28
|
+
* @param segments The requested number of vertices
|
|
29
|
+
* @param fallback The number used when it is omitted or NaN
|
|
30
|
+
*/
|
|
31
|
+
export function normalizeCircleSegments(segments, fallback = DEFAULT_CIRCLE_SEGMENTS) {
|
|
32
|
+
const requested = segments === undefined || Number.isNaN(segments) ? fallback : segments;
|
|
33
|
+
return Math.min(MAX_CIRCLE_SEGMENTS, Math.max(MIN_CIRCLE_SEGMENTS, Math.floor(requested)));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Approximates a geodesic circle with a closed ring.
|
|
37
|
+
*
|
|
38
|
+
* The vertices come from {@link destinationPoint}, so each lies at the radius from the
|
|
39
|
+
* center at any latitude, up to floating-point rounding; only the straight edges between
|
|
40
|
+
* them fall slightly inside the circle. The first vertex is due north of the center and the
|
|
41
|
+
* ring runs clockwise. The number of vertices is rounded down and clamped to 3-1024; NaN
|
|
42
|
+
* gives 64. A circle that reaches a pole cannot be expressed as a ring in longitude and
|
|
43
|
+
* latitude and is out of scope.
|
|
44
|
+
*
|
|
45
|
+
* @param center The center `[lng, lat]` in degrees
|
|
46
|
+
* @param radiusMeters The radius in meters. 0 gives a ring of identical positions
|
|
47
|
+
* @param segments The number of vertices (64 by default)
|
|
48
|
+
* @returns The ring, `segments + 1` positions `[lng, lat]` with the first repeated at the
|
|
49
|
+
* end. An empty array for a center that is not finite and for a radius that is negative
|
|
50
|
+
* or not finite
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { generateCirclePolygon } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
55
|
+
*
|
|
56
|
+
* const ring = generateCirclePolygon([139.767, 35.681], 500, 32);
|
|
57
|
+
* ring.length; // 33
|
|
58
|
+
* const polygon = [ring]; // Polygon coordinates
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export function generateCirclePolygon(center, radiusMeters, segments = DEFAULT_CIRCLE_SEGMENTS) {
|
|
62
|
+
if (!isFiniteCoordinate(center) || !Number.isFinite(radiusMeters) || radiusMeters < 0) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
const count = normalizeCircleSegments(segments);
|
|
66
|
+
const coords = [];
|
|
67
|
+
for (let i = 0; i < count; i++) {
|
|
68
|
+
// Divide evenly from 0 to 360 degrees (clockwise with north as 0 degrees)
|
|
69
|
+
const angleDegrees = (360 / count) * i;
|
|
70
|
+
coords.push(destinationPoint(center, radiusMeters, angleDegrees));
|
|
71
|
+
}
|
|
72
|
+
// Append the first point to make the polygon closed
|
|
73
|
+
coords.push(coords[0]);
|
|
74
|
+
return coords;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The bounding box of a geodesic circle
|
|
78
|
+
*
|
|
79
|
+
* The north and south extremes lie on the meridian of the center. The east and west extremes
|
|
80
|
+
* are where the circle touches a meridian, at the bearing `acos(tan δ · tan φ)` from the
|
|
81
|
+
* center (δ the angular radius, φ the latitude of the center), which is poleward of due east
|
|
82
|
+
* and west. The box is taken from the points reached at those bearings, so it contains the
|
|
83
|
+
* polygon of {@link generateCirclePolygon} for any number of vertices. A circle that
|
|
84
|
+
* contains a pole spans 360 degrees of longitude from the center and reaches the pole.
|
|
85
|
+
*
|
|
86
|
+
* @param center Center coordinate [lng, lat]
|
|
87
|
+
* @param radiusMeters Radius (meters)
|
|
88
|
+
* @returns [minLng, minLat, maxLng, maxLat]. null for a center that is not finite or a
|
|
89
|
+
* radius that is negative or not finite
|
|
90
|
+
*/
|
|
91
|
+
export function circleBoundingBox(center, radiusMeters) {
|
|
92
|
+
if (!isFiniteCoordinate(center) || !Number.isFinite(radiusMeters) || radiusMeters < 0) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const [lng, lat] = center;
|
|
96
|
+
const radiusDegrees = toDegrees(radiusMeters / EARTH_RADIUS_METERS);
|
|
97
|
+
const north = lat + radiusDegrees;
|
|
98
|
+
const south = lat - radiusDegrees;
|
|
99
|
+
if (north >= 90 || south <= -90) {
|
|
100
|
+
return [lng - 180, Math.max(-90, south), lng + 180, Math.min(90, north)];
|
|
101
|
+
}
|
|
102
|
+
const tangent = Math.tan(radiusMeters / EARTH_RADIUS_METERS) * Math.tan((lat * Math.PI) / 180);
|
|
103
|
+
const eastBearing = toDegrees(Math.acos(Math.min(1, Math.max(-1, tangent))));
|
|
104
|
+
const east = destinationPoint(center, radiusMeters, eastBearing)[0];
|
|
105
|
+
const west = destinationPoint(center, radiusMeters, 360 - eastBearing)[0];
|
|
106
|
+
return [Math.min(west, lng), south, Math.max(east, lng), north];
|
|
107
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discrimination and normalization of coordinate shapes
|
|
3
|
+
*
|
|
4
|
+
* Shared helpers for the operations that accept both Polygon coordinates and
|
|
5
|
+
* MultiPolygon coordinates.
|
|
6
|
+
*/
|
|
7
|
+
import type { AreaCoordinates, Coordinate, MultiPolygonCoordinates, Ring } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Determines whether polygon coordinates are MultiPolygon coordinates rather than Polygon
|
|
10
|
+
* coordinates.
|
|
11
|
+
*
|
|
12
|
+
* Polygon coordinates are Ring[] and MultiPolygon coordinates are Ring[][]. The first
|
|
13
|
+
* non-empty element at the second level is a position of a ring for a Polygon and a ring
|
|
14
|
+
* for a MultiPolygon, so the two are told apart by whether that element starts with an
|
|
15
|
+
* array. Empty rings and empty parts are skipped, so a MultiPolygon whose first part is
|
|
16
|
+
* empty is still recognized. Coordinates with no position at all are treated as a Polygon.
|
|
17
|
+
*
|
|
18
|
+
* @param coordinates Polygon or MultiPolygon coordinates
|
|
19
|
+
* @returns `true` for MultiPolygon coordinates (a type guard). `false` for Polygon
|
|
20
|
+
* coordinates and for coordinates with no position
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { isMultiPolygonCoordinates } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
25
|
+
*
|
|
26
|
+
* const ring: [number, number][] = [[0, 0], [1, 0], [1, 1], [0, 0]];
|
|
27
|
+
* isMultiPolygonCoordinates([ring]); // false (Polygon)
|
|
28
|
+
* isMultiPolygonCoordinates([[ring]]); // true (MultiPolygon)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function isMultiPolygonCoordinates(coordinates: AreaCoordinates): coordinates is MultiPolygonCoordinates;
|
|
32
|
+
/**
|
|
33
|
+
* Determines whether a value is a coordinate whose longitude and latitude are finite
|
|
34
|
+
* numbers
|
|
35
|
+
*/
|
|
36
|
+
export declare function isFiniteCoordinate(value: unknown): value is Coordinate;
|
|
37
|
+
/**
|
|
38
|
+
* Determines whether a ring can bound an area: at least 3 positions, every one finite
|
|
39
|
+
*
|
|
40
|
+
* A ring that fails this has no area. The functions that take polygons drop such a ring the
|
|
41
|
+
* same way, and drop a whole part whose outer ring fails (its holes then have nothing to be
|
|
42
|
+
* holes of).
|
|
43
|
+
*/
|
|
44
|
+
export declare function isUsableRing(ring: Ring): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Keeps only the parts and rings that can bound an area (see {@link isUsableRing})
|
|
47
|
+
*
|
|
48
|
+
* Returns MultiPolygon coordinates. The arrays of the rings that are kept are not copied.
|
|
49
|
+
*/
|
|
50
|
+
export declare function usableAreaParts(coordinates: AreaCoordinates): MultiPolygonCoordinates;
|
|
51
|
+
/**
|
|
52
|
+
* Returns Polygon or MultiPolygon coordinates as MultiPolygon coordinates.
|
|
53
|
+
*
|
|
54
|
+
* The input array is not copied: MultiPolygon coordinates are returned as they are, and
|
|
55
|
+
* Polygon coordinates are wrapped as a single part. Nothing is validated or normalized; use
|
|
56
|
+
* {@link normalizeArea} for that.
|
|
57
|
+
*
|
|
58
|
+
* @param coordinates Polygon or MultiPolygon coordinates
|
|
59
|
+
* @returns MultiPolygon coordinates. An empty array for an empty input
|
|
60
|
+
*/
|
|
61
|
+
export declare function toMultiPolygonCoordinates(coordinates: AreaCoordinates): MultiPolygonCoordinates;
|
|
62
|
+
/**
|
|
63
|
+
* Determines whether a ring is closed, that is whether its first and last positions are
|
|
64
|
+
* equal.
|
|
65
|
+
*
|
|
66
|
+
* The comparison is exact (`===` on longitude and latitude).
|
|
67
|
+
*
|
|
68
|
+
* @param ring A coordinate sequence
|
|
69
|
+
* @returns `true` when the first and last positions are equal. `false` for fewer than 2
|
|
70
|
+
* positions
|
|
71
|
+
*/
|
|
72
|
+
export declare function isRingClosed(ring: Ring): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Closes a ring by appending its first position at the end when needed.
|
|
75
|
+
*
|
|
76
|
+
* @param ring A coordinate sequence
|
|
77
|
+
* @returns A new closed array. The input itself when it is already closed or empty
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* import { closeRing } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
82
|
+
*
|
|
83
|
+
* closeRing([[0, 0], [1, 0], [1, 1]]); // [[0, 0], [1, 0], [1, 1], [0, 0]]
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare function closeRing(ring: Ring): Ring;
|
|
87
|
+
/**
|
|
88
|
+
* Returns every position of Polygon or MultiPolygon coordinates as one flat array.
|
|
89
|
+
*
|
|
90
|
+
* Positions are listed part by part and ring by ring, holes included, closing positions
|
|
91
|
+
* included. Nothing is validated.
|
|
92
|
+
*
|
|
93
|
+
* @param coordinates Polygon or MultiPolygon coordinates
|
|
94
|
+
* @returns A new array of the positions (the position arrays themselves are not copied).
|
|
95
|
+
* An empty array for an empty input
|
|
96
|
+
*/
|
|
97
|
+
export declare function flattenAreaCoordinates(coordinates: AreaCoordinates): Coordinate[];
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Determines whether polygon coordinates are MultiPolygon coordinates rather than Polygon
|
|
5
|
+
* coordinates.
|
|
6
|
+
*
|
|
7
|
+
* Polygon coordinates are Ring[] and MultiPolygon coordinates are Ring[][]. The first
|
|
8
|
+
* non-empty element at the second level is a position of a ring for a Polygon and a ring
|
|
9
|
+
* for a MultiPolygon, so the two are told apart by whether that element starts with an
|
|
10
|
+
* array. Empty rings and empty parts are skipped, so a MultiPolygon whose first part is
|
|
11
|
+
* empty is still recognized. Coordinates with no position at all are treated as a Polygon.
|
|
12
|
+
*
|
|
13
|
+
* @param coordinates Polygon or MultiPolygon coordinates
|
|
14
|
+
* @returns `true` for MultiPolygon coordinates (a type guard). `false` for Polygon
|
|
15
|
+
* coordinates and for coordinates with no position
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { isMultiPolygonCoordinates } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
20
|
+
*
|
|
21
|
+
* const ring: [number, number][] = [[0, 0], [1, 0], [1, 1], [0, 0]];
|
|
22
|
+
* isMultiPolygonCoordinates([ring]); // false (Polygon)
|
|
23
|
+
* isMultiPolygonCoordinates([[ring]]); // true (MultiPolygon)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function isMultiPolygonCoordinates(coordinates) {
|
|
27
|
+
for (const element of coordinates) {
|
|
28
|
+
if (!Array.isArray(element))
|
|
29
|
+
continue;
|
|
30
|
+
for (const item of element) {
|
|
31
|
+
if (Array.isArray(item) && item.length > 0)
|
|
32
|
+
return Array.isArray(item[0]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Determines whether a value is a coordinate whose longitude and latitude are finite
|
|
39
|
+
* numbers
|
|
40
|
+
*/
|
|
41
|
+
export function isFiniteCoordinate(value) {
|
|
42
|
+
return (Array.isArray(value) &&
|
|
43
|
+
value.length >= 2 &&
|
|
44
|
+
typeof value[0] === 'number' &&
|
|
45
|
+
typeof value[1] === 'number' &&
|
|
46
|
+
Number.isFinite(value[0]) &&
|
|
47
|
+
Number.isFinite(value[1]));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Determines whether a ring can bound an area: at least 3 positions, every one finite
|
|
51
|
+
*
|
|
52
|
+
* A ring that fails this has no area. The functions that take polygons drop such a ring the
|
|
53
|
+
* same way, and drop a whole part whose outer ring fails (its holes then have nothing to be
|
|
54
|
+
* holes of).
|
|
55
|
+
*/
|
|
56
|
+
export function isUsableRing(ring) {
|
|
57
|
+
return Array.isArray(ring) && ring.length >= 3 && ring.every(isFiniteCoordinate);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Keeps only the parts and rings that can bound an area (see {@link isUsableRing})
|
|
61
|
+
*
|
|
62
|
+
* Returns MultiPolygon coordinates. The arrays of the rings that are kept are not copied.
|
|
63
|
+
*/
|
|
64
|
+
export function usableAreaParts(coordinates) {
|
|
65
|
+
const result = [];
|
|
66
|
+
for (const polygon of toMultiPolygonCoordinates(coordinates)) {
|
|
67
|
+
if (!Array.isArray(polygon) || polygon.length === 0 || !isUsableRing(polygon[0]))
|
|
68
|
+
continue;
|
|
69
|
+
result.push(polygon.filter(isUsableRing));
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns Polygon or MultiPolygon coordinates as MultiPolygon coordinates.
|
|
75
|
+
*
|
|
76
|
+
* The input array is not copied: MultiPolygon coordinates are returned as they are, and
|
|
77
|
+
* Polygon coordinates are wrapped as a single part. Nothing is validated or normalized; use
|
|
78
|
+
* {@link normalizeArea} for that.
|
|
79
|
+
*
|
|
80
|
+
* @param coordinates Polygon or MultiPolygon coordinates
|
|
81
|
+
* @returns MultiPolygon coordinates. An empty array for an empty input
|
|
82
|
+
*/
|
|
83
|
+
export function toMultiPolygonCoordinates(coordinates) {
|
|
84
|
+
if (coordinates.length === 0) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
if (isMultiPolygonCoordinates(coordinates)) {
|
|
88
|
+
return coordinates;
|
|
89
|
+
}
|
|
90
|
+
return [coordinates];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Determines whether a ring is closed, that is whether its first and last positions are
|
|
94
|
+
* equal.
|
|
95
|
+
*
|
|
96
|
+
* The comparison is exact (`===` on longitude and latitude).
|
|
97
|
+
*
|
|
98
|
+
* @param ring A coordinate sequence
|
|
99
|
+
* @returns `true` when the first and last positions are equal. `false` for fewer than 2
|
|
100
|
+
* positions
|
|
101
|
+
*/
|
|
102
|
+
export function isRingClosed(ring) {
|
|
103
|
+
if (ring.length < 2) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const first = ring[0];
|
|
107
|
+
const last = ring[ring.length - 1];
|
|
108
|
+
return first[0] === last[0] && first[1] === last[1];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Closes a ring by appending its first position at the end when needed.
|
|
112
|
+
*
|
|
113
|
+
* @param ring A coordinate sequence
|
|
114
|
+
* @returns A new closed array. The input itself when it is already closed or empty
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { closeRing } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
119
|
+
*
|
|
120
|
+
* closeRing([[0, 0], [1, 0], [1, 1]]); // [[0, 0], [1, 0], [1, 1], [0, 0]]
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export function closeRing(ring) {
|
|
124
|
+
if (ring.length === 0 || isRingClosed(ring)) {
|
|
125
|
+
return ring;
|
|
126
|
+
}
|
|
127
|
+
return [...ring, ring[0]];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns every position of Polygon or MultiPolygon coordinates as one flat array.
|
|
131
|
+
*
|
|
132
|
+
* Positions are listed part by part and ring by ring, holes included, closing positions
|
|
133
|
+
* included. Nothing is validated.
|
|
134
|
+
*
|
|
135
|
+
* @param coordinates Polygon or MultiPolygon coordinates
|
|
136
|
+
* @returns A new array of the positions (the position arrays themselves are not copied).
|
|
137
|
+
* An empty array for an empty input
|
|
138
|
+
*/
|
|
139
|
+
export function flattenAreaCoordinates(coordinates) {
|
|
140
|
+
const result = [];
|
|
141
|
+
for (const polygon of toMultiPolygonCoordinates(coordinates)) {
|
|
142
|
+
for (const ring of polygon) {
|
|
143
|
+
for (const coordinate of ring) {
|
|
144
|
+
result.push(coordinate);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|