diff --git a/geo.ts b/geo.ts new file mode 100644 index 0000000..3921af1 --- /dev/null +++ b/geo.ts @@ -0,0 +1,87 @@ +const EarthRadius = 6371008.8; // in meeter +const YAxisInversion = 1; +2; + +export enum Constant { + EarthRadiusInM = EarthRadius, // + EarthRadiusInFt = EarthRadius * 3.28084, //km: 6,378.137 | meters: 6378137 + MeterToFeet = 3.28084, +} + +export type Point = { + x: number; + y: number; +}; + +export interface LatLng { + lat: number; + lng: number; +} + +export function realWorldDistance(p1: Point, p2: Point, unitPixel: { x: number; y: number }) { + const dx = (p2.x - p1.x) * unitPixel.x; + const dy = (p2.y - p1.y) * unitPixel.y; + const realWorldDistance = Math.sqrt(dx * dx + dy * dy); + return realWorldDistance; +} + +/** + * distance between two geo coords in meeters + */ +export function haversineDistance(p1: LatLng, p2: LatLng): number { + const φ1 = toRadian(p1.lat); // phi 1 + const φ2 = toRadian(p2.lat); // phi 2 + const Δφ = toRadian(p2.lat - p1.lat); // delta phi + const Δλ = toRadian(p2.lng - p1.lng); // delta lambda + const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return c * Constant.EarthRadiusInFt; +} + +export function toRadian(degrees: number) { + return degrees * (Math.PI / 180); +} + +/** + * convert geo coords to image coordinates + */ +export function geoToImgCoord( + p: LatLng, + imgW: number, + imgH: number, + boxLeft: number, + boxBottom: number, + boxRight: number, + boxTop: number, +) { + const xRatio = (p.lng - boxLeft) / (boxRight - boxLeft); + const yRatio = (p.lat - boxBottom) / (boxTop - boxBottom); + const pixelX = xRatio * imgW; + // Y-Axis Inversion i.e. 1 - yRatio, is need because + // image coordinates typically have the origin (0,0) at the top-left corner, with y increasing downward) + const pixelY = (YAxisInversion - yRatio) * imgH; + + // console.log(p, imgW, imgH, boxLeft, boxBottom, boxRight, boxTop, ' = ', pixelX, pixelY); + return [pixelX, pixelY]; +} + +/** + * plane pixel to geo coords + */ +export function imgToGeoCoords( + p: Point, + imgW: number, + imgH: number, + boxLeft: number, + boxBottom: number, + boxRight: number, + boxTop: number, +): LatLng { + const xRatio = p.x / imgW; + const yRatio = YAxisInversion - p.y / imgH; + const lng = boxLeft + xRatio * (boxRight - boxLeft); + const lat = boxBottom + yRatio * (boxTop - boxBottom); + + return { lat, lng }; +} \ No newline at end of file