Skip to content

Commit

Permalink
add support for UTM and Traverse Mercator projection (#2108)
Browse files Browse the repository at this point in the history
* add support for UTM and Traverse Mercator projection

* fix specs

* fix specs

* fix specs
  • Loading branch information
fuzhenn authored Oct 20, 2023
1 parent 55a85ce commit 738bee5
Show file tree
Hide file tree
Showing 8 changed files with 467 additions and 37 deletions.
1 change: 1 addition & 0 deletions src/geo/projection/Projection.EPSG4326.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default extend({}, Common, /** @lends projection.EPSG4326 */ {
* @constant
*/
code: 'EPSG:4326',
aliases: ['EPSG:4490'],
project: function (p, out) {
if (out) {
out.x = p.x;
Expand Down
22 changes: 0 additions & 22 deletions src/geo/projection/Projection.EPSG4490.js

This file was deleted.

89 changes: 89 additions & 0 deletions src/geo/projection/Projection.EPSG9807.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { isNil, extend } from '../../core/util';
import Common from './Projection';
import Coordinate from '../Coordinate';
import { WGS84Sphere } from '../measurer';
import etmerc from './etmerc.js';

// from proj_api.h
const RAD_TO_DEG = 57.295779513082321,
DEG_TO_RAD = 0.017453292519943296;

// from pj_transform.c
const SRS_WGS84_SEMIMAJOR = 6378137;
const SRS_WGS84_ESQUARED = 0.0066943799901413165;

/**
* Traverse Mercator Projection
*
* @class
* @category geo
* @protected
* @memberOf projection
* @name EPSG9807
* @mixes projection.Common
* @mixes measurer.WGS84Sphere
*/
export default {
code: 'EPSG:9807',
aliases: ['Traverse_Mercator'],
create(params) {
const P = {
a: SRS_WGS84_SEMIMAJOR,
es: SRS_WGS84_ESQUARED,
x0: isNil(params.falseEasting) ? 500000 : params.falseEasting,
y0: isNil(params.falseNorthing) ? 0 : params.falseNorthing,
k0: params.scaleFactor || 0.9996,
lam0: (params.centralMeridian || 0) * DEG_TO_RAD,
phi0: (params.latitudeOfOrigin || 0) * DEG_TO_RAD,
originLam0: params.startLongtitude || 0,
originPhi0: params.startLatitude || 0
};
etmerc(P);
const lp = { lam: 0, phi: 0 };
const xy = {};
let originX = 0;
let originY = 0;
if (P.originLam0 || P.originPhi0) {
lp.lam = P.originLam0 * DEG_TO_RAD - P.lam0;
lp.phi = P.originPhi0 * DEG_TO_RAD;
P.fwd(lp, xy);
originX = P.a * xy.x + P.x0;
originY = P.a * xy.y + P.y0;
}

return extend({}, Common, {
/**
* "EPSG:9807", Code of the projection
* @type {String}
* @constant
*/
code: 'EPSG:9807',
project: function (p, out) {
lp.lam = p.x * DEG_TO_RAD - P.lam0;
lp.phi = p.y * DEG_TO_RAD;
P.fwd(lp, xy);
const x = P.a * xy.x + P.x0 - originX;
const y = P.a * xy.y + P.y0 - originY;
if (out) {
out.x = x;
out.y = y;
return out;
}
return new Coordinate(x, y);
},
unproject: function (p, out) {
xy.x = (p.x - P.x0 + originX) / P.a;
xy.y = (p.y - P.y0 + originY) / P.a;
P.inv(xy, lp);
const x = (lp.lam + P.lam0) * RAD_TO_DEG;
const y = lp.phi * RAD_TO_DEG;
if (out) {
out.x = x;
out.y = y;
return out;
}
return new Coordinate(x, y);
}
}, WGS84Sphere);
}
};
37 changes: 37 additions & 0 deletions src/geo/projection/Projection.UTM.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { extend } from '../../core/util';
import PROJ9807 from './Projection.EPSG9807';

/**
* Universal Traverse Mercator projection
*
* @class
* @category geo
* @protected
* @memberOf projection
* @name EPSG4490
* @mixes projection.EPSG4326
* @mixes measurer.WGS84Sphere
*/
export default extend({}, PROJ9807, /** @lends projection.EPSG4490 */ {
/**
* "EPSG:4490", Code of the projection
* @type {String}
* @constant
*/
code: 'utm',
aliases: [],
create(params) {
const P = {};
let zone = parseInt(params.zone);
P.falseNorthing = params.south ? 10000000 : 0;
P.falseEasting = 500000;
if (zone > 0 && zone <= 60) {
zone--;
} else {
throw new Error('zone must be > 0 and <= 60.');
}
P.centralMeridian = (zone + 0.5) * 6 - 180;
P.scaleFactor = 0.9996;
return PROJ9807.create(P);
}
});
Loading

0 comments on commit 738bee5

Please sign in to comment.