UNPKG

vgridjs

Version:

Vgrid DGGS JS

104 lines (103 loc) 3.58 kB
// dggs/maidenhead.ts var MAIDENHEAD_FIELD = "ABCDEFGHIJKLMNOPQRSTUVWX"; var MAIDENHEAD_SQUARE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWX"; var MAIDENHEAD_SUBSQUARE = "abcdefghijklmnopqrstuvwx"; var MaidenheadException = class extends Error { constructor(message) { super(message); this.name = "MaidenheadException"; } }; function encode(lat, lon, precision = 2) { if (lat < -90 || lat > 90) { throw new MaidenheadException("Latitude must be between -90 and 90 degrees"); } if (lon < -180 || lon > 180) { throw new MaidenheadException("Longitude must be between -180 and 180 degrees"); } if (precision < 1 || precision > 3) { throw new MaidenheadException("Precision must be between 1 and 3"); } lon = (lon + 180) % 360; lat = (lat + 90) % 180; let locator = ""; const fieldLon = Math.floor(lon / 20); const fieldLat = Math.floor(lat / 10); locator += MAIDENHEAD_FIELD[fieldLon]; locator += MAIDENHEAD_FIELD[fieldLat]; if (precision >= 2) { const squareLon = Math.floor(lon % 20 / 2); const squareLat = Math.floor(lat % 10 / 1); locator += MAIDENHEAD_SQUARE[squareLon]; locator += MAIDENHEAD_SQUARE[squareLat]; if (precision >= 3) { const subsquareLon = Math.floor(lon % 2 * 12); const subsquareLat = Math.floor(lat % 1 * 24); locator += MAIDENHEAD_SUBSQUARE[subsquareLon]; locator += MAIDENHEAD_SUBSQUARE[subsquareLat]; } } return locator; } function decode(locator) { if (!locator) { throw new MaidenheadException("Empty locator string"); } locator = locator.toUpperCase(); const len = locator.length; if (len < 2 || len > 6 || len % 2 !== 0) { throw new MaidenheadException("Invalid locator length"); } const fieldLon = MAIDENHEAD_FIELD.indexOf(locator[0]); const fieldLat = MAIDENHEAD_FIELD.indexOf(locator[1]); if (fieldLon === -1 || fieldLat === -1) { throw new MaidenheadException("Invalid field characters"); } let lon = fieldLon * 20 - 180; let lat = fieldLat * 10 - 90; if (len >= 4) { const squareLon = MAIDENHEAD_SQUARE.indexOf(locator[2]); const squareLat = MAIDENHEAD_SQUARE.indexOf(locator[3]); if (squareLon === -1 || squareLat === -1) { throw new MaidenheadException("Invalid square characters"); } lon += squareLon * 2; lat += squareLat * 1; if (len >= 6) { const subsquareLon = MAIDENHEAD_SUBSQUARE.indexOf(locator[4].toLowerCase()); const subsquareLat = MAIDENHEAD_SUBSQUARE.indexOf(locator[5].toLowerCase()); if (subsquareLon === -1 || subsquareLat === -1) { throw new MaidenheadException("Invalid subsquare characters"); } lon += subsquareLon / 12; lat += subsquareLat / 24; } } return [lat, lon]; } function maidenheadCell(maidenheadId) { const [centerLat, centerLon] = decode(maidenheadId); const precision = Math.floor(maidenheadId.length / 2); let gridSize; switch (precision) { case 1: gridSize = 10; break; case 2: gridSize = 1; break; case 3: gridSize = 1 / 24; break; default: throw new MaidenheadException(`Invalid precision: ${precision}`); } const minLon = Math.floor(centerLon / gridSize) * gridSize; const maxLon = minLon + gridSize; const minLat = Math.floor(centerLat / gridSize) * gridSize; const maxLat = minLat + gridSize; return [centerLat, centerLon, minLat, minLon, maxLat, maxLon, precision]; } export { MaidenheadException, decode, encode, maidenheadCell }; //# sourceMappingURL=maidenhead.js.map //# sourceMappingURL=maidenhead.js.map