From 2b6ed752ed3c0da4d94ef97d148b39ac78c34b12 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Tue, 30 May 2017 17:28:53 -0500 Subject: [PATCH 1/4] Add Within Polygon to Query --- src/Parse/ParseQuery.php | 20 ++++++++++++++++++++ tests/Parse/ParseGeoPointTest.php | 25 +++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/Parse/ParseQuery.php b/src/Parse/ParseQuery.php index 77431e6b..088c72f7 100755 --- a/src/Parse/ParseQuery.php +++ b/src/Parse/ParseQuery.php @@ -622,6 +622,26 @@ public function withinGeoBox($key, $southwest, $northeast) return $this; } + /** + * Add a constraint to the query that requires a particular key's + * coordinates be contained within a given polygon + * + * @param string $key The key of the ParseGeoPoint + * @param array $points Array of ParseGeoPoint + * + * @return ParseQuery Returns this query, so you can chain this call. + */ + public function withinPolygon($key, $points) + { + $this->addCondition( + $key, + '$geoWithin', + ['$polygon' => $points] + ); + + return $this; + } + /** * Add a constraint to the query that requires a particular key's value to * be contained in the provided list of values. diff --git a/tests/Parse/ParseGeoPointTest.php b/tests/Parse/ParseGeoPointTest.php index 481bdca1..3721f169 100644 --- a/tests/Parse/ParseGeoPointTest.php +++ b/tests/Parse/ParseGeoPointTest.php @@ -200,20 +200,41 @@ public function testGeoMaxDistanceWithUnits() $query->withinMiles('location', $point, 10.0); $results = $query->find(); $this->assertEquals(0, count($results)); - } public function testBadLatitude() { $this->setExpectedException('\Parse\ParseException', 'Latitude must be within range [-90.0, 90.0]'); new ParseGeoPoint(-180, 32); - } public function testBadLongitude() { $this->setExpectedException('\Parse\ParseException', 'Longitude must be within range [-180.0, 180.0]'); new ParseGeoPoint(32, -360); + } + + public function testWithinPolygon() { + $obj1 = ParseObject::create('TestObject'); + $obj2 = ParseObject::create('TestObject'); + $obj3 = ParseObject::create('TestObject'); + + $obj1->set('location', new ParseGeoPoint(1.5, 1.5)); + $obj2->set('location', new ParseGeoPoint(2, 8)); + $obj3->set('location', new ParseGeoPoint(20, 20)); + ParseObject::saveAll([$obj1, $obj2, $obj3]); + + $points = [ + new ParseGeoPoint(0, 0), + new ParseGeoPoint(0, 10), + new ParseGeoPoint(10, 10), + new ParseGeoPoint(10, 0) + ]; + + $query = new ParseQuery('TestObject'); + $query->withinPolygon('location', $points); + $results = $query->find(); + $this->assertEquals(2, count($results)); } } From b0172251855eef0026b91c456e60211290057b76 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Tue, 30 May 2017 17:32:36 -0500 Subject: [PATCH 2/4] lint --- tests/Parse/ParseGeoPointTest.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/Parse/ParseGeoPointTest.php b/tests/Parse/ParseGeoPointTest.php index 3721f169..fdd9a244 100644 --- a/tests/Parse/ParseGeoPointTest.php +++ b/tests/Parse/ParseGeoPointTest.php @@ -202,19 +202,26 @@ public function testGeoMaxDistanceWithUnits() $this->assertEquals(0, count($results)); } - public function testBadLatitude() { - $this->setExpectedException('\Parse\ParseException', - 'Latitude must be within range [-90.0, 90.0]'); + public function testBadLatitude() + { + $this->setExpectedException( + '\Parse\ParseException', + 'Latitude must be within range [-90.0, 90.0]' + ); new ParseGeoPoint(-180, 32); } - public function testBadLongitude() { - $this->setExpectedException('\Parse\ParseException', - 'Longitude must be within range [-180.0, 180.0]'); + public function testBadLongitude() + { + $this->setExpectedException( + '\Parse\ParseException', + 'Longitude must be within range [-180.0, 180.0]' + ); new ParseGeoPoint(32, -360); } - public function testWithinPolygon() { + public function testWithinPolygon() + { $obj1 = ParseObject::create('TestObject'); $obj2 = ParseObject::create('TestObject'); $obj3 = ParseObject::create('TestObject'); From 12e1745d0ffd356dda40f54d7287067feca88489 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Wed, 31 May 2017 16:03:41 -0500 Subject: [PATCH 3/4] added test for open and closed paths --- src/Parse/ParseQuery.php | 5 +- tests/Parse/Helper.php | 6 +- tests/Parse/ParseGeoPointTest.php | 104 +++++++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 12 deletions(-) diff --git a/src/Parse/ParseQuery.php b/src/Parse/ParseQuery.php index 088c72f7..e2854b66 100755 --- a/src/Parse/ParseQuery.php +++ b/src/Parse/ParseQuery.php @@ -624,7 +624,10 @@ public function withinGeoBox($key, $southwest, $northeast) /** * Add a constraint to the query that requires a particular key's - * coordinates be contained within a given polygon + * coordinates be contained within and on the bounds of a given polygon + * Supports closed and open (last point is connected to first) paths + * + * Polygon must have at least 3 points * * @param string $key The key of the ParseGeoPoint * @param array $points Array of ParseGeoPoint diff --git a/tests/Parse/Helper.php b/tests/Parse/Helper.php index a71f0a78..8519eaf9 100644 --- a/tests/Parse/Helper.php +++ b/tests/Parse/Helper.php @@ -15,7 +15,7 @@ class Helper * Application Id * @var string */ - public static $appId = 'app-id-here'; + public static $appId = 'MK5KVBqIzhhM5tIwX9hrKnQLLKpHeJ9O0VHS4Fqp'; /** * Rest API Key @@ -27,7 +27,7 @@ class Helper * Master Key * @var string */ - public static $masterKey = 'master-key-here'; + public static $masterKey = 'G1QPMwxoMOfCNALvY7RrQkk9Z2X2yin7kQkemghg'; /** * Account Key (for parse.com) @@ -106,4 +106,4 @@ public static function setUpWithoutCURLExceptions() ); } -} +} \ No newline at end of file diff --git a/tests/Parse/ParseGeoPointTest.php b/tests/Parse/ParseGeoPointTest.php index fdd9a244..bbbaa601 100644 --- a/tests/Parse/ParseGeoPointTest.php +++ b/tests/Parse/ParseGeoPointTest.php @@ -220,17 +220,17 @@ public function testBadLongitude() new ParseGeoPoint(32, -360); } - public function testWithinPolygon() + public function testWithinPolygonOpenPath() { - $obj1 = ParseObject::create('TestObject'); - $obj2 = ParseObject::create('TestObject'); - $obj3 = ParseObject::create('TestObject'); + $inbound = ParseObject::create('TestObject'); + $onbound = ParseObject::create('TestObject'); + $outbound = ParseObject::create('TestObject'); - $obj1->set('location', new ParseGeoPoint(1.5, 1.5)); - $obj2->set('location', new ParseGeoPoint(2, 8)); - $obj3->set('location', new ParseGeoPoint(20, 20)); + $inbound->set('location', new ParseGeoPoint(1, 1)); + $onbound->set('location', new ParseGeoPoint(10, 10)); + $outbound->set('location', new ParseGeoPoint(20, 20)); - ParseObject::saveAll([$obj1, $obj2, $obj3]); + ParseObject::saveAll([$inbound, $onbound, $outbound]); $points = [ new ParseGeoPoint(0, 0), @@ -238,10 +238,98 @@ public function testWithinPolygon() new ParseGeoPoint(10, 10), new ParseGeoPoint(10, 0) ]; + $query = new ParseQuery('TestObject'); + $query->withinPolygon('location', $points); + $results = $query->find(); + $this->assertEquals(2, count($results)); + } + + public function testWithinPolygonClosedPath() + { + $inbound = ParseObject::create('TestObject'); + $onbound = ParseObject::create('TestObject'); + $outbound = ParseObject::create('TestObject'); + + $inbound->set('location', new ParseGeoPoint(1, 1)); + $onbound->set('location', new ParseGeoPoint(10, 10)); + $outbound->set('location', new ParseGeoPoint(20, 20)); + ParseObject::saveAll([$inbound, $onbound, $outbound]); + + $points = [ + new ParseGeoPoint(0, 0), + new ParseGeoPoint(0, 10), + new ParseGeoPoint(10, 10), + new ParseGeoPoint(10, 0), + new ParseGeoPoint(0, 0) + ]; $query = new ParseQuery('TestObject'); $query->withinPolygon('location', $points); $results = $query->find(); $this->assertEquals(2, count($results)); } + + public function testWithinPolygonEmpty() + { + $obj = ParseObject::create('TestObject'); + $obj->set('location', new ParseGeoPoint(1.5, 1.5)); + $obj->save(); + + $this->setExpectedException( + '\Parse\ParseException', + 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints' + ); + $query = new ParseQuery('TestObject'); + $query->withinPolygon('location', []); + $query->find(); + } + + public function testWithinPolygonTwoGeoPoints() + { + $obj = ParseObject::create('TestObject'); + $obj->set('location', new ParseGeoPoint(1.5, 1.5)); + $obj->save(); + + $this->setExpectedException( + '\Parse\ParseException', + 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints' + ); + $points = [ + new ParseGeoPoint(0, 0), + new ParseGeoPoint(10, 10) + ]; + $query = new ParseQuery('TestObject'); + $query->withinPolygon('location', $points); + $query->find(); + } + + public function testWithinPolygonNonArray() + { + $obj = ParseObject::create('TestObject'); + $obj->set('location', new ParseGeoPoint(1.5, 1.5)); + $obj->save(); + + $this->setExpectedException( + '\Parse\ParseException', + 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints' + ); + $query = new ParseQuery('TestObject'); + $query->withinPolygon('location', 1234); + $query->find(); + } + + public function testWithinPolygonInvalidArray() + { + $obj = ParseObject::create('TestObject'); + $obj->set('location', new ParseGeoPoint(1.5, 1.5)); + $obj->save(); + + $this->setExpectedException( + '\Parse\ParseException', + 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints' + ); + $query = new ParseQuery('TestObject'); + $query->withinPolygon('location', [$obj]); + $query->find(); + } } From 858b177c8196af9d4af6c8706fe8b8b4f9f7d9cc Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Wed, 31 May 2017 16:29:12 -0500 Subject: [PATCH 4/4] remove helper --- tests/Parse/Helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Parse/Helper.php b/tests/Parse/Helper.php index 8519eaf9..e3528e2d 100644 --- a/tests/Parse/Helper.php +++ b/tests/Parse/Helper.php @@ -15,7 +15,7 @@ class Helper * Application Id * @var string */ - public static $appId = 'MK5KVBqIzhhM5tIwX9hrKnQLLKpHeJ9O0VHS4Fqp'; + public static $appId = 'app-id-here'; /** * Rest API Key @@ -27,7 +27,7 @@ class Helper * Master Key * @var string */ - public static $masterKey = 'G1QPMwxoMOfCNALvY7RrQkk9Z2X2yin7kQkemghg'; + public static $masterKey = 'master-key-here'; /** * Account Key (for parse.com)