Initial Watermaps import
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { FeatureCollection, Geometry } from "geojson";
|
||||
import {
|
||||
routeFeatureBounds,
|
||||
routeLocksFromFeatures,
|
||||
voyageHarboursFromFeatures
|
||||
} from "../src/voyageHarbours";
|
||||
|
||||
describe("voyage harbour feature adapter", () => {
|
||||
it("turns normalized point features into amenity-aware harbour candidates", () => {
|
||||
const collection: FeatureCollection<Geometry> = {
|
||||
type: "FeatureCollection",
|
||||
features: [
|
||||
{
|
||||
type: "Feature",
|
||||
id: "hamm-marina",
|
||||
geometry: { type: "Point", coordinates: [7.8, 51.68] },
|
||||
properties: {
|
||||
layer: "harbours",
|
||||
name: "Marina Hamm",
|
||||
leisure: "marina",
|
||||
phone: "+49 2381 123",
|
||||
website: "hamm.example",
|
||||
email: "hafen@hamm.example",
|
||||
vhf: "12",
|
||||
opening_hours: "täglich 08:00-20:00",
|
||||
operator: "Hafen Hamm",
|
||||
"addr:street": "Uferweg",
|
||||
"addr:housenumber": "4",
|
||||
"addr:postcode": "59000",
|
||||
"addr:city": "Hamm",
|
||||
power_supply: "yes",
|
||||
drinking_water: "yes",
|
||||
guest_berths: 8
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "Feature",
|
||||
geometry: { type: "LineString", coordinates: [[7, 52], [8, 52]] },
|
||||
properties: { layer: "harbours", name: "Keine Punktgeometrie" }
|
||||
},
|
||||
{
|
||||
type: "Feature",
|
||||
geometry: { type: "Point", coordinates: [7.7, 51.7] },
|
||||
properties: { layer: "locks", name: "Keine Marina" }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
expect(voyageHarboursFromFeatures(collection)).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "hamm-marina",
|
||||
name: "Marina Hamm",
|
||||
kind: "marina",
|
||||
coordinate: { lat: 51.68, lon: 7.8 },
|
||||
email: "hafen@hamm.example",
|
||||
vhf: "12",
|
||||
openingHours: "täglich 08:00-20:00",
|
||||
operator: "Hafen Hamm",
|
||||
address: "Uferweg 4, 59000 Hamm",
|
||||
amenities: expect.objectContaining({
|
||||
electricity: "available",
|
||||
water: "available",
|
||||
overnight: "available"
|
||||
})
|
||||
})
|
||||
]);
|
||||
});
|
||||
|
||||
it("calculates a nautical-mile padded feature request box", () => {
|
||||
const bounds = routeFeatureBounds(
|
||||
{
|
||||
geometry: {
|
||||
type: "LineString",
|
||||
coordinates: [[7, 52], [8, 53]]
|
||||
}
|
||||
},
|
||||
6
|
||||
);
|
||||
|
||||
expect(bounds[0]).toBeLessThan(6.84);
|
||||
expect(bounds[1]).toBeCloseTo(51.9, 5);
|
||||
expect(bounds[2]).toBeGreaterThan(8.16);
|
||||
expect(bounds[3]).toBeCloseTo(53.1, 5);
|
||||
});
|
||||
|
||||
it("filters and orders route locks while preserving opening hours and phone", () => {
|
||||
const collection: FeatureCollection<Geometry> = {
|
||||
type: "FeatureCollection",
|
||||
features: [
|
||||
{
|
||||
type: "Feature",
|
||||
id: "lock-late",
|
||||
geometry: { type: "Point", coordinates: [7.8, 52] },
|
||||
properties: {
|
||||
layer: "locks",
|
||||
name: "Schleuse Ost",
|
||||
openingHours: "Mo-Su 06:00-22:00",
|
||||
phone: "+49 2381 200"
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "Feature",
|
||||
id: "lock-off-route",
|
||||
geometry: { type: "Point", coordinates: [7.5, 52.02] },
|
||||
properties: { layer: "locks", name: "Entfernte Schleuse" }
|
||||
},
|
||||
{
|
||||
type: "Feature",
|
||||
id: "lock-early",
|
||||
geometry: { type: "Point", coordinates: [7.2, 52] },
|
||||
properties: {
|
||||
layer: "locks",
|
||||
name: "Schleuse West",
|
||||
opening_hours: "nach Anmeldung",
|
||||
phone: "+49 2381 100"
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "Feature",
|
||||
id: "harbour-on-route",
|
||||
geometry: { type: "Point", coordinates: [7.4, 52] },
|
||||
properties: { layer: "harbours", name: "Kein Schleusenpunkt" }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const locks = routeLocksFromFeatures(collection, {
|
||||
geometry: {
|
||||
type: "LineString",
|
||||
coordinates: [[7, 52], [8, 52]]
|
||||
},
|
||||
distanceNm: 41
|
||||
});
|
||||
|
||||
expect(locks.map((lock) => lock.id)).toEqual(["lock-early", "lock-late"]);
|
||||
expect(locks[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
name: "Schleuse West",
|
||||
openingHours: "nach Anmeldung",
|
||||
phone: "+49 2381 100",
|
||||
distanceFromRouteNm: 0
|
||||
})
|
||||
);
|
||||
expect(locks[1]).toEqual(
|
||||
expect.objectContaining({
|
||||
name: "Schleuse Ost",
|
||||
openingHours: "Mo-Su 06:00-22:00",
|
||||
phone: "+49 2381 200",
|
||||
distanceFromRouteNm: 0
|
||||
})
|
||||
);
|
||||
expect(locks[0]!.routeDistanceNm).toBeLessThan(locks[1]!.routeDistanceNm);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user