Browse Source

wrap coordinates at poles

pull/608/head
Peter Johnson 8 years ago
parent
commit
5b8a9a31d2
  1. 8
      sanitiser/_geo_common.js
  2. 36
      sanitiser/wrap.js
  3. 1
      test/unit/run.js
  4. 58
      test/unit/sanitiser/_geo_common.js
  5. 2
      test/unit/sanitiser/reverse.js
  6. 2
      test/unit/sanitiser/search.js
  7. 71
      test/unit/sanitiser/wrap.js

8
sanitiser/_geo_common.js

@ -4,6 +4,7 @@
var groups = require('./_groups'),
util = require('util'),
check = require('check-types'),
wrap = require('./wrap'),
_ = require('lodash');
/**
@ -68,6 +69,7 @@ function sanitize_circle( key_prefix, clean, raw, circle_is_required ) {
* @param {bool} point_is_required
*/
function sanitize_point( key_prefix, clean, raw, point_is_required ) {
// calculate full property names from the key_prefix
var properties = [ 'lat', 'lon'].map(function(prop) {
return key_prefix + '.' + prop;
@ -91,6 +93,11 @@ function sanitize_point( key_prefix, clean, raw, point_is_required ) {
properties.forEach(function(prop) {
sanitize_coord(prop, clean, raw, true);
});
// normalize co-ordinates by wrapping around the poles
var normalized = wrap(clean[properties[0]], clean[properties[1]]);
clean[properties[0]] = normalized.lat;
clean[properties[1]] = normalized.lon;
}
/**
@ -103,6 +110,7 @@ function sanitize_point( key_prefix, clean, raw, point_is_required ) {
*/
function sanitize_coord( key, clean, raw, latlon_is_required ) {
var parsedValue = parseFloat( raw[key] );
if ( _.isFinite( parsedValue ) ) {
clean[key] = parsedValue;
}

36
sanitiser/wrap.js

@ -0,0 +1,36 @@
/**
normalize co-ordinates that lie outside of the normal ranges.
**/
function wrap( lat, lon ){
var flip = false;
var point = { lat: lat, lon: lon };
// north pole
if( point.lat > 90 ){
point.lat = 90 - point.lat % 90;
point.lon += 180;
}
// south pole
else if( point.lat < -90 ){
point.lat = -90 - point.lat % 90;
point.lon += 180;
}
// reduce lon
while( point.lon > 180 ){
point.lon -= 360;
}
// increase lon
while( point.lon < -180 ){
point.lon += 360;
}
return point;
}
module.exports = wrap;

1
test/unit/run.js

@ -56,6 +56,7 @@ var tests = [
require('./sanitiser/place'),
require('./sanitiser/reverse'),
require('./sanitiser/search'),
require('./sanitiser/wrap'),
require('./service/mget'),
require('./service/search'),
];

58
test/unit/sanitiser/_geo_common.js

@ -12,6 +12,64 @@ module.exports.tests.interface = function(test, common) {
});
};
module.exports.tests.wrapping = function(test, common) {
test('control - no wrapping required', function (t) {
var clean = {};
var params = {
'point.lat': 40.7,
'point.lon': -73.9
};
sanitize.sanitize_point( 'point', clean, params, false );
t.equal(clean['point.lat'], params['point.lat']);
t.equal(clean['point.lon'], params['point.lon']);
t.end();
});
test('positive longitude wrapping', function (t) {
var clean = {};
var params = {
'point.lat': 40.7,
'point.lon': 195.1
};
sanitize.sanitize_point( 'point', clean, params, false );
t.equal(clean['point.lat'], 40.7);
t.equal(clean['point.lon'], -164.9);
t.end();
});
test('negative longitude wrapping', function (t) {
var clean = {};
var params = {
'point.lat': 40.7,
'point.lon': -195.1
};
sanitize.sanitize_point( 'point', clean, params, false );
t.equal(clean['point.lat'], 40.7);
t.equal(clean['point.lon'], 164.9);
t.end();
});
test('positive latitudinal wrapping', function (t) {
var clean = {};
var params = {
'point.lat': 98.1,
'point.lon': -73.9
};
sanitize.sanitize_point( 'point', clean, params, false );
t.equal(clean['point.lat'], 81.9);
t.equal(clean['point.lon'], 106.1);
t.end();
});
test('negative latitudinal wrapping', function (t) {
var clean = {};
var params = {
'point.lat': -98.1,
'point.lon': -73.9
};
sanitize.sanitize_point( 'point', clean, params, false );
t.equal(clean['point.lat'], -81.9);
t.equal(clean['point.lon'], 106.1);
t.end();
});
};
module.exports.tests.coord = function(test, common) {
test('valid coord', function (t) {
var clean = {};

2
test/unit/sanitiser/reverse.js

@ -65,7 +65,6 @@ module.exports.tests.sanitize_lat = function(test, common) {
sanitize(req, function(){
var expected_lat = parseFloat( lat );
t.deepEqual(req.errors, [], 'no errors');
t.equal(req.clean['point.lat'], expected_lat, 'clean set correctly (' + lat + ')');
});
});
t.end();
@ -93,7 +92,6 @@ module.exports.tests.sanitize_lon = function(test, common) {
sanitize(req, function(){
var expected_lon = parseFloat( lon );
t.deepEqual(req.errors, [], 'no errors');
t.equal(req.clean['point.lon'], expected_lon, 'clean set correctly (' + lon + ')');
});
});
t.end();

2
test/unit/sanitiser/search.js

@ -129,7 +129,6 @@ module.exports.tests.sanitize_lat = function(test, common) {
sanitize(req, function(){
var expected_lat = parseFloat( lat );
t.equal(req.errors[0], undefined, 'no error');
t.equal(req.clean['focus.point.lat'], expected_lat, 'clean lat set correctly (' + lat + ')');
});
});
t.end();
@ -146,7 +145,6 @@ module.exports.tests.sanitize_lon = function(test, common) {
sanitize( req, function(){
var expected_lon = parseFloat( lon );
t.equal(req.errors[0], undefined, 'no error');
t.deepEqual(req.clean['focus.point.lon'], expected_lon, 'clean set correctly (' + lon + ')');
});
});
t.end();

71
test/unit/sanitiser/wrap.js

@ -0,0 +1,71 @@
var wrap = require('../../../sanitiser/wrap');
module.exports.tests = {};
module.exports.tests.wrapping = function(test, common) {
test('control - no wrapping required', function (t) {
var norm = wrap(55.555, 22.222);
t.equal(norm.lat, 55.555);
t.equal(norm.lon, 22.222);
t.end();
});
test('positive longitude wrapping', function (t) {
var norm = wrap(0, 181);
t.equal(norm.lat, 0);
t.equal(norm.lon, -179);
t.end();
});
test('positive longitude wrapping (double)', function (t) {
var norm = wrap(0, 541);
t.equal(norm.lat, 0);
t.equal(norm.lon, -179);
t.end();
});
test('negative longitude wrapping', function (t) {
var norm = wrap(0, -181);
t.equal(norm.lat, 0);
t.equal(norm.lon, 179);
t.end();
});
test('negative longitude wrapping (double)', function (t) {
var norm = wrap(0, -541);
t.equal(norm.lat, 0);
t.equal(norm.lon, 179);
t.end();
});
test('positive latitudinal wrapping', function (t) {
var norm = wrap(91, 0);
t.equal(norm.lat, 89);
t.equal(norm.lon, 180);
t.end();
});
test('positive latitudinal wrapping (double)', function (t) {
var norm = wrap(271, 0);
t.equal(norm.lat, 89);
t.equal(norm.lon, 180);
t.end();
});
test('negative latitudinal wrapping', function (t) {
var norm = wrap(-91, 0);
t.equal(norm.lat, -89);
t.equal(norm.lon, 180);
t.end();
});
test('negative latitudinal wrapping (double)', function (t) {
var norm = wrap(-271, 0);
t.equal(norm.lat, -89);
t.equal(norm.lon, 180);
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE wrap ' + name, testFunction);
}
for( var testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};
Loading…
Cancel
Save