@osmix/core 0.1.10 → 0.3.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.
Files changed (97) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +136 -72
  4. package/dist/contracts.d.ts +27 -0
  5. package/dist/contracts.d.ts.map +1 -0
  6. package/dist/contracts.js +1 -0
  7. package/dist/contracts.js.map +1 -0
  8. package/dist/entities.d.ts +22 -2
  9. package/dist/entities.d.ts.map +1 -1
  10. package/dist/entities.js +54 -10
  11. package/dist/entities.js.map +1 -1
  12. package/dist/ids.d.ts +20 -5
  13. package/dist/ids.d.ts.map +1 -1
  14. package/dist/ids.js +87 -29
  15. package/dist/ids.js.map +1 -1
  16. package/dist/index.d.ts +7 -4
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +6 -4
  19. package/dist/index.js.map +1 -1
  20. package/dist/indirect-kd-index.d.ts +28 -0
  21. package/dist/indirect-kd-index.d.ts.map +1 -0
  22. package/dist/indirect-kd-index.js +163 -0
  23. package/dist/indirect-kd-index.js.map +1 -0
  24. package/dist/limits.d.ts +30 -0
  25. package/dist/limits.d.ts.map +1 -0
  26. package/dist/limits.js +51 -0
  27. package/dist/limits.js.map +1 -0
  28. package/dist/mocks.d.ts.map +1 -1
  29. package/dist/mocks.js.map +1 -1
  30. package/dist/nodes.d.ts +36 -15
  31. package/dist/nodes.d.ts.map +1 -1
  32. package/dist/nodes.js +185 -62
  33. package/dist/nodes.js.map +1 -1
  34. package/dist/osm.d.ts +60 -4
  35. package/dist/osm.d.ts.map +1 -1
  36. package/dist/osm.js +32 -6
  37. package/dist/osm.js.map +1 -1
  38. package/dist/relations.d.ts +11 -4
  39. package/dist/relations.d.ts.map +1 -1
  40. package/dist/relations.js +73 -29
  41. package/dist/relations.js.map +1 -1
  42. package/dist/renumber.d.ts +23 -0
  43. package/dist/renumber.d.ts.map +1 -0
  44. package/dist/renumber.js +64 -0
  45. package/dist/renumber.js.map +1 -0
  46. package/dist/stringtable.d.ts +2 -1
  47. package/dist/stringtable.d.ts.map +1 -1
  48. package/dist/stringtable.js +9 -14
  49. package/dist/stringtable.js.map +1 -1
  50. package/dist/tags.d.ts +45 -12
  51. package/dist/tags.d.ts.map +1 -1
  52. package/dist/tags.js +153 -27
  53. package/dist/tags.js.map +1 -1
  54. package/dist/typed-arrays.d.ts +63 -48
  55. package/dist/typed-arrays.d.ts.map +1 -1
  56. package/dist/typed-arrays.js +184 -107
  57. package/dist/typed-arrays.js.map +1 -1
  58. package/dist/ways.d.ts +52 -3
  59. package/dist/ways.d.ts.map +1 -1
  60. package/dist/ways.js +223 -46
  61. package/dist/ways.js.map +1 -1
  62. package/package.json +45 -31
  63. package/src/contracts.ts +29 -0
  64. package/src/entities.ts +242 -194
  65. package/src/ids.ts +278 -235
  66. package/src/index.ts +22 -13
  67. package/src/indirect-kd-index.ts +212 -0
  68. package/src/limits.ts +73 -0
  69. package/src/mocks.ts +114 -113
  70. package/src/nodes.ts +538 -397
  71. package/src/osm.ts +282 -207
  72. package/src/relations.ts +580 -558
  73. package/src/renumber.ts +80 -0
  74. package/src/stringtable.ts +189 -184
  75. package/src/tags.ts +406 -272
  76. package/src/typed-arrays.ts +307 -205
  77. package/src/types/geoflatbush.d.ts +28 -33
  78. package/src/ways.ts +577 -406
  79. package/test/entity-index-errors.test.ts +41 -0
  80. package/test/ids.bench.ts +33 -0
  81. package/test/ids.test.ts +122 -0
  82. package/test/limits.test.ts +83 -0
  83. package/test/memory.test.ts +29 -30
  84. package/test/no-shared-array-buffer.test.ts +41 -0
  85. package/test/nodes-spatial-index.test.ts +261 -0
  86. package/test/osm-bbox.test.ts +30 -0
  87. package/test/relations.bench.ts +32 -0
  88. package/test/relations.test.ts +124 -0
  89. package/test/renumber.test.ts +54 -0
  90. package/test/spatial-index-rebuild.test.ts +33 -0
  91. package/test/storage-compaction.test.ts +269 -0
  92. package/test/tags-search.test.ts +89 -56
  93. package/test/typed-arrays.test.ts +252 -132
  94. package/tsconfig.build.json +6 -6
  95. package/tsconfig.json +7 -7
  96. package/src/types/geokdbush.d.ts +0 -37
  97. package/src/types/kdbush.d.ts +0 -47
package/dist/osm.d.ts CHANGED
@@ -1,28 +1,81 @@
1
1
  import type { OsmPbfHeaderBlock } from "@osmix/pbf";
2
- import type { GeoBbox2D } from "@osmix/shared/types";
2
+ import type { GeoBbox2D } from "@osmix/types";
3
3
  import { Nodes, type NodesTransferables } from "./nodes.ts";
4
4
  import { Relations, type RelationsTransferables } from "./relations.ts";
5
5
  import StringTable, { type StringTableTransferables } from "./stringtable.ts";
6
6
  import type { BufferType } from "./typed-arrays.ts";
7
7
  import { Ways, type WaysTransferables } from "./ways.ts";
8
+ export declare const OSM_TRANSFER_VERSION: 2;
9
+ export declare const OSM_CONTENT_HASH_VERSION: 2;
8
10
  export interface OsmTransferables<T extends BufferType = BufferType> {
11
+ transferVersion: typeof OSM_TRANSFER_VERSION;
12
+ contentHashVersion: typeof OSM_CONTENT_HASH_VERSION;
9
13
  id: string;
10
14
  header: OsmPbfHeaderBlock;
11
15
  contentHash: string;
16
+ loadDiagnostics?: OsmLoadDiagnostics;
12
17
  stringTable: StringTableTransferables<T>;
13
18
  nodes: NodesTransferables<T>;
14
19
  ways: WaysTransferables<T>;
15
20
  relations: RelationsTransferables<T>;
16
21
  }
22
+ export type OsmLoadProfile = "auto" | "full" | "view";
23
+ export type ResolvedOsmLoadProfile = Exclude<OsmLoadProfile, "auto">;
24
+ export interface OsmLoadDiagnosticReason {
25
+ code: string;
26
+ level: "info" | "warning";
27
+ message: string;
28
+ }
29
+ /** Plain-data diagnostics attached by loaders and safe to transfer between workers. */
30
+ export interface OsmLoadDiagnostics {
31
+ requestedProfile: OsmLoadProfile;
32
+ selectedProfile: ResolvedOsmLoadProfile;
33
+ reasons: OsmLoadDiagnosticReason[];
34
+ bytes: {
35
+ residentTypedBuffers: number;
36
+ projectedTypedBufferPeak: number;
37
+ largestPlannedAllocation: number;
38
+ storageBytes?: number;
39
+ };
40
+ budgets: {
41
+ workingSet?: number;
42
+ singleAllocation?: number;
43
+ allNodeSpatialIndex?: number;
44
+ arrayBufferCeiling?: number;
45
+ sharedArrayBufferCeiling?: number;
46
+ };
47
+ phaseTimingsMs: Record<string, number>;
48
+ counters: {
49
+ taggedNodes?: number;
50
+ taggedWays?: number;
51
+ taggedRelations?: number;
52
+ nodeTagPairs?: number;
53
+ wayTagPairs?: number;
54
+ relationTagPairs?: number;
55
+ wayReferences?: number;
56
+ missingWayReferences?: number;
57
+ relationMembers?: number;
58
+ };
59
+ }
17
60
  export interface OsmInfo {
18
61
  id: string;
19
- bbox: GeoBbox2D;
62
+ /** Bounding box of all nodes, or `null` when the dataset has no nodes. */
63
+ bbox: GeoBbox2D | null;
20
64
  header: OsmPbfHeaderBlock;
21
65
  stats: {
22
66
  nodes: number;
23
67
  ways: number;
24
68
  relations: number;
25
69
  };
70
+ spatialIndexes: {
71
+ nodes: {
72
+ all: boolean;
73
+ tagged: boolean;
74
+ };
75
+ ways: boolean;
76
+ relations: boolean;
77
+ };
78
+ loadDiagnostics?: OsmLoadDiagnostics;
26
79
  }
27
80
  export interface OsmOptions {
28
81
  id: string;
@@ -40,6 +93,7 @@ export declare class Osm {
40
93
  readonly relations: Relations;
41
94
  private indexBuilt;
42
95
  private _contentHash;
96
+ private _loadDiagnostics?;
43
97
  /**
44
98
  * Create a new OSM Entity index.
45
99
  */
@@ -62,13 +116,15 @@ export declare class Osm {
62
116
  */
63
117
  hasSpatialIndexes(): boolean;
64
118
  /**
65
- * Get the bounding box of all entities in the OSM index.
119
+ * Get the bounding box of all entities in the OSM index, or `null` when there are no nodes.
66
120
  */
67
- bbox(): GeoBbox2D;
121
+ bbox(): GeoBbox2D | null;
68
122
  /**
69
123
  * Get information about the OSM index.
70
124
  */
71
125
  info(): OsmInfo;
126
+ /** Attach loader-provided diagnostics for `info()` and worker transfer. */
127
+ setLoadDiagnostics(loadDiagnostics: OsmLoadDiagnostics | undefined): void;
72
128
  /**
73
129
  * Get transferable objects for passing to another thread.
74
130
  */
package/dist/osm.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"osm.d.ts","sourceRoot":"","sources":["../src/osm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,KAAK,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvE,OAAO,WAAW,EAAE,EAAE,KAAK,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAExD,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAClE,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,iBAAiB,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAA;IACxC,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAA;IAC5B,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAA;IAC1B,SAAS,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,OAAO;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,iBAAiB,CAAA;IACzB,KAAK,EAAE;QACN,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,SAAS,EAAE,MAAM,CAAA;KACjB,CAAA;CACD;AAED,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,iBAAiB,CAAA;CACzB;AAED;;GAEG;AACH,qBAAa,GAAG;IAEf,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAGlC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAE7B,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,YAAY,CAAK;IAEzB;;OAEG;IACH,YAAY,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,gBAAgB,GAAG,GAAG,EA0C9D;IAED;;;OAGG;IACH,YAAY,SAQX;IAED;;OAEG;IACH,OAAO,YAON;IAED;;OAEG;IACH,mBAAmB,SAIlB;IAED;;OAEG;IACH,iBAAiB,IAAI,OAAO,CAM3B;IAED;;OAEG;IACH,IAAI,IAAI,SAAS,CAEhB;IAED;;OAEG;IACH,IAAI,IAAI,OAAO,CAWd;IAED;;OAEG;IACH,aAAa,IAAI,gBAAgB,CAUhC;IAED;;;;;OAKG;IACH,WAAW,IAAI,MAAM,CAEpB;IAED;;;;;;OAMG;IACH,OAAO,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG9C;IAED;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;CAU1B"}
1
+ {"version":3,"file":"osm.d.ts","sourceRoot":"","sources":["../src/osm.ts"],"names":[],"mappings":"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"}
package/dist/osm.js CHANGED
@@ -3,6 +3,8 @@ import { Nodes } from "./nodes.js";
3
3
  import { Relations } from "./relations.js";
4
4
  import StringTable, {} from "./stringtable.js";
5
5
  import { Ways } from "./ways.js";
6
+ export const OSM_TRANSFER_VERSION = 2;
7
+ export const OSM_CONTENT_HASH_VERSION = 2;
6
8
  /**
7
9
  * OSM Entity Index.
8
10
  */
@@ -17,6 +19,7 @@ export class Osm {
17
19
  relations;
18
20
  indexBuilt = false;
19
21
  _contentHash = "";
22
+ _loadDiagnostics;
20
23
  /**
21
24
  * Create a new OSM Entity index.
22
25
  */
@@ -33,14 +36,22 @@ export class Osm {
33
36
  this.ways = new Ways(this.stringTable, this.nodes, opts.ways.transferables());
34
37
  this.relations = new Relations(this.stringTable, this.nodes, this.ways, opts.relations.transferables());
35
38
  this._contentHash = opts._contentHash;
39
+ this._loadDiagnostics = opts._loadDiagnostics;
36
40
  this.indexBuilt = true;
37
41
  }
38
42
  else {
43
+ if (opts.transferVersion !== OSM_TRANSFER_VERSION) {
44
+ throw Error(`Unsupported OSM transfer version: ${String(opts.transferVersion)}. Expected ${String(OSM_TRANSFER_VERSION)}.`);
45
+ }
46
+ if (opts.contentHashVersion !== OSM_CONTENT_HASH_VERSION) {
47
+ throw Error(`Unsupported OSM content hash version: ${String(opts.contentHashVersion)}. Expected ${String(OSM_CONTENT_HASH_VERSION)}.`);
48
+ }
39
49
  this.stringTable = new StringTable(opts.stringTable);
40
50
  this.nodes = new Nodes(this.stringTable, opts.nodes);
41
51
  this.ways = new Ways(this.stringTable, this.nodes, opts.ways);
42
52
  this.relations = new Relations(this.stringTable, this.nodes, this.ways, opts.relations);
43
53
  this._contentHash = opts.contentHash;
54
+ this._loadDiagnostics = opts.loadDiagnostics;
44
55
  this.indexBuilt = true;
45
56
  }
46
57
  }
@@ -68,15 +79,13 @@ export class Osm {
68
79
  * Check if the index is built and ready for use.
69
80
  */
70
81
  isReady() {
71
- return (this.nodes.isReady() &&
72
- this.ways.isReady() &&
73
- this.relations.isReady() &&
74
- this.indexBuilt);
82
+ return (this.nodes.isReady() && this.ways.isReady() && this.relations.isReady() && this.indexBuilt);
75
83
  }
76
84
  /**
77
85
  * Build spatial indexes for all entities.
78
86
  */
79
87
  buildSpatialIndexes() {
88
+ this.nodes.buildSpatialIndex("tagged");
80
89
  this.nodes.buildSpatialIndex();
81
90
  this.ways.buildSpatialIndex();
82
91
  this.relations.buildSpatialIndex();
@@ -86,11 +95,12 @@ export class Osm {
86
95
  */
87
96
  hasSpatialIndexes() {
88
97
  return (this.nodes.hasSpatialIndex() &&
98
+ this.nodes.hasSpatialIndex("tagged") &&
89
99
  this.ways.hasSpatialIndex() &&
90
100
  this.relations.hasSpatialIndex());
91
101
  }
92
102
  /**
93
- * Get the bounding box of all entities in the OSM index.
103
+ * Get the bounding box of all entities in the OSM index, or `null` when there are no nodes.
94
104
  */
95
105
  bbox() {
96
106
  return this.nodes.getBbox();
@@ -108,16 +118,32 @@ export class Osm {
108
118
  ways: this.ways.size,
109
119
  relations: this.relations.size,
110
120
  },
121
+ spatialIndexes: {
122
+ nodes: {
123
+ all: this.nodes.hasSpatialIndex("all"),
124
+ tagged: this.nodes.hasSpatialIndex("tagged"),
125
+ },
126
+ ways: this.ways.hasSpatialIndex(),
127
+ relations: this.relations.hasSpatialIndex(),
128
+ },
129
+ ...(this._loadDiagnostics ? { loadDiagnostics: this._loadDiagnostics } : {}),
111
130
  };
112
131
  }
132
+ /** Attach loader-provided diagnostics for `info()` and worker transfer. */
133
+ setLoadDiagnostics(loadDiagnostics) {
134
+ this._loadDiagnostics = loadDiagnostics;
135
+ }
113
136
  /**
114
137
  * Get transferable objects for passing to another thread.
115
138
  */
116
139
  transferables() {
117
140
  return {
141
+ transferVersion: OSM_TRANSFER_VERSION,
142
+ contentHashVersion: OSM_CONTENT_HASH_VERSION,
118
143
  id: this.id,
119
144
  header: this.header,
120
145
  contentHash: this._contentHash,
146
+ ...(this._loadDiagnostics ? { loadDiagnostics: this._loadDiagnostics } : {}),
121
147
  stringTable: this.stringTable.transferables(),
122
148
  nodes: this.nodes.transferables(),
123
149
  ways: this.ways.transferables(),
@@ -152,7 +178,7 @@ export class Osm {
152
178
  * @returns A hex string hash of the content.
153
179
  */
154
180
  computeContentHash() {
155
- const hasher = new ContentHasher();
181
+ const hasher = new ContentHasher().updateNumber(OSM_CONTENT_HASH_VERSION);
156
182
  // Hash string table first (shared by all entities)
157
183
  this.stringTable.updateHash(hasher);
158
184
  // Hash each entity collection
package/dist/osm.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"osm.js","sourceRoot":"","sources":["../src/osm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"osm.js","sourceRoot":"","sources":["../src/osm.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { OsmPbfRelation } from "@osmix/pbf";
2
2
  import type { ContentHasher } from "@osmix/shared/content-hasher";
3
- import type { GeoBbox2D, LonLat, OsmEntityType, OsmRelation, OsmRelationMember, OsmTags } from "@osmix/shared/types";
3
+ import type { GeoBbox2D, LonLat, OsmEntityType, OsmRelation, OsmRelationMember, OsmTags } from "@osmix/types";
4
4
  import Flatbush from "flatbush";
5
5
  import { Entities, type EntitiesTransferables } from "./entities.ts";
6
6
  import { type IdOrIndex } from "./ids.ts";
@@ -30,10 +30,13 @@ export declare class Relations extends Entities<OsmRelation> {
30
30
  private bbox;
31
31
  private nodes;
32
32
  private ways;
33
+ private wayMemberCache;
33
34
  /**
34
35
  * Create a new Relations index.
35
36
  */
36
37
  constructor(stringTable: StringTable, nodes: Nodes, ways: Ways, transferables?: RelationsTransferables);
38
+ /** Reject a relation whose member count would wrap `memberCount` or `memberStart`. */
39
+ private assertMemberCapacity;
37
40
  /**
38
41
  * Add a single relation to the index.
39
42
  */
@@ -50,6 +53,7 @@ export declare class Relations extends Entities<OsmRelation> {
50
53
  * Build the spatial index for relations.
51
54
  * Handles nested relations by resolving all descendant nodes and ways.
52
55
  * If bbox data already exists (e.g., loaded from storage), reuses it.
56
+ * Returns the existing index when it is already built.
53
57
  */
54
58
  buildSpatialIndex(): Flatbush;
55
59
  /**
@@ -78,10 +82,13 @@ export declare class Relations extends Entities<OsmRelation> {
78
82
  */
79
83
  includesMember(index: number, memberRef: number, memberType: OsmEntityType, memberRole?: string): boolean;
80
84
  /**
81
- * Get all way IDs that are members of relations, including nested relations.
85
+ * Check whether a way is a member of any relation, including through nested relations.
82
86
  * Used to exclude these ways from individual rendering.
87
+ *
88
+ * Membership is computed once and cached as one bit per way index. Requires the way ID index.
83
89
  */
84
- getWayMemberIds(): Set<number>;
90
+ isWayMember(wayIndex: number): boolean;
91
+ private getWayMembers;
85
92
  /**
86
93
  * Get relation geometry based on its kind.
87
94
  * Returns coordinates suitable for rendering based on relation type.
@@ -114,7 +121,7 @@ export declare class Relations extends Entities<OsmRelation> {
114
121
  /**
115
122
  * Get the approximate memory requirements for a given number of relations in bytes.
116
123
  */
117
- static getBytesRequired(count: number): number;
124
+ static getBytesRequired(count: number, memberCount?: number, tagCount?: number): number;
118
125
  /**
119
126
  * Update a ContentHasher with relation-specific data (members).
120
127
  */
@@ -1 +1 @@
1
- {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../src/relations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../src/relations.ts"],"names":[],"mappings":"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"}
package/dist/relations.js CHANGED
@@ -1,18 +1,20 @@
1
+ import { buildRelationRings } from "@osmix/geo/relation-multipolygon";
1
2
  import { assertValue } from "@osmix/shared/assert";
2
- import { buildRelationLineStrings, collectRelationPoints, isAreaRelation, isLineRelation, isPointRelation, isSuperRelation, resolveRelationMembers, } from "@osmix/shared/relation-kind";
3
- import { buildRelationRings } from "@osmix/shared/relation-multipolygon";
4
- import { bboxFromLonLats } from "@osmix/shared/utils";
3
+ import { BitSet } from "@osmix/shared/bit-set";
4
+ import { buildRelationLineStrings, collectRelationPoints, isAreaRelation, isLineRelation, isPointRelation, isSuperRelation, resolveRelationMembers, } from "@osmix/types/relation-kind";
5
+ import { bboxFromLonLats } from "@osmix/types/utils";
5
6
  import Flatbush from "flatbush";
6
7
  import { around as geoAround } from "geoflatbush";
7
- import { Entities } from "./entities.js";
8
+ import { Entities, isValidSpatialBbox } from "./entities.js";
8
9
  import { Ids } from "./ids.js";
10
+ import { MAX_RELATION_MEMBERS, MAX_UINT32_OFFSET, assertCapacity } from "./limits.js";
9
11
  import { Tags } from "./tags.js";
10
12
  import { BufferConstructor, IdArrayType, ResizeableTypedArray as RTA, } from "./typed-arrays.js";
11
13
  const RELATION_MEMBER_TYPES = ["node", "way", "relation"];
12
14
  export class Relations extends Entities {
13
15
  stringTable;
14
16
  memberStart;
15
- memberCount; // Maximum 65,535 members per relation
17
+ memberCount; // Maximum MAX_RELATION_MEMBERS (65,535) per relation
16
18
  // Store the ID of the member because relations have other relations as members.
17
19
  memberRefs;
18
20
  memberTypes;
@@ -26,6 +28,9 @@ export class Relations extends Entities {
26
28
  // Node and Way indexes
27
29
  nodes;
28
30
  ways;
31
+ // Lazily computed relation way membership keyed by way index. Invalidated whenever relations
32
+ // change, and rebuilt if the way count no longer matches.
33
+ wayMemberCache = null;
29
34
  /**
30
35
  * Create a new Relations index.
31
36
  */
@@ -58,10 +63,17 @@ export class Relations extends Entities {
58
63
  this.ways = ways;
59
64
  this.stringTable = stringTable;
60
65
  }
66
+ /** Reject a relation whose member count would wrap `memberCount` or `memberStart`. */
67
+ assertMemberCapacity(relationId, memberCount) {
68
+ assertCapacity("relation-members", memberCount, MAX_RELATION_MEMBERS, () => `Relation ${relationId}`);
69
+ assertCapacity("total-relation-members", this.memberRefs.length + memberCount, MAX_UINT32_OFFSET, () => `The dataset (at relation ${relationId})`);
70
+ }
61
71
  /**
62
72
  * Add a single relation to the index.
63
73
  */
64
74
  addRelation(relation) {
75
+ this.wayMemberCache = null;
76
+ this.assertMemberCapacity(relation.id, relation.members.length);
65
77
  const relationIndex = this.addEntity(relation.id, relation.tags ?? {});
66
78
  this.memberStart.push(this.memberRefs.length);
67
79
  this.memberCount.push(relation.members.length);
@@ -76,6 +88,7 @@ export class Relations extends Entities {
76
88
  * Bulk add relations directly from a PBF PrimitiveBlock.
77
89
  */
78
90
  addRelations(relations, blockStringIndexMap, filter) {
91
+ this.wayMemberCache = null;
79
92
  const blockToStringTable = (k) => {
80
93
  const index = blockStringIndexMap[k];
81
94
  if (index === undefined)
@@ -122,6 +135,7 @@ export class Relations extends Entities {
122
135
  : null;
123
136
  if (filter && filteredRelation === null)
124
137
  continue;
138
+ this.assertMemberCapacity(relation.id, filteredRelation?.members.length ?? memberRefs.length);
125
139
  added++;
126
140
  this.addEntity(relation.id, tagKeys, tagValues);
127
141
  this.memberStart.push(this.memberRefs.length);
@@ -146,14 +160,20 @@ export class Relations extends Entities {
146
160
  * Build the spatial index for relations.
147
161
  * Handles nested relations by resolving all descendant nodes and ways.
148
162
  * If bbox data already exists (e.g., loaded from storage), reuses it.
163
+ * Returns the existing index when it is already built.
149
164
  */
150
165
  buildSpatialIndex() {
151
166
  if (!this.nodes.isReady())
152
167
  throw Error("Node index is not ready.");
153
168
  if (!this.ways.isReady())
154
169
  throw Error("Way index is not ready.");
155
- if (this.size === 0)
170
+ if (this.spatialIndexBuilt)
171
+ return this.spatialIndex;
172
+ if (this.size === 0) {
173
+ this.spatialIndex = new Flatbush(1, 128, Float64Array, BufferConstructor);
174
+ this.spatialIndexBuilt = true;
156
175
  return this.spatialIndex;
176
+ }
157
177
  console.time("RelationIndex.buildSpatialIndex");
158
178
  this.spatialIndex = new Flatbush(this.size, 128, Float64Array, BufferConstructor);
159
179
  // If bbox already has data (loaded from storage), use it directly
@@ -219,12 +239,13 @@ export class Relations extends Entities {
219
239
  if (ll)
220
240
  lls.push(ll);
221
241
  }
222
- // Collect coordinates from resolved ways
242
+ // Collect coordinates from resolved ways. Member ways may reference nodes
243
+ // outside a referentially incomplete extract, so skip unresolvable refs.
223
244
  for (const wayId of resolved.ways) {
224
245
  const wayIndex = this.ways.ids.getIndexFromId(wayId);
225
246
  if (wayIndex === -1)
226
247
  continue;
227
- const wayPositions = this.ways.getCoordinates(wayIndex);
248
+ const wayPositions = this.ways.getResolvedCoordinates(wayIndex);
228
249
  lls.push(...wayPositions);
229
250
  }
230
251
  return lls;
@@ -283,32 +304,42 @@ export class Relations extends Entities {
283
304
  const ref = this.memberRefs.at(i);
284
305
  if (ref !== memberRef)
285
306
  continue;
286
- if (memberRole !== undefined &&
287
- this.stringTable.get(this.memberRoles.at(i)) !== memberRole)
307
+ if (memberRole !== undefined && this.stringTable.get(this.memberRoles.at(i)) !== memberRole)
288
308
  continue;
289
309
  return true;
290
310
  }
291
311
  return false;
292
312
  }
293
313
  /**
294
- * Get all way IDs that are members of relations, including nested relations.
314
+ * Check whether a way is a member of any relation, including through nested relations.
295
315
  * Used to exclude these ways from individual rendering.
316
+ *
317
+ * Membership is computed once and cached as one bit per way index. Requires the way ID index.
296
318
  */
297
- getWayMemberIds() {
298
- const wayIds = new Set();
319
+ isWayMember(wayIndex) {
320
+ return this.getWayMembers().has(wayIndex);
321
+ }
322
+ getWayMembers() {
323
+ if (this.wayMemberCache !== null && this.wayMemberCache.size === this.ways.size) {
324
+ return this.wayMemberCache;
325
+ }
326
+ const members = new BitSet(this.ways.size);
327
+ const getRelation = (relId) => {
328
+ const relIndex = this.ids.getIndexFromId(relId);
329
+ if (relIndex === -1)
330
+ return null;
331
+ return this.getByIndex(relIndex);
332
+ };
299
333
  for (let i = 0; i < this.size; i++) {
300
- const relation = this.getByIndex(i);
301
- const resolved = resolveRelationMembers(relation, (relId) => {
302
- const relIndex = this.ids.getIndexFromId(relId);
303
- if (relIndex === -1)
304
- return null;
305
- return this.getByIndex(relIndex);
306
- }, 10);
334
+ const resolved = resolveRelationMembers(this.getByIndex(i), getRelation, 10);
307
335
  for (const wayId of resolved.ways) {
308
- wayIds.add(wayId);
336
+ const wayIndex = this.ways.ids.getIndexFromId(wayId);
337
+ if (wayIndex !== -1)
338
+ members.add(wayIndex);
309
339
  }
310
340
  }
311
- return wayIds;
341
+ this.wayMemberCache = members;
342
+ return members;
312
343
  }
313
344
  /**
314
345
  * Get relation geometry based on its kind.
@@ -320,19 +351,19 @@ export class Relations extends Entities {
320
351
  const relation = this.getByIndex(index);
321
352
  if (isAreaRelation(relation)) {
322
353
  return {
323
- rings: buildRelationRings(relation, (ref) => this.ways.getById(ref), (id) => this.nodes.getNodeLonLat({ id })),
354
+ rings: buildRelationRings(relation, (ref) => this.ways.getById(ref), (id) => this.nodes.getNodeLonLat({ id }) ?? undefined),
324
355
  };
325
356
  }
326
357
  // Point relations
327
358
  if (isPointRelation(relation)) {
328
359
  return {
329
- points: collectRelationPoints(relation, (id) => this.nodes.getNodeLonLat({ id })),
360
+ points: collectRelationPoints(relation, (id) => this.nodes.getNodeLonLat({ id }) ?? undefined),
330
361
  };
331
362
  }
332
363
  // Line relations
333
364
  if (isLineRelation(relation)) {
334
365
  return {
335
- lineStrings: buildRelationLineStrings(relation, (ref) => this.ways.getById(ref), (id) => this.nodes.getNodeLonLat({ id })),
366
+ lineStrings: buildRelationLineStrings(relation, (ref) => this.ways.getById(ref), (id) => this.nodes.getNodeLonLat({ id }) ?? undefined),
336
367
  };
337
368
  }
338
369
  // Super relations are handled by individual relation geometry methods
@@ -349,7 +380,14 @@ export class Relations extends Entities {
349
380
  intersects(bbox, filterFn) {
350
381
  if (this.size === 0)
351
382
  return [];
352
- return this.spatialIndex.search(bbox[0], bbox[1], bbox[2], bbox[3], filterFn);
383
+ // A relation with no resolvable member geometry stores an inverted bbox.
384
+ // Flatbush's contained-node fast path skips per-leaf intersection tests,
385
+ // so filter inverted boxes out explicitly.
386
+ return this.spatialIndex.search(bbox[0], bbox[1], bbox[2], bbox[3], (index, x0, y0, x1, y1) => {
387
+ if (!isValidSpatialBbox(x0, y0, x1, y1))
388
+ return false;
389
+ return filterFn ? filterFn(index) : true;
390
+ });
353
391
  }
354
392
  /**
355
393
  * Find relation indexes near a point using great-circle distance.
@@ -363,7 +401,10 @@ export class Relations extends Entities {
363
401
  if (this.size === 0)
364
402
  return [];
365
403
  // Use geoflatbush for proper geographic distance calculations
366
- return geoAround(this.spatialIndex, lon, lat, maxResults, maxDistanceKm);
404
+ return geoAround(this.spatialIndex, lon, lat, maxResults, maxDistanceKm, (index) => {
405
+ const offset = index * 4;
406
+ return isValidSpatialBbox(this.bbox.at(offset), this.bbox.at(offset + 1), this.bbox.at(offset + 2), this.bbox.at(offset + 3));
407
+ });
367
408
  }
368
409
  /**
369
410
  * Get transferable objects for passing to another thread.
@@ -388,7 +429,7 @@ export class Relations extends Entities {
388
429
  /**
389
430
  * Get the approximate memory requirements for a given number of relations in bytes.
390
431
  */
391
- static getBytesRequired(count) {
432
+ static getBytesRequired(count, memberCount = 0, tagCount = 0) {
392
433
  if (count === 0)
393
434
  return 0;
394
435
  // Approximate members per relation
@@ -402,9 +443,12 @@ export class Relations extends Entities {
402
443
  const boxesBytes = numNodes * 4 * Float64Array.BYTES_PER_ELEMENT;
403
444
  const spatialIndexBytes = 8 + indexBytes + boxesBytes;
404
445
  return (Ids.getBytesRequired(count) +
405
- Tags.getBytesRequired(count) +
446
+ Tags.getBytesRequired(count, count, tagCount) +
406
447
  count * Uint32Array.BYTES_PER_ELEMENT + // memberStart
407
448
  count * Uint16Array.BYTES_PER_ELEMENT + // memberCount
449
+ memberCount * Float64Array.BYTES_PER_ELEMENT + // memberRefs
450
+ memberCount * Uint8Array.BYTES_PER_ELEMENT + // memberTypes
451
+ memberCount * Uint32Array.BYTES_PER_ELEMENT + // memberRoles
408
452
  count * 4 * Float64Array.BYTES_PER_ELEMENT + // bbox
409
453
  spatialIndexBytes);
410
454
  }