4 changed files with 111 additions and 1289 deletions
File diff suppressed because it is too large
@ -0,0 +1,109 @@ |
|||
type Position = [number, number]; |
|||
type BBox = [number, number, number, number]; |
|||
|
|||
interface GeoJSONGeometry { |
|||
type: string; |
|||
coordinates: Position | Position[] | Position[][] | Position[][][]; |
|||
} |
|||
|
|||
interface Feature<G extends GeoJSONGeometry> { |
|||
type: "Feature"; |
|||
geometry: G; |
|||
properties: Record<string, unknown>; |
|||
} |
|||
|
|||
interface LineStringGeometry { |
|||
type: "LineString"; |
|||
coordinates: Position[]; |
|||
} |
|||
|
|||
function lineString(coordinates: Position[]): Feature<LineStringGeometry> { |
|||
if (!coordinates || coordinates.length < 2) { |
|||
throw new Error("coordinates must contain at least 2 positions"); |
|||
} |
|||
|
|||
for (const [index, coord] of coordinates.entries()) { |
|||
if (!Array.isArray(coord) || coord.length !== 2) { |
|||
throw new Error(`Invalid position at index ${index}`); |
|||
} |
|||
if (!coord.every((n) => typeof n === "number")) { |
|||
throw new Error(`Position must contain numbers at index ${index}`); |
|||
} |
|||
} |
|||
|
|||
return { |
|||
type: "Feature", |
|||
properties: {}, |
|||
geometry: { |
|||
type: "LineString", |
|||
coordinates, |
|||
}, |
|||
}; |
|||
} |
|||
|
|||
function bbox(geojson: Feature<GeoJSONGeometry> | GeoJSONGeometry): BBox { |
|||
if (!geojson) { |
|||
throw new Error("geojson is required"); |
|||
} |
|||
|
|||
const coords = getAllCoordinates(geojson); |
|||
if (coords.length === 0) { |
|||
throw new Error("No coordinates found in geojson"); |
|||
} |
|||
|
|||
const [west, south, east, north] = coords.reduce( |
|||
([minX, minY, maxX, maxY], [x, y]) => [ |
|||
Math.min(minX, x), |
|||
Math.min(minY, y), |
|||
Math.max(maxX, x), |
|||
Math.max(maxY, y), |
|||
], |
|||
[ |
|||
Number.POSITIVE_INFINITY, |
|||
Number.POSITIVE_INFINITY, |
|||
Number.NEGATIVE_INFINITY, |
|||
Number.NEGATIVE_INFINITY, |
|||
], |
|||
); |
|||
|
|||
return [west, south, east, north]; |
|||
} |
|||
|
|||
function getAllCoordinates( |
|||
geojson: Feature<GeoJSONGeometry> | GeoJSONGeometry, |
|||
): Position[] { |
|||
const geometry = |
|||
"type" in geojson && geojson.type === "Feature" && "geometry" in geojson |
|||
? geojson.geometry |
|||
: geojson; |
|||
const coords: Position[] = []; |
|||
|
|||
switch (geometry.type) { |
|||
case "Point": |
|||
coords.push(geometry.coordinates as Position); |
|||
break; |
|||
case "LineString": |
|||
case "MultiPoint": |
|||
coords.push(...(geometry.coordinates as Position[])); |
|||
break; |
|||
case "Polygon": |
|||
case "MultiLineString": |
|||
for (const line of geometry.coordinates as Position[][]) { |
|||
coords.push(...line); |
|||
} |
|||
break; |
|||
case "MultiPolygon": |
|||
for (const poly of geometry.coordinates as Position[][][]) { |
|||
for (const line of poly) { |
|||
coords.push(...line); |
|||
} |
|||
} |
|||
break; |
|||
default: |
|||
throw new Error(`Unsupported geometry type: ${geometry.type}`); |
|||
} |
|||
|
|||
return coords; |
|||
} |
|||
|
|||
export { bbox, lineString } |
|||
Loading…
Reference in new issue