From 0f763da17d646b2fec2cd980d3857e46072a8a07 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Tue, 11 Oct 2022 17:27:29 -0500 Subject: [PATCH] feat: liveQuery support for unsorted distance queries (#8221) --- spec/ParseLiveQuery.spec.js | 34 ++++++++++++++++++++++++++++++++++ src/LiveQuery/QueryTools.js | 22 +++++++++++++++++++--- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/spec/ParseLiveQuery.spec.js b/spec/ParseLiveQuery.spec.js index 7f3794fa62..d112fceded 100644 --- a/spec/ParseLiveQuery.spec.js +++ b/spec/ParseLiveQuery.spec.js @@ -1156,6 +1156,40 @@ describe('ParseLiveQuery', function () { ]); }); + it('can subscribe to query and return object with withinKilometers with last parameter on update', async done => { + await reconfigureServer({ + liveQuery: { + classNames: ['TestObject'], + }, + startLiveQueryServer: true, + verbose: false, + silent: true, + }); + const object = new TestObject(); + const firstPoint = new Parse.GeoPoint({ latitude: 40.0, longitude: -30.0 }); + object.set({ location: firstPoint }); + await object.save(); + + // unsorted will use $centerSphere operator + const sorted = false; + const query = new Parse.Query(TestObject); + query.withinKilometers( + 'location', + new Parse.GeoPoint({ latitude: 40.0, longitude: -30.0 }), + 2, + sorted + ); + const subscription = await query.subscribe(); + subscription.on('update', obj => { + expect(obj.id).toBe(object.id); + done(); + }); + + const secondPoint = new Parse.GeoPoint({ latitude: 40.0, longitude: -30.0 }); + object.set({ location: secondPoint }); + await object.save(); + }); + afterEach(async function (done) { const client = await Parse.CoreManager.getLiveQueryController().getDefaultLiveQueryClient(); client.close(); diff --git a/src/LiveQuery/QueryTools.js b/src/LiveQuery/QueryTools.js index a50699f03e..50d8d3394a 100644 --- a/src/LiveQuery/QueryTools.js +++ b/src/LiveQuery/QueryTools.js @@ -344,9 +344,25 @@ function matchesKeyConstraints(object, key, constraints) { return true; } case '$geoWithin': { - const points = compareTo.$polygon.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]); - const polygon = new Parse.Polygon(points); - return polygon.containsPoint(object[key]); + if (compareTo.$polygon) { + const points = compareTo.$polygon.map(geoPoint => [ + geoPoint.latitude, + geoPoint.longitude, + ]); + const polygon = new Parse.Polygon(points); + return polygon.containsPoint(object[key]); + } + if (compareTo.$centerSphere) { + const [WGS84Point, maxDistance] = compareTo.$centerSphere; + const centerPoint = new Parse.GeoPoint({ + latitude: WGS84Point[1], + longitude: WGS84Point[0], + }); + const point = new Parse.GeoPoint(object[key]); + const distance = point.radiansTo(centerPoint); + return distance <= maxDistance; + } + break; } case '$geoIntersects': { const polygon = new Parse.Polygon(object[key].coordinates);