@totemsdk/spatial-proof 0.1.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 +23 -16
package/dist/relations.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Spatial relation evaluation for @totemsdk/spatial-proof.
|
|
4
3
|
*
|
|
@@ -12,10 +11,8 @@
|
|
|
12
11
|
*
|
|
13
12
|
* All functions are deterministic and dependency-free.
|
|
14
13
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const canonical_js_1 = require("./canonical.js");
|
|
18
|
-
const geometry_js_1 = require("./geometry.js");
|
|
14
|
+
import { computeGeometryHash, computeSpatialRelationId } from './canonical.js';
|
|
15
|
+
import { bboxCovers, bboxIntersects, distanceMeters, distancePointToLineStringMeters, distancePointToSegmentMeters, getBoundingBox, isPointNearBoundary, pointInMultiPolygon, pointInPolygon, validateSpatialObject, } from './geometry.js';
|
|
19
16
|
const ENGINE_NAME = '@totemsdk/spatial-proof';
|
|
20
17
|
const ENGINE_VERSION = '0.1.0';
|
|
21
18
|
const BBOX_UNCERTAINTY = 'Relation evaluated using bounding-box approximation; exact polygon intersection not implemented.';
|
|
@@ -33,9 +30,9 @@ function isLineStringGeometry(g) {
|
|
|
33
30
|
}
|
|
34
31
|
function pointInside(g, point) {
|
|
35
32
|
if (isPolygonGeometry(g))
|
|
36
|
-
return
|
|
33
|
+
return pointInPolygon(point.coordinates, g);
|
|
37
34
|
if (isMultiPolygonGeometry(g))
|
|
38
|
-
return
|
|
35
|
+
return pointInMultiPolygon(point.coordinates, g);
|
|
39
36
|
return false;
|
|
40
37
|
}
|
|
41
38
|
/**
|
|
@@ -44,15 +41,15 @@ function pointInside(g, point) {
|
|
|
44
41
|
* The claim's relationId is content-derived from all fields except relationId
|
|
45
42
|
* and metadata, so identical evaluations always produce the same ID.
|
|
46
43
|
*/
|
|
47
|
-
function evaluateSpatialRelation(params) {
|
|
44
|
+
export function evaluateSpatialRelation(params) {
|
|
48
45
|
const { subjectId, subjectKind, spatialObject, relation, computedAt = Date.now() } = params;
|
|
49
|
-
const validation =
|
|
46
|
+
const validation = validateSpatialObject(spatialObject);
|
|
50
47
|
if (!validation.valid) {
|
|
51
48
|
throw new Error('invalid spatial object: ' + validation.errors.join('; '));
|
|
52
49
|
}
|
|
53
|
-
const spatialGeometryHash =
|
|
50
|
+
const spatialGeometryHash = computeGeometryHash(spatialObject.geometry);
|
|
54
51
|
const subjectGeometryHash = params.subjectGeometry
|
|
55
|
-
?
|
|
52
|
+
? computeGeometryHash(params.subjectGeometry)
|
|
56
53
|
: undefined;
|
|
57
54
|
// NOTE: relationId is NOT computed here. It is stamped once, at the very end,
|
|
58
55
|
// after every branch has finalised engine.algorithm and result, so recomputing
|
|
@@ -76,7 +73,7 @@ function evaluateSpatialRelation(params) {
|
|
|
76
73
|
};
|
|
77
74
|
function emit(overrides = {}) {
|
|
78
75
|
const body = { ...base, ...overrides };
|
|
79
|
-
return { ...body, relationId:
|
|
76
|
+
return { ...body, relationId: computeSpatialRelationId(body) };
|
|
80
77
|
}
|
|
81
78
|
if (!params.subjectGeometry) {
|
|
82
79
|
return emit({
|
|
@@ -130,7 +127,7 @@ function evaluateSpatialRelation(params) {
|
|
|
130
127
|
// ── within_distance (point vs point via Haversine) ─────────────────────────
|
|
131
128
|
if (relation === 'within_distance') {
|
|
132
129
|
if (isPointGeometry(subject) && isPointGeometry(obj)) {
|
|
133
|
-
const distanceM =
|
|
130
|
+
const distanceM = distanceMeters(subject.coordinates, obj.coordinates);
|
|
134
131
|
const maxDistanceM = params.maxDistanceM ?? 0;
|
|
135
132
|
return emit({
|
|
136
133
|
engine: { name: ENGINE_NAME, version: ENGINE_VERSION, algorithm: 'haversine great-circle distance' },
|
|
@@ -156,14 +153,14 @@ function evaluateSpatialRelation(params) {
|
|
|
156
153
|
let nearest = Infinity;
|
|
157
154
|
let matched = false;
|
|
158
155
|
for (const poly of polys) {
|
|
159
|
-
const inside =
|
|
160
|
-
const near =
|
|
156
|
+
const inside = pointInPolygon(subject.coordinates, poly);
|
|
157
|
+
const near = isPointNearBoundary(subject.coordinates, poly, thresholdM);
|
|
161
158
|
if (!inside && near)
|
|
162
159
|
matched = true;
|
|
163
160
|
// distance to nearest ring vertex as a rough distance figure
|
|
164
161
|
for (const ring of poly.coordinates) {
|
|
165
162
|
for (let i = 1; i < ring.length; i++) {
|
|
166
|
-
const d =
|
|
163
|
+
const d = distancePointToSegmentMeters(subject.coordinates, ring[i - 1], ring[i]);
|
|
167
164
|
if (!inside && d < nearest)
|
|
168
165
|
nearest = d;
|
|
169
166
|
}
|
|
@@ -188,7 +185,7 @@ function evaluateSpatialRelation(params) {
|
|
|
188
185
|
// ── on_route (point near LineString) ───────────────────────────────────────
|
|
189
186
|
if (relation === 'on_route') {
|
|
190
187
|
if (isPointGeometry(subject) && isLineStringGeometry(obj)) {
|
|
191
|
-
const distanceM =
|
|
188
|
+
const distanceM = distancePointToLineStringMeters(subject.coordinates, obj);
|
|
192
189
|
const maxDistanceM = params.maxDistanceM ?? 0;
|
|
193
190
|
return emit({
|
|
194
191
|
engine: { name: ENGINE_NAME, version: ENGINE_VERSION, algorithm: 'point-to-LineString distance (equirectangular approximation)' },
|
|
@@ -209,9 +206,9 @@ function evaluateSpatialRelation(params) {
|
|
|
209
206
|
}
|
|
210
207
|
// ── intersects / overlaps (bbox precheck; polygon relation where feasible) ─
|
|
211
208
|
if (relation === 'intersects' || relation === 'overlaps') {
|
|
212
|
-
const subBox =
|
|
213
|
-
const objBox =
|
|
214
|
-
const boxOk =
|
|
209
|
+
const subBox = getBoundingBox(subject);
|
|
210
|
+
const objBox = getBoundingBox(obj);
|
|
211
|
+
const boxOk = bboxIntersects(subBox, objBox);
|
|
215
212
|
// When both are polygons we can say more than the box: check vertices.
|
|
216
213
|
const exact = isPolygonGeometry(subject) && (isPolygonGeometry(obj) || isMultiPolygonGeometry(obj))
|
|
217
214
|
? polygonIntersectsExact(subject, obj)
|
|
@@ -231,9 +228,9 @@ function evaluateSpatialRelation(params) {
|
|
|
231
228
|
}
|
|
232
229
|
// ── covers / covered_by (scene footprint bbox covers site boundary bbox) ──
|
|
233
230
|
if (relation === 'covers' || relation === 'covered_by') {
|
|
234
|
-
const subBox =
|
|
235
|
-
const objBox =
|
|
236
|
-
const matched = relation === 'covers' ?
|
|
231
|
+
const subBox = getBoundingBox(subject);
|
|
232
|
+
const objBox = getBoundingBox(obj);
|
|
233
|
+
const matched = relation === 'covers' ? bboxCovers(subBox, objBox) : bboxCovers(objBox, subBox);
|
|
237
234
|
return emit({
|
|
238
235
|
engine: { name: ENGINE_NAME, version: ENGINE_VERSION, algorithm: 'bbox cover check' },
|
|
239
236
|
result: {
|
|
@@ -255,13 +252,13 @@ function polygonIntersectsExact(subject, obj) {
|
|
|
255
252
|
for (const poly of objPolys) {
|
|
256
253
|
for (const ring of subject.coordinates) {
|
|
257
254
|
for (const v of ring) {
|
|
258
|
-
if (
|
|
255
|
+
if (pointInPolygon(v, poly))
|
|
259
256
|
return true;
|
|
260
257
|
}
|
|
261
258
|
}
|
|
262
259
|
for (const ring of poly.coordinates) {
|
|
263
260
|
for (const v of ring) {
|
|
264
|
-
if (
|
|
261
|
+
if (pointInPolygon(v, subject))
|
|
265
262
|
return true;
|
|
266
263
|
}
|
|
267
264
|
}
|
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totemsdk/spatial-proof",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Generic spatial relationship proof primitives for Totem Edge — geometry hashes, geofence relations, route checks, and proof envelope integration",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"types": "dist/cjs/index.d.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
"import": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"require": {
|
|
14
|
+
"types": "./dist/cjs/index.d.ts",
|
|
15
|
+
"default": "./dist/cjs/index.js"
|
|
16
|
+
}
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
19
|
"files": [
|
|
15
20
|
"dist",
|
|
16
21
|
"README.md",
|
|
17
|
-
"LICENSE"
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"NOTICE"
|
|
18
24
|
],
|
|
19
25
|
"dependencies": {
|
|
20
|
-
"@totemsdk/core": "^1.2
|
|
21
|
-
"@totemsdk/proof": "^0.
|
|
22
|
-
"@totemsdk/location-proof": "^0.1
|
|
23
|
-
"@totemsdk/proofgraph": "^
|
|
26
|
+
"@totemsdk/core": "^1.4.2",
|
|
27
|
+
"@totemsdk/proof": "^1.0.2",
|
|
28
|
+
"@totemsdk/location-proof": "^1.0.1",
|
|
29
|
+
"@totemsdk/proofgraph": "^1.1.0"
|
|
24
30
|
},
|
|
25
31
|
"devDependencies": {
|
|
26
32
|
"@types/jest": "^30.0.0",
|
|
@@ -35,15 +41,15 @@
|
|
|
35
41
|
"publishConfig": {
|
|
36
42
|
"access": "public"
|
|
37
43
|
},
|
|
38
|
-
"license": "
|
|
44
|
+
"license": "Apache-2.0",
|
|
39
45
|
"author": "Totem SDK",
|
|
40
|
-
"homepage": "https://totem.ing",
|
|
46
|
+
"homepage": "https://docs.totem.ing",
|
|
41
47
|
"bugs": {
|
|
42
|
-
"url": "https://github.com/
|
|
48
|
+
"url": "https://github.com/Totem-Edge/totem-sdk/issues"
|
|
43
49
|
},
|
|
44
50
|
"repository": {
|
|
45
51
|
"type": "git",
|
|
46
|
-
"url": "git+https://github.com/
|
|
52
|
+
"url": "git+https://github.com/Totem-Edge/totem-sdk.git",
|
|
47
53
|
"directory": "packages/spatial-proof"
|
|
48
54
|
},
|
|
49
55
|
"keywords": [
|
|
@@ -59,8 +65,9 @@
|
|
|
59
65
|
"edge",
|
|
60
66
|
"autonomous-devices"
|
|
61
67
|
],
|
|
68
|
+
"type": "module",
|
|
62
69
|
"scripts": {
|
|
63
|
-
"build": "tsc",
|
|
70
|
+
"build": "tsc && tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('dist/cjs/package.json', JSON.stringify({type:'commonjs'})+'\\n')\"",
|
|
64
71
|
"clean": "rm -rf dist",
|
|
65
72
|
"test": "jest"
|
|
66
73
|
}
|