feat: map the complete municipality of Mol
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
export interface GeoJsonBounds {
|
||||
minX: number
|
||||
minY: number
|
||||
maxX: number
|
||||
maxY: number
|
||||
}
|
||||
|
||||
function extendBounds(bounds: GeoJsonBounds | null, x: number, y: number): GeoJsonBounds {
|
||||
if (!bounds) {
|
||||
return { minX: x, minY: y, maxX: x, maxY: y }
|
||||
}
|
||||
bounds.minX = Math.min(bounds.minX, x)
|
||||
bounds.minY = Math.min(bounds.minY, y)
|
||||
bounds.maxX = Math.max(bounds.maxX, x)
|
||||
bounds.maxY = Math.max(bounds.maxY, y)
|
||||
return bounds
|
||||
}
|
||||
|
||||
function scanCoordinates(coordinates: unknown, initial: GeoJsonBounds | null): GeoJsonBounds | null {
|
||||
let bounds = initial
|
||||
const stack: unknown[] = [coordinates]
|
||||
while (stack.length > 0) {
|
||||
const value = stack.pop()
|
||||
if (!Array.isArray(value)) {
|
||||
continue
|
||||
}
|
||||
if (value.length >= 2 && typeof value[0] === 'number' && typeof value[1] === 'number') {
|
||||
if (Number.isFinite(value[0]) && Number.isFinite(value[1])) {
|
||||
bounds = extendBounds(bounds, value[0], value[1])
|
||||
}
|
||||
continue
|
||||
}
|
||||
for (const child of value) {
|
||||
stack.push(child)
|
||||
}
|
||||
}
|
||||
return bounds
|
||||
}
|
||||
|
||||
export function geometryBounds(geometry: GeoJSON.Geometry | null | undefined): GeoJsonBounds | null {
|
||||
if (!geometry) {
|
||||
return null
|
||||
}
|
||||
if (geometry.type === 'GeometryCollection') {
|
||||
return geometry.geometries.reduce<GeoJsonBounds | null>(
|
||||
(bounds, child) => mergeBounds(bounds, geometryBounds(child)),
|
||||
null,
|
||||
)
|
||||
}
|
||||
return scanCoordinates(geometry.coordinates, null)
|
||||
}
|
||||
|
||||
export function mergeBounds(left: GeoJsonBounds | null, right: GeoJsonBounds | null): GeoJsonBounds | null {
|
||||
if (!left) {
|
||||
return right ? { ...right } : null
|
||||
}
|
||||
if (!right) {
|
||||
return left
|
||||
}
|
||||
left.minX = Math.min(left.minX, right.minX)
|
||||
left.minY = Math.min(left.minY, right.minY)
|
||||
left.maxX = Math.max(left.maxX, right.maxX)
|
||||
left.maxY = Math.max(left.maxY, right.maxY)
|
||||
return left
|
||||
}
|
||||
|
||||
export function featureCollectionBounds(collection: GeoJSON.FeatureCollection | null | undefined): GeoJsonBounds | null {
|
||||
if (!collection) {
|
||||
return null
|
||||
}
|
||||
return collection.features.reduce<GeoJsonBounds | null>(
|
||||
(bounds, feature) => mergeBounds(bounds, geometryBounds(feature.geometry)),
|
||||
null,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user