1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 | require('should');
|
9 |
|
10 | const GeoPoint = require('../lib/geo').GeoPoint;
|
11 | const nearFilter = require('../lib/geo').nearFilter;
|
12 | const geoFilter = require('../lib/geo').filter;
|
13 | const DELTA = 0.0000001;
|
14 |
|
15 | describe('GeoPoint', function() {
|
16 | describe('constructor', function() {
|
17 | it('should support a valid array', function() {
|
18 | const point = new GeoPoint([-34, 150]);
|
19 |
|
20 | point.lat.should.equal(-34);
|
21 | point.lng.should.equal(150);
|
22 | });
|
23 |
|
24 | it('should support a valid object', function() {
|
25 | const point = new GeoPoint({lat: -34, lng: 150});
|
26 |
|
27 | point.lat.should.equal(-34);
|
28 | point.lng.should.equal(150);
|
29 | });
|
30 |
|
31 | it('should support valid string geo coordinates', function() {
|
32 | const point = new GeoPoint('-34,150');
|
33 |
|
34 | point.lat.should.equal(-34);
|
35 | point.lng.should.equal(150);
|
36 | });
|
37 |
|
38 | it('should support coordinates as inline parameters', function() {
|
39 | const point = new GeoPoint(-34, 150);
|
40 |
|
41 | point.lat.should.equal(-34);
|
42 | point.lng.should.equal(150);
|
43 | });
|
44 |
|
45 | it('should reject invalid parameters', function() {
|
46 |
|
47 | let fn = function() {
|
48 | new GeoPoint('150,-34');
|
49 | };
|
50 | fn.should.throw();
|
51 |
|
52 | fn = function() {
|
53 | new GeoPoint('invalid_string');
|
54 | };
|
55 | fn.should.throw();
|
56 |
|
57 | fn = function() {
|
58 | new GeoPoint([150, -34]);
|
59 | };
|
60 | fn.should.throw();
|
61 |
|
62 | fn = function() {
|
63 | new GeoPoint({
|
64 | lat: 150,
|
65 | lng: null,
|
66 | });
|
67 | };
|
68 | fn.should.throw();
|
69 |
|
70 | fn = function() {
|
71 | new GeoPoint(150, -34);
|
72 | };
|
73 | fn.should.throw();
|
74 |
|
75 | fn = function() {
|
76 | new GeoPoint();
|
77 | };
|
78 | fn.should.throw();
|
79 | });
|
80 | });
|
81 |
|
82 | describe('toString()', function() {
|
83 | it('should return a string in the form "lat,lng"', function() {
|
84 | const point = new GeoPoint({lat: -34, lng: 150});
|
85 | point.toString().should.equal('-34,150');
|
86 | });
|
87 | });
|
88 |
|
89 | describe('distance calculation between two points', function() {
|
90 | const here = new GeoPoint({lat: 40.77492964101182, lng: -73.90950187151662});
|
91 | const there = new GeoPoint({lat: 40.7753227, lng: -73.909217});
|
92 |
|
93 | it('should return value in miles by default', function() {
|
94 | const distance = GeoPoint.distanceBetween(here, there);
|
95 | distance.should.be.a.Number;
|
96 | distance.should.be.approximately(0.03097916611592679, DELTA);
|
97 | });
|
98 |
|
99 | it('should return value using specified unit', function() {
|
100 | |
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 | let distance = here.distanceTo(there, {type: 'radians'});
|
110 | distance.should.be.a.Number;
|
111 | distance.should.be.approximately(0.000007825491914348416, DELTA);
|
112 |
|
113 | distance = here.distanceTo(there, {type: 'kilometers'});
|
114 | distance.should.be.a.Number;
|
115 | distance.should.be.approximately(0.04985613511367009, DELTA);
|
116 |
|
117 | distance = here.distanceTo(there, {type: 'meters'});
|
118 | distance.should.be.a.Number;
|
119 | distance.should.be.approximately(49.856135113670085, DELTA);
|
120 |
|
121 | distance = here.distanceTo(there, {type: 'miles'});
|
122 | distance.should.be.a.Number;
|
123 | distance.should.be.approximately(0.03097916611592679, DELTA);
|
124 |
|
125 | distance = here.distanceTo(there, {type: 'feet'});
|
126 | distance.should.be.a.Number;
|
127 | distance.should.be.approximately(163.56999709209347, DELTA);
|
128 |
|
129 | distance = here.distanceTo(there, {type: 'degrees'});
|
130 | distance.should.be.a.Number;
|
131 | distance.should.be.approximately(0.0004483676593058972, DELTA);
|
132 | });
|
133 | });
|
134 |
|
135 | describe('nearFilter()', function() {
|
136 | it('should return a filter includes minDistance if where contains minDistance option', function() {
|
137 | const where = {
|
138 | location: {
|
139 | near: {
|
140 | lat: 40.77492964101182,
|
141 | lng: -73.90950187151662,
|
142 | },
|
143 | minDistance: 100,
|
144 | },
|
145 | };
|
146 | const filter = nearFilter(where);
|
147 | filter[0].key.should.equal('location');
|
148 | filter[0].should.have.properties({
|
149 | key: 'location',
|
150 | near: {
|
151 | lat: 40.77492964101182,
|
152 | lng: -73.90950187151662,
|
153 | },
|
154 | minDistance: 100,
|
155 | });
|
156 | });
|
157 | });
|
158 |
|
159 | describe('filter()', function() {
|
160 | it('should be able to filter geo points via minDistance', function() {
|
161 | const points = [{
|
162 | location: {
|
163 | lat: 30.283552,
|
164 | lng: 120.126048,
|
165 | },
|
166 | }, {
|
167 | location: {
|
168 | lat: 30.380307,
|
169 | lng: 119.979445,
|
170 | },
|
171 | }, {
|
172 | location: {
|
173 | lat: 30.229896,
|
174 | lng: 119.744592,
|
175 | },
|
176 | }, {
|
177 | location: {
|
178 | lat: 30.250863,
|
179 | lng: 120.129498,
|
180 | },
|
181 | }, {
|
182 | location: {
|
183 | lat: 31.244209,
|
184 | lng: 121.483687,
|
185 | },
|
186 | }];
|
187 | const filter = [{
|
188 | key: 'location',
|
189 | near: {
|
190 | lat: 30.278562,
|
191 | lng: 120.139846,
|
192 | },
|
193 | unit: 'meters',
|
194 | minDistance: 10000,
|
195 | }];
|
196 | const results = geoFilter(points, filter);
|
197 | results.length.should.be.equal(3);
|
198 | });
|
199 | });
|
200 | });
|