107 lines
2.8 KiB
JavaScript
107 lines
2.8 KiB
JavaScript
|
import {D2R, R2D, PJD_3PARAM, PJD_7PARAM, PJD_GRIDSHIFT} from './constants/values';
|
||
|
import datum_transform from './datum_transform';
|
||
|
import adjust_axis from './adjust_axis';
|
||
|
import proj from './Proj';
|
||
|
import toPoint from './common/toPoint';
|
||
|
import checkSanity from './checkSanity';
|
||
|
|
||
|
function checkNotWGS(source, dest) {
|
||
|
return (
|
||
|
(source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM || source.datum.datum_type === PJD_GRIDSHIFT) && dest.datumCode !== 'WGS84') ||
|
||
|
((dest.datum.datum_type === PJD_3PARAM || dest.datum.datum_type === PJD_7PARAM || dest.datum.datum_type === PJD_GRIDSHIFT) && source.datumCode !== 'WGS84');
|
||
|
}
|
||
|
|
||
|
export default function transform(source, dest, point, enforceAxis) {
|
||
|
var wgs84;
|
||
|
if (Array.isArray(point)) {
|
||
|
point = toPoint(point);
|
||
|
} else {
|
||
|
// Clone the point object so inputs don't get modified
|
||
|
point = {
|
||
|
x: point.x,
|
||
|
y: point.y,
|
||
|
z: point.z,
|
||
|
m: point.m
|
||
|
};
|
||
|
}
|
||
|
var hasZ = point.z !== undefined;
|
||
|
checkSanity(point);
|
||
|
// Workaround for datum shifts towgs84, if either source or destination projection is not wgs84
|
||
|
if (source.datum && dest.datum && checkNotWGS(source, dest)) {
|
||
|
wgs84 = new proj('WGS84');
|
||
|
point = transform(source, wgs84, point, enforceAxis);
|
||
|
source = wgs84;
|
||
|
}
|
||
|
// DGR, 2010/11/12
|
||
|
if (enforceAxis && source.axis !== 'enu') {
|
||
|
point = adjust_axis(source, false, point);
|
||
|
}
|
||
|
// Transform source points to long/lat, if they aren't already.
|
||
|
if (source.projName === 'longlat') {
|
||
|
point = {
|
||
|
x: point.x * D2R,
|
||
|
y: point.y * D2R,
|
||
|
z: point.z || 0
|
||
|
};
|
||
|
} else {
|
||
|
if (source.to_meter) {
|
||
|
point = {
|
||
|
x: point.x * source.to_meter,
|
||
|
y: point.y * source.to_meter,
|
||
|
z: point.z || 0
|
||
|
};
|
||
|
}
|
||
|
point = source.inverse(point); // Convert Cartesian to longlat
|
||
|
if (!point) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
// Adjust for the prime meridian if necessary
|
||
|
if (source.from_greenwich) {
|
||
|
point.x += source.from_greenwich;
|
||
|
}
|
||
|
|
||
|
// Convert datums if needed, and if possible.
|
||
|
point = datum_transform(source.datum, dest.datum, point);
|
||
|
if (!point) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Adjust for the prime meridian if necessary
|
||
|
if (dest.from_greenwich) {
|
||
|
point = {
|
||
|
x: point.x - dest.from_greenwich,
|
||
|
y: point.y,
|
||
|
z: point.z || 0
|
||
|
};
|
||
|
}
|
||
|
|
||
|
if (dest.projName === 'longlat') {
|
||
|
// convert radians to decimal degrees
|
||
|
point = {
|
||
|
x: point.x * R2D,
|
||
|
y: point.y * R2D,
|
||
|
z: point.z || 0
|
||
|
};
|
||
|
} else { // else project
|
||
|
point = dest.forward(point);
|
||
|
if (dest.to_meter) {
|
||
|
point = {
|
||
|
x: point.x / dest.to_meter,
|
||
|
y: point.y / dest.to_meter,
|
||
|
z: point.z || 0
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// DGR, 2010/11/12
|
||
|
if (enforceAxis && dest.axis !== 'enu') {
|
||
|
return adjust_axis(dest, true, point);
|
||
|
}
|
||
|
|
||
|
if (!hasZ) {
|
||
|
delete point.z;
|
||
|
}
|
||
|
return point;
|
||
|
}
|