proj4js/lib/Proj.js
2025-06-29 14:39:58 +02:00

102 lines
3.5 KiB
JavaScript

import parseCode from './parseCode';
import extend from './extend';
import projections from './projections';
import { sphere as dc_sphere, eccentricity as dc_eccentricity } from './deriveConstants';
import Datum from './constants/Datum';
import datum from './datum';
import match from './match';
import { getNadgrids } from './nadgrid';
/**
* @typedef {Object} DatumDefinition
* @property {number} datum_type - The type of datum.
* @property {number} a - Semi-major axis of the ellipsoid.
* @property {number} b - Semi-minor axis of the ellipsoid.
* @property {number} es - Eccentricity squared of the ellipsoid.
* @property {number} ep2 - Second eccentricity squared of the ellipsoid.
*/
/**
* @param {string | import('./core').PROJJSONDefinition | import('./defs').ProjectionDefinition} srsCode
* @param {(errorMessage?: string, instance?: Projection) => void} [callback]
*/
function Projection(srsCode, callback) {
if (!(this instanceof Projection)) {
return new Projection(srsCode);
}
/** @type {<T extends import('./core').TemplateCoordinates>(coordinates: T, enforceAxis?: boolean) => T} */
this.forward = null;
/** @type {<T extends import('./core').TemplateCoordinates>(coordinates: T, enforceAxis?: boolean) => T} */
this.inverse = null;
/** @type {function(): void} */
this.init = null;
/** @type {string} */
this.name;
/** @type {Array<string>} */
this.names = null;
/** @type {string} */
this.title;
callback = callback || function (error) {
if (error) {
throw error;
}
};
var json = parseCode(srsCode);
if (typeof json !== 'object') {
callback('Could not parse to valid json: ' + srsCode);
return;
}
var ourProj = Projection.projections.get(json.projName);
if (!ourProj) {
callback('Could not get projection name from: ' + srsCode);
return;
}
if (json.datumCode && json.datumCode !== 'none') {
var datumDef = match(Datum, json.datumCode);
if (datumDef) {
json.datum_params = json.datum_params || (datumDef.towgs84 ? datumDef.towgs84.split(',') : null);
json.ellps = datumDef.ellipse;
json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode;
}
}
json.k0 = json.k0 || 1.0;
json.axis = json.axis || 'enu';
json.ellps = json.ellps || 'wgs84';
json.lat1 = json.lat1 || json.lat0; // Lambert_Conformal_Conic_1SP, for example, needs this
var sphere_ = dc_sphere(json.a, json.b, json.rf, json.ellps, json.sphere);
var ecc = dc_eccentricity(sphere_.a, sphere_.b, sphere_.rf, json.R_A);
var nadgrids = getNadgrids(json.nadgrids);
/** @type {DatumDefinition} */
var datumObj = json.datum || datum(json.datumCode, json.datum_params, sphere_.a, sphere_.b, ecc.es, ecc.ep2,
nadgrids);
extend(this, json); // transfer everything over from the projection because we don't know what we'll need
extend(this, ourProj); // transfer all the methods from the projection
// copy the 4 things over we calculated in deriveConstants.sphere
this.a = sphere_.a;
this.b = sphere_.b;
this.rf = sphere_.rf;
this.sphere = sphere_.sphere;
// copy the 3 things we calculated in deriveConstants.eccentricity
this.es = ecc.es;
this.e = ecc.e;
this.ep2 = ecc.ep2;
// add in the datum object
this.datum = datumObj;
// init the projection
if ('init' in this && typeof this.init === 'function') {
this.init();
}
// legecy callback from back in the day when it went to spatialreference.org
callback(null, this);
}
Projection.projections = projections;
Projection.projections.start();
export default Projection;