@fleet-frontend/mower-maps
Version:
a mower maps in google maps
1,653 lines (1,538 loc) • 1.12 MB
JavaScript
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var ReactDOM = require('react-dom');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
function globals (defs) {
defs('EPSG:4326', '+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees');
defs('EPSG:4269', '+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees');
defs('EPSG:3857', '+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs');
// UTM WGS84
for (var i = 1; i <= 60; ++i) {
defs('EPSG:' + (32600 + i), '+proj=utm +zone=' + i + ' +datum=WGS84 +units=m');
defs('EPSG:' + (32700 + i), '+proj=utm +zone=' + i + ' +south +datum=WGS84 +units=m');
}
defs('EPSG:5041', '+title=WGS 84 / UPS North (E,N) +proj=stere +lat_0=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +datum=WGS84 +units=m');
defs('EPSG:5042', '+title=WGS 84 / UPS South (E,N) +proj=stere +lat_0=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +datum=WGS84 +units=m');
defs.WGS84 = defs['EPSG:4326'];
defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857
defs.GOOGLE = defs['EPSG:3857'];
defs['EPSG:900913'] = defs['EPSG:3857'];
defs['EPSG:102113'] = defs['EPSG:3857'];
}
var PJD_3PARAM = 1;
var PJD_7PARAM = 2;
var PJD_GRIDSHIFT = 3;
var PJD_WGS84 = 4; // WGS84 or equivalent
var PJD_NODATUM = 5; // WGS84 or equivalent
var SRS_WGS84_SEMIMAJOR = 6378137.0; // only used in grid shift transforms
var SRS_WGS84_SEMIMINOR = 6356752.314; // only used in grid shift transforms
var SRS_WGS84_ESQUARED = 0.0066943799901413165; // only used in grid shift transforms
var SEC_TO_RAD = 4.84813681109535993589914102357e-6;
var HALF_PI = Math.PI / 2;
// ellipoid pj_set_ell.c
var SIXTH = 0.1666666666666666667;
/* 1/6 */
var RA4 = 0.04722222222222222222;
/* 17/360 */
var RA6 = 0.02215608465608465608;
var EPSLN = 1.0e-10;
// you'd think you could use Number.EPSILON above but that makes
// Mollweide get into an infinate loop.
var D2R$1 = 0.01745329251994329577;
var R2D = 57.29577951308232088;
var FORTPI = Math.PI / 4;
var TWO_PI = Math.PI * 2;
// SPI is slightly greater than Math.PI, so values that exceed the -180..180
// degree range by a tiny amount don't get wrapped. This prevents points that
// have drifted from their original location along the 180th meridian (due to
// floating point error) from changing their sign.
var SPI = 3.14159265359;
var primeMeridian = {};
primeMeridian.greenwich = 0.0; // "0dE",
primeMeridian.lisbon = -9.131906111111; // "9d07'54.862\"W",
primeMeridian.paris = 2.337229166667; // "2d20'14.025\"E",
primeMeridian.bogota = -74.080916666667; // "74d04'51.3\"W",
primeMeridian.madrid = -3.687938888889; // "3d41'16.58\"W",
primeMeridian.rome = 12.452333333333; // "12d27'8.4\"E",
primeMeridian.bern = 7.439583333333; // "7d26'22.5\"E",
primeMeridian.jakarta = 106.807719444444; // "106d48'27.79\"E",
primeMeridian.ferro = -17.666666666667; // "17d40'W",
primeMeridian.brussels = 4.367975; // "4d22'4.71\"E",
primeMeridian.stockholm = 18.058277777778; // "18d3'29.8\"E",
primeMeridian.athens = 23.7163375; // "23d42'58.815\"E",
primeMeridian.oslo = 10.722916666667; // "10d43'22.5\"E"
var units = {
mm: { to_meter: 0.001 },
cm: { to_meter: 0.01 },
ft: { to_meter: 0.3048 },
'us-ft': { to_meter: 1200 / 3937 },
fath: { to_meter: 1.8288 },
kmi: { to_meter: 1852 },
'us-ch': { to_meter: 20.1168402336805 },
'us-mi': { to_meter: 1609.34721869444 },
km: { to_meter: 1000 },
'ind-ft': { to_meter: 0.30479841 },
'ind-yd': { to_meter: 0.91439523 },
mi: { to_meter: 1609.344 },
yd: { to_meter: 0.9144 },
ch: { to_meter: 20.1168 },
link: { to_meter: 0.201168 },
dm: { to_meter: 0.1 },
in: { to_meter: 0.0254 },
'ind-ch': { to_meter: 20.11669506 },
'us-in': { to_meter: 0.025400050800101 },
'us-yd': { to_meter: 0.914401828803658 }
};
var ignoredChar = /[\s_\-\/\(\)]/g;
function match(obj, key) {
if (obj[key]) {
return obj[key];
}
var keys = Object.keys(obj);
var lkey = key.toLowerCase().replace(ignoredChar, '');
var i = -1;
var testkey, processedKey;
while (++i < keys.length) {
testkey = keys[i];
processedKey = testkey.toLowerCase().replace(ignoredChar, '');
if (processedKey === lkey) {
return obj[testkey];
}
}
}
/**
* @param {string} defData
* @returns {import('./defs').ProjectionDefinition}
*/
function projStr (defData) {
/** @type {import('./defs').ProjectionDefinition} */
var self = {};
var paramObj = defData.split('+').map(function (v) {
return v.trim();
}).filter(function (a) {
return a;
}).reduce(function (p, a) {
/** @type {Array<?>} */
var split = a.split('=');
split.push(true);
p[split[0].toLowerCase()] = split[1];
return p;
}, {});
var paramName, paramVal, paramOutname;
var params = {
proj: 'projName',
datum: 'datumCode',
rf: function (v) {
self.rf = parseFloat(v);
},
lat_0: function (v) {
self.lat0 = v * D2R$1;
},
lat_1: function (v) {
self.lat1 = v * D2R$1;
},
lat_2: function (v) {
self.lat2 = v * D2R$1;
},
lat_ts: function (v) {
self.lat_ts = v * D2R$1;
},
lon_0: function (v) {
self.long0 = v * D2R$1;
},
lon_1: function (v) {
self.long1 = v * D2R$1;
},
lon_2: function (v) {
self.long2 = v * D2R$1;
},
alpha: function (v) {
self.alpha = parseFloat(v) * D2R$1;
},
gamma: function (v) {
self.rectified_grid_angle = parseFloat(v) * D2R$1;
},
lonc: function (v) {
self.longc = v * D2R$1;
},
x_0: function (v) {
self.x0 = parseFloat(v);
},
y_0: function (v) {
self.y0 = parseFloat(v);
},
k_0: function (v) {
self.k0 = parseFloat(v);
},
k: function (v) {
self.k0 = parseFloat(v);
},
a: function (v) {
self.a = parseFloat(v);
},
b: function (v) {
self.b = parseFloat(v);
},
r: function (v) {
self.a = self.b = parseFloat(v);
},
r_a: function () {
self.R_A = true;
},
zone: function (v) {
self.zone = parseInt(v, 10);
},
south: function () {
self.utmSouth = true;
},
towgs84: function (v) {
self.datum_params = v.split(',').map(function (a) {
return parseFloat(a);
});
},
to_meter: function (v) {
self.to_meter = parseFloat(v);
},
units: function (v) {
self.units = v;
var unit = match(units, v);
if (unit) {
self.to_meter = unit.to_meter;
}
},
from_greenwich: function (v) {
self.from_greenwich = v * D2R$1;
},
pm: function (v) {
var pm = match(primeMeridian, v);
self.from_greenwich = (pm ? pm : parseFloat(v)) * D2R$1;
},
nadgrids: function (v) {
if (v === '@null') {
self.datumCode = 'none';
} else {
self.nadgrids = v;
}
},
axis: function (v) {
var legalAxis = 'ewnsud';
if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) {
self.axis = v;
}
},
approx: function () {
self.approx = true;
},
over: function () {
self.over = true;
}
};
for (paramName in paramObj) {
paramVal = paramObj[paramName];
if (paramName in params) {
paramOutname = params[paramName];
if (typeof paramOutname === 'function') {
paramOutname(paramVal);
} else {
self[paramOutname] = paramVal;
}
} else {
self[paramName] = paramVal;
}
}
if (typeof self.datumCode === 'string' && self.datumCode !== 'WGS84') {
self.datumCode = self.datumCode.toLowerCase();
}
self['projStr'] = defData;
return self;
}
class PROJJSONBuilderBase {
static getId(node) {
const idNode = node.find((child) => Array.isArray(child) && child[0] === 'ID');
if (idNode && idNode.length >= 3) {
return {
authority: idNode[1],
code: parseInt(idNode[2], 10),
};
}
return null;
}
static convertUnit(node, type = 'unit') {
if (!node || node.length < 3) {
return { type, name: 'unknown', conversion_factor: null };
}
const name = node[1];
const conversionFactor = parseFloat(node[2]) || null;
const idNode = node.find((child) => Array.isArray(child) && child[0] === 'ID');
const id = idNode
? {
authority: idNode[1],
code: parseInt(idNode[2], 10),
}
: null;
return {
type,
name,
conversion_factor: conversionFactor,
id,
};
}
static convertAxis(node) {
const name = node[1] || 'Unknown';
// Determine the direction
let direction;
const abbreviationMatch = name.match(/^\((.)\)$/); // Match abbreviations like "(E)" or "(N)"
if (abbreviationMatch) {
// Use the abbreviation to determine the direction
const abbreviation = abbreviationMatch[1].toUpperCase();
if (abbreviation === 'E') direction = 'east';
else if (abbreviation === 'N') direction = 'north';
else if (abbreviation === 'U') direction = 'up';
else throw new Error(`Unknown axis abbreviation: ${abbreviation}`);
} else {
// Use the explicit direction provided in the AXIS node
direction = node[2] ? node[2].toLowerCase() : 'unknown';
}
const orderNode = node.find((child) => Array.isArray(child) && child[0] === 'ORDER');
const order = orderNode ? parseInt(orderNode[1], 10) : null;
const unitNode = node.find(
(child) =>
Array.isArray(child) &&
(child[0] === 'LENGTHUNIT' || child[0] === 'ANGLEUNIT' || child[0] === 'SCALEUNIT')
);
const unit = this.convertUnit(unitNode);
return {
name,
direction, // Use the valid PROJJSON direction value
unit,
order,
};
}
static extractAxes(node) {
return node
.filter((child) => Array.isArray(child) && child[0] === 'AXIS')
.map((axis) => this.convertAxis(axis))
.sort((a, b) => (a.order || 0) - (b.order || 0)); // Sort by the "order" property
}
static convert(node, result = {}) {
switch (node[0]) {
case 'PROJCRS':
result.type = 'ProjectedCRS';
result.name = node[1];
result.base_crs = node.find((child) => Array.isArray(child) && child[0] === 'BASEGEOGCRS')
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'BASEGEOGCRS'))
: null;
result.conversion = node.find((child) => Array.isArray(child) && child[0] === 'CONVERSION')
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'CONVERSION'))
: null;
const csNode = node.find((child) => Array.isArray(child) && child[0] === 'CS');
if (csNode) {
result.coordinate_system = {
type: csNode[1],
axis: this.extractAxes(node),
};
}
const lengthUnitNode = node.find((child) => Array.isArray(child) && child[0] === 'LENGTHUNIT');
if (lengthUnitNode) {
const unit = this.convertUnit(lengthUnitNode);
result.coordinate_system.unit = unit; // Add unit to coordinate_system
}
result.id = this.getId(node);
break;
case 'BASEGEOGCRS':
case 'GEOGCRS':
result.type = 'GeographicCRS';
result.name = node[1];
// Handle DATUM or ENSEMBLE
const datumOrEnsembleNode = node.find(
(child) => Array.isArray(child) && (child[0] === 'DATUM' || child[0] === 'ENSEMBLE')
);
if (datumOrEnsembleNode) {
const datumOrEnsemble = this.convert(datumOrEnsembleNode);
if (datumOrEnsembleNode[0] === 'ENSEMBLE') {
result.datum_ensemble = datumOrEnsemble;
} else {
result.datum = datumOrEnsemble;
}
const primem = node.find((child) => Array.isArray(child) && child[0] === 'PRIMEM');
if (primem && primem[1] !== 'Greenwich') {
datumOrEnsemble.prime_meridian = {
name: primem[1],
longitude: parseFloat(primem[2]),
};
}
}
result.coordinate_system = {
type: 'ellipsoidal',
axis: this.extractAxes(node),
};
result.id = this.getId(node);
break;
case 'DATUM':
result.type = 'GeodeticReferenceFrame';
result.name = node[1];
result.ellipsoid = node.find((child) => Array.isArray(child) && child[0] === 'ELLIPSOID')
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'ELLIPSOID'))
: null;
break;
case 'ENSEMBLE':
result.type = 'DatumEnsemble';
result.name = node[1];
// Extract ensemble members
result.members = node
.filter((child) => Array.isArray(child) && child[0] === 'MEMBER')
.map((member) => ({
type: 'DatumEnsembleMember',
name: member[1],
id: this.getId(member), // Extract ID as { authority, code }
}));
// Extract accuracy
const accuracyNode = node.find((child) => Array.isArray(child) && child[0] === 'ENSEMBLEACCURACY');
if (accuracyNode) {
result.accuracy = parseFloat(accuracyNode[1]);
}
// Extract ellipsoid
const ellipsoidNode = node.find((child) => Array.isArray(child) && child[0] === 'ELLIPSOID');
if (ellipsoidNode) {
result.ellipsoid = this.convert(ellipsoidNode); // Convert the ellipsoid node
}
// Extract identifier for the ensemble
result.id = this.getId(node);
break;
case 'ELLIPSOID':
result.type = 'Ellipsoid';
result.name = node[1];
result.semi_major_axis = parseFloat(node[2]);
result.inverse_flattening = parseFloat(node[3]);
node.find((child) => Array.isArray(child) && child[0] === 'LENGTHUNIT')
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'LENGTHUNIT'), result)
: null;
break;
case 'CONVERSION':
result.type = 'Conversion';
result.name = node[1];
result.method = node.find((child) => Array.isArray(child) && child[0] === 'METHOD')
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'METHOD'))
: null;
result.parameters = node
.filter((child) => Array.isArray(child) && child[0] === 'PARAMETER')
.map((param) => this.convert(param));
break;
case 'METHOD':
result.type = 'Method';
result.name = node[1];
result.id = this.getId(node);
break;
case 'PARAMETER':
result.type = 'Parameter';
result.name = node[1];
result.value = parseFloat(node[2]);
result.unit = this.convertUnit(
node.find(
(child) =>
Array.isArray(child) &&
(child[0] === 'LENGTHUNIT' || child[0] === 'ANGLEUNIT' || child[0] === 'SCALEUNIT')
)
);
result.id = this.getId(node);
break;
case 'BOUNDCRS':
result.type = 'BoundCRS';
// Process SOURCECRS
const sourceCrsNode = node.find((child) => Array.isArray(child) && child[0] === 'SOURCECRS');
if (sourceCrsNode) {
const sourceCrsContent = sourceCrsNode.find((child) => Array.isArray(child));
result.source_crs = sourceCrsContent ? this.convert(sourceCrsContent) : null;
}
// Process TARGETCRS
const targetCrsNode = node.find((child) => Array.isArray(child) && child[0] === 'TARGETCRS');
if (targetCrsNode) {
const targetCrsContent = targetCrsNode.find((child) => Array.isArray(child));
result.target_crs = targetCrsContent ? this.convert(targetCrsContent) : null;
}
// Process ABRIDGEDTRANSFORMATION
const transformationNode = node.find((child) => Array.isArray(child) && child[0] === 'ABRIDGEDTRANSFORMATION');
if (transformationNode) {
result.transformation = this.convert(transformationNode);
} else {
result.transformation = null;
}
break;
case 'ABRIDGEDTRANSFORMATION':
result.type = 'Transformation';
result.name = node[1];
result.method = node.find((child) => Array.isArray(child) && child[0] === 'METHOD')
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'METHOD'))
: null;
result.parameters = node
.filter((child) => Array.isArray(child) && (child[0] === 'PARAMETER' || child[0] === 'PARAMETERFILE'))
.map((param) => {
if (param[0] === 'PARAMETER') {
return this.convert(param);
} else if (param[0] === 'PARAMETERFILE') {
return {
name: param[1],
value: param[2],
id: {
'authority': 'EPSG',
'code': 8656
}
};
}
});
// Adjust the Scale difference parameter if present
if (result.parameters.length === 7) {
const scaleDifference = result.parameters[6];
if (scaleDifference.name === 'Scale difference') {
scaleDifference.value = Math.round((scaleDifference.value - 1) * 1e12) / 1e6;
}
}
result.id = this.getId(node);
break;
case 'AXIS':
if (!result.coordinate_system) {
result.coordinate_system = { type: 'unspecified', axis: [] };
}
result.coordinate_system.axis.push(this.convertAxis(node));
break;
case 'LENGTHUNIT':
const unit = this.convertUnit(node, 'LinearUnit');
if (result.coordinate_system && result.coordinate_system.axis) {
result.coordinate_system.axis.forEach((axis) => {
if (!axis.unit) {
axis.unit = unit;
}
});
}
if (unit.conversion_factor && unit.conversion_factor !== 1) {
if (result.semi_major_axis) {
result.semi_major_axis = {
value: result.semi_major_axis,
unit,
};
}
}
break;
default:
result.keyword = node[0];
break;
}
return result;
}
}
class PROJJSONBuilder2015 extends PROJJSONBuilderBase {
static convert(node, result = {}) {
super.convert(node, result);
// Skip `CS` and `USAGE` nodes for WKT2-2015
if (result.coordinate_system && result.coordinate_system.subtype === 'Cartesian') {
delete result.coordinate_system;
}
if (result.usage) {
delete result.usage;
}
return result;
}
}
class PROJJSONBuilder2019 extends PROJJSONBuilderBase {
static convert(node, result = {}) {
super.convert(node, result);
// Handle `CS` node for WKT2-2019
const csNode = node.find((child) => Array.isArray(child) && child[0] === 'CS');
if (csNode) {
result.coordinate_system = {
subtype: csNode[1],
axis: this.extractAxes(node),
};
}
// Handle `USAGE` node for WKT2-2019
const usageNode = node.find((child) => Array.isArray(child) && child[0] === 'USAGE');
if (usageNode) {
const scope = usageNode.find((child) => Array.isArray(child) && child[0] === 'SCOPE');
const area = usageNode.find((child) => Array.isArray(child) && child[0] === 'AREA');
const bbox = usageNode.find((child) => Array.isArray(child) && child[0] === 'BBOX');
result.usage = {};
if (scope) {
result.usage.scope = scope[1];
}
if (area) {
result.usage.area = area[1];
}
if (bbox) {
result.usage.bbox = bbox.slice(1);
}
}
return result;
}
}
/**
* Detects the WKT2 version based on the structure of the WKT.
* @param {Array} root The root WKT array node.
* @returns {string} The detected version ("2015" or "2019").
*/
function detectWKT2Version(root) {
// Check for WKT2-2019-specific nodes
if (root.find((child) => Array.isArray(child) && child[0] === 'USAGE')) {
return '2019'; // `USAGE` is specific to WKT2-2019
}
// Check for WKT2-2015-specific nodes
if (root.find((child) => Array.isArray(child) && child[0] === 'CS')) {
return '2015'; // `CS` is valid in both, but default to 2015 unless `USAGE` is present
}
if (root[0] === 'BOUNDCRS' || root[0] === 'PROJCRS' || root[0] === 'GEOGCRS') {
return '2015'; // These are valid in both, but default to 2015
}
// Default to WKT2-2015 if no specific indicators are found
return '2015';
}
/**
* Builds a PROJJSON object from a WKT array structure.
* @param {Array} root The root WKT array node.
* @returns {Object} The PROJJSON object.
*/
function buildPROJJSON(root) {
const version = detectWKT2Version(root);
const builder = version === '2019' ? PROJJSONBuilder2019 : PROJJSONBuilder2015;
return builder.convert(root);
}
/**
* Detects whether the WKT string is WKT1 or WKT2.
* @param {string} wkt The WKT string.
* @returns {string} The detected version ("WKT1" or "WKT2").
*/
function detectWKTVersion(wkt) {
// Normalize the WKT string for easier keyword matching
const normalizedWKT = wkt.toUpperCase();
// Check for WKT2-specific keywords
if (
normalizedWKT.includes('PROJCRS') ||
normalizedWKT.includes('GEOGCRS') ||
normalizedWKT.includes('BOUNDCRS') ||
normalizedWKT.includes('VERTCRS') ||
normalizedWKT.includes('LENGTHUNIT') ||
normalizedWKT.includes('ANGLEUNIT') ||
normalizedWKT.includes('SCALEUNIT')
) {
return 'WKT2';
}
// Check for WKT1-specific keywords
if (
normalizedWKT.includes('PROJCS') ||
normalizedWKT.includes('GEOGCS') ||
normalizedWKT.includes('LOCAL_CS') ||
normalizedWKT.includes('VERT_CS') ||
normalizedWKT.includes('UNIT')
) {
return 'WKT1';
}
// Default to WKT1 if no specific indicators are found
return 'WKT1';
}
var NEUTRAL = 1;
var KEYWORD = 2;
var NUMBER = 3;
var QUOTED = 4;
var AFTERQUOTE = 5;
var ENDED = -1;
var whitespace$1 = /\s/;
var latin = /[A-Za-z]/;
var keyword = /[A-Za-z84_]/;
var endThings = /[,\]]/;
var digets = /[\d\.E\-\+]/;
// const ignoredChar = /[\s_\-\/\(\)]/g;
function Parser(text) {
if (typeof text !== 'string') {
throw new Error('not a string');
}
this.text = text.trim();
this.level = 0;
this.place = 0;
this.root = null;
this.stack = [];
this.currentObject = null;
this.state = NEUTRAL;
}
Parser.prototype.readCharicter = function() {
var char = this.text[this.place++];
if (this.state !== QUOTED) {
while (whitespace$1.test(char)) {
if (this.place >= this.text.length) {
return;
}
char = this.text[this.place++];
}
}
switch (this.state) {
case NEUTRAL:
return this.neutral(char);
case KEYWORD:
return this.keyword(char)
case QUOTED:
return this.quoted(char);
case AFTERQUOTE:
return this.afterquote(char);
case NUMBER:
return this.number(char);
case ENDED:
return;
}
};
Parser.prototype.afterquote = function(char) {
if (char === '"') {
this.word += '"';
this.state = QUOTED;
return;
}
if (endThings.test(char)) {
this.word = this.word.trim();
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in afterquote yet, index ' + this.place);
};
Parser.prototype.afterItem = function(char) {
if (char === ',') {
if (this.word !== null) {
this.currentObject.push(this.word);
}
this.word = null;
this.state = NEUTRAL;
return;
}
if (char === ']') {
this.level--;
if (this.word !== null) {
this.currentObject.push(this.word);
this.word = null;
}
this.state = NEUTRAL;
this.currentObject = this.stack.pop();
if (!this.currentObject) {
this.state = ENDED;
}
return;
}
};
Parser.prototype.number = function(char) {
if (digets.test(char)) {
this.word += char;
return;
}
if (endThings.test(char)) {
this.word = parseFloat(this.word);
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in number yet, index ' + this.place);
};
Parser.prototype.quoted = function(char) {
if (char === '"') {
this.state = AFTERQUOTE;
return;
}
this.word += char;
return;
};
Parser.prototype.keyword = function(char) {
if (keyword.test(char)) {
this.word += char;
return;
}
if (char === '[') {
var newObjects = [];
newObjects.push(this.word);
this.level++;
if (this.root === null) {
this.root = newObjects;
} else {
this.currentObject.push(newObjects);
}
this.stack.push(this.currentObject);
this.currentObject = newObjects;
this.state = NEUTRAL;
return;
}
if (endThings.test(char)) {
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in keyword yet, index ' + this.place);
};
Parser.prototype.neutral = function(char) {
if (latin.test(char)) {
this.word = char;
this.state = KEYWORD;
return;
}
if (char === '"') {
this.word = '';
this.state = QUOTED;
return;
}
if (digets.test(char)) {
this.word = char;
this.state = NUMBER;
return;
}
if (endThings.test(char)) {
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in neutral yet, index ' + this.place);
};
Parser.prototype.output = function() {
while (this.place < this.text.length) {
this.readCharicter();
}
if (this.state === ENDED) {
return this.root;
}
throw new Error('unable to parse string "' +this.text + '". State is ' + this.state);
};
function parseString(txt) {
var parser = new Parser(txt);
return parser.output();
}
function mapit(obj, key, value) {
if (Array.isArray(key)) {
value.unshift(key);
key = null;
}
var thing = key ? {} : obj;
var out = value.reduce(function(newObj, item) {
sExpr(item, newObj);
return newObj
}, thing);
if (key) {
obj[key] = out;
}
}
function sExpr(v, obj) {
if (!Array.isArray(v)) {
obj[v] = true;
return;
}
var key = v.shift();
if (key === 'PARAMETER') {
key = v.shift();
}
if (v.length === 1) {
if (Array.isArray(v[0])) {
obj[key] = {};
sExpr(v[0], obj[key]);
return;
}
obj[key] = v[0];
return;
}
if (!v.length) {
obj[key] = true;
return;
}
if (key === 'TOWGS84') {
obj[key] = v;
return;
}
if (key === 'AXIS') {
if (!(key in obj)) {
obj[key] = [];
}
obj[key].push(v);
return;
}
if (!Array.isArray(key)) {
obj[key] = {};
}
var i;
switch (key) {
case 'UNIT':
case 'PRIMEM':
case 'VERT_DATUM':
obj[key] = {
name: v[0].toLowerCase(),
convert: v[1]
};
if (v.length === 3) {
sExpr(v[2], obj[key]);
}
return;
case 'SPHEROID':
case 'ELLIPSOID':
obj[key] = {
name: v[0],
a: v[1],
rf: v[2]
};
if (v.length === 4) {
sExpr(v[3], obj[key]);
}
return;
case 'EDATUM':
case 'ENGINEERINGDATUM':
case 'LOCAL_DATUM':
case 'DATUM':
case 'VERT_CS':
case 'VERTCRS':
case 'VERTICALCRS':
v[0] = ['name', v[0]];
mapit(obj, key, v);
return;
case 'COMPD_CS':
case 'COMPOUNDCRS':
case 'FITTED_CS':
// the followings are the crs defined in
// https://github.com/proj4js/proj4js/blob/1da4ed0b865d0fcb51c136090569210cdcc9019e/lib/parseCode.js#L11
case 'PROJECTEDCRS':
case 'PROJCRS':
case 'GEOGCS':
case 'GEOCCS':
case 'PROJCS':
case 'LOCAL_CS':
case 'GEODCRS':
case 'GEODETICCRS':
case 'GEODETICDATUM':
case 'ENGCRS':
case 'ENGINEERINGCRS':
v[0] = ['name', v[0]];
mapit(obj, key, v);
obj[key].type = key;
return;
default:
i = -1;
while (++i < v.length) {
if (!Array.isArray(v[i])) {
return sExpr(v, obj[key]);
}
}
return mapit(obj, key, v);
}
}
var D2R = 0.01745329251994329577;
function d2r(input) {
return input * D2R;
}
function applyProjectionDefaults(wkt) {
// Normalize projName for WKT2 compatibility
const normalizedProjName = (wkt.projName || '').toLowerCase().replace(/_/g, ' ');
if (!wkt.long0 && wkt.longc && (normalizedProjName === 'albers conic equal area' || normalizedProjName === 'lambert azimuthal equal area')) {
wkt.long0 = wkt.longc;
}
if (!wkt.lat_ts && wkt.lat1 && (normalizedProjName === 'stereographic south pole' || normalizedProjName === 'polar stereographic (variant b)')) {
wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90);
wkt.lat_ts = wkt.lat1;
delete wkt.lat1;
} else if (!wkt.lat_ts && wkt.lat0 && (normalizedProjName === 'polar stereographic' || normalizedProjName === 'polar stereographic (variant a)')) {
wkt.lat_ts = wkt.lat0;
wkt.lat0 = d2r(wkt.lat0 > 0 ? 90 : -90);
delete wkt.lat1;
}
}
// Helper function to process units and to_meter
function processUnit(unit) {
let result = { units: null, to_meter: undefined };
if (typeof unit === 'string') {
result.units = unit.toLowerCase();
if (result.units === 'metre') {
result.units = 'meter'; // Normalize 'metre' to 'meter'
}
if (result.units === 'meter') {
result.to_meter = 1; // Only set to_meter if units are 'meter'
}
} else if (unit && unit.name) {
result.units = unit.name.toLowerCase();
if (result.units === 'metre') {
result.units = 'meter'; // Normalize 'metre' to 'meter'
}
result.to_meter = unit.conversion_factor;
}
return result;
}
function toValue(valueOrObject) {
if (typeof valueOrObject === 'object') {
return valueOrObject.value * valueOrObject.unit.conversion_factor;
}
return valueOrObject;
}
function calculateEllipsoid(value, result) {
if (value.ellipsoid.radius) {
result.a = value.ellipsoid.radius;
result.rf = 0;
} else {
result.a = toValue(value.ellipsoid.semi_major_axis);
if (value.ellipsoid.inverse_flattening !== undefined) {
result.rf = value.ellipsoid.inverse_flattening;
} else if (value.ellipsoid.semi_major_axis !== undefined && value.ellipsoid.semi_minor_axis !== undefined) {
result.rf = result.a / (result.a - toValue(value.ellipsoid.semi_minor_axis));
}
}
}
function transformPROJJSON(projjson, result = {}) {
if (!projjson || typeof projjson !== 'object') {
return projjson; // Return primitive values as-is
}
if (projjson.type === 'BoundCRS') {
transformPROJJSON(projjson.source_crs, result);
if (projjson.transformation) {
if (projjson.transformation.method && projjson.transformation.method.name === 'NTv2') {
// Set nadgrids to the filename from the parameterfile
result.nadgrids = projjson.transformation.parameters[0].value;
} else {
// Populate datum_params if no parameterfile is found
result.datum_params = projjson.transformation.parameters.map((param) => param.value);
}
}
return result; // Return early for BoundCRS
}
// Handle specific keys in PROJJSON
Object.keys(projjson).forEach((key) => {
const value = projjson[key];
if (value === null) {
return;
}
switch (key) {
case 'name':
if (result.srsCode) {
break;
}
result.name = value;
result.srsCode = value; // Map `name` to `srsCode`
break;
case 'type':
if (value === 'GeographicCRS') {
result.projName = 'longlat';
} else if (value === 'ProjectedCRS' && projjson.conversion && projjson.conversion.method) {
result.projName = projjson.conversion.method.name; // Retain original capitalization
}
break;
case 'datum':
case 'datum_ensemble': // Handle both datum and ensemble
if (value.ellipsoid) {
// Extract ellipsoid properties
result.ellps = value.ellipsoid.name;
calculateEllipsoid(value, result);
}
if (value.prime_meridian) {
result.from_greenwich = value.prime_meridian.longitude * Math.PI / 180; // Convert to radians
}
break;
case 'ellipsoid':
result.ellps = value.name;
calculateEllipsoid(value, result);
break;
case 'prime_meridian':
result.long0 = (value.longitude || 0) * Math.PI / 180; // Convert to radians
break;
case 'coordinate_system':
if (value.axis) {
result.axis = value.axis
.map((axis) => {
const direction = axis.direction;
if (direction === 'east') return 'e';
if (direction === 'north') return 'n';
if (direction === 'west') return 'w';
if (direction === 'south') return 's';
throw new Error(`Unknown axis direction: ${direction}`);
})
.join('') + 'u'; // Combine into a single string (e.g., "enu")
if (value.unit) {
const { units, to_meter } = processUnit(value.unit);
result.units = units;
result.to_meter = to_meter;
} else if (value.axis[0] && value.axis[0].unit) {
const { units, to_meter } = processUnit(value.axis[0].unit);
result.units = units;
result.to_meter = to_meter;
}
}
break;
case 'id':
if (value.authority && value.code) {
result.title = value.authority + ':' + value.code;
}
break;
case 'conversion':
if (value.method && value.method.name) {
result.projName = value.method.name; // Retain original capitalization
}
if (value.parameters) {
value.parameters.forEach((param) => {
const paramName = param.name.toLowerCase().replace(/\s+/g, '_');
const paramValue = param.value;
if (param.unit && param.unit.conversion_factor) {
result[paramName] = paramValue * param.unit.conversion_factor; // Convert to radians or meters
} else if (param.unit === 'degree') {
result[paramName] = paramValue * Math.PI / 180; // Convert to radians
} else {
result[paramName] = paramValue;
}
});
}
break;
case 'unit':
if (value.name) {
result.units = value.name.toLowerCase();
if (result.units === 'metre') {
result.units = 'meter';
}
}
if (value.conversion_factor) {
result.to_meter = value.conversion_factor;
}
break;
case 'base_crs':
transformPROJJSON(value, result); // Pass `result` directly
result.datumCode = value.id ? value.id.authority + '_' + value.id.code : value.name; // Set datumCode
break;
}
});
// Additional calculated properties
if (result.latitude_of_false_origin !== undefined) {
result.lat0 = result.latitude_of_false_origin; // Already in radians
}
if (result.longitude_of_false_origin !== undefined) {
result.long0 = result.longitude_of_false_origin;
}
if (result.latitude_of_standard_parallel !== undefined) {
result.lat0 = result.latitude_of_standard_parallel;
result.lat1 = result.latitude_of_standard_parallel;
}
if (result.latitude_of_1st_standard_parallel !== undefined) {
result.lat1 = result.latitude_of_1st_standard_parallel;
}
if (result.latitude_of_2nd_standard_parallel !== undefined) {
result.lat2 = result.latitude_of_2nd_standard_parallel;
}
if (result.latitude_of_projection_centre !== undefined) {
result.lat0 = result.latitude_of_projection_centre;
}
if (result.longitude_of_projection_centre !== undefined) {
result.longc = result.longitude_of_projection_centre;
}
if (result.easting_at_false_origin !== undefined) {
result.x0 = result.easting_at_false_origin;
}
if (result.northing_at_false_origin !== undefined) {
result.y0 = result.northing_at_false_origin;
}
if (result.latitude_of_natural_origin !== undefined) {
result.lat0 = result.latitude_of_natural_origin;
}
if (result.longitude_of_natural_origin !== undefined) {
result.long0 = result.longitude_of_natural_origin;
}
if (result.longitude_of_origin !== undefined) {
result.long0 = result.longitude_of_origin;
}
if (result.false_easting !== undefined) {
result.x0 = result.false_easting;
}
if (result.easting_at_projection_centre) {
result.x0 = result.easting_at_projection_centre;
}
if (result.false_northing !== undefined) {
result.y0 = result.false_northing;
}
if (result.northing_at_projection_centre) {
result.y0 = result.northing_at_projection_centre;
}
if (result.standard_parallel_1 !== undefined) {
result.lat1 = result.standard_parallel_1;
}
if (result.standard_parallel_2 !== undefined) {
result.lat2 = result.standard_parallel_2;
}
if (result.scale_factor_at_natural_origin !== undefined) {
result.k0 = result.scale_factor_at_natural_origin;
}
if (result.scale_factor_at_projection_centre !== undefined) {
result.k0 = result.scale_factor_at_projection_centre;
}
if (result.scale_factor_on_pseudo_standard_parallel !== undefined) {
result.k0 = result.scale_factor_on_pseudo_standard_parallel;
}
if (result.azimuth !== undefined) {
result.alpha = result.azimuth;
}
if (result.azimuth_at_projection_centre !== undefined) {
result.alpha = result.azimuth_at_projection_centre;
}
if (result.angle_from_rectified_to_skew_grid) {
result.rectified_grid_angle = result.angle_from_rectified_to_skew_grid;
}
// Apply projection defaults
applyProjectionDefaults(result);
return result;
}
var knownTypes = ['PROJECTEDCRS', 'PROJCRS', 'GEOGCS', 'GEOCCS', 'PROJCS', 'LOCAL_CS', 'GEODCRS',
'GEODETICCRS', 'GEODETICDATUM', 'ENGCRS', 'ENGINEERINGCRS'];
function rename(obj, params) {
var outName = params[0];
var inName = params[1];
if (!(outName in obj) && (inName in obj)) {
obj[outName] = obj[inName];
if (params.length === 3) {
obj[outName] = params[2](obj[outName]);
}
}
}
function cleanWKT(wkt) {
var keys = Object.keys(wkt);
for (var i = 0, ii = keys.length; i <ii; ++i) {
var key = keys[i];
// the followings are the crs defined in
// https://github.com/proj4js/proj4js/blob/1da4ed0b865d0fcb51c136090569210cdcc9019e/lib/parseCode.js#L11
if (knownTypes.indexOf(key) !== -1) {
setPropertiesFromWkt(wkt[key]);
}
if (typeof wkt[key] === 'object') {
cleanWKT(wkt[key]);
}
}
}
function setPropertiesFromWkt(wkt) {
if (wkt.AUTHORITY) {
var authority = Object.keys(wkt.AUTHORITY)[0];
if (authority && authority in wkt.AUTHORITY) {
wkt.title = authority + ':' + wkt.AUTHORITY[authority];
}
}
if (wkt.type === 'GEOGCS') {
wkt.projName = 'longlat';
} else if (wkt.type === 'LOCAL_CS') {
wkt.projName = 'identity';
wkt.local = true;
} else {
if (typeof wkt.PROJECTION === 'object') {
wkt.projName = Object.keys(wkt.PROJECTION)[0];
} else {
wkt.projName = wkt.PROJECTION;
}
}
if (wkt.AXIS) {
var axisOrder = '';
for (var i = 0, ii = wkt.AXIS.length; i < ii; ++i) {
var axis = [wkt.AXIS[i][0].toLowerCase(), wkt.AXIS[i][1].toLowerCase()];
if (axis[0].indexOf('north') !== -1 || ((axis[0] === 'y' || axis[0] === 'lat') && axis[1] === 'north')) {
axisOrder += 'n';
} else if (axis[0].indexOf('south') !== -1 || ((axis[0] === 'y' || axis[0] === 'lat') && axis[1] === 'south')) {
axisOrder += 's';
} else if (axis[0].indexOf('east') !== -1 || ((axis[0] === 'x' || axis[0] === 'lon') && axis[1] === 'east')) {
axisOrder += 'e';
} else if (axis[0].indexOf('west') !== -1 || ((axis[0] === 'x' || axis[0] === 'lon') && axis[1] === 'west')) {
axisOrder += 'w';
}
}
if (axisOrder.length === 2) {
axisOrder += 'u';
}
if (axisOrder.length === 3) {
wkt.axis = axisOrder;
}
}
if (wkt.UNIT) {
wkt.units = wkt.UNIT.name.toLowerCase();
if (wkt.units === 'metre') {
wkt.units = 'meter';
}
if (wkt.UNIT.convert) {
if (wkt.type === 'GEOGCS') {
if (wkt.DATUM && wkt.DATUM.SPHEROID) {
wkt.to_meter = wkt.UNIT.convert*wkt.DATUM.SPHEROID.a;
}
} else {
wkt.to_meter = wkt.UNIT.convert;
}
}
}
var geogcs = wkt.GEOGCS;
if (wkt.type === 'GEOGCS') {
geogcs = wkt;
}
if (geogcs) {
//if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){
// wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R;
//}
if (geogcs.DATUM) {
wkt.datumCode = geogcs.DATUM.name.toLowerCase();
} else {
wkt.datumCode = geogcs.name.toLowerCase();
}
if (wkt.datumCode.slice(0, 2) === 'd_') {
wkt.datumCode = wkt.datumCode.slice(2);
}
if (wkt.datumCode === 'new_zealand_1949') {
wkt.datumCode = 'nzgd49';
}
if (wkt.datumCode === 'wgs_1984' || wkt.datumCode === 'world_geodetic_system_1984') {
if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {
wkt.sphere = true;
}
wkt.datumCode = 'wgs84';
}
if (wkt.datumCode === 'belge_1972') {
wkt.datumCode = 'rnb72';
}
if (geogcs.DATUM && geogcs.DATUM.SPHEROID) {
wkt.ellps = geogcs.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk');
if (wkt.ellps.toLowerCase().slice(0, 13) === 'international') {
wkt.ellps = 'intl';
}
wkt.a = geogcs.DATUM.SPHEROID.a;
wkt.rf = parseFloat(geogcs.DATUM.SPHEROID.rf, 10);
}
if (geogcs.DATUM && geogcs.DATUM.TOWGS84) {
wkt.datum_params = geogcs.DATUM.TOWGS84;
}
if (~wkt.datumCode.indexOf('osgb_1936')) {
wkt.datumCode = 'osgb36';
}
if (~wkt.datumCode.indexOf('osni_1952')) {
wkt.datumCode = 'osni52';
}
if (~wkt.datumCode.indexOf('tm65')
|| ~wkt.datumCode.indexOf('geodetic_datum_of_1965')) {
wkt.datumCode = 'ire65';
}
if (wkt.datumCode === 'ch1903+') {
wkt.datumCode = 'ch1903';
}
if (~wkt.datumCode.indexOf('israel')) {
wkt.datumCode = 'isr93';
}
}
if (wkt.b && !isFinite(wkt.b)) {
wkt.b = wkt.a;
}
if (wkt.rectified_grid_angle) {
wkt.rectified_grid_angle = d2r(wkt.rectified_grid_angle);
}
function toMeter(input) {
var ratio = wkt.to_meter || 1;
return input * ratio;
}
var renamer = function(a) {
return rename(wkt, a);
};
var list = [
['standard_parallel_1', 'Standard_Parallel_1'],
['standard_parallel_1', 'Latitude of 1st standard parallel'],
['standard_parallel_2', 'Standard_Parallel_2'],
['standard_parallel_2', 'Latitude of 2nd standard parallel'],
['false_easting', 'False_Easting'],
['false_easting', 'False easting'],
['false-easting', 'Easting at false origin'],
['false_northing', 'False_Northing'],
['false_northing', 'False northing'],
['false_northing', 'Northing at false origin'],
['central_meridian', 'Central_Meridian'],
['central_meridian', 'Longitude of natural origin'],
['central_meridian', 'Longitude of false origin'],
['latitude_of_origin', 'Latitude_Of_Origin'],
['latitude_of_origin', 'Central_Parallel'],
['latitude_of_origin', 'Latitude of natural origin'],
['latitude_of_origin', 'Latitude of false origin'],
['scale_factor', 'Scale_Factor'],
['k0', 'scale_factor'],
['latitude_of_center', 'Latitude_Of_Center'],
['latitude_of_center', 'Latitude_of_center'],
['lat0', 'latitude_of_center', d2r],
['longitude_of_center', 'Longitude_Of_Center'],
['longitude_of_center', 'Longitude_of_center'],
['longc', 'longitude_of_center', d2r],
['x0', 'false_easting', toMeter],
['y0', 'false_northing', toMeter],
['long0', 'central_meridian', d2r],
['lat0', 'latitude_of_origin', d2r],
['lat0', 'standard_parallel_1', d2r],
['lat1', 'standard_parallel_1', d2r],
['lat2', 'standard_parallel_2', d2r],
['azimuth', 'Azimuth'],
['alpha', 'azimuth', d2r],
['srsCode', 'name']
];
list.forEach(renamer);
applyProjectionDefaults(wkt);
}
function wkt(wkt) {
if (typeof wkt === 'object') {
return transformPROJJSON(wkt);
}
const version = detectWKTVersion(wkt);
var lisp = parseString(wkt);
if (version === 'WKT2') {
const projjson = buildPROJJSON(lisp);
return transformPROJJSON(projjson);
}
var type = lisp[0];
var obj = {};
sExpr(lisp, obj);
cleanWKT(obj);
return obj[type];
}
/**
* @typedef {Object} ProjectionDefinition
* @property {string} title
* @property {string} [projName]
* @property {string} [ellps]
* @property {import('./Proj.js').DatumDefinition} [datum]
* @property {string} [datumName]
* @property {number} [rf]
* @property {number} [lat0]
* @property {number} [lat1]
* @property {number} [lat2]
* @property {number} [lat_ts]
* @property {number} [long0]
* @property {number} [long1]
* @property {number} [long2]
* @property {number} [alpha]
* @property {number} [longc]
* @property {number} [x0]
* @property {number} [y0]
* @property {number} [k0]
* @property {number} [a]
* @property {number} [b]
* @property {true} [R_A]
* @property {number} [zone]
* @property {true} [utmSouth]
* @property {string|Array<number>} [datum_params]
* @property {number} [to_meter]
* @property {string} [units]
* @property {number} [from_greenwich]
* @property {string} [datumCode]
* @property {string} [nadgrids]
* @property {string} [axis]
* @property {boolean} [sphere]
* @property {number} [rectified_grid_angle]
* @property {boolean} [approx]
* @property {boolean} [over]
* @property {string} [projStr]
* @property {<T extends import('./core').TemplateCoordinates>(coordinates: T, enforceAxis?: boolean) => T} inverse
* @property {<T extends import('./core').TemplateCoordinates>(coordinates: T, enforceAxis?: boolean) => T} forward
*/
/**
* @overload
* @param {string} name
* @param {string|ProjectionDefinition|import('./core.js').PROJJSONDefinition} projection
* @returns {void}
*/
/**
* @overload
* @param {Array<[string, string]>} name
* @returns {Array<ProjectionDefinition|undefined>}
*/
/**
* @overload
* @param {string} name
* @returns {ProjectionDefinition}
*/
/**
* @param {string | Array<Array<string>> | Partial<Record<'EPSG'|'ESRI'|'IAU2000', ProjectionDefinition>>} name
* @returns {ProjectionDefinition | Array<ProjectionDefinition|undefined> | void}
*/
function defs(name) {
/* global console */
var that = this;
if (arguments.length === 2) {
var def = arguments[1];
if (typeof def === 'string') {
if (def.charAt(0) === '+') {
defs[/** @type {string} */ (name)] = projStr(arguments[1]);
} else {
defs[/** @type {string} */ (name)] = wkt(arguments[1]);
}
} else if (def && typeof def === 'object' && !('projName' in def)) {
// PROJJSON
defs[/** @type {string} */ (name)] = wkt(arguments[1]);
} else {
defs[/** @type {string} */ (name)] = def;
if (!def) {
delete defs[/** @type {string} */ (name)];
}
}
} else if (arguments.length === 1) {
if (Array.isArray(name)) {
return name.map(function (v) {
if (Array.isArray(v)) {
return defs.apply(that, v);
} else {
return defs(v);
}
});
} else if (typeof name === 'string') {
if (name in defs) {
return defs[name];
}
} else if ('EPSG' in name) {
defs['EPSG:' + name.EPSG] = name;
} else if ('ESRI' in name) {
defs['ESRI:' + name.ESRI] = name;
} else if ('IAU2000' in name) {
defs['IAU2000:' + name.IAU2000] = name;
} else {
console.log(name);
}
return;
}
}
globals(defs);
function testObj(code) {
return typeof code === 'string';
}
function testDef(code) {
return code in defs;
}
function testWKT(code) {
return (code.indexOf('+') !== 0 && code.indexOf('[') !== -1) || (typeof code === 'object' && !('srsCode' in code));
}
var codes = ['3857', '900913', '3785', '102113'];
function checkMercator(item) {
var auth = match(item, 'authority');
if (!auth) {
return;
}
var code = match(auth, 'epsg');
return code && codes.indexOf(code) > -1;
}
function checkProjStr(item) {
var ext = match(item, 'extension');
if (!ext) {
return;
}
return match(ext, 'proj4');
}
function testProj(code) {
return code[0] === '+';
}
/**
* @param {string | import('./core').PROJJSONDefinition | import('./defs').ProjectionDefinition} code
* @returns {import('./defs').ProjectionDefinition}
*/
function parse$1(code) {
if (testObj(code)) {
// check to see if this is a WKT string
if (testDef(code)) {
return defs[code];
}
if (testWKT(code)) {
var out = wkt(code);
// test of spetial case, due to this being a very common and often malformed
if (checkMercator(out)) {
return defs['EPSG:3857'];
}
var maybeProjStr = checkProjStr(out);