Skip to content

Commit 1b26adc

Browse files
dplewisflovilmart
authored andcommitted
Added WithinPolygon to Query (#438)
* Added withinPolygon to query * test * more test and documentation * reused objects for test * clean up test
1 parent 8126508 commit 1b26adc

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ lib
44
logs
55
node_modules
66
test_output
7+
integration/test_logs
78
*~
89
.DS_Store
910
.idea/

integration/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"dependencies": {
44
"express": "^4.13.4",
55
"mocha": "^2.4.5",
6-
"parse-server": "2.4.2"
6+
"parse-server": "^2.4.2"
77
},
88
"scripts": {
99
"test": "mocha --reporter dot -t 5000"

integration/test/ParseGeoPointTest.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,61 @@ describe('Geo Point', () => {
236236
done();
237237
});
238238
});
239+
240+
it('supports withinPolygon open path', (done) => {
241+
const points = [
242+
new Parse.GeoPoint(37.85, -122.33),
243+
new Parse.GeoPoint(37.85, -122.90),
244+
new Parse.GeoPoint(37.68, -122.90),
245+
new Parse.GeoPoint(37.68, -122.33)
246+
];
247+
const query = new Parse.Query(TestPoint);
248+
query.withinPolygon('location', points);
249+
return query.find().then((results) => {
250+
assert.equal(results.length, 1);
251+
done();
252+
});
253+
});
254+
255+
it('supports withinPolygon closed path', (done) => {
256+
const points = [
257+
new Parse.GeoPoint(38.52, -121.50),
258+
new Parse.GeoPoint(37.75, -157.93),
259+
new Parse.GeoPoint(37.578072, -121.379914),
260+
new Parse.GeoPoint(38.52, -121.50)
261+
];
262+
const query = new Parse.Query(TestPoint);
263+
query.withinPolygon('location', points);
264+
return query.find().then((results) => {
265+
assert.equal(results.length, 2);
266+
done();
267+
});
268+
});
269+
270+
it('non array withinPolygon', (done) => {
271+
const query = new Parse.Query(TestPoint);
272+
query.withinPolygon('location', 1234);
273+
return query.find().fail((err) => {
274+
assert.equal(err.code, Parse.Error.INVALID_JSON);
275+
done();
276+
});
277+
});
278+
279+
it('invalid array withinPolygon', (done) => {
280+
const query = new Parse.Query(TestPoint);
281+
query.withinPolygon('location', [1234]);
282+
return query.find().fail((err) => {
283+
assert.equal(err.code, Parse.Error.INVALID_JSON);
284+
done();
285+
});
286+
});
287+
288+
it('minimum 3 points withinPolygon', (done) => {
289+
const query = new Parse.Query(TestPoint);
290+
query.withinPolygon('location', []);
291+
return query.find().fail((err) => {
292+
assert.equal(err.code, Parse.Error.INTERNAL_SERVER_ERROR);
293+
done();
294+
});
295+
});
239296
});

src/ParseQuery.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function handleSelectResult(data: any, select: Array<string>){
5959
data[field] = undefined
6060
} else if (hasSubObjectSelect) {
6161
// this field references a sub-object,
62-
// so we need to walk down the path components
62+
// so we need to walk down the path components
6363
let pathComponents = field.split(".");
6464
var obj = data;
6565
var serverMask = serverDataMask;
@@ -358,7 +358,7 @@ export default class ParseQuery {
358358
if (select) {
359359
handleSelectResult(data, select);
360360
}
361-
361+
362362
return ParseObject.fromJSON(data, !select);
363363
});
364364
})._thenRunCallbacks(options);
@@ -928,6 +928,22 @@ export default class ParseQuery {
928928
return this;
929929
}
930930

931+
/**
932+
* Adds a constraint to the query that requires a particular key's
933+
* coordinates be contained within and on the bounds of a given polygon.
934+
* Supports closed and open (last point is connected to first) paths
935+
*
936+
* Polygon must have at least 3 points
937+
*
938+
* @method withinPolygon
939+
* @param {String} key The key to be constrained.
940+
* @param {Array} array of geopoints
941+
* @return {Parse.Query} Returns the query, so you can chain this call.
942+
*/
943+
withinPolygon(key: string, points: Array): ParseQuery {
944+
return this._addCondition(key, '$geoWithin', { '$polygon': points });
945+
}
946+
931947
/** Query Orderings **/
932948

933949
/**

0 commit comments

Comments
 (0)