@honua/react 0.0.20-alpha.0 → 0.1.1-beta.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/contract/discovery.d.ts +231 -0
- package/contract/discovery.d.ts.map +1 -0
- package/contract/discovery.js +554 -0
- package/contract/edit-sketch.d.ts +8 -0
- package/contract/edit-sketch.d.ts.map +1 -1
- package/contract/edit-sketch.js +15 -0
- package/contract/edit-snapping.d.ts +160 -0
- package/contract/edit-snapping.d.ts.map +1 -0
- package/contract/edit-snapping.js +675 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts +35 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -0
- package/contract/generated/projjson-v0.7-crs-validator.js +3941 -0
- package/contract/index.d.ts +12 -1
- package/contract/index.d.ts.map +1 -1
- package/contract/index.js +4 -0
- package/contract/pmtiles.d.ts +193 -0
- package/contract/pmtiles.d.ts.map +1 -0
- package/contract/pmtiles.js +195 -0
- package/contract/protocol-module.d.ts +70 -0
- package/contract/protocol-module.d.ts.map +1 -0
- package/contract/protocol-module.js +1 -0
- package/contract/schema-envelope.d.ts +26 -0
- package/contract/schema-envelope.d.ts.map +1 -0
- package/contract/schema-envelope.js +25 -0
- package/contract/schema.d.ts +582 -0
- package/contract/schema.d.ts.map +1 -0
- package/contract/schema.js +2483 -0
- package/contract/source-capability-support.d.ts +6 -0
- package/contract/source-capability-support.d.ts.map +1 -0
- package/contract/source-capability-support.js +154 -0
- package/contract/source.d.ts +57 -15
- package/contract/source.d.ts.map +1 -1
- package/contract/source.js +368 -65
- package/contract/types.d.ts +171 -6
- package/contract/types.d.ts.map +1 -1
- package/contract/types.js +14 -14
- package/core/auth/client-credentials-provider.d.ts +51 -0
- package/core/auth/client-credentials-provider.d.ts.map +1 -0
- package/core/auth/client-credentials-provider.js +115 -0
- package/core/auth/credential-store.d.ts +52 -0
- package/core/auth/credential-store.d.ts.map +1 -0
- package/core/auth/credential-store.js +82 -0
- package/core/auth/index.d.ts +23 -0
- package/core/auth/index.d.ts.map +1 -0
- package/core/auth/index.js +20 -0
- package/core/auth/oauth2-provider.d.ts +114 -0
- package/core/auth/oauth2-provider.d.ts.map +1 -0
- package/core/auth/oauth2-provider.js +408 -0
- package/core/auth/pkce.d.ts +25 -0
- package/core/auth/pkce.d.ts.map +1 -0
- package/core/auth/pkce.js +46 -0
- package/core/auth/static-providers.d.ts +20 -0
- package/core/auth/static-providers.d.ts.map +1 -0
- package/core/auth/static-providers.js +26 -0
- package/core/auth/token-endpoint.d.ts +40 -0
- package/core/auth/token-endpoint.d.ts.map +1 -0
- package/core/auth/token-endpoint.js +133 -0
- package/core/auth/types.d.ts +144 -0
- package/core/auth/types.d.ts.map +1 -0
- package/core/auth/types.js +8 -0
- package/core/bounded-json.d.ts +4 -0
- package/core/bounded-json.d.ts.map +1 -0
- package/core/bounded-json.js +38 -0
- package/core/cache-state.d.ts +9 -0
- package/core/cache-state.d.ts.map +1 -1
- package/core/cache-state.js +10 -0
- package/core/capabilities-xml.d.ts +33 -0
- package/core/capabilities-xml.d.ts.map +1 -0
- package/core/capabilities-xml.js +331 -0
- package/core/client.d.ts +35 -2
- package/core/client.d.ts.map +1 -1
- package/core/client.js +167 -29
- package/core/error-classifications.d.ts +153 -0
- package/core/error-classifications.d.ts.map +1 -0
- package/core/error-classifications.js +140 -0
- package/core/error-code-registry.d.ts +158 -0
- package/core/error-code-registry.d.ts.map +1 -0
- package/core/error-code-registry.js +143 -0
- package/core/error-envelope.d.ts +68 -0
- package/core/error-envelope.d.ts.map +1 -0
- package/core/error-envelope.js +357 -0
- package/core/errors.d.ts +73 -25
- package/core/errors.d.ts.map +1 -1
- package/core/errors.js +113 -46
- package/core/geoparquet-sql.d.ts +190 -0
- package/core/geoparquet-sql.d.ts.map +1 -0
- package/core/geoparquet-sql.js +368 -0
- package/core/odata-key-path.d.ts +12 -0
- package/core/odata-key-path.d.ts.map +1 -0
- package/core/odata-key-path.js +28 -0
- package/core/odata-write-codec.d.ts +66 -0
- package/core/odata-write-codec.d.ts.map +1 -0
- package/core/odata-write-codec.js +1083 -0
- package/core/odata.d.ts +59 -7
- package/core/odata.d.ts.map +1 -1
- package/core/odata.js +431 -99
- package/core/ogc-endpoint-layout.d.ts +70 -0
- package/core/ogc-endpoint-layout.d.ts.map +1 -0
- package/core/ogc-endpoint-layout.js +173 -0
- package/core/ogc-features.d.ts.map +1 -1
- package/core/ogc-features.js +35 -17
- package/core/ogc-maps.d.ts +7 -0
- package/core/ogc-maps.d.ts.map +1 -1
- package/core/ogc-maps.js +46 -7
- package/core/ogc-processes.d.ts +2 -1
- package/core/ogc-processes.d.ts.map +1 -1
- package/core/ogc-processes.js +33 -5
- package/core/ogc-records.d.ts +9 -0
- package/core/ogc-records.d.ts.map +1 -1
- package/core/ogc-records.js +78 -29
- package/core/ogc-tiles.d.ts +10 -1
- package/core/ogc-tiles.d.ts.map +1 -1
- package/core/ogc-tiles.js +56 -17
- package/core/path-utils.d.ts +9 -0
- package/core/path-utils.d.ts.map +1 -1
- package/core/path-utils.js +19 -0
- package/core/protocol-transport.d.ts +1 -0
- package/core/protocol-transport.d.ts.map +1 -1
- package/core/request-pipeline.d.ts.map +1 -1
- package/core/request-pipeline.js +1 -1
- package/core/spatial-filter.d.ts +8 -4
- package/core/spatial-filter.d.ts.map +1 -1
- package/core/spatial-filter.js +206 -16
- package/core/stac-static.d.ts +55 -0
- package/core/stac-static.d.ts.map +1 -0
- package/core/stac-static.js +386 -0
- package/core/stac.d.ts +12 -0
- package/core/stac.d.ts.map +1 -1
- package/core/stac.js +45 -15
- package/core/surfaces.d.ts +13 -0
- package/core/surfaces.d.ts.map +1 -1
- package/core/surfaces.js +127 -16
- package/core/types.d.ts +174 -7
- package/core/types.d.ts.map +1 -1
- package/core/wfs-capabilities.d.ts +12 -0
- package/core/wfs-capabilities.d.ts.map +1 -1
- package/core/wfs-capabilities.js +22 -3
- package/core/wfs.d.ts +13 -0
- package/core/wfs.d.ts.map +1 -1
- package/core/wfs.js +35 -5
- package/core/wms-capabilities.d.ts +56 -84
- package/core/wms-capabilities.d.ts.map +1 -1
- package/core/wms-capabilities.js +212 -509
- package/core/wmts-capabilities.d.ts +62 -62
- package/core/wmts-capabilities.d.ts.map +1 -1
- package/core/wmts-capabilities.js +224 -371
- package/esri-compat/editor.d.ts +8 -0
- package/esri-compat/editor.d.ts.map +1 -1
- package/esri-compat/editor.js +13 -0
- package/esri-compat/feature-layer.d.ts +2 -0
- package/esri-compat/feature-layer.d.ts.map +1 -1
- package/esri-compat/feature-layer.js +1 -0
- package/esri-compat/identity-manager.d.ts +43 -0
- package/esri-compat/identity-manager.d.ts.map +1 -1
- package/esri-compat/identity-manager.js +131 -1
- package/esri-compat/layer-list.d.ts +11 -0
- package/esri-compat/layer-list.d.ts.map +1 -1
- package/esri-compat/layer-list.js +49 -0
- package/esri-compat/legend.d.ts +10 -0
- package/esri-compat/legend.d.ts.map +1 -1
- package/esri-compat/legend.js +27 -0
- package/esri-compat/oauth-info.d.ts +15 -0
- package/esri-compat/oauth-info.d.ts.map +1 -1
- package/esri-compat/oauth-info.js +27 -0
- package/esri-compat/portal.d.ts +197 -0
- package/esri-compat/portal.d.ts.map +1 -0
- package/esri-compat/portal.js +251 -0
- package/esri-compat/renderer-objects.d.ts +40 -0
- package/esri-compat/renderer-objects.d.ts.map +1 -0
- package/esri-compat/renderer-objects.js +62 -0
- package/esri-compat/sketch.d.ts +43 -0
- package/esri-compat/sketch.d.ts.map +1 -1
- package/esri-compat/sketch.js +46 -0
- package/esri-compat/snapping.d.ts +43 -0
- package/esri-compat/snapping.d.ts.map +1 -0
- package/esri-compat/snapping.js +45 -0
- package/esri-compat/url.d.ts.map +1 -1
- package/esri-compat/url.js +1 -1
- package/esri-compat/widget-host.d.ts +84 -0
- package/esri-compat/widget-host.d.ts.map +1 -0
- package/esri-compat/widget-host.js +159 -0
- package/filter-registry/index.d.ts +145 -0
- package/filter-registry/index.d.ts.map +1 -0
- package/filter-registry/index.js +531 -0
- package/generated-app/errors.d.ts +18 -2
- package/generated-app/errors.d.ts.map +1 -1
- package/generated-app/errors.js +44 -11
- package/map/automatic-mount-integration.d.ts +134 -0
- package/map/automatic-mount-integration.d.ts.map +1 -0
- package/map/automatic-mount-integration.js +305 -0
- package/map/automatic-source-strategy.d.ts +125 -0
- package/map/automatic-source-strategy.d.ts.map +1 -0
- package/map/automatic-source-strategy.js +494 -0
- package/map/data-to-map-bridge.d.ts +293 -0
- package/map/data-to-map-bridge.d.ts.map +1 -0
- package/map/data-to-map-bridge.js +817 -0
- package/map/geojson-projection.d.ts +33 -0
- package/map/geojson-projection.d.ts.map +1 -0
- package/map/geojson-projection.js +118 -0
- package/map/index.d.ts +14 -0
- package/map/index.d.ts.map +1 -1
- package/map/index.js +8 -0
- package/map/raster-source-spec.d.ts +30 -0
- package/map/raster-source-spec.d.ts.map +1 -0
- package/map/raster-source-spec.js +190 -0
- package/map/raster-source-strategy.d.ts +65 -0
- package/map/raster-source-strategy.d.ts.map +1 -0
- package/map/raster-source-strategy.js +232 -0
- package/map/source-to-maplibre.d.ts +91 -0
- package/map/source-to-maplibre.d.ts.map +1 -0
- package/map/source-to-maplibre.js +454 -0
- package/map/temporal-playback.d.ts +139 -0
- package/map/temporal-playback.d.ts.map +1 -0
- package/map/temporal-playback.js +247 -0
- package/package.json +19 -1
- package/query-planner/canonical.d.ts +7 -0
- package/query-planner/canonical.d.ts.map +1 -0
- package/query-planner/canonical.js +145 -0
- package/query-planner/cql2-json.d.ts +17 -0
- package/query-planner/cql2-json.d.ts.map +1 -0
- package/query-planner/cql2-json.js +646 -0
- package/query-planner/diagnostics.d.ts +35 -0
- package/query-planner/diagnostics.d.ts.map +1 -0
- package/query-planner/diagnostics.js +373 -0
- package/query-planner/duckdb.d.ts +79 -0
- package/query-planner/duckdb.d.ts.map +1 -0
- package/query-planner/duckdb.js +758 -0
- package/query-planner/execution-context.d.ts +5 -0
- package/query-planner/execution-context.d.ts.map +1 -0
- package/query-planner/execution-context.js +50 -0
- package/query-planner/executor.d.ts +5 -0
- package/query-planner/executor.d.ts.map +1 -0
- package/query-planner/executor.js +223 -0
- package/query-planner/geoservices.d.ts +91 -0
- package/query-planner/geoservices.d.ts.map +1 -0
- package/query-planner/geoservices.js +667 -0
- package/query-planner/grpc.d.ts +100 -0
- package/query-planner/grpc.d.ts.map +1 -0
- package/query-planner/grpc.js +736 -0
- package/query-planner/index.d.ts +44 -0
- package/query-planner/index.d.ts.map +1 -0
- package/query-planner/index.js +30 -0
- package/query-planner/ir.d.ts +20 -0
- package/query-planner/ir.d.ts.map +1 -0
- package/query-planner/ir.js +417 -0
- package/query-planner/local-aggregate.d.ts +5 -0
- package/query-planner/local-aggregate.d.ts.map +1 -0
- package/query-planner/local-aggregate.js +126 -0
- package/query-planner/odata.d.ts +48 -0
- package/query-planner/odata.d.ts.map +1 -0
- package/query-planner/odata.js +662 -0
- package/query-planner/ogc-compiler.d.ts +55 -0
- package/query-planner/ogc-compiler.d.ts.map +1 -0
- package/query-planner/ogc-compiler.js +480 -0
- package/query-planner/ogc-features.d.ts +53 -0
- package/query-planner/ogc-features.d.ts.map +1 -0
- package/query-planner/ogc-features.js +617 -0
- package/query-planner/planner.d.ts +17 -0
- package/query-planner/planner.d.ts.map +1 -0
- package/query-planner/planner.js +818 -0
- package/query-planner/resource.d.ts +94 -0
- package/query-planner/resource.d.ts.map +1 -0
- package/query-planner/resource.js +526 -0
- package/query-planner/semantic-canonical.d.ts +15 -0
- package/query-planner/semantic-canonical.d.ts.map +1 -0
- package/query-planner/semantic-canonical.js +62 -0
- package/query-planner/semantic-compat.d.ts +10 -0
- package/query-planner/semantic-compat.d.ts.map +1 -0
- package/query-planner/semantic-compat.js +35 -0
- package/query-planner/semantic-compiler.d.ts +64 -0
- package/query-planner/semantic-compiler.d.ts.map +1 -0
- package/query-planner/semantic-compiler.js +81 -0
- package/query-planner/semantic-literals.d.ts +30 -0
- package/query-planner/semantic-literals.d.ts.map +1 -0
- package/query-planner/semantic-literals.js +133 -0
- package/query-planner/semantic-types.d.ts +265 -0
- package/query-planner/semantic-types.d.ts.map +1 -0
- package/query-planner/semantic-types.js +1 -0
- package/query-planner/semantic.d.ts +54 -0
- package/query-planner/semantic.d.ts.map +1 -0
- package/query-planner/semantic.js +1421 -0
- package/query-planner/types.d.ts +560 -0
- package/query-planner/types.d.ts.map +1 -0
- package/query-planner/types.js +49 -0
- package/query-planner/wfs-semantic.d.ts +58 -0
- package/query-planner/wfs-semantic.d.ts.map +1 -0
- package/query-planner/wfs-semantic.js +547 -0
- package/query-planner/wfs.d.ts +6 -0
- package/query-planner/wfs.d.ts.map +1 -0
- package/query-planner/wfs.js +71 -0
- package/react/external-map.d.ts +67 -0
- package/react/external-map.d.ts.map +1 -0
- package/react/external-map.js +63 -0
- package/react/honua-map.d.ts.map +1 -1
- package/react/honua-map.js +3 -2
- package/react/honua-source-layer.d.ts +110 -0
- package/react/honua-source-layer.d.ts.map +1 -0
- package/react/honua-source-layer.js +101 -0
- package/react/hooks.d.ts +28 -0
- package/react/hooks.d.ts.map +1 -1
- package/react/hooks.js +26 -4
- package/react/index.d.ts +8 -0
- package/react/index.d.ts.map +1 -1
- package/react/index.js +5 -0
- package/react/query-cache.d.ts +26 -4
- package/react/query-cache.d.ts.map +1 -1
- package/react/query-cache.js +51 -8
- package/react/selection.d.ts +177 -0
- package/react/selection.d.ts.map +1 -0
- package/react/selection.js +0 -0
- package/react/use-mounted-source.d.ts +69 -0
- package/react/use-mounted-source.d.ts.map +1 -0
- package/react/use-mounted-source.js +346 -0
- package/runtime/edit-snapping.d.ts +107 -0
- package/runtime/edit-snapping.d.ts.map +1 -0
- package/runtime/edit-snapping.js +190 -0
- package/runtime/errors.d.ts +3 -2
- package/runtime/errors.d.ts.map +1 -1
- package/runtime/errors.js +19 -2
- package/runtime/index.d.ts +8 -2
- package/runtime/index.d.ts.map +1 -1
- package/runtime/index.js +4 -4
- package/runtime/load-package.d.ts.map +1 -1
- package/runtime/load-package.js +8 -0
- package/runtime/map-package-validation.d.ts +0 -13
- package/runtime/map-package-validation.d.ts.map +1 -1
- package/runtime/map-package-validation.js +0 -12
- package/runtime/map-package.d.ts +1 -1
- package/runtime/map-package.d.ts.map +1 -1
- package/runtime/maplibre-renderer.d.ts +41 -0
- package/runtime/maplibre-renderer.d.ts.map +1 -0
- package/runtime/maplibre-renderer.js +322 -0
- package/runtime/pmtiles-protocol.d.ts +77 -0
- package/runtime/pmtiles-protocol.d.ts.map +1 -0
- package/runtime/pmtiles-protocol.js +120 -0
- package/runtime/query-tiles.d.ts +2 -1
- package/runtime/query-tiles.d.ts.map +1 -1
- package/runtime/query-tiles.js +6 -2
- package/runtime/source-bridge.d.ts +4 -4
- package/runtime/source-bridge.d.ts.map +1 -1
- package/runtime/source-bridge.js +36 -56
- package/runtime/style-interactions.d.ts +3 -2
- package/runtime/style-interactions.d.ts.map +1 -1
- package/runtime/style-interactions.js +11 -3
- package/runtime/terra-draw-sketch.d.ts +275 -0
- package/runtime/terra-draw-sketch.d.ts.map +1 -0
- package/runtime/terra-draw-sketch.js +404 -0
- package/source-capability-registry.d.ts +1 -0
- package/source-capability-registry.js +1 -0
- package/source-capability-types.d.ts +186 -0
- package/source-capability-types.js +7 -0
- package/style/index.d.ts +2 -0
- package/style/index.d.ts.map +1 -1
- package/style/index.js +2 -0
- package/style/renderers.d.ts +326 -0
- package/style/renderers.d.ts.map +1 -0
- package/style/renderers.js +517 -0
- package/webmap/convert-renderer.d.ts +24 -3
- package/webmap/convert-renderer.d.ts.map +1 -1
- package/webmap/convert-renderer.js +93 -112
- package/webmap/index.d.ts +1 -1
- package/webmap/index.d.ts.map +1 -1
- package/webmap/index.js +1 -1
package/core/spatial-filter.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HonuaGeometryError } from "./errors.js";
|
|
1
2
|
/**
|
|
2
3
|
* Create an envelope (bounding box) spatial filter.
|
|
3
4
|
*
|
|
@@ -62,8 +63,12 @@ export function polygon(rings, spatialReference) {
|
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
|
-
* Create an envelope spatial filter centered on a point
|
|
66
|
-
*
|
|
66
|
+
* Create an axis-aligned envelope spatial filter centered on a point.
|
|
67
|
+
*
|
|
68
|
+
* This is a planar expansion in the input coordinate system's units. It is an
|
|
69
|
+
* envelope approximation, not a circular, geodesic, or topological geometry
|
|
70
|
+
* buffer. Use `buffer` from `@honua/sdk-js/geometry` when a true geometry
|
|
71
|
+
* buffer is required.
|
|
67
72
|
*
|
|
68
73
|
* @param x - Center x coordinate
|
|
69
74
|
* @param y - Center y coordinate
|
|
@@ -75,12 +80,25 @@ export function polygon(rings, spatialReference) {
|
|
|
75
80
|
* // 0.5-degree bounding box around a point
|
|
76
81
|
* const req: QueryFeaturesRequest = {
|
|
77
82
|
* serviceId: "svc", layerId: 0,
|
|
78
|
-
* ...
|
|
83
|
+
* ...bufferEnvelope(-118.24, 34.05, 0.5),
|
|
79
84
|
* };
|
|
80
85
|
* ```
|
|
81
86
|
*/
|
|
82
|
-
export function
|
|
83
|
-
|
|
87
|
+
export function bufferEnvelope(x, y, distance, spatialReference) {
|
|
88
|
+
if (![x, y, distance].every(isFiniteNumber) || distance < 0) {
|
|
89
|
+
throw new HonuaGeometryError("malformed-geometry", "Cannot create a buffer envelope: x, y, and distance must be finite numbers and distance must be non-negative", {
|
|
90
|
+
operation: "buffer-envelope",
|
|
91
|
+
reason: "invalid-coordinate-or-distance",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const bounds = [x - distance, y - distance, x + distance, y + distance];
|
|
95
|
+
if (!bounds.every(isFiniteNumber)) {
|
|
96
|
+
throw new HonuaGeometryError("malformed-geometry", "Cannot create a buffer envelope: computed bounds must be finite", {
|
|
97
|
+
operation: "buffer-envelope",
|
|
98
|
+
reason: "computed-bounds-not-finite",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return envelope(...bounds, spatialReference);
|
|
84
102
|
}
|
|
85
103
|
/**
|
|
86
104
|
* Wrap an existing geometry with `esriSpatialRelIntersects`.
|
|
@@ -131,23 +149,195 @@ export function spatialWithin(geometry) {
|
|
|
131
149
|
* Detect the Esri geometry type from a plain geometry object by inspecting
|
|
132
150
|
* its shape (duck-typing).
|
|
133
151
|
*
|
|
152
|
+
* @see https://developers.arcgis.com/rest/services-reference/enterprise/geometry-objects/
|
|
134
153
|
* @internal
|
|
135
154
|
*/
|
|
136
155
|
function detectGeometryType(geometry) {
|
|
137
|
-
if (
|
|
138
|
-
|
|
156
|
+
if (!isGeometryRecord(geometry)) {
|
|
157
|
+
throw new HonuaGeometryError("malformed-geometry", "Unable to classify geometry: geometry must be a non-null object", {
|
|
158
|
+
operation: "classify",
|
|
159
|
+
reason: "geometry-must-be-object",
|
|
160
|
+
keys: [],
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const keys = Object.keys(geometry).sort();
|
|
164
|
+
const candidates = [
|
|
165
|
+
hasAnyOwn(geometry, ["xmin", "ymin", "xmax", "ymax"]) ? "envelope" : undefined,
|
|
166
|
+
hasOwn(geometry, "rings") ? "polygon" : undefined,
|
|
167
|
+
hasOwn(geometry, "paths") ? "polyline" : undefined,
|
|
168
|
+
hasOwn(geometry, "points") ? "multipoint" : undefined,
|
|
169
|
+
hasAnyOwn(geometry, ["x", "y"]) ? "point" : undefined,
|
|
170
|
+
].filter((candidate) => candidate !== undefined);
|
|
171
|
+
if (candidates.length === 0) {
|
|
172
|
+
throw geometryClassificationError("unknown-geometry", "no supported Esri geometry shape was found", keys);
|
|
173
|
+
}
|
|
174
|
+
if (candidates.length > 1) {
|
|
175
|
+
throw geometryClassificationError("malformed-geometry", `geometry contains conflicting shape discriminators: ${candidates.join(", ")}`, keys);
|
|
176
|
+
}
|
|
177
|
+
const candidate = candidates[0];
|
|
178
|
+
switch (candidate) {
|
|
179
|
+
case "envelope":
|
|
180
|
+
assertEnvelope(geometry, keys);
|
|
181
|
+
return "esriGeometryEnvelope";
|
|
182
|
+
case "polygon":
|
|
183
|
+
assertParts(geometry, "rings", "polygon", 4, true, keys);
|
|
184
|
+
return "esriGeometryPolygon";
|
|
185
|
+
case "polyline":
|
|
186
|
+
assertParts(geometry, "paths", "polyline", 2, false, keys);
|
|
187
|
+
return "esriGeometryPolyline";
|
|
188
|
+
case "multipoint":
|
|
189
|
+
assertPositions(geometry, keys);
|
|
190
|
+
return "esriGeometryMultipoint";
|
|
191
|
+
case "point":
|
|
192
|
+
assertPoint(geometry, keys);
|
|
193
|
+
return "esriGeometryPoint";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function isGeometryRecord(value) {
|
|
197
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
198
|
+
}
|
|
199
|
+
function hasOwn(value, key) {
|
|
200
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
201
|
+
}
|
|
202
|
+
function hasAnyOwn(value, keys) {
|
|
203
|
+
return keys.some((key) => hasOwn(value, key));
|
|
204
|
+
}
|
|
205
|
+
function isFiniteNumber(value) {
|
|
206
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
207
|
+
}
|
|
208
|
+
function assertPoint(geometry, keys) {
|
|
209
|
+
if (hasOwn(geometry, "x") && geometry.x === null) {
|
|
210
|
+
assertEmptyMembers(geometry, ["y", "z", "m", "id"], "point", keys);
|
|
211
|
+
return;
|
|
139
212
|
}
|
|
140
|
-
if (
|
|
141
|
-
|
|
213
|
+
if (!isFiniteNumber(geometry.x) || !isFiniteNumber(geometry.y)) {
|
|
214
|
+
throw geometryClassificationError("malformed-geometry", "point requires finite numeric x and y coordinates", keys, "point");
|
|
215
|
+
}
|
|
216
|
+
assertOptionalFiniteMember(geometry, "z", "point", keys);
|
|
217
|
+
assertOptionalFiniteMember(geometry, "m", "point", keys, true);
|
|
218
|
+
assertOptionalFiniteMember(geometry, "id", "point", keys);
|
|
219
|
+
}
|
|
220
|
+
function assertEnvelope(geometry, keys) {
|
|
221
|
+
if (hasOwn(geometry, "xmin") && geometry.xmin === null) {
|
|
222
|
+
assertEmptyMembers(geometry, ["ymin", "xmax", "ymax", "zmin", "zmax", "mmin", "mmax", "idmin", "idmax"], "envelope", keys);
|
|
223
|
+
return;
|
|
142
224
|
}
|
|
143
|
-
|
|
144
|
-
|
|
225
|
+
const { xmin, ymin, xmax, ymax } = geometry;
|
|
226
|
+
if (![xmin, ymin, xmax, ymax].every(isFiniteNumber)) {
|
|
227
|
+
throw geometryClassificationError("malformed-geometry", "envelope requires finite numeric xmin, ymin, xmax, and ymax coordinates", keys, "envelope");
|
|
145
228
|
}
|
|
146
|
-
if (
|
|
147
|
-
|
|
229
|
+
if (xmin > xmax || ymin > ymax) {
|
|
230
|
+
throw geometryClassificationError("malformed-geometry", "envelope minimum coordinates must not exceed maximum coordinates", keys, "envelope");
|
|
148
231
|
}
|
|
149
|
-
|
|
150
|
-
|
|
232
|
+
assertOptionalBounds(geometry, "zmin", "zmax", "envelope", keys);
|
|
233
|
+
assertOptionalBounds(geometry, "mmin", "mmax", "envelope", keys);
|
|
234
|
+
assertOptionalBounds(geometry, "idmin", "idmax", "envelope", keys);
|
|
235
|
+
}
|
|
236
|
+
function assertPositions(geometry, keys) {
|
|
237
|
+
const value = geometry.points;
|
|
238
|
+
if (!Array.isArray(value)) {
|
|
239
|
+
throw geometryClassificationError("malformed-geometry", "multipoint points must be an array of coordinate positions", keys, "multipoint");
|
|
240
|
+
}
|
|
241
|
+
const dimensions = geometryDimensions(geometry, "multipoint", keys);
|
|
242
|
+
for (const position of value) {
|
|
243
|
+
// ArcGIS permits empty point slots in multipoints and ignores them during
|
|
244
|
+
// spatial evaluation. Preserve that wire-compatible behavior while still
|
|
245
|
+
// rejecting every non-empty malformed position.
|
|
246
|
+
if (Array.isArray(position) && position.length === 0)
|
|
247
|
+
continue;
|
|
248
|
+
assertPosition(position, dimensions, "multipoint", keys);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function assertParts(geometry, property, shape, minimumPositions, requireClosure, keys) {
|
|
252
|
+
const value = geometry[property];
|
|
253
|
+
if (!Array.isArray(value)) {
|
|
254
|
+
throw geometryClassificationError("malformed-geometry", `${shape} ${property} must be an array of coordinate arrays`, keys, shape);
|
|
151
255
|
}
|
|
152
|
-
|
|
256
|
+
const dimensions = geometryDimensions(geometry, shape, keys);
|
|
257
|
+
for (const part of value) {
|
|
258
|
+
if (!Array.isArray(part)) {
|
|
259
|
+
throw geometryClassificationError("malformed-geometry", `${shape} ${property} must contain coordinate arrays`, keys, shape);
|
|
260
|
+
}
|
|
261
|
+
// The REST empty sentinel is an empty outer paths/rings array. Empty inner
|
|
262
|
+
// parts are not canonical and cannot be mixed with populated parts.
|
|
263
|
+
if (part.length < minimumPositions) {
|
|
264
|
+
throw geometryClassificationError("malformed-geometry", `${shape} ${property} parts require at least ${minimumPositions} positions`, keys, shape);
|
|
265
|
+
}
|
|
266
|
+
for (const position of part)
|
|
267
|
+
assertPosition(position, dimensions, shape, keys);
|
|
268
|
+
if (requireClosure) {
|
|
269
|
+
const first = part[0];
|
|
270
|
+
const last = part[part.length - 1];
|
|
271
|
+
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
272
|
+
throw geometryClassificationError("malformed-geometry", `${shape} ${property} parts must be closed`, keys, shape);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function geometryDimensions(geometry, shape, keys) {
|
|
278
|
+
return {
|
|
279
|
+
hasZ: geometryBooleanFlag(geometry, "hasZ", shape, keys),
|
|
280
|
+
hasM: geometryBooleanFlag(geometry, "hasM", shape, keys),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function geometryBooleanFlag(geometry, property, shape, keys) {
|
|
284
|
+
if (!hasOwn(geometry, property))
|
|
285
|
+
return false;
|
|
286
|
+
if (typeof geometry[property] !== "boolean") {
|
|
287
|
+
throw geometryClassificationError("malformed-geometry", `${shape} ${property} must be a boolean when present`, keys, shape);
|
|
288
|
+
}
|
|
289
|
+
return geometry[property];
|
|
290
|
+
}
|
|
291
|
+
function assertPosition(value, dimensions, shape, keys) {
|
|
292
|
+
const minimumArity = dimensions.hasZ ? 3 : 2;
|
|
293
|
+
const maximumArity = minimumArity + (dimensions.hasM ? 1 : 0);
|
|
294
|
+
if (!Array.isArray(value) || value.length < minimumArity || value.length > maximumArity || value.length > 4) {
|
|
295
|
+
throw geometryClassificationError("malformed-geometry", `${shape} positions must match declared hasZ/hasM dimensions and contain at most four ordinates`, keys, shape);
|
|
296
|
+
}
|
|
297
|
+
if (!isFiniteNumber(value[0]) || !isFiniteNumber(value[1])) {
|
|
298
|
+
throw geometryClassificationError("malformed-geometry", `${shape} positions require finite numeric x and y ordinates`, keys, shape);
|
|
299
|
+
}
|
|
300
|
+
if (dimensions.hasZ && !isFiniteNumber(value[2])) {
|
|
301
|
+
throw geometryClassificationError("malformed-geometry", `${shape} positions require a finite z ordinate when hasZ is true`, keys, shape);
|
|
302
|
+
}
|
|
303
|
+
if (dimensions.hasM && value.length === maximumArity) {
|
|
304
|
+
const measure = value[maximumArity - 1];
|
|
305
|
+
if (measure !== null && !isFiniteNumber(measure)) {
|
|
306
|
+
throw geometryClassificationError("malformed-geometry", `${shape} m ordinates must be finite numbers, null, or omitted`, keys, shape);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function assertEmptyMembers(geometry, members, shape, keys) {
|
|
311
|
+
const contradictory = members.filter((member) => hasOwn(geometry, member) && geometry[member] !== null);
|
|
312
|
+
if (contradictory.length > 0) {
|
|
313
|
+
throw geometryClassificationError("malformed-geometry", `${shape} empty sentinel conflicts with non-null members: ${contradictory.join(", ")}`, keys, shape);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function assertOptionalFiniteMember(geometry, property, shape, keys, allowNull = false) {
|
|
317
|
+
if (!hasOwn(geometry, property))
|
|
318
|
+
return;
|
|
319
|
+
const value = geometry[property];
|
|
320
|
+
if ((allowNull && value === null) || isFiniteNumber(value))
|
|
321
|
+
return;
|
|
322
|
+
const expectation = allowNull ? "a finite number or null" : "a finite number";
|
|
323
|
+
throw geometryClassificationError("malformed-geometry", `${shape} ${property} must be ${expectation} when present`, keys, shape);
|
|
324
|
+
}
|
|
325
|
+
function assertOptionalBounds(geometry, minimumProperty, maximumProperty, shape, keys) {
|
|
326
|
+
const hasMinimum = hasOwn(geometry, minimumProperty);
|
|
327
|
+
const hasMaximum = hasOwn(geometry, maximumProperty);
|
|
328
|
+
if (!hasMinimum && !hasMaximum)
|
|
329
|
+
return;
|
|
330
|
+
const minimum = geometry[minimumProperty];
|
|
331
|
+
const maximum = geometry[maximumProperty];
|
|
332
|
+
if (!hasMinimum || !hasMaximum || !isFiniteNumber(minimum) || !isFiniteNumber(maximum) || minimum > maximum) {
|
|
333
|
+
throw geometryClassificationError("malformed-geometry", `envelope ${minimumProperty}/${maximumProperty} must be a complete ordered pair of finite numbers`, keys, shape);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function geometryClassificationError(code, reason, keys, shape) {
|
|
337
|
+
return new HonuaGeometryError(code, `Unable to classify geometry: ${reason}`, {
|
|
338
|
+
operation: "classify",
|
|
339
|
+
reason,
|
|
340
|
+
keys,
|
|
341
|
+
...(shape === undefined ? {} : { shape }),
|
|
342
|
+
});
|
|
153
343
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static STAC catalog reader.
|
|
3
|
+
*
|
|
4
|
+
* A large share of public STAC catalogs are not API servers — they are
|
|
5
|
+
* static `catalog.json` / `collection.json` / item trees served from object
|
|
6
|
+
* storage, with no `/search` endpoint. This reader walks such a tree the
|
|
7
|
+
* spec-driven way: it follows `rel="child"` links to descend catalogs /
|
|
8
|
+
* collections and `rel="item"` links to reach STAC Items, resolving every
|
|
9
|
+
* href against the document it was found in (STAC best-practice relative
|
|
10
|
+
* links). Filtering (`collections` / `bbox` / `datetime` / `limit`) is
|
|
11
|
+
* applied client-side and the result is projected onto the same
|
|
12
|
+
* {@link HonuaStacItemCollectionResponse} envelope the STAC API search path
|
|
13
|
+
* returns, so the canonical `Source` surface is identical across both
|
|
14
|
+
* layouts.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
import type { SourceLocator } from "../contract/types.js";
|
|
19
|
+
import type { HonuaClient } from "./client.js";
|
|
20
|
+
import type { HonuaStacItemCollectionResponse } from "./types.js";
|
|
21
|
+
/** Bounded search parameters for a static catalog traversal. */
|
|
22
|
+
export interface StacStaticSearchParams {
|
|
23
|
+
collections?: readonly string[];
|
|
24
|
+
bbox?: readonly [number, number, number, number];
|
|
25
|
+
datetime?: string;
|
|
26
|
+
limit?: number;
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Reader bound to the URL of a static STAC catalog / collection root. The
|
|
31
|
+
* URL is the client baseUrl (the transport resolves same-origin absolute
|
|
32
|
+
* child/item hrefs directly), so `rootUrl` is normally `""` (the baseUrl
|
|
33
|
+
* itself) but may be an absolute `catalog.json` URL.
|
|
34
|
+
*/
|
|
35
|
+
export declare class HonuaStacStaticCatalog {
|
|
36
|
+
readonly client: HonuaClient;
|
|
37
|
+
private readonly rootUrl;
|
|
38
|
+
private readonly policy;
|
|
39
|
+
constructor(client: HonuaClient, rootUrl?: string, policy?: SourceLocator["stacStatic"]);
|
|
40
|
+
/**
|
|
41
|
+
* Traverse the catalog tree, collect matching items, and return them in
|
|
42
|
+
* the STAC search envelope shape.
|
|
43
|
+
*/
|
|
44
|
+
search(params?: StacStaticSearchParams): Promise<HonuaStacItemCollectionResponse>;
|
|
45
|
+
private fetchDoc;
|
|
46
|
+
/**
|
|
47
|
+
* Breadth-first walk collecting item documents. Descends `rel="child"`
|
|
48
|
+
* links; a `collections` filter prunes Collection subtrees whose `id`
|
|
49
|
+
* is not requested. Every attempted document, traversal depth, per-document
|
|
50
|
+
* link list, response body, redirect, and origin is bounded by the locator's
|
|
51
|
+
* admitted policy.
|
|
52
|
+
*/
|
|
53
|
+
private collectItems;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=stac-static.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stac-static.d.ts","sourceRoot":"","sources":["../../../src/core/stac-static.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,+BAA+B,EAAyB,MAAM,YAAY,CAAC;AAEzF,gEAAgE;AAChE,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA6CD;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,SAAgB,MAAM,EAAE,WAAW,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;gBAE7B,MAAM,EAAE,WAAW,EAAE,OAAO,SAAK,EAAE,MAAM,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC;IAM1F;;;OAGG;IACU,MAAM,CAAC,MAAM,GAAE,sBAA2B,GAAG,OAAO,CAAC,+BAA+B,CAAC;YAcpF,QAAQ;IA0BtB;;;;;;OAMG;YACW,YAAY;CAkE3B"}
|