loopback-datasource-juggler/test/geo.test.js

201 lines
5.3 KiB
JavaScript
Raw Normal View History

// Copyright IBM Corp. 2014,2019. All Rights Reserved.
2016-04-01 22:25:16 +00:00
// Node module: loopback-datasource-juggler
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
2016-08-22 19:55:22 +00:00
'use strict';
2014-12-10 22:41:49 +00:00
require('should');
2018-12-07 14:54:29 +00:00
const GeoPoint = require('../lib/geo').GeoPoint;
const nearFilter = require('../lib/geo').nearFilter;
const geoFilter = require('../lib/geo').filter;
const DELTA = 0.0000001;
2014-12-10 22:41:49 +00:00
2016-04-01 11:48:17 +00:00
describe('GeoPoint', function() {
describe('constructor', function() {
2016-04-01 11:48:17 +00:00
it('should support a valid array', function() {
2018-12-07 14:54:29 +00:00
const point = new GeoPoint([-34, 150]);
point.lat.should.equal(-34);
point.lng.should.equal(150);
});
2016-04-01 11:48:17 +00:00
it('should support a valid object', function() {
2018-12-07 14:54:29 +00:00
const point = new GeoPoint({lat: -34, lng: 150});
point.lat.should.equal(-34);
point.lng.should.equal(150);
});
2016-04-01 11:48:17 +00:00
it('should support valid string geo coordinates', function() {
2018-12-07 14:54:29 +00:00
const point = new GeoPoint('-34,150');
point.lat.should.equal(-34);
point.lng.should.equal(150);
});
2016-04-01 11:48:17 +00:00
it('should support coordinates as inline parameters', function() {
2018-12-07 14:54:29 +00:00
const point = new GeoPoint(-34, 150);
point.lat.should.equal(-34);
point.lng.should.equal(150);
});
2016-04-01 11:48:17 +00:00
it('should reject invalid parameters', function() {
/* jshint -W024 */
2018-12-07 14:54:29 +00:00
let fn = function() {
new GeoPoint('150,-34');
};
fn.should.throw();
fn = function() {
new GeoPoint('invalid_string');
};
fn.should.throw();
fn = function() {
new GeoPoint([150, -34]);
};
fn.should.throw();
fn = function() {
new GeoPoint({
lat: 150,
2016-04-01 11:48:17 +00:00
lng: null,
});
};
fn.should.throw();
fn = function() {
new GeoPoint(150, -34);
};
fn.should.throw();
fn = function() {
new GeoPoint();
};
fn.should.throw();
});
});
2014-12-11 00:43:49 +00:00
describe('toString()', function() {
it('should return a string in the form "lat,lng"', function() {
2018-12-07 14:54:29 +00:00
const point = new GeoPoint({lat: -34, lng: 150});
2014-12-11 00:43:49 +00:00
point.toString().should.equal('-34,150');
});
});
2016-04-01 11:48:17 +00:00
describe('distance calculation between two points', function() {
2018-12-07 14:54:29 +00:00
const here = new GeoPoint({lat: 40.77492964101182, lng: -73.90950187151662});
const there = new GeoPoint({lat: 40.7753227, lng: -73.909217});
2014-12-10 22:41:49 +00:00
2016-04-01 11:48:17 +00:00
it('should return value in miles by default', function() {
2018-12-07 14:54:29 +00:00
const distance = GeoPoint.distanceBetween(here, there);
2014-12-10 22:41:49 +00:00
distance.should.be.a.Number;
2015-01-05 18:53:26 +00:00
distance.should.be.approximately(0.03097916611592679, DELTA);
2014-12-10 22:41:49 +00:00
});
2016-04-01 11:48:17 +00:00
it('should return value using specified unit', function() {
2014-12-10 22:41:49 +00:00
/* Supported units:
* - `radians`
* - `kilometers`
* - `meters`
* - `miles`
* - `feet`
* - `degrees`
*/
2018-12-07 14:54:29 +00:00
let distance = here.distanceTo(there, {type: 'radians'});
2014-12-10 22:41:49 +00:00
distance.should.be.a.Number;
2015-01-05 18:53:26 +00:00
distance.should.be.approximately(0.000007825491914348416, DELTA);
2014-12-10 22:41:49 +00:00
2016-08-19 17:46:59 +00:00
distance = here.distanceTo(there, {type: 'kilometers'});
2014-12-10 22:41:49 +00:00
distance.should.be.a.Number;
2015-01-05 18:53:26 +00:00
distance.should.be.approximately(0.04985613511367009, DELTA);
2014-12-10 22:41:49 +00:00
2016-08-19 17:46:59 +00:00
distance = here.distanceTo(there, {type: 'meters'});
2014-12-10 22:41:49 +00:00
distance.should.be.a.Number;
2015-01-05 18:53:26 +00:00
distance.should.be.approximately(49.856135113670085, DELTA);
2014-12-10 22:41:49 +00:00
2016-08-19 17:46:59 +00:00
distance = here.distanceTo(there, {type: 'miles'});
2014-12-10 22:41:49 +00:00
distance.should.be.a.Number;
2015-01-05 18:53:26 +00:00
distance.should.be.approximately(0.03097916611592679, DELTA);
2014-12-10 22:41:49 +00:00
2016-08-19 17:46:59 +00:00
distance = here.distanceTo(there, {type: 'feet'});
2014-12-10 22:41:49 +00:00
distance.should.be.a.Number;
2015-01-05 18:53:26 +00:00
distance.should.be.approximately(163.56999709209347, DELTA);
2014-12-10 22:41:49 +00:00
2016-08-19 17:46:59 +00:00
distance = here.distanceTo(there, {type: 'degrees'});
2014-12-10 22:41:49 +00:00
distance.should.be.a.Number;
2015-01-05 18:53:26 +00:00
distance.should.be.approximately(0.0004483676593058972, DELTA);
2014-12-10 22:41:49 +00:00
});
2014-12-10 22:47:32 +00:00
});
describe('nearFilter()', function() {
it('should return a filter includes minDistance if where contains minDistance option', function() {
2018-12-07 14:54:29 +00:00
const where = {
location: {
near: {
lat: 40.77492964101182,
lng: -73.90950187151662,
},
minDistance: 100,
},
};
2018-12-07 14:54:29 +00:00
const filter = nearFilter(where);
filter[0].key.should.equal('location');
filter[0].should.have.properties({
key: 'location',
near: {
lat: 40.77492964101182,
lng: -73.90950187151662,
},
minDistance: 100,
});
});
});
describe('filter()', function() {
it('should be able to filter geo points via minDistance', function() {
2018-12-07 14:54:29 +00:00
const points = [{
location: {
lat: 30.283552,
lng: 120.126048,
},
}, {
location: {
lat: 30.380307,
lng: 119.979445,
},
}, {
location: {
lat: 30.229896,
lng: 119.744592,
},
}, {
location: {
lat: 30.250863,
lng: 120.129498,
},
}, {
location: {
lat: 31.244209,
lng: 121.483687,
},
}];
2018-12-07 14:54:29 +00:00
const filter = [{
key: 'location',
near: {
lat: 30.278562,
lng: 120.139846,
},
unit: 'meters',
minDistance: 10000,
}];
2018-12-07 14:54:29 +00:00
const results = geoFilter(points, filter);
results.length.should.be.equal(3);
});
});
2014-12-10 22:41:49 +00:00
});