"use strict"; /** * Spatial utility functions for geographic calculations. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.isPointInPolygon = isPointInPolygon; exports.parseGeoJsonPolygon = parseGeoJsonPolygon; exports.calculateBounds = calculateBounds; exports.haversineDistance = haversineDistance; exports.calculateCentroid = calculateCentroid; /** * Ray-casting algorithm to determine if a point is inside a polygon. * @param lat Point latitude * @param lng Point longitude * @param polygonCoords Array of [lng, lat] coordinate pairs (GeoJSON order) */ function isPointInPolygon(lat, lng, polygonCoords) { let inside = false; for (let i = 0, j = polygonCoords.length - 1; i < polygonCoords.length; j = i++) { const xi = polygonCoords[i][1]; // lat const yi = polygonCoords[i][0]; // lng const xj = polygonCoords[j][1]; const yj = polygonCoords[j][0]; const intersect = ((yi > lng) !== (yj > lng)) && (lat < (xj - xi) * (lng - yi) / (yj - yi) + xi); if (intersect) inside = !inside; } return inside; } /** * Parse GeoJSON string and extract coordinate arrays for all polygons. * Supports Polygon and MultiPolygon types. * Returns array of coordinate rings (outer rings only). */ function parseGeoJsonPolygon(geojsonString) { const geojson = JSON.parse(geojsonString); if (geojson.type === 'Polygon') { // Polygon coordinates: [ring][point][lng,lat] return [geojson.coordinates[0]]; } if (geojson.type === 'MultiPolygon') { // MultiPolygon coordinates: [polygon][ring][point][lng,lat] return geojson.coordinates.map((poly) => poly[0]); } throw new Error(`Unsupported GeoJSON type: ${geojson.type}`); } /** * Calculate bounding box from an array of [lng, lat] coordinate pairs. * Returns { minLat, maxLat, minLng, maxLng }. */ function calculateBounds(coordinates) { let minLat = Infinity; let maxLat = -Infinity; let minLng = Infinity; let maxLng = -Infinity; for (const coord of coordinates) { const lng = coord[0]; const lat = coord[1]; if (lat < minLat) minLat = lat; if (lat > maxLat) maxLat = lat; if (lng < minLng) minLng = lng; if (lng > maxLng) maxLng = lng; } return { minLat, maxLat, minLng, maxLng }; } /** * Haversine distance between two lat/lng points in meters. */ function haversineDistance(lat1, lng1, lat2, lng2) { const R = 6371000; // Earth radius in meters const toRad = (deg) => (deg * Math.PI) / 180; const dLat = toRad(lat2 - lat1); const dLng = toRad(lng2 - lng1); const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; } /** * Calculate the centroid of an array of [lng, lat] coordinate pairs. * Returns { lat, lng }. */ function calculateCentroid(coordinates) { let sumLat = 0; let sumLng = 0; for (const coord of coordinates) { sumLng += coord[0]; sumLat += coord[1]; } return { lat: sumLat / coordinates.length, lng: sumLng / coordinates.length, }; } //# sourceMappingURL=spatial.js.map