UNPKG

@chauffleet/expo-custom-map

Version:

Open source custom map library for Expo/React Native. Use your own tiles without Google Maps, Mapbox, or API keys. Created by ChaufFleet.

118 lines 5.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.interpolateCoordinates = exports.normalizeCoordinate = exports.calculateTileBounds = exports.getBoundsZoom = exports.isPointInBounds = exports.getGeoBounds = exports.calculateBearing = exports.calculateDistance = exports.tileToLatLon = exports.latLonToTile = exports.rad2deg = exports.deg2rad = void 0; // src/utils/geoUtils.ts const deg2rad = (deg) => (deg * Math.PI) / 180; exports.deg2rad = deg2rad; const rad2deg = (rad) => (rad * 180) / Math.PI; exports.rad2deg = rad2deg; const latLonToTile = (lat, lon, zoom) => { const x = Math.floor(((lon + 180) / 360) * Math.pow(2, zoom)); const y = Math.floor(((1 - Math.log(Math.tan((0, exports.deg2rad)(lat)) + 1 / Math.cos((0, exports.deg2rad)(lat))) / Math.PI) / 2) * Math.pow(2, zoom)); return { x, y }; }; exports.latLonToTile = latLonToTile; const tileToLatLon = (x, y, zoom) => { const n = Math.pow(2, zoom); const lon = (x / n) * 360 - 180; const lat = (0, exports.rad2deg)(Math.atan(Math.sinh(Math.PI * (1 - (2 * y) / n)))); return { lat, lon }; }; exports.tileToLatLon = tileToLatLon; const calculateDistance = (coord1, coord2) => { const R = 6371; // Earth radius in km const dLat = (0, exports.deg2rad)(coord2[1] - coord1[1]); const dLon = (0, exports.deg2rad)(coord2[0] - coord1[0]); const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos((0, exports.deg2rad)(coord1[1])) * Math.cos((0, exports.deg2rad)(coord2[1])) * Math.sin(dLon / 2) * Math.sin(dLon / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; }; exports.calculateDistance = calculateDistance; const calculateBearing = (start, end) => { const startLat = (0, exports.deg2rad)(start[1]); const startLng = (0, exports.deg2rad)(start[0]); const endLat = (0, exports.deg2rad)(end[1]); const endLng = (0, exports.deg2rad)(end[0]); const dLng = endLng - startLng; const y = Math.sin(dLng) * Math.cos(endLat); const x = Math.cos(startLat) * Math.sin(endLat) - Math.sin(startLat) * Math.cos(endLat) * Math.cos(dLng); const bearing = (0, exports.rad2deg)(Math.atan2(y, x)); return (bearing + 360) % 360; }; exports.calculateBearing = calculateBearing; const getGeoBounds = (coordinates) => { if (coordinates.length === 0) { throw new Error('Cannot calculate bounds of empty coordinates array'); } let north = coordinates[0][1]; let south = coordinates[0][1]; let east = coordinates[0][0]; let west = coordinates[0][0]; coordinates.forEach(([lon, lat]) => { if (lat > north) north = lat; if (lat < south) south = lat; if (lon > east) east = lon; if (lon < west) west = lon; }); return { north, south, east, west }; }; exports.getGeoBounds = getGeoBounds; const isPointInBounds = (point, bounds) => { const [lon, lat] = point; return lat <= bounds.north && lat >= bounds.south && lon <= bounds.east && lon >= bounds.west; }; exports.isPointInBounds = isPointInBounds; const getBoundsZoom = (bounds, screenWidth, screenHeight, tileSize = 256) => { const latDiff = bounds.north - bounds.south; const lonDiff = bounds.east - bounds.west; const maxDiff = Math.max(latDiff, lonDiff); const zoom = Math.floor(Math.log2(360 / maxDiff)); return Math.max(1, Math.min(18, zoom)); }; exports.getBoundsZoom = getBoundsZoom; const calculateTileBounds = (lat, lon, radiusKm, zoom) => { const latRad = (0, exports.deg2rad)(lat); const degreeDistance = 111; // km par degré approximatif const latDelta = radiusKm / degreeDistance; const lonDelta = radiusKm / (degreeDistance * Math.cos(latRad)); const minLat = lat - latDelta; const maxLat = lat + latDelta; const minLon = lon - lonDelta; const maxLon = lon + lonDelta; const minTile = (0, exports.latLonToTile)(minLat, minLon, zoom); const maxTile = (0, exports.latLonToTile)(maxLat, maxLon, zoom); return { minX: Math.min(minTile.x, maxTile.x), maxX: Math.max(minTile.x, maxTile.x), minY: Math.min(minTile.y, maxTile.y), maxY: Math.max(minTile.y, maxTile.y), }; }; exports.calculateTileBounds = calculateTileBounds; const normalizeCoordinate = (coordinate) => { let [lon, lat] = coordinate; // Normaliser la longitude (-180 to 180) lon = ((lon + 180) % 360) - 180; // Clamp la latitude (-90 to 90) lat = Math.max(-90, Math.min(90, lat)); return [lon, lat]; }; exports.normalizeCoordinate = normalizeCoordinate; const interpolateCoordinates = (start, end, progress) => { const startLon = start[0]; const startLat = start[1]; const endLon = end[0]; const endLat = end[1]; const lon = startLon + (endLon - startLon) * progress; const lat = startLat + (endLat - startLat) * progress; return [lon, lat]; }; exports.interpolateCoordinates = interpolateCoordinates; //# sourceMappingURL=geoUtils.js.map