vgridjs
Version:
Vgrid DGGS JS
104 lines (103 loc) • 3.58 kB
JavaScript
// 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