feat: add Docker/OpenTofu deployment and DE/NL routing
This commit is contained in:
@@ -40,6 +40,44 @@ const ALTERNATIVE_GRAPH: FairwayGraph = {
|
||||
]
|
||||
};
|
||||
|
||||
const COMPONENT_AWARE_SNAP_GRAPH: FairwayGraph = {
|
||||
id: "component-aware-snap-test",
|
||||
name: "Komponentenbewusster Snap-Test",
|
||||
maxSnapDistanceNm: 0.3,
|
||||
nodes: [
|
||||
{ id: "start-decoy-a", coordinate: { lat: 53.3416, lon: 7.186 } },
|
||||
{ id: "start-decoy-b", coordinate: { lat: 53.342, lon: 7.187 } },
|
||||
{ id: "destination-decoy-a", coordinate: { lat: 53.3282, lon: 6.9304 } },
|
||||
{ id: "destination-decoy-b", coordinate: { lat: 53.3286, lon: 6.9294 } },
|
||||
{ id: "shared-start", coordinate: { lat: 53.3395697, lon: 7.1848883 } },
|
||||
{ id: "shared-east", coordinate: { lat: 53.3321722, lon: 7.1329034 } },
|
||||
{ id: "shared-south", coordinate: { lat: 53.313849, lon: 7.0011017 } },
|
||||
{ id: "shared-destination", coordinate: { lat: 53.3303531, lon: 6.9334715 } }
|
||||
],
|
||||
edges: [
|
||||
edge("start-decoy", "start-decoy-a", "start-decoy-b", [
|
||||
{ lat: 53.3416, lon: 7.186 },
|
||||
{ lat: 53.342, lon: 7.187 }
|
||||
], { source: "closer-but-disconnected-start" }),
|
||||
edge("destination-decoy", "destination-decoy-a", "destination-decoy-b", [
|
||||
{ lat: 53.3282, lon: 6.9304 },
|
||||
{ lat: 53.3286, lon: 6.9294 }
|
||||
], { source: "closer-but-disconnected-destination" }),
|
||||
edge("shared-east", "shared-start", "shared-east", [
|
||||
{ lat: 53.3395697, lon: 7.1848883 },
|
||||
{ lat: 53.3321722, lon: 7.1329034 }
|
||||
], { source: "shared-local-component" }),
|
||||
edge("shared-south", "shared-east", "shared-south", [
|
||||
{ lat: 53.3321722, lon: 7.1329034 },
|
||||
{ lat: 53.313849, lon: 7.0011017 }
|
||||
], { source: "shared-local-component" }),
|
||||
edge("shared-west", "shared-south", "shared-destination", [
|
||||
{ lat: 53.313849, lon: 7.0011017 },
|
||||
{ lat: 53.3303531, lon: 6.9334715 }
|
||||
], { source: "shared-local-component" })
|
||||
]
|
||||
};
|
||||
|
||||
function edge(
|
||||
id: string,
|
||||
from: string,
|
||||
@@ -162,6 +200,88 @@ describe("route assessment", () => {
|
||||
expect(result.dataSources).toContain("fairway-graph:ems-borkum-seed");
|
||||
});
|
||||
|
||||
it("uses a shared reachable component when the individually nearest edges are disconnected", () => {
|
||||
const start = { lat: 53.3416, lon: 7.186 };
|
||||
const destination = { lat: 53.3282, lon: 6.9304 };
|
||||
const routes = buildFairwayRoutes(
|
||||
{
|
||||
start,
|
||||
destination,
|
||||
vesselProfile: { draughtM: 1, safetyReserveM: 0.3 }
|
||||
},
|
||||
COMPONENT_AWARE_SNAP_GRAPH
|
||||
);
|
||||
|
||||
expect(routes).toHaveLength(1);
|
||||
expect(routes[0]?.geometry.coordinates[0]).toEqual([start.lon, start.lat]);
|
||||
expect(routes[0]?.geometry.coordinates.at(-1)).toEqual([destination.lon, destination.lat]);
|
||||
expect(routes[0]?.dataSources).toContain("shared-local-component");
|
||||
expect(routes[0]?.dataSources).not.toContain("closer-but-disconnected-start");
|
||||
expect(routes[0]?.dataSources).not.toContain("closer-but-disconnected-destination");
|
||||
expect(routes[0]?.distanceNm).toBeGreaterThan(9.5);
|
||||
expect(routes[0]?.distanceNm).toBeLessThan(10.5);
|
||||
});
|
||||
|
||||
it("returns no route when start and destination have no shared component inside the snap radius", () => {
|
||||
const disconnectedGraph: FairwayGraph = {
|
||||
...COMPONENT_AWARE_SNAP_GRAPH,
|
||||
nodes: COMPONENT_AWARE_SNAP_GRAPH.nodes.slice(0, 4),
|
||||
edges: COMPONENT_AWARE_SNAP_GRAPH.edges.slice(0, 2)
|
||||
};
|
||||
|
||||
expect(
|
||||
buildFairwayRoute(
|
||||
{
|
||||
start: { lat: 53.3416, lon: 7.186 },
|
||||
destination: { lat: 53.3282, lon: 6.9304 },
|
||||
vesselProfile: { draughtM: 1, safetyReserveM: 0.3 }
|
||||
},
|
||||
disconnectedGraph
|
||||
)
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("tries another snap in the same component when the nearest one-way branch cannot be exited", () => {
|
||||
const graph: FairwayGraph = {
|
||||
id: "oneway-snap-fallback",
|
||||
name: "Einbahnstraßen-Snap-Fallback",
|
||||
maxSnapDistanceNm: 0.2,
|
||||
nodes: [
|
||||
{ id: "junction", coordinate: { lat: 52, lon: 7 } },
|
||||
{ id: "destination", coordinate: { lat: 52, lon: 7.04 } },
|
||||
{ id: "oneway-dead-end", coordinate: { lat: 52.001, lon: 7 } }
|
||||
],
|
||||
edges: [
|
||||
edge(
|
||||
"oneway-trap",
|
||||
"junction",
|
||||
"oneway-dead-end",
|
||||
[{ lat: 52, lon: 7 }, { lat: 52.001, lon: 7 }],
|
||||
{ oneway: true, source: "oneway-trap" }
|
||||
),
|
||||
edge(
|
||||
"main-route",
|
||||
"junction",
|
||||
"destination",
|
||||
[{ lat: 52, lon: 7 }, { lat: 52, lon: 7.04 }],
|
||||
{ source: "routable-main-edge" }
|
||||
)
|
||||
]
|
||||
};
|
||||
const route = buildFairwayRoute(
|
||||
{
|
||||
start: { lat: 52.001, lon: 7 },
|
||||
destination: { lat: 52, lon: 7.04 },
|
||||
vesselProfile: { draughtM: 1, safetyReserveM: 0.3 }
|
||||
},
|
||||
graph
|
||||
);
|
||||
|
||||
expect(route).not.toBeNull();
|
||||
expect(route?.dataSources).toContain("routable-main-edge");
|
||||
expect(route?.dataSources).not.toContain("oneway-trap");
|
||||
});
|
||||
|
||||
it("does not fall back to a misleading straight line when no fairway graph matches", () => {
|
||||
const result = buildRoute({
|
||||
start: { lat: 54.1749, lon: 12.0731 },
|
||||
|
||||
Reference in New Issue
Block a user