Skip to content

Commit

Permalink
Merge pull request #561 from OpenGeoscience/proj-defs
Browse files Browse the repository at this point in the history
Expose methods to define new proj4 definitions
  • Loading branch information
jbeezley committed May 2, 2016
2 parents a28fa86 + c15a309 commit e0cd944
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 2 deletions.
50 changes: 48 additions & 2 deletions src/transform.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
var proj4 = require('proj4');

//////////////////////////////////////////////////////////////////////////////
/**
* This purpose of this class is to provide a generic interface for computing
Expand Down Expand Up @@ -28,8 +30,6 @@ var transform = function (options) {
return new transform(options);
}

var proj4 = require('proj4');

var m_this = this,
m_proj, // The raw proj4js object
m_source, // The source projection
Expand Down Expand Up @@ -157,6 +157,52 @@ var transform = function (options) {
return this;
};

/**
* Contains a reference to `proj4.defs`. The functions serves two
* purposes.
*
* 1. It is a key value mapping of all loaded projection definitions
* 2. It is a function that will add additional definitions.
*
* See:
* http://proj4js.org/
*/
transform.defs = proj4.defs;

/**
* Look up a projection definition from epsg.io
* For the moment, we only handle `EPSG` codes.
*
* @param {string} projection A projection alias (e.g. EPSG:4326)
* @returns {promise} Resolves with the proj4 definition
*/
transform.lookup = function (projection) {
var $ = require('jquery');
var code, defer = new $.Deferred(), parts;

if (proj4.defs.hasOwnProperty(projection)) {
return defer.resolve(proj4.defs[projection]);
}

parts = projection.split(':');
if (parts.length !== 2 || parts[0].toUpperCase() !== 'EPSG') {
return defer.reject('Invalid projection code').promise();
}
code = parts[1];

return $.ajax({
url: 'http://epsg.io/?q=' + code + '&format=json'
}).then(function (data) {
var result = (data.results || [])[0];
if (!result || !result.proj4) {
return defer.reject(data).promise();
}

proj4.defs(projection, result.proj4);
return $.when(proj4.defs[projection]);
});
};

/**
* Transform an array of coordinates from one projection into another. The
* transformation may occur in place (modifying the input coordinate array),
Expand Down
83 changes: 83 additions & 0 deletions tests/cases/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,87 @@ describe('geo.transform', function () {
[{x: 1669792, y: -19971868}, {x: 1669792, y: -19971868}]
]
);

describe('defs', function () {
var server;

beforeEach(function () {
server = sinon.fakeServer.create();
});

afterEach(function () {
server.restore();
});

it('predefined definitions', function () {
expect(geo.transform.defs.hasOwnProperty('EPSG:4326')).toBe(true);
expect(geo.transform.defs.hasOwnProperty('EPSG:3857')).toBe(true);
});

it('custom definition', function () {
geo.transform.defs('my projection', '+proj=longlat +datum=WGS84 +no_defs');
expect(geo.transform.defs.hasOwnProperty('my projection')).toBe(true);
var p = geo.transform({source: 'EPSG:4326', target: 'my projection'});

expect(p.forward({x: 10, y: -10, z: 0})).toEqual({x: 10, y: -10, z: 0});
});

it('lookup', function () {
var spy = sinon.spy(), request;
geo.transform.lookup('EPSG:5000').then(spy);

request = server.requests[0];
expect(request.url).toMatch(/\?q=5000/);
request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
status: 'ok',
number_result: 1,
results: [{
code: '5000',
kind: 'CRS-PROJCRS',
bbox: [
85.06,
180.0,
85.06,
180.0
],
unit: 'degree',
proj4: '+proj=longlat +datum=WGS84 +no_defs',
name: 'WGS 84',
area: 'World',
default_trans: 0,
trans: [],
accuracy: ''
}]
}));

expect(spy.calledOnce).toBe(true);
expect(geo.transform.defs.hasOwnProperty('EPSG:5000')).toBe(true);

geo.transform.lookup('EPSG:5000');
expect(server.requests.length).toBe(1);
});

it('invalid projection code', function () {
var spy = sinon.spy(), request;
geo.transform.lookup('EPSG:5001').fail(spy);

request = server.requests[0];
request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
status: 'ok',
number_result: 0,
results: []
}));

expect(spy.calledOnce).toBe(true);
expect(geo.transform.defs.hasOwnProperty('EPSG:5001')).toBe(false);
});

it('unknown projection type', function () {
var spy = sinon.spy();
geo.transform.lookup('unknown:5002').fail(spy);

expect(spy.calledOnce).toBe(true);
expect(geo.transform.defs.hasOwnProperty('unknown:5002')).toBe(false);
});
});
});

0 comments on commit e0cd944

Please sign in to comment.