UNPKG

vgridjs

Version:

Vgrid DGGS JS

1 lines 14.6 kB
{"version":3,"sources":["../dggs/georef.ts"],"names":[],"mappings":"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","file":"georef.cjs","sourcesContent":["/**\r\n * GEOREF implementation in TypeScript\r\n * Adapted from GeographicLib's GEOREF code\r\n * Original C++ version by Charles Karney (2015-2020) <charles@karney.com>\r\n * Licensed under the MIT/X11 License\r\n */\r\n\r\nconst digits = \"0123456789\";\r\nconst lontile = \"ABCDEFGHJKLMNPQRSTUVWXYZ\";\r\nconst lattile = \"ABCDEFGHJKLMM\"; // Repeat the last M for 90 degrees which rounds up - Prevents extra checks in the code\r\nconst degrees = \"ABCDEFGHJKLMNPQ\";\r\nconst tile = 15;\r\nconst lonorig = -180;\r\nconst latorig = -90;\r\nconst base = 10;\r\nconst baselen = 4;\r\nconst maxprec = 11;\r\nconst maxlen = baselen + 2 * maxprec;\r\n\r\nexport class GeorefException extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'GeorefException';\r\n }\r\n}\r\n\r\nfunction findFirstNotOf(s: string, sSet: string): number {\r\n for (let i = 0; i < s.length; i++) {\r\n if (!sSet.includes(s[i])) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n}\r\n\r\nfunction lookup(s: string, c: string): number {\r\n const r = s.indexOf(c);\r\n return r < 0 ? -1 : r;\r\n}\r\n\r\nexport function encode(lat: number, lon: number, prec: number): string {\r\n if (lat > 90 || lat < -90) {\r\n throw new GeorefException('Latitude not in -90 to 90 range');\r\n }\r\n if (lon < -180 || lon > 360) {\r\n throw new GeorefException('Longitude is out of range');\r\n }\r\n if (lon >= 180) { // make longitude in the range -180, 180\r\n lon = lon - 360;\r\n }\r\n\r\n if (lat === 90) {\r\n lat = lat - Number.EPSILON;\r\n }\r\n prec = Math.max(-1, Math.min(Math.floor(maxprec), prec));\r\n\r\n if (prec === 1) {\r\n prec = prec + 1; // Disallow prec = 1\r\n }\r\n const m = 60000000000;\r\n const x = Math.floor(lon * m) - lonorig * m;\r\n const y = Math.floor(lat * m) - latorig * m;\r\n const ilon = Math.floor(x / m);\r\n const ilat = Math.floor(y / m);\r\n const georef1: string[] = new Array(maxlen).fill(\"\");\r\n georef1[0] = lontile[Math.floor(ilon / tile)];\r\n georef1[1] = lattile[Math.floor(ilat / tile)];\r\n if (prec >= 0) {\r\n georef1[2] = degrees[ilon % tile];\r\n georef1[3] = degrees[ilat % tile];\r\n if (prec > 0) {\r\n let x1 = Math.floor(x - m * ilon);\r\n let y1 = Math.floor(y - m * ilat);\r\n const d = Math.pow(base, maxprec - prec);\r\n x1 = Math.floor(x1 / d);\r\n y1 = Math.floor(y1 / d);\r\n let c = prec;\r\n while (c) {\r\n georef1[baselen + c] = digits[x1 % base];\r\n x1 = Math.floor(x1 / base);\r\n georef1[baselen + c + prec] = digits[y1 % base];\r\n y1 = Math.floor(y1 / base);\r\n c = c - 1;\r\n }\r\n }\r\n }\r\n return georef1.join('');\r\n}\r\n\r\nexport function decode(georef: string, centerp: boolean = false): [number, number, number] {\r\n if (!georef) {\r\n throw new GeorefException('Invalid Georef string: None');\r\n }\r\n georef = georef.toUpperCase();\r\n const leng = georef.length;\r\n if (leng >= 3 && georef[0] === 'I' && georef[1] === 'N' && georef[2] === 'V') {\r\n throw new GeorefException('Invalid Georef string');\r\n }\r\n if (leng < baselen - 2) {\r\n throw new GeorefException(`Georef must start with at least 2 letters: ${georef}`);\r\n }\r\n const prec1 = Math.floor((2 + leng - baselen) / 2 - 1);\r\n let k = lookup(lontile, georef[0]);\r\n if (k < 0) {\r\n throw new GeorefException(`Bad longitude tile letter in georef: ${georef}`);\r\n }\r\n let lon1 = k + lonorig / tile;\r\n k = lookup(lattile, georef[1]);\r\n if (k < 0) {\r\n throw new GeorefException(`Bad latitude tile letter in georef: ${georef}`);\r\n }\r\n let lat1 = k + latorig / tile;\r\n let unit = 1;\r\n if (leng > 2) {\r\n unit = unit * tile;\r\n k = lookup(degrees, georef[2]);\r\n if (k < 0) {\r\n throw new GeorefException(`Bad longitude degree letter in georef: ${georef}`);\r\n }\r\n lon1 = lon1 * tile + k;\r\n if (leng < 4) {\r\n throw new GeorefException(`Missing latitude degree letter in georef: ${georef}`);\r\n }\r\n k = lookup(degrees, georef[3]);\r\n if (k < 0) {\r\n throw new GeorefException(`Bad latitude degree letter in georef: ${georef}`);\r\n }\r\n lat1 = lat1 * tile + k;\r\n if (prec1 > 0) {\r\n if (findFirstNotOf(georef.slice(baselen), digits) !== -1) {\r\n throw new GeorefException(`Non digits in trailing portion of georef: ${georef.slice(baselen)}`);\r\n }\r\n if (leng % 2) {\r\n throw new GeorefException(`Georef must end with an even number of digits: ${georef.slice(baselen)}`);\r\n }\r\n if (prec1 === 1) {\r\n throw new GeorefException(`Georef needs at least 4 digits for minutes: ${georef.slice(baselen)}`);\r\n }\r\n if (prec1 > maxprec) {\r\n throw new GeorefException(`More than ${2 * maxprec} digits in georef: ${georef.slice(baselen)}`);\r\n }\r\n let i = 0;\r\n while (i < prec1) {\r\n const m = i ? base : 6;\r\n unit = unit * m;\r\n const x = lookup(digits, georef[baselen + i]);\r\n const y = lookup(digits, georef[baselen + i + prec1]);\r\n if (!(i || (x < m && y < m))) {\r\n throw new GeorefException(`Minutes terms in georef must be less than 60: ${georef.slice(baselen)}`);\r\n }\r\n lon1 = m * lon1 + x;\r\n lat1 = m * lat1 + y;\r\n i = i + 1;\r\n }\r\n }\r\n }\r\n if (centerp) {\r\n unit = unit * 2;\r\n lat1 = 2 * lat1 + 1;\r\n lon1 = 2 * lon1 + 1;\r\n }\r\n const lat = (tile * lat1) / unit;\r\n const lon = (tile * lon1) / unit;\r\n const prec = prec1;\r\n return [lat, lon, prec];\r\n}\r\n\r\n// Vgrid specific functions\r\nexport function georefCell(georefId: string): [number, number, number, number, number, number, number] {\r\n // Decode the GEOREF code to get the center coordinates and resolution\r\n const [centerLat, centerLon, resolution] = decode(georefId, true); // true for center point, not bottom-left\r\n let gridSize: number;\r\n \r\n switch (resolution) {\r\n case 0:\r\n gridSize = 15;\r\n break;\r\n case 1:\r\n gridSize = 1;\r\n break;\r\n case 2:\r\n gridSize = 1/60;\r\n break;\r\n case 3:\r\n gridSize = 1/600;\r\n break;\r\n case 4:\r\n gridSize = 1/6000;\r\n break;\r\n case 5:\r\n gridSize = 1/60000;\r\n break;\r\n default:\r\n throw new GeorefException(`Invalid resolution: ${resolution}`);\r\n }\r\n\r\n const minLon = Math.floor(centerLon / gridSize) * gridSize;\r\n const maxLon = minLon + gridSize;\r\n const minLat = Math.floor(centerLat / gridSize) * gridSize;\r\n const maxLat = minLat + gridSize;\r\n\r\n return [centerLat, centerLon, minLat, minLon, maxLat, maxLon, resolution];\r\n} "]}