@sakuzu/maplibre-gl-draw 1.0.0 → 2.1.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 +1109 -2
- package/README.ja.md +83 -50
- package/README.md +89 -53
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/api/datasets.d.ts +263 -0
- package/dist/api/document.d.ts +66 -0
- package/dist/api/draw.d.ts +137 -0
- package/dist/api/draw.js +20 -0
- package/dist/api/drawing.d.ts +87 -0
- package/dist/api/errors.d.ts +35 -0
- package/dist/api/errors.js +35 -0
- package/dist/api/events.d.ts +316 -0
- package/dist/api/extension/context.d.ts +247 -0
- package/dist/api/extension/feature-type.d.ts +129 -0
- package/dist/api/extension/mode.d.ts +123 -0
- package/dist/api/extension/plugin.d.ts +51 -0
- package/dist/api/extension/plugin.js +3 -0
- package/dist/api/extension/provider.d.ts +119 -0
- package/dist/api/extension/provider.js +3 -0
- package/dist/api/extension/render.d.ts +176 -0
- package/dist/api/extension/render.js +3 -0
- package/dist/api/extension/store.d.ts +190 -0
- package/dist/api/extension/store.js +3 -0
- package/dist/api/extensions.d.ts +306 -0
- package/dist/api/extensions.js +3 -0
- package/dist/api/features.d.ts +188 -0
- package/dist/api/features.js +3 -0
- package/dist/api/groups.d.ts +111 -0
- package/dist/api/groups.js +3 -0
- package/dist/api/hidden.d.ts +45 -0
- package/dist/api/hidden.js +3 -0
- package/dist/api/impl/adapters.js +463 -0
- package/dist/api/impl/contexts.js +466 -0
- package/dist/api/impl/create-draw.js +124 -0
- package/dist/api/impl/datasets.js +405 -0
- package/dist/api/impl/destroy-guard.js +74 -0
- package/dist/api/impl/document.js +280 -0
- package/dist/api/impl/drawing.js +180 -0
- package/dist/api/impl/engine-context.d.ts +7 -0
- package/dist/api/{context.js → impl/engine-context.js} +49 -38
- package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
- package/dist/api/impl/events.js +423 -0
- package/dist/api/impl/extension-host.js +364 -0
- package/dist/api/impl/extensions.js +229 -0
- package/dist/api/impl/features.js +445 -0
- package/dist/api/impl/geometry/apply.d.ts +32 -0
- package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
- package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
- package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
- package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
- package/dist/api/{geometry → impl/geometry}/split.js +10 -21
- package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
- package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
- package/dist/api/impl/geometry/types.js +3 -0
- package/dist/api/impl/groups.d.ts +3 -0
- package/dist/api/impl/groups.js +268 -0
- package/dist/api/impl/hidden.js +60 -0
- package/dist/api/impl/import-export/constants.d.ts +22 -0
- package/dist/api/impl/import-export/constants.js +24 -0
- package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
- package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
- package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
- package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
- package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
- package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
- package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
- package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
- package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
- package/dist/api/impl/import-export/image-import.d.ts +16 -0
- package/dist/api/impl/import-export/image-import.js +73 -0
- package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
- package/dist/api/impl/import-export/legacy-image-style.js +49 -0
- package/dist/api/impl/import-export/native-format.d.ts +14 -0
- package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
- package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
- package/dist/api/impl/import-export/native-upgrade.js +139 -0
- package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
- package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
- package/dist/api/impl/import-export/style-validation.d.ts +24 -0
- package/dist/api/impl/import-export/style-validation.js +86 -0
- package/dist/api/impl/import-export/types.d.ts +52 -0
- package/dist/api/impl/import-export/types.js +3 -0
- package/dist/api/impl/input.js +180 -0
- package/dist/api/impl/layers.js +307 -0
- package/dist/api/impl/metadata.d.ts +1 -0
- package/dist/api/impl/metadata.js +22 -0
- package/dist/api/impl/options.d.ts +1 -0
- package/dist/api/impl/options.js +851 -0
- package/dist/api/impl/placement.d.ts +1 -0
- package/dist/api/impl/placement.js +138 -0
- package/dist/api/impl/render-context.d.ts +13 -0
- package/dist/api/impl/render-context.js +272 -0
- package/dist/api/impl/rows.d.ts +1 -0
- package/dist/api/impl/rows.js +46 -0
- package/dist/api/impl/selection.d.ts +1 -0
- package/dist/api/impl/selection.js +186 -0
- package/dist/api/impl/shared.d.ts +64 -0
- package/dist/api/impl/shared.js +178 -0
- package/dist/api/impl/validate-extension.d.ts +1 -0
- package/dist/api/impl/validate-extension.js +159 -0
- package/dist/api/layers.d.ts +130 -0
- package/dist/api/layers.js +3 -0
- package/dist/api/metadata.d.ts +18 -0
- package/dist/api/metadata.js +3 -0
- package/dist/api/model.d.ts +487 -0
- package/dist/api/model.js +47 -0
- package/dist/api/options.d.ts +466 -0
- package/dist/api/options.js +3 -0
- package/dist/api/selection.d.ts +94 -0
- package/dist/api/selection.js +3 -0
- package/dist/api/state.d.ts +155 -0
- package/dist/api/state.js +12 -0
- package/dist/{display → dataset}/chunk.d.ts +1 -1
- package/dist/{display → dataset}/chunk.js +4 -3
- package/dist/{display → dataset}/dataset.js +21 -21
- package/dist/dataset/interaction.d.ts +1 -0
- package/dist/{display → dataset}/interaction.js +18 -6
- package/dist/dataset/manager.d.ts +1 -0
- package/dist/dataset/provider.d.ts +1 -0
- package/dist/{display → dataset}/retained.d.ts +1 -1
- package/dist/{display → dataset}/retained.js +8 -7
- package/dist/dataset/source.d.ts +1 -0
- package/dist/{display → dataset}/source.js +17 -4
- package/dist/dataset/spatial.d.ts +1 -0
- package/dist/{display → dataset}/spatial.js +1 -1
- package/dist/dataset/style.d.ts +1 -0
- package/dist/{display → dataset}/style.js +1 -1
- package/dist/dataset/table-source.d.ts +1 -0
- package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
- package/dist/{display → dataset}/thinning.d.ts +0 -10
- package/dist/{display → dataset}/thinning.js +3 -2
- package/dist/dataset/triangulation.d.ts +1 -0
- package/dist/{display → dataset}/triangulation.js +0 -0
- package/dist/{display → dataset}/types.d.ts +84 -121
- package/dist/dataset/types.js +61 -0
- package/dist/dispatcher/hit-test/box-strategies.js +13 -13
- package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
- package/dist/dispatcher/hit-test/globe-shape.js +5 -4
- package/dist/dispatcher/hit-test/service.d.ts +17 -0
- package/dist/dispatcher/hit-test/service.js +80 -16
- package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
- package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
- package/dist/dispatcher/hit-test/strategies/image.js +6 -18
- package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
- package/dist/dispatcher/hit-test/strategies/line.js +9 -2
- package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
- package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
- package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
- package/dist/dispatcher/hit-test/strategies/point.js +8 -4
- package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
- package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
- package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
- package/dist/dispatcher/input-router.js +154 -70
- package/dist/dispatcher/normalizer.js +25 -4
- package/dist/dispatcher/types.d.ts +6 -1
- package/dist/extension/feature-handler.d.ts +1 -182
- package/dist/extension/index.d.ts +4 -7
- package/dist/extension/renderers.d.ts +1 -208
- package/dist/geometry/angle.d.ts +0 -8
- package/dist/geometry/angle.js +0 -8
- package/dist/geometry/bbox.d.ts +4 -12
- package/dist/geometry/bbox.js +4 -12
- package/dist/geometry/boolean.d.ts +0 -51
- package/dist/geometry/boolean.js +0 -51
- package/dist/geometry/buffer.d.ts +0 -26
- package/dist/geometry/buffer.js +0 -26
- package/dist/geometry/circle.d.ts +0 -9
- package/dist/geometry/circle.js +0 -9
- package/dist/geometry/coords.d.ts +0 -16
- package/dist/geometry/coords.js +0 -16
- package/dist/geometry/distance.d.ts +0 -24
- package/dist/geometry/distance.js +0 -24
- package/dist/geometry/errors.d.ts +21 -36
- package/dist/geometry/errors.js +49 -29
- package/dist/geometry/geojson.d.ts +85 -0
- package/dist/geometry/geojson.js +173 -0
- package/dist/geometry/index.d.ts +38 -23
- package/dist/geometry/index.js +43 -31
- package/dist/geometry/measure.d.ts +0 -27
- package/dist/geometry/measure.js +0 -27
- package/dist/geometry/predicates.d.ts +0 -9
- package/dist/geometry/predicates.js +0 -9
- package/dist/geometry/public-bounds.d.ts +26 -0
- package/dist/geometry/public-bounds.js +30 -0
- package/dist/geometry/public-combine.d.ts +78 -0
- package/dist/geometry/public-combine.js +82 -0
- package/dist/geometry/public-create.d.ts +54 -0
- package/dist/geometry/public-create.js +70 -0
- package/dist/geometry/public-measure.d.ts +170 -0
- package/dist/geometry/public-measure.js +283 -0
- package/dist/geometry/public-predicates.d.ts +54 -0
- package/dist/geometry/public-predicates.js +144 -0
- package/dist/geometry/public-repair.d.ts +75 -0
- package/dist/geometry/public-repair.js +77 -0
- package/dist/geometry/simplify.d.ts +0 -7
- package/dist/geometry/simplify.js +0 -7
- package/dist/geometry/split.d.ts +0 -20
- package/dist/geometry/split.js +0 -20
- package/dist/geometry/units.d.ts +20 -12
- package/dist/geometry/units.js +20 -12
- package/dist/index.d.ts +66 -66
- package/dist/index.js +6 -18
- package/dist/messages.d.ts +7 -7
- package/dist/modes/draw/circle.js +83 -207
- package/dist/modes/draw/commit-layer.d.ts +5 -16
- package/dist/modes/draw/commit-layer.js +2 -13
- package/dist/modes/draw/freehand.js +108 -246
- package/dist/modes/draw/image.js +4 -2
- package/dist/modes/draw/index.d.ts +5 -5
- package/dist/modes/draw/index.js +5 -5
- package/dist/modes/draw/line.js +18 -354
- package/dist/modes/draw/point.js +29 -78
- package/dist/modes/draw/polygon.js +23 -368
- package/dist/modes/draw/trace-support.d.ts +43 -36
- package/dist/modes/draw/trace-support.js +95 -98
- package/dist/modes/draw/vertex-drawing.d.ts +1 -0
- package/dist/modes/draw/vertex-drawing.js +176 -0
- package/dist/modes/handler.d.ts +1 -285
- package/dist/modes/manager.d.ts +2 -2
- package/dist/modes/manager.js +3 -0
- package/dist/modes/select/box-selection.d.ts +3 -3
- package/dist/modes/select/box-selection.js +2 -1
- package/dist/modes/select/click-handler.d.ts +5 -5
- package/dist/modes/select/click-handler.js +22 -20
- package/dist/modes/select/cursor-handler.d.ts +2 -2
- package/dist/modes/select/drag/intermediate-writes.js +1 -1
- package/dist/modes/select/drag/move.js +3 -3
- package/dist/modes/select/drag/operation.d.ts +3 -3
- package/dist/modes/select/drag/radius.js +5 -4
- package/dist/modes/select/drag/transform.d.ts +2 -2
- package/dist/modes/select/drag/transform.js +11 -5
- package/dist/modes/select/drag/vertex.d.ts +2 -2
- package/dist/modes/select/drag/vertex.js +13 -8
- package/dist/modes/select/drag-handler.js +44 -25
- package/dist/modes/select/mode.js +17 -17
- package/dist/modes/select/shortcut-handler.d.ts +8 -8
- package/dist/modes/select/shortcut-handler.js +9 -7
- package/dist/operations/layer-operations.js +29 -168
- package/dist/operations/resize.d.ts +2 -2
- package/dist/operations/resize.js +5 -5
- package/dist/operations/rotate.js +5 -5
- package/dist/operations/selection-operations.d.ts +16 -1
- package/dist/operations/selection-operations.js +28 -13
- package/dist/operations/shared-vertex.js +4 -2
- package/dist/operations/trace-graph.d.ts +0 -18
- package/dist/operations/trace-graph.js +0 -18
- package/dist/operations/vertex.js +36 -35
- package/dist/shared/color.d.ts +1 -0
- package/dist/shared/color.js +245 -0
- package/dist/shared/config/constants.d.ts +1 -54
- package/dist/shared/config/constants.js +1 -58
- package/dist/shared/config/feature-style.d.ts +16 -13
- package/dist/shared/config/feature-style.js +9 -0
- package/dist/shared/config/rendering.d.ts +3 -3
- package/dist/shared/config/selection-highlight.d.ts +0 -15
- package/dist/shared/config/selection-highlight.js +4 -7
- package/dist/shared/config/selection.d.ts +2 -32
- package/dist/shared/config/selection.js +0 -18
- package/dist/shared/config/topology.d.ts +2 -2
- package/dist/shared/config/trace.d.ts +4 -4
- package/dist/shared/math/angle.d.ts +1 -1
- package/dist/shared/math/angle.js +1 -1
- package/dist/shared/math/circle.d.ts +1 -1
- package/dist/shared/math/circle.js +1 -1
- package/dist/shared/math/distance.d.ts +2 -1
- package/dist/shared/math/distance.js +3 -2
- package/dist/shared/math/index.d.ts +1 -1
- package/dist/shared/math/index.js +1 -1
- package/dist/shared/math/transform.d.ts +23 -0
- package/dist/shared/math/transform.js +47 -28
- package/dist/shared/properties.d.ts +18 -0
- package/dist/shared/properties.js +129 -0
- package/dist/shared/types/events.d.ts +15 -7
- package/dist/shared/types/model.d.ts +109 -159
- package/dist/shared/types/style.d.ts +1 -1
- package/dist/shared/utils/color.d.ts +2 -36
- package/dist/shared/utils/color.js +13 -70
- package/dist/shared/utils/coordinates.d.ts +30 -4
- package/dist/shared/utils/coordinates.js +56 -10
- package/dist/shared/utils/event-emitter.d.ts +1 -262
- package/dist/shared/utils/event-emitter.js +4 -3
- package/dist/shared/utils/feature-bbox.js +8 -7
- package/dist/shared/utils/feature-segments.js +5 -4
- package/dist/shared/utils/image.d.ts +0 -4
- package/dist/shared/utils/image.js +0 -6
- package/dist/shared/utils/name-generator.d.ts +14 -20
- package/dist/shared/utils/name-generator.js +20 -3
- package/dist/shared/utils/pixel-ratio.d.ts +9 -3
- package/dist/shared/utils/pixel-ratio.js +13 -4
- package/dist/shared/utils/property.d.ts +7 -50
- package/dist/shared/utils/property.js +22 -87
- package/dist/snapping/custom-targets.js +21 -4
- package/dist/snapping/indicator.js +20 -11
- package/dist/snapping/providers/display.d.ts +6 -1
- package/dist/snapping/providers/display.js +2 -1
- package/dist/snapping/providers/guide.d.ts +3 -43
- package/dist/snapping/providers/guide.js +1 -44
- package/dist/snapping/providers/intersection.js +1 -1
- package/dist/snapping/providers/store.js +3 -3
- package/dist/snapping/service.js +18 -7
- package/dist/snapping/types.d.ts +9 -35
- package/dist/store/draw-store.js +233 -142
- package/dist/store/local-visibility.d.ts +11 -6
- package/dist/store/local-visibility.js +38 -7
- package/dist/store/lock.d.ts +0 -6
- package/dist/store/lock.js +0 -6
- package/dist/store/memory/change-bus.d.ts +3 -3
- package/dist/store/memory/change-bus.js +12 -0
- package/dist/store/memory/file-store.d.ts +2 -2
- package/dist/store/memory/ui-state.d.ts +1 -51
- package/dist/store/memory/ui-state.js +122 -134
- package/dist/store/memory.d.ts +1 -8
- package/dist/store/memory.js +249 -45
- package/dist/store/ordering.d.ts +9 -0
- package/dist/store/ordering.js +17 -0
- package/dist/store/spatial/spatial-index.d.ts +1 -1
- package/dist/store/spatial/spatial-index.js +1 -1
- package/dist/store/spatial/store-spatial-index.d.ts +3 -1
- package/dist/store/spatial/store-spatial-index.js +9 -3
- package/dist/store/store.d.ts +66 -107
- package/dist/store/types.d.ts +1 -1
- package/dist/store/writable-layer.d.ts +1 -1
- package/dist/store/writable-layer.js +2 -2
- package/dist/table/builder.d.ts +83 -0
- package/dist/table/builder.js +381 -0
- package/dist/table/index.d.ts +37 -0
- package/dist/table/index.js +5 -0
- package/dist/table/packed-rtree.d.ts +1 -0
- package/dist/{display → table}/packed-rtree.js +1 -1
- package/dist/table/partition.d.ts +1 -0
- package/dist/{display → table}/partition.js +3 -3
- package/dist/table/prepare.d.ts +44 -0
- package/dist/table/prepare.js +136 -0
- package/dist/table/table.d.ts +1 -0
- package/dist/{display/columnar → table}/table.js +29 -25
- package/dist/{display/columnar → table}/types.d.ts +68 -72
- package/dist/table/types.js +3 -0
- package/dist/view/coordinator.js +4 -3
- package/dist/view/feature-companion.d.ts +13 -7
- package/dist/view/feature-companion.js +11 -3
- package/dist/view/globe-subdivision.js +3 -3
- package/dist/view/layer/attach.d.ts +12 -6
- package/dist/view/layer/attach.js +86 -10
- package/dist/view/layer/custom-layer.js +40 -11
- package/dist/view/layer/display-list.js +2 -1
- package/dist/view/layer/drape-planner.d.ts +2 -2
- package/dist/view/layer/frame-render.d.ts +3 -3
- package/dist/view/layer/frame-render.js +7 -2
- package/dist/view/layer/frame-state.d.ts +6 -6
- package/dist/view/layer/index.d.ts +2 -2
- package/dist/view/layer/index.js +1 -1
- package/dist/view/layer/render.d.ts +4 -4
- package/dist/view/layer/render.js +3 -8
- package/dist/view/layer/renderers.d.ts +2 -2
- package/dist/view/layer/renderers.js +1 -1
- package/dist/view/layer/slot-manager.d.ts +2 -2
- package/dist/view/layer/slot-manager.js +4 -4
- package/dist/view/layer/slots.d.ts +2 -2
- package/dist/view/layer/slots.js +1 -1
- package/dist/view/layer/store-retained-bbox.js +3 -2
- package/dist/view/layer/store-retained-classify.d.ts +5 -7
- package/dist/view/layer/store-retained-classify.js +19 -7
- package/dist/view/layer/store-retained-collect.js +8 -7
- package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
- package/dist/view/layer/store-retained-coord-patch.js +13 -4
- package/dist/view/layer/store-retained-immediate.d.ts +3 -3
- package/dist/view/layer/store-retained-immediate.js +3 -8
- package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
- package/dist/view/layer/store-retained.d.ts +2 -2
- package/dist/view/layer/store-retained.js +1 -1
- package/dist/view/renderers/batch-manager.js +8 -7
- package/dist/view/renderers/drawer.js +21 -15
- package/dist/view/renderers/image.js +13 -39
- package/dist/view/renderers/line/line-types.d.ts +3 -3
- package/dist/view/renderers/line/sdf-line.js +3 -1
- package/dist/view/renderers/point/billboard-depth.js +1 -1
- package/dist/view/renderers/point/point-instance.js +1 -1
- package/dist/view/renderers/point/point-shape.js +2 -2
- package/dist/view/renderers/point/point-style.js +48 -4
- package/dist/view/renderers/polygon/batch.js +1 -2
- package/dist/view/renderers/polygon/fill.js +3 -1
- package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
- package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
- package/dist/view/renderers/stroke.js +3 -1
- package/dist/view/shaders/helpers.d.ts +2 -42
- package/dist/view/shaders/helpers.js +0 -6
- package/dist/view/shaders/projection.d.ts +15 -7
- package/dist/view/shaders/projection.js +23 -6
- package/dist/view/shaders/quad.d.ts +16 -12
- package/dist/view/shaders/quad.js +34 -13
- package/dist/view/style-rule.d.ts +5 -42
- package/dist/view/style-rule.js +20 -44
- package/dist/view/terrain/binding.d.ts +1 -0
- package/dist/view/terrain/binding.js +29 -0
- package/dist/view/terrain/context.d.ts +3 -4
- package/dist/view/terrain/context.js +4 -5
- package/dist/view/terrain/drape/geometry.js +1 -1
- package/dist/view/terrain/drape/pass.d.ts +1 -1
- package/dist/view/terrain/drape/pass.js +8 -7
- package/dist/view/terrain/polygon.d.ts +9 -5
- package/dist/view/terrain/polygon.js +16 -2
- package/dist/view/terrain/state.d.ts +1 -1
- package/dist/view/terrain/state.js +1 -1
- package/dist/view/terrain/tessellation.d.ts +2 -2
- package/dist/view/terrain/tessellation.js +1 -1
- package/dist/view/ui/auxiliary-handles.d.ts +6 -29
- package/dist/view/ui/bounds.js +8 -12
- package/dist/view/ui/handle-test.js +2 -2
- package/dist/view/ui/handle-thinning.js +17 -17
- package/dist/view/ui/handles.js +21 -13
- package/dist/view/ui/helper.d.ts +1 -1
- package/dist/view/ui/helper.js +1 -1
- package/dist/view/ui/index.d.ts +1 -1
- package/dist/view/ui/selection-scope.js +4 -2
- package/dist/view/ui/selection-ui/bounding-box.js +6 -6
- package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
- package/dist/view/ui/selection-ui/extension-registry.js +70 -7
- package/dist/view/ui/selection-ui/index.d.ts +2 -2
- package/dist/view/ui/selection-ui/index.js +1 -1
- package/dist/view/ui/selection-ui/renderer.js +15 -38
- package/dist/view/ui/selection-ui/types.d.ts +17 -2
- package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
- package/dist/view/ui/selection-ui-drawer.js +63 -2
- package/dist/view/ui/tentative.js +1 -1
- package/dist/webgl/index.d.ts +65 -0
- package/dist/webgl/index.js +62 -0
- package/package.json +38 -15
- package/dist/api/api.d.ts +0 -1259
- package/dist/api/api.js +0 -86
- package/dist/api/context.d.ts +0 -173
- package/dist/api/display-api.js +0 -23
- package/dist/api/event-api.d.ts +0 -13
- package/dist/api/event-api.js +0 -17
- package/dist/api/extension-api.d.ts +0 -46
- package/dist/api/extension-api.js +0 -85
- package/dist/api/feature-api.d.ts +0 -11
- package/dist/api/feature-api.js +0 -101
- package/dist/api/geometry/apply.d.ts +0 -51
- package/dist/api/geometry/boolean.d.ts +0 -28
- package/dist/api/geometry/boolean.js +0 -65
- package/dist/api/geometry/types.d.ts +0 -31
- package/dist/api/geometry-operations.d.ts +0 -162
- package/dist/api/geometry-operations.js +0 -94
- package/dist/api/group-api.d.ts +0 -10
- package/dist/api/group-api.js +0 -78
- package/dist/api/import-export/constants.d.ts +0 -29
- package/dist/api/import-export/constants.js +0 -40
- package/dist/api/import-export/file-name.d.ts +0 -10
- package/dist/api/import-export/file-name.js +0 -20
- package/dist/api/import-export/geojson-export.d.ts +0 -19
- package/dist/api/import-export/image-import.d.ts +0 -12
- package/dist/api/import-export/image-import.js +0 -53
- package/dist/api/import-export/index.d.ts +0 -9
- package/dist/api/import-export/index.js +0 -107
- package/dist/api/import-export/native-format.d.ts +0 -15
- package/dist/api/import-export/style-validation.d.ts +0 -27
- package/dist/api/import-export/style-validation.js +0 -49
- package/dist/api/import-export/types.d.ts +0 -26
- package/dist/api/index.d.ts +0 -15
- package/dist/api/index.js +0 -3
- package/dist/api/input-api.d.ts +0 -158
- package/dist/api/input-api.js +0 -144
- package/dist/api/instance-api.d.ts +0 -38
- package/dist/api/instance-api.js +0 -136
- package/dist/api/layer-api.d.ts +0 -12
- package/dist/api/layer-api.js +0 -62
- package/dist/api/selection-api.d.ts +0 -7
- package/dist/api/selection-api.js +0 -78
- package/dist/api/snapping-api.d.ts +0 -125
- package/dist/api/snapping-api.js +0 -50
- package/dist/api/topology-api.d.ts +0 -30
- package/dist/api/topology-api.js +0 -16
- package/dist/api/tracing-api.d.ts +0 -31
- package/dist/api/tracing-api.js +0 -16
- package/dist/dispatcher/hit-test/index.d.ts +0 -14
- package/dist/dispatcher/hit-test/index.js +0 -9
- package/dist/dispatcher/index.d.ts +0 -15
- package/dist/dispatcher/index.js +0 -3
- package/dist/display/columnar/index.d.ts +0 -12
- package/dist/display/columnar/index.js +0 -13
- package/dist/display/columnar/prepare.d.ts +0 -42
- package/dist/display/columnar/prepare.js +0 -116
- package/dist/display/index.d.ts +0 -13
- package/dist/display/types.js +0 -43
- package/dist/maplibre-gl-draw.d.ts +0 -47
- package/dist/modes/cursor.js +0 -72
- package/dist/modes/index.d.ts +0 -7
- package/dist/operations/index.d.ts +0 -9
- package/dist/operations/index.js +0 -3
- package/dist/plugins/index.d.ts +0 -10
- package/dist/plugins/mutation-hooks.d.ts +0 -28
- package/dist/plugins/mutation-hooks.js +0 -84
- package/dist/plugins/plugin-context.js +0 -367
- package/dist/plugins/plugin-manager.d.ts +0 -103
- package/dist/plugins/plugin-manager.js +0 -316
- package/dist/plugins/plugin.d.ts +0 -529
- package/dist/shared/config/index.d.ts +0 -17
- package/dist/shared/config/index.js +0 -8
- package/dist/shared/utils/index.d.ts +0 -15
- package/dist/shared/utils/index.js +0 -24
- package/dist/snapping/index.d.ts +0 -14
- package/dist/snapping/index.js +0 -4
- package/dist/store/change-merger.js +0 -102
- package/dist/store/event-bridge.js +0 -161
- package/dist/store/index.d.ts +0 -12
- package/dist/store/index.js +0 -4
- package/dist/view/index.d.ts +0 -47
- package/dist/view/index.js +0 -20
- /package/dist/api/{geometry/types.js → datasets.js} +0 -0
- /package/dist/api/{import-export/types.js → document.js} +0 -0
- /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
- /package/dist/{display/index.js → api/events.js} +0 -0
- /package/dist/{modes/index.js → api/extension/context.js} +0 -0
- /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
- /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
- /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
- /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
- /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
- /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
- /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
- /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
- /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
- /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
- /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
- /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
- /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
- /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
- /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
- /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
- /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
- /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
- /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
- /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
- /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
- /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
- /package/dist/{display → dataset}/chunk-set.js +0 -0
- /package/dist/{display → dataset}/dataset.d.ts +0 -0
- /package/dist/{display → dataset}/manager.js +0 -0
- /package/dist/{display → dataset}/provider.js +0 -0
- /package/dist/{display → dataset}/selection.d.ts +0 -0
- /package/dist/{display → dataset}/selection.js +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { differenceAll, intersectionAll, unionAll } from './boolean.js';
|
|
4
|
+
import { withOperation } from './errors.js';
|
|
5
|
+
import { areaOf, areasOf, lineOf, toAreaGeometry } from './geojson.js';
|
|
6
|
+
import { splitArea } from './split.js';
|
|
7
|
+
/**
|
|
8
|
+
* Returns the union of polygons.
|
|
9
|
+
*
|
|
10
|
+
* @param polygons The Polygons and MultiPolygons, or features whose geometry is one;
|
|
11
|
+
* coordinates in degrees. Rings with fewer than 3 positions or a position that is not finite
|
|
12
|
+
* are left out
|
|
13
|
+
* @returns A Polygon, or a MultiPolygon when the union falls apart, with self-intersections
|
|
14
|
+
* resolved and the rings oriented as RFC 7946 recommends. null when nothing has an area
|
|
15
|
+
* @throws {@link GeometryError} (`invalid-input`) when an element is not a Polygon or a
|
|
16
|
+
* MultiPolygon, and (`engine-failure`) when the boolean operation fails
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { union } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
21
|
+
*
|
|
22
|
+
* union([
|
|
23
|
+
* { type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]] },
|
|
24
|
+
* { type: 'Polygon', coordinates: [[[0.5, 0], [1.5, 0], [1.5, 1], [0.5, 1], [0.5, 0]]] },
|
|
25
|
+
* ]);
|
|
26
|
+
* // { type: 'Polygon', coordinates: [[[0, 0], [1.5, 0], [1.5, 1], [0, 1], [0, 0]]] }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function union(polygons) {
|
|
30
|
+
const inputs = areasOf(polygons, 'union');
|
|
31
|
+
return withOperation('union', () => toAreaGeometry(unionAll(inputs)));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns the part that polygons have in common.
|
|
35
|
+
*
|
|
36
|
+
* @param polygons The Polygons and MultiPolygons, or features whose geometry is one;
|
|
37
|
+
* coordinates in degrees
|
|
38
|
+
* @returns A Polygon or a MultiPolygon in the form {@link union} returns. null when the
|
|
39
|
+
* polygons share no area (touching boundaries included), when one has no area, and for an
|
|
40
|
+
* empty array
|
|
41
|
+
* @throws {@link GeometryError} (`invalid-input`) when an element is not a Polygon or a
|
|
42
|
+
* MultiPolygon, and (`engine-failure`) when the boolean operation fails
|
|
43
|
+
*/
|
|
44
|
+
export function intersection(polygons) {
|
|
45
|
+
const inputs = areasOf(polygons, 'intersection');
|
|
46
|
+
return withOperation('intersection', () => toAreaGeometry(intersectionAll(inputs)));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns a polygon with other polygons removed from it.
|
|
50
|
+
*
|
|
51
|
+
* @param subject The Polygon or MultiPolygon to remove from, or a feature whose geometry is
|
|
52
|
+
* one; coordinates in degrees
|
|
53
|
+
* @param others The Polygons and MultiPolygons to remove, or features whose geometry is one;
|
|
54
|
+
* coordinates in degrees
|
|
55
|
+
* @returns A Polygon or a MultiPolygon in the form {@link union} returns; a removed area inside
|
|
56
|
+
* the subject becomes a hole. null when nothing remains
|
|
57
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not a Polygon or a
|
|
58
|
+
* MultiPolygon, and (`engine-failure`) when the boolean operation fails
|
|
59
|
+
*/
|
|
60
|
+
export function difference(subject, others) {
|
|
61
|
+
const left = areaOf(subject, 'difference');
|
|
62
|
+
const right = areasOf(others, 'difference');
|
|
63
|
+
return withOperation('difference', () => toAreaGeometry(differenceAll(left, right)));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Cuts a polygon with a line and returns the pieces.
|
|
67
|
+
*
|
|
68
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
69
|
+
* in degrees
|
|
70
|
+
* @param line The cutting LineString, or a feature whose geometry is one; coordinates in
|
|
71
|
+
* degrees. A stretch that runs along the boundary does not cut, and positions closer than
|
|
72
|
+
* 1e-9 degrees count as one
|
|
73
|
+
* @returns One Polygon per piece, holes kept. When the line does not cut across, the polygon
|
|
74
|
+
* itself (one Polygon per part of a MultiPolygon). An empty array when it has no area
|
|
75
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not of the expected
|
|
76
|
+
* type, and (`engine-failure`) when the boolean operation fails
|
|
77
|
+
*/
|
|
78
|
+
export function split(polygon, line) {
|
|
79
|
+
const area = areaOf(polygon, 'split');
|
|
80
|
+
const path = lineOf(line, 'split');
|
|
81
|
+
return withOperation('split', () => splitArea(area, path).flatMap((piece) => piece.map((coordinates) => ({ type: 'Polygon', coordinates }))));
|
|
82
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create: the public functions that build polygons from distances in meters
|
|
3
|
+
*/
|
|
4
|
+
import type { Geometry, MultiPolygon, Point, Polygon, Position } from 'geojson';
|
|
5
|
+
/**
|
|
6
|
+
* Returns a polygon that approximates the geodesic circle of a radius in meters around a
|
|
7
|
+
* center.
|
|
8
|
+
*
|
|
9
|
+
* @param center The center, a position `[lng, lat]` in degrees or a Point
|
|
10
|
+
* @param radiusMeters The radius in meters, 0 or more. Every vertex lies at this great-circle
|
|
11
|
+
* distance from the center
|
|
12
|
+
* @param options `segments`, the number of vertices (64 by default, rounded down and clamped
|
|
13
|
+
* to 3-1024)
|
|
14
|
+
* @returns The Polygon, its ring starting due north of the center and running
|
|
15
|
+
* counter-clockwise, with the first position repeated at the end
|
|
16
|
+
* @throws {@link GeometryError} (`invalid-input`) when the center is not a position or a
|
|
17
|
+
* Point or is not finite, and when the radius is negative or not finite
|
|
18
|
+
*/
|
|
19
|
+
export declare function circle(center: Position | Point, radiusMeters: number, options?: {
|
|
20
|
+
segments?: number;
|
|
21
|
+
}): Polygon;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the area within a distance in meters of a geometry, or a polygon shrunk by it when
|
|
24
|
+
* the distance is negative.
|
|
25
|
+
*
|
|
26
|
+
* @param geometry The geometry, or a feature whose geometry it is; coordinates in degrees. The
|
|
27
|
+
* members of a GeometryCollection are buffered one by one and the results merged
|
|
28
|
+
* @param distanceMeters The distance in meters. A negative distance shrinks a polygon and
|
|
29
|
+
* leaves nothing of a point or a line
|
|
30
|
+
* @param options `segments`, the number of segments of each circle (64 by default, rounded
|
|
31
|
+
* down and clamped to 3-1024)
|
|
32
|
+
* @returns A Polygon, or a MultiPolygon when the area falls apart. null when nothing remains,
|
|
33
|
+
* and when a vertex is so close to a pole or an edge so long in longitude (over 180 degrees)
|
|
34
|
+
* that the area cannot be drawn in longitude and latitude
|
|
35
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a geometry or a
|
|
36
|
+
* feature with one and when the distance is not a finite number, and (`engine-failure`)
|
|
37
|
+
* when merging the parts fails
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { buffer } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
42
|
+
*
|
|
43
|
+
* // The area within 100 m of a road
|
|
44
|
+
* const corridor = buffer(
|
|
45
|
+
* { type: 'LineString', coordinates: [[139.76, 35.68], [139.77, 35.69]] },
|
|
46
|
+
* 100,
|
|
47
|
+
* );
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function buffer(geometry: Geometry | {
|
|
51
|
+
readonly geometry: Geometry;
|
|
52
|
+
}, distanceMeters: number, options?: {
|
|
53
|
+
segments?: number;
|
|
54
|
+
}): Polygon | MultiPolygon | null;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { unionAll } from './boolean.js';
|
|
4
|
+
import { buffer as bufferCoordinates } from './buffer.js';
|
|
5
|
+
import { generateCirclePolygon } from './circle.js';
|
|
6
|
+
import { invalidInput, withOperation } from './errors.js';
|
|
7
|
+
import { geometryOf, positionOf, toAreaGeometry, toPosition } from './geojson.js';
|
|
8
|
+
/**
|
|
9
|
+
* Returns a polygon that approximates the geodesic circle of a radius in meters around a
|
|
10
|
+
* center.
|
|
11
|
+
*
|
|
12
|
+
* @param center The center, a position `[lng, lat]` in degrees or a Point
|
|
13
|
+
* @param radiusMeters The radius in meters, 0 or more. Every vertex lies at this great-circle
|
|
14
|
+
* distance from the center
|
|
15
|
+
* @param options `segments`, the number of vertices (64 by default, rounded down and clamped
|
|
16
|
+
* to 3-1024)
|
|
17
|
+
* @returns The Polygon, its ring starting due north of the center and running
|
|
18
|
+
* counter-clockwise, with the first position repeated at the end
|
|
19
|
+
* @throws {@link GeometryError} (`invalid-input`) when the center is not a position or a
|
|
20
|
+
* Point or is not finite, and when the radius is negative or not finite
|
|
21
|
+
*/
|
|
22
|
+
export function circle(center, radiusMeters, options) {
|
|
23
|
+
const ring = generateCirclePolygon(positionOf(center, 'circle'), radiusMeters, options?.segments);
|
|
24
|
+
if (ring.length === 0) {
|
|
25
|
+
throw invalidInput('circle', 'the center or the radius is not a finite number');
|
|
26
|
+
}
|
|
27
|
+
return { type: 'Polygon', coordinates: [ring.map(toPosition).reverse()] };
|
|
28
|
+
}
|
|
29
|
+
/** The buffer of a geometry as MultiPolygon coordinates, each member of a collection alone */
|
|
30
|
+
function bufferOf(geometry, distanceMeters, segments) {
|
|
31
|
+
if (geometry.type === 'GeometryCollection') {
|
|
32
|
+
return unionAll(geometry.geometries.map((member) => bufferOf(geometryOf(member, 'buffer'), distanceMeters, segments)));
|
|
33
|
+
}
|
|
34
|
+
return bufferCoordinates(geometry, distanceMeters, { segments }) ?? [];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the area within a distance in meters of a geometry, or a polygon shrunk by it when
|
|
38
|
+
* the distance is negative.
|
|
39
|
+
*
|
|
40
|
+
* @param geometry The geometry, or a feature whose geometry it is; coordinates in degrees. The
|
|
41
|
+
* members of a GeometryCollection are buffered one by one and the results merged
|
|
42
|
+
* @param distanceMeters The distance in meters. A negative distance shrinks a polygon and
|
|
43
|
+
* leaves nothing of a point or a line
|
|
44
|
+
* @param options `segments`, the number of segments of each circle (64 by default, rounded
|
|
45
|
+
* down and clamped to 3-1024)
|
|
46
|
+
* @returns A Polygon, or a MultiPolygon when the area falls apart. null when nothing remains,
|
|
47
|
+
* and when a vertex is so close to a pole or an edge so long in longitude (over 180 degrees)
|
|
48
|
+
* that the area cannot be drawn in longitude and latitude
|
|
49
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a geometry or a
|
|
50
|
+
* feature with one and when the distance is not a finite number, and (`engine-failure`)
|
|
51
|
+
* when merging the parts fails
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { buffer } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
56
|
+
*
|
|
57
|
+
* // The area within 100 m of a road
|
|
58
|
+
* const corridor = buffer(
|
|
59
|
+
* { type: 'LineString', coordinates: [[139.76, 35.68], [139.77, 35.69]] },
|
|
60
|
+
* 100,
|
|
61
|
+
* );
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export function buffer(geometry, distanceMeters, options) {
|
|
65
|
+
const input = geometryOf(geometry, 'buffer');
|
|
66
|
+
if (!Number.isFinite(distanceMeters)) {
|
|
67
|
+
throw invalidInput('buffer', 'the distance is not a finite number');
|
|
68
|
+
}
|
|
69
|
+
return withOperation('buffer', () => toAreaGeometry(bufferOf(input, distanceMeters, options?.segments)));
|
|
70
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Measure: the public functions that measure distances, bearings, lengths and areas
|
|
3
|
+
*
|
|
4
|
+
* Every distance is taken along great circles on the sphere of EARTH_RADIUS_METERS, the
|
|
5
|
+
* same as the internal haversine and direct-problem functions.
|
|
6
|
+
*/
|
|
7
|
+
import type { Geometry, LineString, MultiLineString, MultiPolygon, Point, Polygon, Position } from 'geojson';
|
|
8
|
+
/**
|
|
9
|
+
* Returns the great-circle distance in meters between two points.
|
|
10
|
+
*
|
|
11
|
+
* @param from The first point, a position `[lng, lat]` in degrees or a Point
|
|
12
|
+
* @param to The second point, a position `[lng, lat]` in degrees or a Point
|
|
13
|
+
* @returns The distance in meters on the sphere of {@link EARTH_RADIUS_METERS}. NaN when a
|
|
14
|
+
* coordinate is not finite
|
|
15
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
|
|
16
|
+
* Point
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { distance } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
21
|
+
*
|
|
22
|
+
* distance([139.767, 35.681], [135.495, 34.702]); // about 403,139 m
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function distance(from: Position | Point, to: Position | Point): number;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the initial bearing in degrees of the great circle from one point to another.
|
|
28
|
+
*
|
|
29
|
+
* @param from The start, a position `[lng, lat]` in degrees or a Point
|
|
30
|
+
* @param to The end, a position `[lng, lat]` in degrees or a Point
|
|
31
|
+
* @returns The bearing at the start in degrees, clockwise from north, in [0, 360). 0 when the
|
|
32
|
+
* points are identical
|
|
33
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
|
|
34
|
+
* Point
|
|
35
|
+
*/
|
|
36
|
+
export declare function bearing(from: Position | Point, to: Position | Point): number;
|
|
37
|
+
/**
|
|
38
|
+
* Returns the point reached from an origin after a distance in meters along a great circle
|
|
39
|
+
* that starts at a bearing in degrees.
|
|
40
|
+
*
|
|
41
|
+
* @param origin The start, a position `[lng, lat]` in degrees or a Point
|
|
42
|
+
* @param distanceMeters The distance in meters; a negative value goes the opposite way
|
|
43
|
+
* @param bearingDegrees The initial bearing in degrees, clockwise from north
|
|
44
|
+
* @returns The position `[lng, lat]` in degrees. The longitude continues from the origin
|
|
45
|
+
* and is not wrapped into [-180, 180]
|
|
46
|
+
* @throws {@link GeometryError} (`invalid-input`) when the origin is not a position or a
|
|
47
|
+
* Point
|
|
48
|
+
*/
|
|
49
|
+
export declare function destination(origin: Position | Point, distanceMeters: number, bearingDegrees: number): Position;
|
|
50
|
+
/**
|
|
51
|
+
* Returns the point halfway between two points along the great circle that joins them.
|
|
52
|
+
*
|
|
53
|
+
* @param from The first point, a position `[lng, lat]` in degrees or a Point
|
|
54
|
+
* @param to The second point, a position `[lng, lat]` in degrees or a Point
|
|
55
|
+
* @returns The position `[lng, lat]` in degrees, at the same distance in meters from both
|
|
56
|
+
* points. The longitude continues from `from`
|
|
57
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
|
|
58
|
+
* Point
|
|
59
|
+
*/
|
|
60
|
+
export declare function midpoint(from: Position | Point, to: Position | Point): Position;
|
|
61
|
+
/**
|
|
62
|
+
* Returns the point at a distance in meters along a line, measured from its start.
|
|
63
|
+
*
|
|
64
|
+
* @param line The LineString, or a feature whose geometry is one; coordinates in degrees
|
|
65
|
+
* @param distanceMeters The distance from the start in meters. 0 or less gives the start,
|
|
66
|
+
* and a distance longer than the line gives its end
|
|
67
|
+
* @returns The position `[lng, lat]` in degrees
|
|
68
|
+
* @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or has no
|
|
69
|
+
* position, and when the distance is not a finite number
|
|
70
|
+
*/
|
|
71
|
+
export declare function along(line: LineString | {
|
|
72
|
+
readonly geometry: Geometry;
|
|
73
|
+
}, distanceMeters: number): Position;
|
|
74
|
+
/**
|
|
75
|
+
* Returns the point of a line nearest to a given point, with its distance in meters and the
|
|
76
|
+
* index of the segment it lies on.
|
|
77
|
+
*
|
|
78
|
+
* @param line The LineString or MultiLineString, or a feature whose geometry is one;
|
|
79
|
+
* coordinates in degrees. Each segment is taken as a great-circle arc
|
|
80
|
+
* @param point The point, a position `[lng, lat]` in degrees or a Point
|
|
81
|
+
* @returns `position`, the nearest point `[lng, lat]` in degrees; `distanceMeters`, its
|
|
82
|
+
* distance from `point` in meters; and `segmentIndex`, the segment it lies on, counted from
|
|
83
|
+
* 0 across the lines of a MultiLineString in order (segment `i` of a LineString joins its
|
|
84
|
+
* positions `i` and `i + 1`)
|
|
85
|
+
* @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or a
|
|
86
|
+
* MultiLineString or has no position, and when the point is not a position or a Point
|
|
87
|
+
*/
|
|
88
|
+
export declare function nearestPointOnLine(line: LineString | MultiLineString | {
|
|
89
|
+
readonly geometry: Geometry;
|
|
90
|
+
}, point: Position | Point): {
|
|
91
|
+
position: Position;
|
|
92
|
+
distanceMeters: number;
|
|
93
|
+
segmentIndex: number;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Returns the length in meters of a line.
|
|
97
|
+
*
|
|
98
|
+
* @param line The LineString or MultiLineString, or a feature whose geometry is one;
|
|
99
|
+
* coordinates in degrees
|
|
100
|
+
* @returns The sum of the great-circle distances of the segments, in meters. 0 for a line
|
|
101
|
+
* with fewer than 2 positions
|
|
102
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a LineString or a
|
|
103
|
+
* MultiLineString
|
|
104
|
+
*/
|
|
105
|
+
export declare function length(line: LineString | MultiLineString | {
|
|
106
|
+
readonly geometry: Geometry;
|
|
107
|
+
}): number;
|
|
108
|
+
/**
|
|
109
|
+
* Returns the area in square meters of a polygon on the sphere.
|
|
110
|
+
*
|
|
111
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
112
|
+
* in degrees. Self-intersections are resolved and ring orientation does not matter
|
|
113
|
+
* @returns The area in square meters, holes subtracted. 0 when nothing with an area remains
|
|
114
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
115
|
+
* MultiPolygon, and (`engine-failure`) when resolving its self-intersections fails
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* import { area } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
120
|
+
*
|
|
121
|
+
* // A 1 x 1 degree square on the equator
|
|
122
|
+
* area({ type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]] });
|
|
123
|
+
* // about 1.236e10 m²
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export declare function area(polygon: Polygon | MultiPolygon | {
|
|
127
|
+
readonly geometry: Geometry;
|
|
128
|
+
}): number;
|
|
129
|
+
/**
|
|
130
|
+
* Returns the length in meters of the boundary of a polygon, the rings of its holes included.
|
|
131
|
+
*
|
|
132
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
133
|
+
* in degrees. An open ring is measured as if closed; a ring with fewer than 3 positions or a
|
|
134
|
+
* position that is not finite is left out
|
|
135
|
+
* @returns The sum of the great-circle lengths of every ring, in meters
|
|
136
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
137
|
+
* MultiPolygon
|
|
138
|
+
*/
|
|
139
|
+
export declare function perimeter(polygon: Polygon | MultiPolygon | {
|
|
140
|
+
readonly geometry: Geometry;
|
|
141
|
+
}): number;
|
|
142
|
+
/**
|
|
143
|
+
* Returns the centroid of a polygon, weighted by area.
|
|
144
|
+
*
|
|
145
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
146
|
+
* in degrees. Holes are subtracted and the parts are weighted by their areas on the lng/lat
|
|
147
|
+
* plane
|
|
148
|
+
* @returns The centroid as a Point, in degrees; it can fall outside a concave polygon (see
|
|
149
|
+
* {@link pointOnSurface}). The mean of the positions when the area is 0. null when there is
|
|
150
|
+
* no position
|
|
151
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
152
|
+
* MultiPolygon
|
|
153
|
+
*/
|
|
154
|
+
export declare function centroid(polygon: Polygon | MultiPolygon | {
|
|
155
|
+
readonly geometry: Geometry;
|
|
156
|
+
}): Point | null;
|
|
157
|
+
/**
|
|
158
|
+
* Returns a point that always lies inside a polygon, such as the anchor of a label.
|
|
159
|
+
*
|
|
160
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
161
|
+
* in degrees
|
|
162
|
+
* @returns The {@link centroid} when it lies inside, otherwise the middle of the widest
|
|
163
|
+
* section of the polygon along the parallel of the centroid, as a Point in degrees. null
|
|
164
|
+
* when there is no position
|
|
165
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
166
|
+
* MultiPolygon
|
|
167
|
+
*/
|
|
168
|
+
export declare function pointOnSurface(polygon: Polygon | MultiPolygon | {
|
|
169
|
+
readonly geometry: Geometry;
|
|
170
|
+
}): Point | null;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { closeRing, usableAreaParts } from './coords.js';
|
|
4
|
+
import { destinationPoint, haversineDistanceMeters, initialBearingDegrees } from './distance.js';
|
|
5
|
+
import { invalidInput, withOperation } from './errors.js';
|
|
6
|
+
import { areaOf, lineOf, linesOf, positionOf, toPoint, toPosition } from './geojson.js';
|
|
7
|
+
import { geodesicLength, centroid as planarCentroid, pointOnSurface as planarPointOnSurface, sphericalArea, } from './measure.js';
|
|
8
|
+
import { toDegrees, toRadians } from './units.js';
|
|
9
|
+
/**
|
|
10
|
+
* Returns the great-circle distance in meters between two points.
|
|
11
|
+
*
|
|
12
|
+
* @param from The first point, a position `[lng, lat]` in degrees or a Point
|
|
13
|
+
* @param to The second point, a position `[lng, lat]` in degrees or a Point
|
|
14
|
+
* @returns The distance in meters on the sphere of {@link EARTH_RADIUS_METERS}. NaN when a
|
|
15
|
+
* coordinate is not finite
|
|
16
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
|
|
17
|
+
* Point
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { distance } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
22
|
+
*
|
|
23
|
+
* distance([139.767, 35.681], [135.495, 34.702]); // about 403,139 m
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function distance(from, to) {
|
|
27
|
+
return haversineDistanceMeters(positionOf(from, 'distance'), positionOf(to, 'distance'));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns the initial bearing in degrees of the great circle from one point to another.
|
|
31
|
+
*
|
|
32
|
+
* @param from The start, a position `[lng, lat]` in degrees or a Point
|
|
33
|
+
* @param to The end, a position `[lng, lat]` in degrees or a Point
|
|
34
|
+
* @returns The bearing at the start in degrees, clockwise from north, in [0, 360). 0 when the
|
|
35
|
+
* points are identical
|
|
36
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
|
|
37
|
+
* Point
|
|
38
|
+
*/
|
|
39
|
+
export function bearing(from, to) {
|
|
40
|
+
return initialBearingDegrees(positionOf(from, 'bearing'), positionOf(to, 'bearing'));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns the point reached from an origin after a distance in meters along a great circle
|
|
44
|
+
* that starts at a bearing in degrees.
|
|
45
|
+
*
|
|
46
|
+
* @param origin The start, a position `[lng, lat]` in degrees or a Point
|
|
47
|
+
* @param distanceMeters The distance in meters; a negative value goes the opposite way
|
|
48
|
+
* @param bearingDegrees The initial bearing in degrees, clockwise from north
|
|
49
|
+
* @returns The position `[lng, lat]` in degrees. The longitude continues from the origin
|
|
50
|
+
* and is not wrapped into [-180, 180]
|
|
51
|
+
* @throws {@link GeometryError} (`invalid-input`) when the origin is not a position or a
|
|
52
|
+
* Point
|
|
53
|
+
*/
|
|
54
|
+
export function destination(origin, distanceMeters, bearingDegrees) {
|
|
55
|
+
return toPosition(destinationPoint(positionOf(origin, 'destination'), distanceMeters, bearingDegrees));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns the point halfway between two points along the great circle that joins them.
|
|
59
|
+
*
|
|
60
|
+
* @param from The first point, a position `[lng, lat]` in degrees or a Point
|
|
61
|
+
* @param to The second point, a position `[lng, lat]` in degrees or a Point
|
|
62
|
+
* @returns The position `[lng, lat]` in degrees, at the same distance in meters from both
|
|
63
|
+
* points. The longitude continues from `from`
|
|
64
|
+
* @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
|
|
65
|
+
* Point
|
|
66
|
+
*/
|
|
67
|
+
export function midpoint(from, to) {
|
|
68
|
+
const [lng1, lat1] = positionOf(from, 'midpoint');
|
|
69
|
+
const [lng2, lat2] = positionOf(to, 'midpoint');
|
|
70
|
+
const phi1 = toRadians(lat1);
|
|
71
|
+
const phi2 = toRadians(lat2);
|
|
72
|
+
const dLambda = toRadians(lng2 - lng1);
|
|
73
|
+
const bx = Math.cos(phi2) * Math.cos(dLambda);
|
|
74
|
+
const by = Math.cos(phi2) * Math.sin(dLambda);
|
|
75
|
+
const phi = Math.atan2(Math.sin(phi1) + Math.sin(phi2), Math.sqrt((Math.cos(phi1) + bx) ** 2 + by ** 2));
|
|
76
|
+
const lambda = Math.atan2(by, Math.cos(phi1) + bx);
|
|
77
|
+
return [lng1 + toDegrees(lambda), toDegrees(phi)];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the point at a distance in meters along a line, measured from its start.
|
|
81
|
+
*
|
|
82
|
+
* @param line The LineString, or a feature whose geometry is one; coordinates in degrees
|
|
83
|
+
* @param distanceMeters The distance from the start in meters. 0 or less gives the start,
|
|
84
|
+
* and a distance longer than the line gives its end
|
|
85
|
+
* @returns The position `[lng, lat]` in degrees
|
|
86
|
+
* @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or has no
|
|
87
|
+
* position, and when the distance is not a finite number
|
|
88
|
+
*/
|
|
89
|
+
export function along(line, distanceMeters) {
|
|
90
|
+
const path = lineOf(line, 'along');
|
|
91
|
+
if (path.length === 0) {
|
|
92
|
+
throw invalidInput('along', 'the line has no position');
|
|
93
|
+
}
|
|
94
|
+
if (!Number.isFinite(distanceMeters)) {
|
|
95
|
+
throw invalidInput('along', 'the distance is not a finite number');
|
|
96
|
+
}
|
|
97
|
+
let remaining = distanceMeters;
|
|
98
|
+
if (remaining <= 0)
|
|
99
|
+
return toPosition(path[0]);
|
|
100
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
101
|
+
const start = path[i];
|
|
102
|
+
const end = path[i + 1];
|
|
103
|
+
const section = haversineDistanceMeters(start, end);
|
|
104
|
+
if (remaining < section) {
|
|
105
|
+
return toPosition(destinationPoint(start, remaining, initialBearingDegrees(start, end)));
|
|
106
|
+
}
|
|
107
|
+
remaining -= section;
|
|
108
|
+
}
|
|
109
|
+
return toPosition(path[path.length - 1]);
|
|
110
|
+
}
|
|
111
|
+
function toVector([lng, lat]) {
|
|
112
|
+
const lambda = toRadians(lng);
|
|
113
|
+
const phi = toRadians(lat);
|
|
114
|
+
return [Math.cos(phi) * Math.cos(lambda), Math.cos(phi) * Math.sin(lambda), Math.sin(phi)];
|
|
115
|
+
}
|
|
116
|
+
function cross(a, b) {
|
|
117
|
+
return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
|
|
118
|
+
}
|
|
119
|
+
function dot(a, b) {
|
|
120
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
121
|
+
}
|
|
122
|
+
function norm(a) {
|
|
123
|
+
return Math.hypot(a[0], a[1], a[2]);
|
|
124
|
+
}
|
|
125
|
+
/** The vectors shorter than this are treated as zero (a degenerate great circle) */
|
|
126
|
+
const VECTOR_EPSILON = 1e-15;
|
|
127
|
+
/**
|
|
128
|
+
* The position of a unit vector, with the longitude taken nearest to a reference longitude
|
|
129
|
+
*/
|
|
130
|
+
function toCoordinate(v, nearLng) {
|
|
131
|
+
const lat = toDegrees(Math.atan2(v[2], Math.hypot(v[0], v[1])));
|
|
132
|
+
const lng = toDegrees(Math.atan2(v[1], v[0]));
|
|
133
|
+
return [lng + 360 * Math.round((nearLng - lng) / 360), lat];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The point of the great-circle arc from a to b nearest to p
|
|
137
|
+
*
|
|
138
|
+
* p is projected onto the plane of the great circle through a and b. When the projection
|
|
139
|
+
* falls on the arc between them, it is the nearest point; otherwise the nearer end is.
|
|
140
|
+
*/
|
|
141
|
+
function nearestOnSegment(p, a, b) {
|
|
142
|
+
const va = toVector(a);
|
|
143
|
+
const vb = toVector(b);
|
|
144
|
+
const vp = toVector(p);
|
|
145
|
+
const normal = cross(va, vb);
|
|
146
|
+
const normalLength = norm(normal);
|
|
147
|
+
if (normalLength < VECTOR_EPSILON)
|
|
148
|
+
return a;
|
|
149
|
+
const n = [normal[0] / normalLength, normal[1] / normalLength, normal[2] / normalLength];
|
|
150
|
+
const offset = dot(vp, n);
|
|
151
|
+
const projected = [vp[0] - offset * n[0], vp[1] - offset * n[1], vp[2] - offset * n[2]];
|
|
152
|
+
if (norm(projected) >= VECTOR_EPSILON && dot(cross(va, projected), n) >= 0) {
|
|
153
|
+
if (dot(cross(projected, vb), n) >= 0) {
|
|
154
|
+
const size = norm(projected);
|
|
155
|
+
return toCoordinate([projected[0] / size, projected[1] / size, projected[2] / size], a[0]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return haversineDistanceMeters(p, a) <= haversineDistanceMeters(p, b) ? a : b;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Returns the point of a line nearest to a given point, with its distance in meters and the
|
|
162
|
+
* index of the segment it lies on.
|
|
163
|
+
*
|
|
164
|
+
* @param line The LineString or MultiLineString, or a feature whose geometry is one;
|
|
165
|
+
* coordinates in degrees. Each segment is taken as a great-circle arc
|
|
166
|
+
* @param point The point, a position `[lng, lat]` in degrees or a Point
|
|
167
|
+
* @returns `position`, the nearest point `[lng, lat]` in degrees; `distanceMeters`, its
|
|
168
|
+
* distance from `point` in meters; and `segmentIndex`, the segment it lies on, counted from
|
|
169
|
+
* 0 across the lines of a MultiLineString in order (segment `i` of a LineString joins its
|
|
170
|
+
* positions `i` and `i + 1`)
|
|
171
|
+
* @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or a
|
|
172
|
+
* MultiLineString or has no position, and when the point is not a position or a Point
|
|
173
|
+
*/
|
|
174
|
+
export function nearestPointOnLine(line, point) {
|
|
175
|
+
const lines = linesOf(line, 'nearestPointOnLine');
|
|
176
|
+
const target = positionOf(point, 'nearestPointOnLine');
|
|
177
|
+
let best = null;
|
|
178
|
+
let segmentIndex = 0;
|
|
179
|
+
for (const path of lines) {
|
|
180
|
+
if (path.length === 0)
|
|
181
|
+
continue;
|
|
182
|
+
const segments = Math.max(1, path.length - 1);
|
|
183
|
+
for (let i = 0; i < segments; i++) {
|
|
184
|
+
const candidate = path.length === 1 ? path[0] : nearestOnSegment(target, path[i], path[i + 1]);
|
|
185
|
+
const distanceMeters = haversineDistanceMeters(target, candidate);
|
|
186
|
+
if (best === null || distanceMeters < best.distanceMeters) {
|
|
187
|
+
best = { position: candidate, distanceMeters, segmentIndex };
|
|
188
|
+
}
|
|
189
|
+
segmentIndex++;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (best === null) {
|
|
193
|
+
throw invalidInput('nearestPointOnLine', 'the line has no position');
|
|
194
|
+
}
|
|
195
|
+
return { ...best, position: toPosition(best.position) };
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Returns the length in meters of a line.
|
|
199
|
+
*
|
|
200
|
+
* @param line The LineString or MultiLineString, or a feature whose geometry is one;
|
|
201
|
+
* coordinates in degrees
|
|
202
|
+
* @returns The sum of the great-circle distances of the segments, in meters. 0 for a line
|
|
203
|
+
* with fewer than 2 positions
|
|
204
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a LineString or a
|
|
205
|
+
* MultiLineString
|
|
206
|
+
*/
|
|
207
|
+
export function length(line) {
|
|
208
|
+
let total = 0;
|
|
209
|
+
for (const path of linesOf(line, 'length'))
|
|
210
|
+
total += geodesicLength(path);
|
|
211
|
+
return total;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Returns the area in square meters of a polygon on the sphere.
|
|
215
|
+
*
|
|
216
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
217
|
+
* in degrees. Self-intersections are resolved and ring orientation does not matter
|
|
218
|
+
* @returns The area in square meters, holes subtracted. 0 when nothing with an area remains
|
|
219
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
220
|
+
* MultiPolygon, and (`engine-failure`) when resolving its self-intersections fails
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* import { area } from '@sakuzu/maplibre-gl-draw/geometry';
|
|
225
|
+
*
|
|
226
|
+
* // A 1 x 1 degree square on the equator
|
|
227
|
+
* area({ type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]] });
|
|
228
|
+
* // about 1.236e10 m²
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export function area(polygon) {
|
|
232
|
+
const coordinates = areaOf(polygon, 'area');
|
|
233
|
+
return withOperation('area', () => sphericalArea(coordinates));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Returns the length in meters of the boundary of a polygon, the rings of its holes included.
|
|
237
|
+
*
|
|
238
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
239
|
+
* in degrees. An open ring is measured as if closed; a ring with fewer than 3 positions or a
|
|
240
|
+
* position that is not finite is left out
|
|
241
|
+
* @returns The sum of the great-circle lengths of every ring, in meters
|
|
242
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
243
|
+
* MultiPolygon
|
|
244
|
+
*/
|
|
245
|
+
export function perimeter(polygon) {
|
|
246
|
+
let total = 0;
|
|
247
|
+
for (const part of usableAreaParts(areaOf(polygon, 'perimeter'))) {
|
|
248
|
+
for (const ring of part)
|
|
249
|
+
total += geodesicLength(closeRing(ring));
|
|
250
|
+
}
|
|
251
|
+
return total;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Returns the centroid of a polygon, weighted by area.
|
|
255
|
+
*
|
|
256
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
257
|
+
* in degrees. Holes are subtracted and the parts are weighted by their areas on the lng/lat
|
|
258
|
+
* plane
|
|
259
|
+
* @returns The centroid as a Point, in degrees; it can fall outside a concave polygon (see
|
|
260
|
+
* {@link pointOnSurface}). The mean of the positions when the area is 0. null when there is
|
|
261
|
+
* no position
|
|
262
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
263
|
+
* MultiPolygon
|
|
264
|
+
*/
|
|
265
|
+
export function centroid(polygon) {
|
|
266
|
+
const result = planarCentroid(areaOf(polygon, 'centroid'));
|
|
267
|
+
return result === null ? null : toPoint(result);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Returns a point that always lies inside a polygon, such as the anchor of a label.
|
|
271
|
+
*
|
|
272
|
+
* @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
|
|
273
|
+
* in degrees
|
|
274
|
+
* @returns The {@link centroid} when it lies inside, otherwise the middle of the widest
|
|
275
|
+
* section of the polygon along the parallel of the centroid, as a Point in degrees. null
|
|
276
|
+
* when there is no position
|
|
277
|
+
* @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
|
|
278
|
+
* MultiPolygon
|
|
279
|
+
*/
|
|
280
|
+
export function pointOnSurface(polygon) {
|
|
281
|
+
const result = planarPointOnSurface(areaOf(polygon, 'pointOnSurface'));
|
|
282
|
+
return result === null ? null : toPoint(result);
|
|
283
|
+
}
|