Skip to content

Instantly share code, notes, and snippets.

@missinglink
Last active May 1, 2024 16:50
Show Gist options
  • Save missinglink/d0a085188a8eab2ca66db385bb7c023a to your computer and use it in GitHub Desktop.
Save missinglink/d0a085188a8eab2ca66db385bb7c023a to your computer and use it in GitHub Desktop.
wrap latitude and longitude values around the poles in order to normalize their ranges
/**
normalize co-ordinates that lie outside of the normal ranges.
longitude wrapping simply requires adding +- 360 to the value until it comes
in to range.
for the latitude values we need to flip the longitude whenever the latitude
crosses a pole.
**/
function wrap( lat, lon ){
var point = { lat: lat, lon: lon };
var quadrant = Math.floor( Math.abs( lat ) / 90) % 4;
var pole = ( lat > 0 ) ? 90 : -90;
var offset = lat % 90;
switch( quadrant ){
case 0:
point.lat = offset;
break;
case 1:
point.lat = pole - offset;
point.lon += 180;
break;
case 2:
point.lat = -offset
point.lon += 180;
break;
case 3:
point.lat = -pole + offset;
break;
}
if( point.lon > 180 || point.lon < -180 ){
point.lon -= Math.floor(( point.lon + 180 ) / 360) * 360;
}
return point;
}
module.exports = wrap;
var wrap = require('./wrap');
module.exports.tests = {};
module.exports.tests.control = 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();
});
};
module.exports.tests.latitude_positive = function(test, common) {
test('positive latitude wrapping - 1 degree', function (t) {
var norm = wrap(1, 0);
t.equal(norm.lat, 1);
t.equal(norm.lon, 0);
t.end();
});
test('positive latitude wrapping - 91 degrees', function (t) {
var norm = wrap(91, 0);
t.equal(norm.lat, 89);
t.equal(norm.lon, 180);
t.end();
});
test('positive latitude wrapping - 181 degrees', function (t) {
var norm = wrap(181, 0);
t.equal(norm.lat, -1);
t.equal(norm.lon, 180);
t.end();
});
test('positive latitude wrapping - 271 degrees', function (t) {
var norm = wrap(271, 0);
t.equal(norm.lat, -89);
t.equal(norm.lon, 0);
t.end();
});
test('positive latitude wrapping - 361 degrees', function (t) {
var norm = wrap(361, 0);
t.equal(norm.lat, 1);
t.equal(norm.lon, 0);
t.end();
});
test('positive latitude wrapping - 631 degrees', function (t) {
var norm = wrap(631, 0);
t.equal(norm.lat, -89);
t.equal(norm.lon, 0);
t.end();
});
test('positive latitude wrapping - 721 degrees', function (t) {
var norm = wrap(721, 0);
t.equal(norm.lat, 1);
t.equal(norm.lon, 0);
t.end();
});
};
module.exports.tests.latitude_negative = function(test, common) {
test('negative latitude wrapping - 1 degree', function (t) {
var norm = wrap(-1, 0);
t.equal(norm.lat, -1);
t.equal(norm.lon, 0);
t.end();
});
test('negative latitude wrapping - 91 degrees', function (t) {
var norm = wrap(-91, 0);
t.equal(norm.lat, -89);
t.equal(norm.lon, 180);
t.end();
});
test('negative latitude wrapping - 181 degrees', function (t) {
var norm = wrap(-181, 0);
t.equal(norm.lat, 1);
t.equal(norm.lon, 180);
t.end();
});
test('negative latitude wrapping - 271 degrees', function (t) {
var norm = wrap(-271, 0);
t.equal(norm.lat, 89);
t.equal(norm.lon, 0);
t.end();
});
test('negative latitude wrapping - 361 degrees', function (t) {
var norm = wrap(-361, 0);
t.equal(norm.lat, -1);
t.equal(norm.lon, 0);
t.end();
});
test('negative latitude wrapping - 631 degrees', function (t) {
var norm = wrap(-631, 0);
t.equal(norm.lat, 89);
t.equal(norm.lon, 0);
t.end();
});
test('negative latitude wrapping - 721 degrees', function (t) {
var norm = wrap(-721, 0);
t.equal(norm.lat, -1);
t.equal(norm.lon, 0);
t.end();
});
};
module.exports.tests.longitude_positive = function(test, common) {
test('positive longitude wrapping - 1 degree', function (t) {
var norm = wrap(0, 1);
t.equal(norm.lat, 0);
t.equal(norm.lon, 1);
t.end();
});
test('positive longitude wrapping - 181 degrees', function (t) {
var norm = wrap(0, 181);
t.equal(norm.lat, 0);
t.equal(norm.lon, -179);
t.end();
});
test('positive longitude wrapping - 271 degrees', function (t) {
var norm = wrap(0, 271);
t.equal(norm.lat, 0);
t.equal(norm.lon, -89);
t.end();
});
test('positive longitude wrapping - 361 degrees', function (t) {
var norm = wrap(0, 361);
t.equal(norm.lat, 0);
t.equal(norm.lon, 1);
t.end();
});
test('positive longitude wrapping - 631 degrees', function (t) {
var norm = wrap(0, 631);
t.equal(norm.lat, 0);
t.equal(norm.lon, -89);
t.end();
});
test('positive longitude wrapping - 721 degrees', function (t) {
var norm = wrap(0, 721);
t.equal(norm.lat, 0);
t.equal(norm.lon, 1);
t.end();
});
};
module.exports.tests.longitude_negative = function(test, common) {
test('negative longitude wrapping - 1 degree', function (t) {
var norm = wrap(0, -1);
t.equal(norm.lat, 0);
t.equal(norm.lon, -1);
t.end();
});
test('negative longitude wrapping - 181 degrees', function (t) {
var norm = wrap(0, -181);
t.equal(norm.lat, 0);
t.equal(norm.lon, 179);
t.end();
});
test('negative longitude wrapping - 271 degrees', function (t) {
var norm = wrap(0, -271);
t.equal(norm.lat, 0);
t.equal(norm.lon, 89);
t.end();
});
test('negative longitude wrapping - 361 degrees', function (t) {
var norm = wrap(0, -361);
t.equal(norm.lat, 0);
t.equal(norm.lon, -1);
t.end();
});
test('negative longitude wrapping - 631 degrees', function (t) {
var norm = wrap(0, -631);
t.equal(norm.lat, 0);
t.equal(norm.lon, 89);
t.end();
});
test('negative longitude wrapping - 721 degrees', function (t) {
var norm = wrap(0, -721);
t.equal(norm.lat, 0);
t.equal(norm.lon, -1);
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);
}
};
@missinglink
Copy link
Author

Oops, I've updated the incorrect test case, thanks for spotting that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment