@osmix/router 0.0.13 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +21 -0
  3. package/README.md +138 -53
  4. package/dist/algorithms/bidirectional.d.ts +6 -9
  5. package/dist/algorithms/bidirectional.d.ts.map +1 -1
  6. package/dist/algorithms/bidirectional.js +84 -104
  7. package/dist/algorithms/bidirectional.js.map +1 -1
  8. package/dist/algorithms/index.d.ts +1 -1
  9. package/dist/algorithms/index.d.ts.map +1 -1
  10. package/dist/algorithms/index.js +1 -1
  11. package/dist/algorithms/index.js.map +1 -1
  12. package/dist/algorithms/shortest-path.d.ts +2 -1
  13. package/dist/algorithms/shortest-path.d.ts.map +1 -1
  14. package/dist/algorithms/shortest-path.js +9 -7
  15. package/dist/algorithms/shortest-path.js.map +1 -1
  16. package/dist/binary-heap.d.ts +5 -0
  17. package/dist/binary-heap.d.ts.map +1 -1
  18. package/dist/binary-heap.js +11 -4
  19. package/dist/binary-heap.js.map +1 -1
  20. package/dist/graph.d.ts +35 -7
  21. package/dist/graph.d.ts.map +1 -1
  22. package/dist/graph.js +161 -119
  23. package/dist/graph.js.map +1 -1
  24. package/dist/index.d.ts +9 -4
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +9 -4
  27. package/dist/index.js.map +1 -1
  28. package/dist/router.d.ts +1 -1
  29. package/dist/router.d.ts.map +1 -1
  30. package/dist/router.js +6 -3
  31. package/dist/router.js.map +1 -1
  32. package/dist/topology-stats.d.ts +37 -0
  33. package/dist/topology-stats.d.ts.map +1 -0
  34. package/dist/topology-stats.js +62 -0
  35. package/dist/topology-stats.js.map +1 -0
  36. package/dist/types.d.ts +15 -2
  37. package/dist/types.d.ts.map +1 -1
  38. package/dist/utils.d.ts +1 -1
  39. package/dist/utils.d.ts.map +1 -1
  40. package/dist/utils.js +1 -7
  41. package/dist/utils.js.map +1 -1
  42. package/package.json +32 -29
  43. package/src/algorithms/bidirectional.ts +124 -136
  44. package/src/algorithms/index.ts +10 -10
  45. package/src/algorithms/shortest-path.ts +96 -92
  46. package/src/binary-heap.ts +133 -129
  47. package/src/graph.ts +389 -355
  48. package/src/index.ts +14 -9
  49. package/src/router.ts +221 -233
  50. package/src/topology-stats.ts +84 -0
  51. package/src/types.ts +102 -87
  52. package/src/utils.ts +67 -74
  53. package/test/algorithms.test.ts +396 -353
  54. package/test/binary-heap.test.ts +27 -0
  55. package/test/limits.test.ts +82 -0
  56. package/test/no-shared-array-buffer.test.ts +37 -0
  57. package/test/router.bench.ts +171 -188
  58. package/test/router.test.ts +685 -726
  59. package/test/spatial-capability.test.ts +23 -0
  60. package/test/topology-stats.test.ts +82 -0
  61. package/tsconfig.build.json +6 -6
  62. package/tsconfig.json +7 -7
@@ -0,0 +1,23 @@
1
+ import { Osm, SpatialIndexNotBuiltError } from "@osmix/core";
2
+ import { describe, expect, it } from "vitest";
3
+
4
+ import { buildGraph } from "../src/graph.ts";
5
+
6
+ describe("routing node spatial capability", () => {
7
+ it("requires an all-node index for snapping and succeeds once it is built", () => {
8
+ const osm = new Osm({ id: "routing-capability" });
9
+ osm.nodes.addNode({ id: 1, lon: 0, lat: 0 });
10
+ osm.nodes.addNode({ id: 2, lon: 0.01, lat: 0 });
11
+ osm.ways.addWay({ id: 10, refs: [1, 2], tags: { highway: "primary" } });
12
+ osm.buildIndexes();
13
+ osm.nodes.buildSpatialIndex("tagged");
14
+ const graph = buildGraph(osm);
15
+
16
+ expect(() => graph.findNearestRoutableNode(osm, [0, 0], 100)).toThrowError(
17
+ SpatialIndexNotBuiltError,
18
+ );
19
+
20
+ osm.nodes.buildSpatialIndex("all");
21
+ expect(graph.findNearestRoutableNode(osm, [0, 0], 100)).toMatchObject({ nodeIndex: 0 });
22
+ });
23
+ });
@@ -0,0 +1,82 @@
1
+ import { Osm } from "@osmix/core";
2
+ import { fromPbf } from "@osmix/load";
3
+ import { getFixtureFile, PBFs } from "@osmix/test-utils/fixtures";
4
+ import { describe, expect, it } from "vitest";
5
+
6
+ import {
7
+ defaultHighwayFilter,
8
+ type HighwayFilter,
9
+ RoutingGraph,
10
+ routingTopologyStats,
11
+ } from "../src/index.ts";
12
+
13
+ /** The reference: the same counts read from a fully built `RoutingGraph`. */
14
+ function graphStats(osm: Osm, filter: HighwayFilter) {
15
+ const graph = new RoutingGraph(osm, filter);
16
+ const parent = new Map<number, number>();
17
+ const find = (index: number): number => {
18
+ let root = index;
19
+ while (parent.get(root) !== root) root = parent.get(root)!;
20
+ return root;
21
+ };
22
+ for (let index = 0; index < graph.size; index++) {
23
+ if (graph.isRoutable(index)) parent.set(index, index);
24
+ }
25
+ for (const index of parent.keys()) {
26
+ for (const edge of graph.getEdges(index)) parent.set(find(edge.targetNodeIndex), find(index));
27
+ }
28
+ const roots = new Set([...parent.keys()].map(find));
29
+ return {
30
+ nodes: graph.size,
31
+ routableNodes: parent.size,
32
+ edges: graph.edges,
33
+ components: roots.size,
34
+ };
35
+ }
36
+
37
+ const osmSource = (osm: Osm) => ({ nodeCount: osm.nodes.size, ways: () => osm.ways });
38
+ const walkFilter: HighwayFilter = (tags) =>
39
+ tags?.["highway"] != null || tags?.["public_transport"] === "platform";
40
+
41
+ function syntheticOsm() {
42
+ const osm = new Osm({ id: "synthetic" });
43
+ for (let id = 1; id <= 14; id++) osm.nodes.addNode({ id, lon: id * 0.001, lat: 0 });
44
+ osm.nodes.buildIndex();
45
+ osm.ways.addWay({ id: 1, refs: [1, 2, 3], tags: { highway: "residential" } });
46
+ osm.ways.addWay({ id: 2, refs: [3, 4], tags: { highway: "primary", oneway: "yes" } });
47
+ osm.ways.addWay({ id: 3, refs: [4, 5], tags: { highway: "primary", oneway: "-1" } });
48
+ osm.ways.addWay({
49
+ id: 4,
50
+ refs: [6, 7, 8, 6],
51
+ tags: { highway: "primary", junction: "roundabout", oneway: "reversible" },
52
+ });
53
+ osm.ways.addWay({ id: 5, refs: [9, 10], tags: { highway: "footway" } });
54
+ osm.ways.addWay({ id: 6, refs: [11, 12], tags: { building: "yes" } });
55
+ osm.ways.addWay({ id: 7, refs: [13], tags: { highway: "residential" } });
56
+ osm.ways.addWay({ id: 8, refs: [13, 14], tags: { public_transport: "platform" } });
57
+ osm.ways.addWay({ id: 9, refs: [5, 6], tags: { highway: "service", oneway: "alternating" } });
58
+ osm.buildIndexes();
59
+ return osm;
60
+ }
61
+
62
+ describe("routingTopologyStats", () => {
63
+ it("matches RoutingGraph on one-way, roundabout, filtered and single-node ways", () => {
64
+ const osm = syntheticOsm();
65
+ for (const filter of [defaultHighwayFilter, walkFilter]) {
66
+ expect(routingTopologyStats(osmSource(osm), filter)).toEqual(graphStats(osm, filter));
67
+ }
68
+ expect(routingTopologyStats(osmSource(osm), walkFilter)).toEqual({
69
+ nodes: 14,
70
+ routableNodes: 12,
71
+ edges: 15,
72
+ components: 3,
73
+ });
74
+ });
75
+
76
+ it("matches RoutingGraph on Monaco", async () => {
77
+ const osm = await fromPbf(await getFixtureFile(PBFs["monaco"]!.url));
78
+ for (const filter of [defaultHighwayFilter, walkFilter]) {
79
+ expect(routingTopologyStats(osmSource(osm), filter)).toEqual(graphStats(osm, filter));
80
+ }
81
+ });
82
+ });
@@ -1,8 +1,8 @@
1
1
  {
2
- "$schema": "https://json.schemastore.org/tsconfig",
3
- "extends": "./tsconfig.json",
4
- "include": ["src"],
5
- "compilerOptions": {
6
- "rootDir": "./src"
7
- }
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "extends": "./tsconfig.json",
4
+ "include": ["src"],
5
+ "compilerOptions": {
6
+ "rootDir": "./src"
7
+ }
8
8
  }
package/tsconfig.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
- "$schema": "https://json.schemastore.org/tsconfig",
3
- "extends": "@osmix/shared/tsconfig/base.json",
4
- "exclude": ["node_modules", "dist"],
5
- "include": ["src", "test"],
6
- "compilerOptions": {
7
- "outDir": "./dist"
8
- }
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "extends": "@osmix/shared/tsconfig/base.json",
4
+ "exclude": ["node_modules", "dist"],
5
+ "include": ["src", "test"],
6
+ "compilerOptions": {
7
+ "outDir": "./dist"
8
+ }
9
9
  }