@totemsdk/spatial-proof 1.0.0 → 1.0.1
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/LICENSE +202 -21
- package/NOTICE +60 -0
- package/README.md +3 -3
- package/dist/canonical.js +14 -23
- package/dist/cjs/canonical.d.ts +53 -0
- package/dist/cjs/canonical.js +97 -0
- package/dist/cjs/claim.d.ts +34 -0
- package/dist/cjs/claim.js +75 -0
- package/dist/cjs/geometry.d.ts +91 -0
- package/dist/cjs/geometry.js +334 -0
- package/dist/cjs/index.d.ts +31 -0
- package/dist/cjs/index.js +68 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/proof.d.ts +54 -0
- package/dist/cjs/proof.js +189 -0
- package/dist/cjs/proofgraph.d.ts +44 -0
- package/dist/cjs/proofgraph.js +98 -0
- package/dist/cjs/relations.d.ts +21 -0
- package/dist/cjs/relations.js +270 -0
- package/dist/cjs/types.d.ts +126 -0
- package/dist/cjs/types.js +13 -0
- package/dist/claim.js +4 -8
- package/dist/geometry.js +15 -32
- package/dist/index.js +7 -45
- package/dist/proof.js +18 -26
- package/dist/proofgraph.js +15 -21
- package/dist/relations.js +22 -25
- package/dist/types.js +1 -2
- package/package.json +21 -14
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @totemsdk/spatial-proof — Type definitions
|
|
3
|
+
*
|
|
4
|
+
* Pure schema for geospatial relationship proofs.
|
|
5
|
+
*
|
|
6
|
+
* COORDINATE ORDER: GeoJSON order — [longitude, latitude] in decimal degrees
|
|
7
|
+
* (WGS84 / EPSG:4326). This is the opposite of "lat, lon". All geometry
|
|
8
|
+
* functions and hashes in this package assume [lon, lat].
|
|
9
|
+
*
|
|
10
|
+
* No network, no storage, no map rendering, no GIS engine dependency.
|
|
11
|
+
*/
|
|
12
|
+
export type Coordinate = [number, number];
|
|
13
|
+
export type GeoGeometry = GeoPointGeometry | GeoLineStringGeometry | GeoPolygonGeometry | GeoMultiPolygonGeometry;
|
|
14
|
+
export interface GeoPointGeometry {
|
|
15
|
+
type: 'Point';
|
|
16
|
+
coordinates: Coordinate;
|
|
17
|
+
}
|
|
18
|
+
export interface GeoLineStringGeometry {
|
|
19
|
+
type: 'LineString';
|
|
20
|
+
coordinates: Coordinate[];
|
|
21
|
+
}
|
|
22
|
+
export interface GeoPolygonGeometry {
|
|
23
|
+
type: 'Polygon';
|
|
24
|
+
coordinates: Coordinate[][];
|
|
25
|
+
}
|
|
26
|
+
export interface GeoMultiPolygonGeometry {
|
|
27
|
+
type: 'MultiPolygon';
|
|
28
|
+
coordinates: Coordinate[][][];
|
|
29
|
+
}
|
|
30
|
+
/** Optional feature-type geometry that can be normalized to bbox or points. */
|
|
31
|
+
export type SpatialSubjectGeometry = GeoGeometry;
|
|
32
|
+
export interface BoundingBox {
|
|
33
|
+
minLon: number;
|
|
34
|
+
minLat: number;
|
|
35
|
+
maxLon: number;
|
|
36
|
+
maxLat: number;
|
|
37
|
+
}
|
|
38
|
+
export type SpatialObjectKind = 'site-boundary' | 'zone' | 'route' | 'scene-footprint' | 'asset-footprint' | 'restricted-area' | 'inspection-area' | 'custom';
|
|
39
|
+
export interface SpatialObject {
|
|
40
|
+
spatialId: string;
|
|
41
|
+
kind: SpatialObjectKind;
|
|
42
|
+
geometry: GeoGeometry;
|
|
43
|
+
crs?: 'EPSG:4326' | string;
|
|
44
|
+
name?: string;
|
|
45
|
+
metadata?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
export type SpatialRelationType = 'inside' | 'outside' | 'intersects' | 'overlaps' | 'covers' | 'covered_by' | 'within_distance' | 'near_boundary' | 'on_route' | 'entered_zone' | 'exited_zone' | 'unknown';
|
|
48
|
+
export interface EngineInfo {
|
|
49
|
+
name: string;
|
|
50
|
+
version: string;
|
|
51
|
+
algorithm: string;
|
|
52
|
+
}
|
|
53
|
+
export interface SpatialRelationClaimInputs {
|
|
54
|
+
/** totem:geo:<hex> hash of the subject geometry (when supplied). */
|
|
55
|
+
subjectGeometryHash?: string;
|
|
56
|
+
/** totem:geo:<hex> hash of the spatial object's geometry. */
|
|
57
|
+
spatialGeometryHash: string;
|
|
58
|
+
/** Optional subject proof ID the geometry was derived from. */
|
|
59
|
+
subjectProofId?: string;
|
|
60
|
+
/** Optional location claim ID the geometry was derived from. */
|
|
61
|
+
locationClaimId?: string;
|
|
62
|
+
/** Optional raster/scene manifest ID the geometry was derived from. */
|
|
63
|
+
rasterManifestId?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface SpatialRelationClaimResult {
|
|
66
|
+
matched: boolean;
|
|
67
|
+
distanceM?: number;
|
|
68
|
+
confidenceScore?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Explicit notes on approximation. Present whenever a relation was
|
|
71
|
+
* evaluated with an approximate algorithm (e.g. bbox-only). Honesty is
|
|
72
|
+
* critical — the package never silently claims exactness.
|
|
73
|
+
*/
|
|
74
|
+
uncertainty?: string[];
|
|
75
|
+
}
|
|
76
|
+
export interface SpatialRelationClaim {
|
|
77
|
+
relationId: string;
|
|
78
|
+
subjectId: string;
|
|
79
|
+
subjectKind: string;
|
|
80
|
+
spatialObjectId: string;
|
|
81
|
+
relation: SpatialRelationType;
|
|
82
|
+
computedAt: number;
|
|
83
|
+
engine: EngineInfo;
|
|
84
|
+
inputs: SpatialRelationClaimInputs;
|
|
85
|
+
result: SpatialRelationClaimResult;
|
|
86
|
+
metadata?: Record<string, unknown>;
|
|
87
|
+
}
|
|
88
|
+
export interface SpatialValidationResult {
|
|
89
|
+
valid: boolean;
|
|
90
|
+
errors: string[];
|
|
91
|
+
warnings: string[];
|
|
92
|
+
}
|
|
93
|
+
export interface EvaluateSpatialRelationParams {
|
|
94
|
+
subjectId: string;
|
|
95
|
+
subjectKind: string;
|
|
96
|
+
spatialObject: SpatialObject;
|
|
97
|
+
relation: SpatialRelationType;
|
|
98
|
+
subjectGeometry?: SpatialSubjectGeometry;
|
|
99
|
+
/** Required for distance-based relations (within_distance, on_route, near_boundary). */
|
|
100
|
+
maxDistanceM?: number;
|
|
101
|
+
computedAt?: number;
|
|
102
|
+
subjectProofId?: string;
|
|
103
|
+
locationClaimId?: string;
|
|
104
|
+
rasterManifestId?: string;
|
|
105
|
+
metadata?: Record<string, unknown>;
|
|
106
|
+
}
|
|
107
|
+
export interface CreateSpatialProofParams {
|
|
108
|
+
claim: SpatialRelationClaim;
|
|
109
|
+
/** Full spatial object used to compute its evidence hash. */
|
|
110
|
+
spatialObject: SpatialObject;
|
|
111
|
+
/** Optional subject geometry used to add a geometry evidence ref. */
|
|
112
|
+
subjectGeometry?: GeoGeometry;
|
|
113
|
+
issuer?: string;
|
|
114
|
+
issuedAt?: number;
|
|
115
|
+
expiresAt?: number;
|
|
116
|
+
}
|
|
117
|
+
export interface SpatialProofVerifyResult {
|
|
118
|
+
valid: boolean;
|
|
119
|
+
reason?: string;
|
|
120
|
+
signerAddress?: string;
|
|
121
|
+
spatialObjectId?: string;
|
|
122
|
+
relationId?: string;
|
|
123
|
+
payloadValid?: boolean;
|
|
124
|
+
evidenceHashValid?: boolean;
|
|
125
|
+
relationIdValid?: boolean;
|
|
126
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @totemsdk/spatial-proof — Type definitions
|
|
4
|
+
*
|
|
5
|
+
* Pure schema for geospatial relationship proofs.
|
|
6
|
+
*
|
|
7
|
+
* COORDINATE ORDER: GeoJSON order — [longitude, latitude] in decimal degrees
|
|
8
|
+
* (WGS84 / EPSG:4326). This is the opposite of "lat, lon". All geometry
|
|
9
|
+
* functions and hashes in this package assume [lon, lat].
|
|
10
|
+
*
|
|
11
|
+
* No network, no storage, no map rendering, no GIS engine dependency.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/dist/claim.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Spatial relation claim construction for @totemsdk/spatial-proof.
|
|
4
3
|
*
|
|
@@ -6,10 +5,7 @@
|
|
|
6
5
|
* @totemsdk/location-proof LocationClaim into a spatial relation claim
|
|
7
6
|
* without any circular dependency (spatial-proof → location-proof only).
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
|
-
exports.spatialRelationFromLocationClaim = spatialRelationFromLocationClaim;
|
|
11
|
-
exports.validateSpatialRelationClaim = validateSpatialRelationClaim;
|
|
12
|
-
const relations_js_1 = require("./relations.js");
|
|
8
|
+
import { evaluateSpatialRelation } from './relations.js';
|
|
13
9
|
/**
|
|
14
10
|
* Derive a spatial relation claim from a location claim.
|
|
15
11
|
*
|
|
@@ -17,7 +13,7 @@ const relations_js_1 = require("./relations.js");
|
|
|
17
13
|
* its claimId is recorded as the locationClaimId input, so the resulting
|
|
18
14
|
* spatial claim provably references the location claim it was computed from.
|
|
19
15
|
*/
|
|
20
|
-
function spatialRelationFromLocationClaim(params) {
|
|
16
|
+
export function spatialRelationFromLocationClaim(params) {
|
|
21
17
|
const { locationClaim, spatialObject, relation } = params;
|
|
22
18
|
const location = locationClaim.location;
|
|
23
19
|
const evalParams = {
|
|
@@ -34,14 +30,14 @@ function spatialRelationFromLocationClaim(params) {
|
|
|
34
30
|
...(params.metadata !== undefined ? { metadata: params.metadata } : {}),
|
|
35
31
|
locationClaimId: locationClaim.claimId,
|
|
36
32
|
};
|
|
37
|
-
return
|
|
33
|
+
return evaluateSpatialRelation(evalParams);
|
|
38
34
|
}
|
|
39
35
|
/**
|
|
40
36
|
* Validate the structure of a spatial relation claim (does not re-evaluate the
|
|
41
37
|
* geometry — verification of the proof envelope also checks the claim ID and
|
|
42
38
|
* evidence hashes).
|
|
43
39
|
*/
|
|
44
|
-
function validateSpatialRelationClaim(claim) {
|
|
40
|
+
export function validateSpatialRelationClaim(claim) {
|
|
45
41
|
const errors = [];
|
|
46
42
|
const warnings = [];
|
|
47
43
|
if (typeof claim.relationId !== 'string' || claim.relationId.length === 0) {
|
package/dist/geometry.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Pure TypeScript geometry helpers for @totemsdk/spatial-proof.
|
|
4
3
|
*
|
|
@@ -9,22 +8,6 @@
|
|
|
9
8
|
*
|
|
10
9
|
* No network, no storage, no GDAL, no PostGIS, no map rendering.
|
|
11
10
|
*/
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.validateCoordinate = validateCoordinate;
|
|
14
|
-
exports.isRingClosed = isRingClosed;
|
|
15
|
-
exports.normalizePolygonRing = normalizePolygonRing;
|
|
16
|
-
exports.normalizePolygon = normalizePolygon;
|
|
17
|
-
exports.validateGeometry = validateGeometry;
|
|
18
|
-
exports.validateSpatialObject = validateSpatialObject;
|
|
19
|
-
exports.getBoundingBox = getBoundingBox;
|
|
20
|
-
exports.bboxIntersects = bboxIntersects;
|
|
21
|
-
exports.bboxCovers = bboxCovers;
|
|
22
|
-
exports.distanceMeters = distanceMeters;
|
|
23
|
-
exports.distancePointToSegmentMeters = distancePointToSegmentMeters;
|
|
24
|
-
exports.distancePointToLineStringMeters = distancePointToLineStringMeters;
|
|
25
|
-
exports.pointInPolygon = pointInPolygon;
|
|
26
|
-
exports.pointInMultiPolygon = pointInMultiPolygon;
|
|
27
|
-
exports.isPointNearBoundary = isPointNearBoundary;
|
|
28
11
|
const EARTH_RADIUS_M = 6371000;
|
|
29
12
|
function toRadians(deg) {
|
|
30
13
|
return (deg * Math.PI) / 180;
|
|
@@ -48,7 +31,7 @@ function ok() {
|
|
|
48
31
|
* Validate a single [lon, lat] coordinate.
|
|
49
32
|
* Returns an error if the coordinate is out of range or not finite.
|
|
50
33
|
*/
|
|
51
|
-
function validateCoordinate(coord) {
|
|
34
|
+
export function validateCoordinate(coord) {
|
|
52
35
|
const errors = [];
|
|
53
36
|
const warnings = [];
|
|
54
37
|
if (!Array.isArray(coord) || coord.length !== 2) {
|
|
@@ -75,7 +58,7 @@ function validateCoordinate(coord) {
|
|
|
75
58
|
* closed, it is rejected (see normalizePolygonRing for the deterministic
|
|
76
59
|
* normalizer).
|
|
77
60
|
*/
|
|
78
|
-
function isRingClosed(ring) {
|
|
61
|
+
export function isRingClosed(ring) {
|
|
79
62
|
if (ring.length < 2)
|
|
80
63
|
return false;
|
|
81
64
|
const first = ring[0];
|
|
@@ -87,7 +70,7 @@ function isRingClosed(ring) {
|
|
|
87
70
|
* first point. Idempotent for already-closed rings. The returned array is a
|
|
88
71
|
* fresh copy — the input is never mutated.
|
|
89
72
|
*/
|
|
90
|
-
function normalizePolygonRing(ring) {
|
|
73
|
+
export function normalizePolygonRing(ring) {
|
|
91
74
|
if (isRingClosed(ring))
|
|
92
75
|
return [...ring];
|
|
93
76
|
return [...ring.map((c) => [c[0], c[1]]), [ring[0][0], ring[0][1]]];
|
|
@@ -95,7 +78,7 @@ function normalizePolygonRing(ring) {
|
|
|
95
78
|
/**
|
|
96
79
|
* Deterministic normalizer for a whole polygon: closes every ring.
|
|
97
80
|
*/
|
|
98
|
-
function normalizePolygon(polygon) {
|
|
81
|
+
export function normalizePolygon(polygon) {
|
|
99
82
|
return {
|
|
100
83
|
type: 'Polygon',
|
|
101
84
|
coordinates: polygon.coordinates.map(normalizePolygonRing),
|
|
@@ -110,7 +93,7 @@ function normalizePolygon(polygon) {
|
|
|
110
93
|
* - Polygon: at least 4 points per ring; rings must be closed
|
|
111
94
|
* - MultiPolygon: at least 1 polygon, each valid
|
|
112
95
|
*/
|
|
113
|
-
function validateGeometry(geometry) {
|
|
96
|
+
export function validateGeometry(geometry) {
|
|
114
97
|
const errors = [];
|
|
115
98
|
const warnings = [];
|
|
116
99
|
switch (geometry.type) {
|
|
@@ -171,7 +154,7 @@ function validateGeometry(geometry) {
|
|
|
171
154
|
* Validate a spatial object. CRS defaults to EPSG:4326; any other CRS
|
|
172
155
|
* produces a warning (all geometry math here assumes WGS84 lon/lat).
|
|
173
156
|
*/
|
|
174
|
-
function validateSpatialObject(obj) {
|
|
157
|
+
export function validateSpatialObject(obj) {
|
|
175
158
|
const errors = [];
|
|
176
159
|
const warnings = [];
|
|
177
160
|
if (typeof obj.spatialId !== 'string' || obj.spatialId.length === 0) {
|
|
@@ -194,7 +177,7 @@ function validateSpatialObject(obj) {
|
|
|
194
177
|
* Compute the axis-aligned bounding box of any geometry. Handles Point,
|
|
195
178
|
* LineString, Polygon, and MultiPolygon (multi-dimensional flattening).
|
|
196
179
|
*/
|
|
197
|
-
function getBoundingBox(geometry) {
|
|
180
|
+
export function getBoundingBox(geometry) {
|
|
198
181
|
const coords = [];
|
|
199
182
|
const collect = (c) => { coords.push(c); };
|
|
200
183
|
switch (geometry.type) {
|
|
@@ -230,13 +213,13 @@ function getBoundingBox(geometry) {
|
|
|
230
213
|
/**
|
|
231
214
|
* True when two bounding boxes share any area or edge.
|
|
232
215
|
*/
|
|
233
|
-
function bboxIntersects(a, b) {
|
|
216
|
+
export function bboxIntersects(a, b) {
|
|
234
217
|
return !(a.maxLon < b.minLon || b.maxLon < a.minLon || a.maxLat < b.minLat || b.maxLat < a.minLat);
|
|
235
218
|
}
|
|
236
219
|
/**
|
|
237
220
|
* True when box `a` fully covers box `b`.
|
|
238
221
|
*/
|
|
239
|
-
function bboxCovers(a, b) {
|
|
222
|
+
export function bboxCovers(a, b) {
|
|
240
223
|
return a.minLon <= b.minLon && a.maxLon >= b.maxLon && a.minLat <= b.minLat && a.maxLat >= b.maxLat;
|
|
241
224
|
}
|
|
242
225
|
// ── Distance ─────────────────────────────────────────────────────────────────
|
|
@@ -244,7 +227,7 @@ function bboxCovers(a, b) {
|
|
|
244
227
|
* Great-circle distance between two [lon, lat] points using the Haversine
|
|
245
228
|
* formula. Approximate (spherical Earth, R = 6371 km).
|
|
246
229
|
*/
|
|
247
|
-
function distanceMeters(a, b) {
|
|
230
|
+
export function distanceMeters(a, b) {
|
|
248
231
|
const dLat = toRadians(b[1] - a[1]);
|
|
249
232
|
const dLon = toRadians(b[0] - a[0]);
|
|
250
233
|
const lat1 = toRadians(a[1]);
|
|
@@ -258,7 +241,7 @@ function distanceMeters(a, b) {
|
|
|
258
241
|
* Uses an equirectangular local approximation scaled to meters — accurate for
|
|
259
242
|
* short segments, approximate over large distances or near the poles.
|
|
260
243
|
*/
|
|
261
|
-
function distancePointToSegmentMeters(point, a, b) {
|
|
244
|
+
export function distancePointToSegmentMeters(point, a, b) {
|
|
262
245
|
const refLat = (point[1] + a[1] + b[1]) / 3;
|
|
263
246
|
const mPerLon = metersPerDegreeLon(refLat);
|
|
264
247
|
const mPerLat = metersPerDegreeLat();
|
|
@@ -282,7 +265,7 @@ function distancePointToSegmentMeters(point, a, b) {
|
|
|
282
265
|
* Minimum distance from a point to a LineString.
|
|
283
266
|
* Approximate: equirectangular scaling applied per segment.
|
|
284
267
|
*/
|
|
285
|
-
function distancePointToLineStringMeters(point, line) {
|
|
268
|
+
export function distancePointToLineStringMeters(point, line) {
|
|
286
269
|
let min = Infinity;
|
|
287
270
|
for (let i = 1; i < line.coordinates.length; i++) {
|
|
288
271
|
const d = distancePointToSegmentMeters(point, line.coordinates[i - 1], line.coordinates[i]);
|
|
@@ -297,7 +280,7 @@ function distancePointToLineStringMeters(point, line) {
|
|
|
297
280
|
* Uses a normalized (closed) copy of the ring. Approximate on the lon/lat
|
|
298
281
|
* plane — fine for typical geofences; not geodesic.
|
|
299
282
|
*/
|
|
300
|
-
function pointInPolygon(point, polygon) {
|
|
283
|
+
export function pointInPolygon(point, polygon) {
|
|
301
284
|
const ring = normalizePolygonRing(polygon.coordinates[0]);
|
|
302
285
|
let inside = false;
|
|
303
286
|
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
|
@@ -313,7 +296,7 @@ function pointInPolygon(point, polygon) {
|
|
|
313
296
|
/**
|
|
314
297
|
* Point-in-MultiPolygon: true when the point is inside any of the polygons.
|
|
315
298
|
*/
|
|
316
|
-
function pointInMultiPolygon(point, multi) {
|
|
299
|
+
export function pointInMultiPolygon(point, multi) {
|
|
317
300
|
return multi.coordinates.some((poly) => pointInPolygon(point, { type: 'Polygon', coordinates: poly }));
|
|
318
301
|
}
|
|
319
302
|
// ── Boundary distance ────────────────────────────────────────────────────────
|
|
@@ -321,7 +304,7 @@ function pointInMultiPolygon(point, multi) {
|
|
|
321
304
|
* True when a point is within `thresholdM` meters of any boundary ring of a
|
|
322
305
|
* Polygon (outer ring and holes). Uses the equirectangular approximation.
|
|
323
306
|
*/
|
|
324
|
-
function isPointNearBoundary(point, polygon, thresholdM) {
|
|
307
|
+
export function isPointNearBoundary(point, polygon, thresholdM) {
|
|
325
308
|
for (const rawRing of polygon.coordinates) {
|
|
326
309
|
const ring = normalizePolygonRing(rawRing);
|
|
327
310
|
for (let i = 1; i < ring.length; i++) {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @module @totemsdk/spatial-proof
|
|
4
3
|
*
|
|
@@ -22,47 +21,10 @@
|
|
|
22
21
|
*
|
|
23
22
|
* COORDINATE ORDER: [lon, lat] (GeoJSON / EPSG:4326).
|
|
24
23
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Object.defineProperty(exports, "computeSpatialObjectId", { enumerable: true, get: function () { return canonical_js_2.computeSpatialObjectId; } });
|
|
33
|
-
Object.defineProperty(exports, "computeSpatialRelationId", { enumerable: true, get: function () { return canonical_js_2.computeSpatialRelationId; } });
|
|
34
|
-
Object.defineProperty(exports, "hashSpatialObject", { enumerable: true, get: function () { return canonical_js_2.hashSpatialObject; } });
|
|
35
|
-
Object.defineProperty(exports, "hashSpatialRelationClaim", { enumerable: true, get: function () { return canonical_js_2.hashSpatialRelationClaim; } });
|
|
36
|
-
var geometry_js_1 = require("./geometry.js");
|
|
37
|
-
Object.defineProperty(exports, "validateCoordinate", { enumerable: true, get: function () { return geometry_js_1.validateCoordinate; } });
|
|
38
|
-
Object.defineProperty(exports, "validateGeometry", { enumerable: true, get: function () { return geometry_js_1.validateGeometry; } });
|
|
39
|
-
Object.defineProperty(exports, "validateSpatialObject", { enumerable: true, get: function () { return geometry_js_1.validateSpatialObject; } });
|
|
40
|
-
Object.defineProperty(exports, "getBoundingBox", { enumerable: true, get: function () { return geometry_js_1.getBoundingBox; } });
|
|
41
|
-
Object.defineProperty(exports, "bboxIntersects", { enumerable: true, get: function () { return geometry_js_1.bboxIntersects; } });
|
|
42
|
-
Object.defineProperty(exports, "bboxCovers", { enumerable: true, get: function () { return geometry_js_1.bboxCovers; } });
|
|
43
|
-
Object.defineProperty(exports, "distanceMeters", { enumerable: true, get: function () { return geometry_js_1.distanceMeters; } });
|
|
44
|
-
Object.defineProperty(exports, "distancePointToSegmentMeters", { enumerable: true, get: function () { return geometry_js_1.distancePointToSegmentMeters; } });
|
|
45
|
-
Object.defineProperty(exports, "distancePointToLineStringMeters", { enumerable: true, get: function () { return geometry_js_1.distancePointToLineStringMeters; } });
|
|
46
|
-
Object.defineProperty(exports, "pointInPolygon", { enumerable: true, get: function () { return geometry_js_1.pointInPolygon; } });
|
|
47
|
-
Object.defineProperty(exports, "pointInMultiPolygon", { enumerable: true, get: function () { return geometry_js_1.pointInMultiPolygon; } });
|
|
48
|
-
Object.defineProperty(exports, "isPointNearBoundary", { enumerable: true, get: function () { return geometry_js_1.isPointNearBoundary; } });
|
|
49
|
-
Object.defineProperty(exports, "isRingClosed", { enumerable: true, get: function () { return geometry_js_1.isRingClosed; } });
|
|
50
|
-
Object.defineProperty(exports, "normalizePolygonRing", { enumerable: true, get: function () { return geometry_js_1.normalizePolygonRing; } });
|
|
51
|
-
Object.defineProperty(exports, "normalizePolygon", { enumerable: true, get: function () { return geometry_js_1.normalizePolygon; } });
|
|
52
|
-
var relations_js_1 = require("./relations.js");
|
|
53
|
-
Object.defineProperty(exports, "evaluateSpatialRelation", { enumerable: true, get: function () { return relations_js_1.evaluateSpatialRelation; } });
|
|
54
|
-
var claim_js_1 = require("./claim.js");
|
|
55
|
-
Object.defineProperty(exports, "spatialRelationFromLocationClaim", { enumerable: true, get: function () { return claim_js_1.spatialRelationFromLocationClaim; } });
|
|
56
|
-
Object.defineProperty(exports, "validateSpatialRelationClaim", { enumerable: true, get: function () { return claim_js_1.validateSpatialRelationClaim; } });
|
|
57
|
-
var proof_js_1 = require("./proof.js");
|
|
58
|
-
Object.defineProperty(exports, "spatialObjectToEvidenceRef", { enumerable: true, get: function () { return proof_js_1.spatialObjectToEvidenceRef; } });
|
|
59
|
-
Object.defineProperty(exports, "spatialRelationToEvidenceRef", { enumerable: true, get: function () { return proof_js_1.spatialRelationToEvidenceRef; } });
|
|
60
|
-
Object.defineProperty(exports, "spatialClaimEvidenceRefs", { enumerable: true, get: function () { return proof_js_1.spatialClaimEvidenceRefs; } });
|
|
61
|
-
Object.defineProperty(exports, "createUnsignedSpatialProof", { enumerable: true, get: function () { return proof_js_1.createUnsignedSpatialProof; } });
|
|
62
|
-
Object.defineProperty(exports, "signSpatialProof", { enumerable: true, get: function () { return proof_js_1.signSpatialProof; } });
|
|
63
|
-
Object.defineProperty(exports, "verifySpatialProof", { enumerable: true, get: function () { return proof_js_1.verifySpatialProof; } });
|
|
64
|
-
var proofgraph_js_1 = require("./proofgraph.js");
|
|
65
|
-
Object.defineProperty(exports, "spatialObjectToProofGraphNode", { enumerable: true, get: function () { return proofgraph_js_1.spatialObjectToProofGraphNode; } });
|
|
66
|
-
Object.defineProperty(exports, "spatialRelationToProofGraphNode", { enumerable: true, get: function () { return proofgraph_js_1.spatialRelationToProofGraphNode; } });
|
|
67
|
-
Object.defineProperty(exports, "spatialRelationToGraphEdges", { enumerable: true, get: function () { return proofgraph_js_1.spatialRelationToGraphEdges; } });
|
|
68
|
-
Object.defineProperty(exports, "addSpatialRelationToGraph", { enumerable: true, get: function () { return proofgraph_js_1.addSpatialRelationToGraph; } });
|
|
24
|
+
export { canonicalJson, toHex } from './canonical.js';
|
|
25
|
+
export { computeGeometryHash, computeSpatialObjectId, computeSpatialRelationId, hashSpatialObject, hashSpatialRelationClaim, } from './canonical.js';
|
|
26
|
+
export { validateCoordinate, validateGeometry, validateSpatialObject, getBoundingBox, bboxIntersects, bboxCovers, distanceMeters, distancePointToSegmentMeters, distancePointToLineStringMeters, pointInPolygon, pointInMultiPolygon, isPointNearBoundary, isRingClosed, normalizePolygonRing, normalizePolygon, } from './geometry.js';
|
|
27
|
+
export { evaluateSpatialRelation } from './relations.js';
|
|
28
|
+
export { spatialRelationFromLocationClaim, validateSpatialRelationClaim, } from './claim.js';
|
|
29
|
+
export { spatialObjectToEvidenceRef, spatialRelationToEvidenceRef, spatialClaimEvidenceRefs, createUnsignedSpatialProof, signSpatialProof, verifySpatialProof, } from './proof.js';
|
|
30
|
+
export { spatialObjectToProofGraphNode, spatialRelationToProofGraphNode, spatialRelationToGraphEdges, addSpatialRelationToGraph, } from './proofgraph.js';
|
package/dist/proof.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Proof envelope integration for @totemsdk/spatial-proof.
|
|
4
3
|
*
|
|
@@ -6,34 +5,27 @@
|
|
|
6
5
|
* evidence refs and signed proof envelopes. Signing/verification delegate to
|
|
7
6
|
* @totemsdk/proof. Anchoring is deliberately NOT required for verification.
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
exports.spatialClaimEvidenceRefs = spatialClaimEvidenceRefs;
|
|
13
|
-
exports.createUnsignedSpatialProof = createUnsignedSpatialProof;
|
|
14
|
-
exports.signSpatialProof = signSpatialProof;
|
|
15
|
-
exports.verifySpatialProof = verifySpatialProof;
|
|
16
|
-
const proof_1 = require("@totemsdk/proof");
|
|
17
|
-
const canonical_js_1 = require("./canonical.js");
|
|
18
|
-
const claim_js_1 = require("./claim.js");
|
|
8
|
+
import { createProof, signProof, verifyProof } from '@totemsdk/proof';
|
|
9
|
+
import { computeGeometryHash, computeSpatialRelationId, hashSpatialObject, hashSpatialRelationClaim, } from './canonical.js';
|
|
10
|
+
import { validateSpatialRelationClaim } from './claim.js';
|
|
19
11
|
/**
|
|
20
12
|
* Convert a SpatialObject into an EvidenceRef for inclusion in a proof.
|
|
21
13
|
*/
|
|
22
|
-
function spatialObjectToEvidenceRef(obj) {
|
|
14
|
+
export function spatialObjectToEvidenceRef(obj) {
|
|
23
15
|
return {
|
|
24
16
|
id: obj.spatialId,
|
|
25
17
|
kind: 'spatial-object',
|
|
26
|
-
hash:
|
|
18
|
+
hash: hashSpatialObject(obj),
|
|
27
19
|
};
|
|
28
20
|
}
|
|
29
21
|
/**
|
|
30
22
|
* Convert a SpatialRelationClaim into an EvidenceRef for inclusion in a proof.
|
|
31
23
|
*/
|
|
32
|
-
function spatialRelationToEvidenceRef(claim) {
|
|
24
|
+
export function spatialRelationToEvidenceRef(claim) {
|
|
33
25
|
return {
|
|
34
26
|
id: claim.relationId,
|
|
35
27
|
kind: 'spatial-relation',
|
|
36
|
-
hash:
|
|
28
|
+
hash: hashSpatialRelationClaim(claim),
|
|
37
29
|
};
|
|
38
30
|
}
|
|
39
31
|
/**
|
|
@@ -43,13 +35,13 @@ function spatialRelationToEvidenceRef(claim) {
|
|
|
43
35
|
* adds the subject geometry hash, subject proof ID, location claim ID, and
|
|
44
36
|
* raster manifest ID when present on the claim.
|
|
45
37
|
*/
|
|
46
|
-
function spatialClaimEvidenceRefs(claim, obj, subjectGeometry) {
|
|
38
|
+
export function spatialClaimEvidenceRefs(claim, obj, subjectGeometry) {
|
|
47
39
|
const refs = [spatialRelationToEvidenceRef(claim), spatialObjectToEvidenceRef(obj)];
|
|
48
40
|
if (claim.inputs.subjectGeometryHash) {
|
|
49
41
|
refs.push({
|
|
50
42
|
id: claim.inputs.subjectGeometryHash,
|
|
51
43
|
kind: 'geometry',
|
|
52
|
-
hash: subjectGeometry ?
|
|
44
|
+
hash: subjectGeometry ? computeGeometryHash(subjectGeometry) : claim.inputs.subjectGeometryHash,
|
|
53
45
|
});
|
|
54
46
|
}
|
|
55
47
|
if (claim.inputs.subjectProofId) {
|
|
@@ -70,9 +62,9 @@ function spatialClaimEvidenceRefs(claim, obj, subjectGeometry) {
|
|
|
70
62
|
* at this time, computed by this engine." It does NOT claim the relation is
|
|
71
63
|
* geodetically exact — approximation notes travel inside the claim result.
|
|
72
64
|
*/
|
|
73
|
-
function createUnsignedSpatialProof(params) {
|
|
65
|
+
export function createUnsignedSpatialProof(params) {
|
|
74
66
|
const { claim, spatialObject } = params;
|
|
75
|
-
return
|
|
67
|
+
return createProof({
|
|
76
68
|
kind: 'attestation',
|
|
77
69
|
subject: {
|
|
78
70
|
id: claim.subjectId,
|
|
@@ -95,8 +87,8 @@ function createUnsignedSpatialProof(params) {
|
|
|
95
87
|
* The caller is responsible for reserving the WOTS key index (see
|
|
96
88
|
* @totemsdk/wots-lease) before calling — one-time key warning applies.
|
|
97
89
|
*/
|
|
98
|
-
function signSpatialProof(unsigned, seed, keyIndex) {
|
|
99
|
-
return
|
|
90
|
+
export function signSpatialProof(unsigned, seed, keyIndex) {
|
|
91
|
+
return signProof(unsigned, seed, keyIndex);
|
|
100
92
|
}
|
|
101
93
|
/**
|
|
102
94
|
* Verify a signed spatial proof end to end.
|
|
@@ -111,8 +103,8 @@ function signSpatialProof(unsigned, seed, keyIndex) {
|
|
|
111
103
|
*
|
|
112
104
|
* Anchoring is not required.
|
|
113
105
|
*/
|
|
114
|
-
function verifySpatialProof(signed) {
|
|
115
|
-
const base =
|
|
106
|
+
export function verifySpatialProof(signed) {
|
|
107
|
+
const base = verifyProof(signed);
|
|
116
108
|
if (!base.valid) {
|
|
117
109
|
return {
|
|
118
110
|
valid: false,
|
|
@@ -125,7 +117,7 @@ function verifySpatialProof(signed) {
|
|
|
125
117
|
if (!claim || typeof claim !== 'object') {
|
|
126
118
|
return { valid: false, reason: 'payload missing spatialRelation claim', signerAddress };
|
|
127
119
|
}
|
|
128
|
-
const validation =
|
|
120
|
+
const validation = validateSpatialRelationClaim(claim);
|
|
129
121
|
if (!validation.valid) {
|
|
130
122
|
return {
|
|
131
123
|
valid: false,
|
|
@@ -135,7 +127,7 @@ function verifySpatialProof(signed) {
|
|
|
135
127
|
};
|
|
136
128
|
}
|
|
137
129
|
const { relationId: _relationId, ...rest } = claim;
|
|
138
|
-
const recomputedId =
|
|
130
|
+
const recomputedId = computeSpatialRelationId(rest);
|
|
139
131
|
if (recomputedId !== claim.relationId) {
|
|
140
132
|
return {
|
|
141
133
|
valid: false,
|
|
@@ -156,7 +148,7 @@ function verifySpatialProof(signed) {
|
|
|
156
148
|
signerAddress,
|
|
157
149
|
};
|
|
158
150
|
}
|
|
159
|
-
const expectedRelationHash =
|
|
151
|
+
const expectedRelationHash = hashSpatialRelationClaim(claim);
|
|
160
152
|
if (relationEvidence.hash !== expectedRelationHash) {
|
|
161
153
|
return {
|
|
162
154
|
valid: false,
|
package/dist/proofgraph.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Proofgraph integration helpers for @totemsdk/spatial-proof.
|
|
4
3
|
*
|
|
@@ -12,28 +11,23 @@
|
|
|
12
11
|
* 'spatial-object' / 'spatial-relation' node type is ever wanted, propose it
|
|
13
12
|
* in @totemsdk/proofgraph (do not silently fork the vocabulary).
|
|
14
13
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
exports.spatialRelationToProofGraphNode = spatialRelationToProofGraphNode;
|
|
18
|
-
exports.spatialRelationToGraphEdges = spatialRelationToGraphEdges;
|
|
19
|
-
exports.addSpatialRelationToGraph = addSpatialRelationToGraph;
|
|
20
|
-
const proofgraph_1 = require("@totemsdk/proofgraph");
|
|
21
|
-
const canonical_js_1 = require("./canonical.js");
|
|
14
|
+
import { addNode, buildEdge, computeNodeId } from '@totemsdk/proofgraph';
|
|
15
|
+
import { computeGeometryHash } from './canonical.js';
|
|
22
16
|
/**
|
|
23
17
|
* Build a ProofGraphNode for a spatial object.
|
|
24
18
|
*
|
|
25
19
|
* Uses the 'custom' node type (no native proofgraph node type fits a spatial
|
|
26
20
|
* object). Node ID is deterministic: "custom:<spatialId>".
|
|
27
21
|
*/
|
|
28
|
-
function spatialObjectToProofGraphNode(obj) {
|
|
22
|
+
export function spatialObjectToProofGraphNode(obj) {
|
|
29
23
|
return {
|
|
30
|
-
id:
|
|
24
|
+
id: computeNodeId('custom', obj.spatialId),
|
|
31
25
|
type: 'custom',
|
|
32
26
|
refId: obj.spatialId,
|
|
33
27
|
data: {
|
|
34
28
|
kind: 'spatial-object',
|
|
35
29
|
spatialKind: obj.kind,
|
|
36
|
-
geometryHash:
|
|
30
|
+
geometryHash: computeGeometryHash(obj.geometry),
|
|
37
31
|
...(obj.name !== undefined ? { name: obj.name } : {}),
|
|
38
32
|
...(obj.crs !== undefined ? { crs: obj.crs } : {}),
|
|
39
33
|
},
|
|
@@ -45,9 +39,9 @@ function spatialObjectToProofGraphNode(obj) {
|
|
|
45
39
|
*
|
|
46
40
|
* Uses the 'custom' node type. Node ID is deterministic: "custom:<relationId>".
|
|
47
41
|
*/
|
|
48
|
-
function spatialRelationToProofGraphNode(claim) {
|
|
42
|
+
export function spatialRelationToProofGraphNode(claim) {
|
|
49
43
|
return {
|
|
50
|
-
id:
|
|
44
|
+
id: computeNodeId('custom', claim.relationId),
|
|
51
45
|
type: 'custom',
|
|
52
46
|
refId: claim.relationId,
|
|
53
47
|
data: {
|
|
@@ -70,19 +64,19 @@ function spatialRelationToProofGraphNode(claim) {
|
|
|
70
64
|
*
|
|
71
65
|
* Edge IDs are deterministic (content-derived in @totemsdk/proofgraph).
|
|
72
66
|
*/
|
|
73
|
-
function spatialRelationToGraphEdges(claim) {
|
|
67
|
+
export function spatialRelationToGraphEdges(claim) {
|
|
74
68
|
const edges = [
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
buildEdge('about', claim.relationId, claim.subjectId, claim.relationId),
|
|
70
|
+
buildEdge('references', claim.relationId, claim.spatialObjectId, claim.relationId),
|
|
77
71
|
];
|
|
78
72
|
if (claim.inputs.locationClaimId) {
|
|
79
|
-
edges.push(
|
|
73
|
+
edges.push(buildEdge('derived_from', claim.relationId, claim.inputs.locationClaimId, claim.relationId));
|
|
80
74
|
}
|
|
81
75
|
if (claim.inputs.subjectProofId) {
|
|
82
|
-
edges.push(
|
|
76
|
+
edges.push(buildEdge('references', claim.relationId, claim.inputs.subjectProofId, claim.relationId));
|
|
83
77
|
}
|
|
84
78
|
if (claim.inputs.rasterManifestId) {
|
|
85
|
-
edges.push(
|
|
79
|
+
edges.push(buildEdge('references', claim.relationId, claim.inputs.rasterManifestId, claim.relationId));
|
|
86
80
|
}
|
|
87
81
|
return edges;
|
|
88
82
|
}
|
|
@@ -90,8 +84,8 @@ function spatialRelationToGraphEdges(claim) {
|
|
|
90
84
|
* Add a spatial relation claim as a 'custom' node to a proof graph (immutable
|
|
91
85
|
* — returns a new graph).
|
|
92
86
|
*/
|
|
93
|
-
function addSpatialRelationToGraph(graph, claim) {
|
|
94
|
-
return
|
|
87
|
+
export function addSpatialRelationToGraph(graph, claim) {
|
|
88
|
+
return addNode(graph, 'custom', claim.relationId, {
|
|
95
89
|
kind: 'spatial-relation',
|
|
96
90
|
...claim,
|
|
97
91
|
});
|