-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
executable file
·192 lines (162 loc) · 5.17 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
var BSI = require('bindings')('BoostSpatialIndex');
/**
* @constructor
*/
function BoostSpatialIndex () {
this.spatialIndex = new BSI.SpatialIndex();
return this;
}
/**
* Adds a bounding box shape to the index
*
* @param {string} id - bounding box identifier
* @param {Number} min_lat
* @param {Number} min_lon
* @param {Number} max_lat
* @param {Number} max_lon
* @return {boolean}
*/
BoostSpatialIndex.prototype.addBoundingBox = function addBoundingBox (id, min_lat, min_lon, max_lat, max_lon) {
if (! id || typeof id !== 'string' || id.length === 0) {
throw new Error('Invalid "id" parameter: must be a non-empty string');
}
if ([min_lat, min_lon, max_lat, max_lon].findIndex(v => typeof v !== 'number') !== -1) {
throw new Error('Invalid coordinates parameter');
}
if (min_lat >= max_lat) {
throw new Error('min_lat argument cannot be greater or equal max_lat');
}
if (min_lon >= max_lon) {
throw new Error('min_lon argument cannot be greater or equal max_lon');
}
return this.spatialIndex.addBBox(id, min_lat, min_lon, max_lat, max_lon);
};
/**
* Adds a circle shape to the index
*
* @param {string} id - circle identifier
* @param {Number} lat
* @param {Number} lon
* @param {Number} radius in meters
* @return {boolean}
*/
BoostSpatialIndex.prototype.addCircle = function addCircle (id, lat, lon, radius) {
if (! id || typeof id !== 'string' || id.length === 0) {
throw new Error('Invalid "id" parameter: must be a non-empty string');
}
if ([lat, lon, radius].findIndex(v => typeof v !== 'number') !== -1) {
throw new Error('Invalid coordinates parameter');
}
return this.spatialIndex.addCircle(id, lat, lon, radius);
};
/**
* Adds an annulus shape to the index
*
* @param {string} id - annulus identifier
* @param {Number} lat
* @param {Number} lon
* @param {Number} outerRadius in meters
* @param {Number} innerRadius in meters
* @return {boolean}
*/
BoostSpatialIndex.prototype.addAnnulus = function addAnnulus (id, lat, lon, outer, inner) {
if (! id || typeof id !== 'string' || id.length === 0) {
throw new Error('Invalid "id" parameter: must be a non-empty string');
}
if ([lat, lon, outer, inner].findIndex(v => typeof v !== 'number') !== -1) {
throw new Error('Invalid coordinates parameter');
}
if (outer <= inner) {
throw new Error('Outer radius must be strictly greater than the inner one');
}
return this.spatialIndex.addAnnulus(id, lat, lon, outer, inner);
};
/**
* Adds a polygon shape to the index
* The polygon is open (automatically closed)
*
* The "points" argument is an array of array of coordinates.
* Example:
* [[lat, lon], [lat, lon], [lat, lon], ...]
*
* @param {string} id - polygon identifier
* @param {Array<Array<Number>>} points
* @return {boolean}
*/
BoostSpatialIndex.prototype.addPolygon = function addPolygon (id, points) {
var idx;
if (! id || typeof id !== 'string' || id.length === 0) {
throw new Error('Invalid "id" parameter: must be a non-empty string');
}
if (! points || typeof points !== 'object' || ! Array.isArray(points)) {
throw new Error('Invalid points arguments');
}
idx = points.findIndex(v => {
return ! v ||
typeof v !== 'object' ||
! Array.isArray(v) ||
v.length !== 2 ||
v.find(coord => typeof coord !== 'number');
});
if (idx !== -1) {
throw new Error('points arguments must only contain arrays, each one being a point coordinates');
}
return this.spatialIndex.addPolygon(id, points);
};
/**
* Gets all shapes identifiers covering the provided coordinates
*
* @param {Number} lat
* @param {Number} lon
* @return {Array<string>}
*/
BoostSpatialIndex.prototype.queryPoint = function queryPoint (lat, lon) {
if (typeof lat !== 'number') {
throw new Error('Invalid lat parameter');
}
if (typeof lon !== 'number') {
throw new Error('Invalid lon parameter');
}
return this.spatialIndex.queryPoint(lat, lon);
};
/**
* Gets all shape identifiers intersecting the polygon
* created using the "points" argument
* The polygon is open (automatically closed)
*
* The "points" argument is an array of array of coordinates.
* Example:
* [[lat, lon], [lat, lon], [lat, lon], ...]
*
* @param {Array<Array<Number>>} points
* @return {Array<string>}
*/
BoostSpatialIndex.prototype.queryIntersect = function queryIntersect (points) {
if (! points || typeof points !== 'object' || ! Array.isArray(points)) {
throw new Error('Invalid points arguments');
}
let idx = points.findIndex(v => {
return ! v ||
typeof v !== 'object' ||
! Array.isArray(v) ||
v.length !== 2 ||
v.find(coord => typeof coord !== 'number');
});
if (idx !== -1) {
throw new Error('points arguments must only contain arrays, each one being point coordinates');
}
return this.spatialIndex.queryIntersect(points);
};
/**
* Removes an id from the spatial index
*
* @param {string} id - shape identifier to remove
* @return {boolean}
*/
BoostSpatialIndex.prototype.remove = function remove (id) {
if (! id || typeof id !== 'string' || id.length === 0) {
throw new Error('Invalid id parameter');
}
return this.spatialIndex.remove(id);
};
module.exports = BoostSpatialIndex;