diff --git a/README.md b/README.md index 0ad3def..c067222 100644 --- a/README.md +++ b/README.md @@ -761,6 +761,23 @@ $point = $this->collection ->findOne(); ``` +Search documents with points (stored as legacy coordinates) within polygon: +```php +collection + ->find() + ->withinPolygon( + 'point', + array( + array(0, 0), + array(0, 10), + array(10, 10), + array(10, 0), + ) + ) + ->findOne(); +``` + Pagination ---------- diff --git a/src/Expression.php b/src/Expression.php index 05c8cbb..adb83cc 100644 --- a/src/Expression.php +++ b/src/Expression.php @@ -539,7 +539,7 @@ public function withinCircleSpherical($field, $longitude, $latitude, $radiusInRa * Based on grid coordinates and does not query for GeoJSON shapes. * * Use planar geometry, so 2d index may be used but not required - * + * * @param string $field * @param array $bottomLeftCoordinate Bottom left coordinate of box * @param array $upperRightCoordinate Upper right coordinate of box @@ -559,6 +559,29 @@ public function withinBox($field, array $bottomLeftCoordinate, array $upperRight return $this; } + /** + * Return documents that are within the polygon, according + * to their point-based location data. + * + * Based on grid coordinates and does not query for GeoJSON shapes. + * + * Use planar geometry, so 2d index may be used but not required + * + * @param string $field + * @param array $points array of coordinates + * @return \Sokil\Mongo\Expression + */ + public function withinPolygon($field, array $points) + { + $this->where($field, array( + '$geoWithin' => array( + '$polygon' => $points, + ), + )); + + return $this; + } + public function toArray() { return $this->_expression; diff --git a/tests/DocumentGeoTest.php b/tests/DocumentGeoTest.php index e0d5e2e..e8a0cef 100644 --- a/tests/DocumentGeoTest.php +++ b/tests/DocumentGeoTest.php @@ -699,4 +699,37 @@ public function testExpressionWithinBox() $this->assertNotEmpty($point); $this->assertEquals($point1Id, $point->getId()); } + + public function testExpressionWithinPolygon() + { + $this->collection->ensure2dIndex('point'); + + $point1Id = $this->collection + ->createDocument() + ->setLegacyPoint('point', 5, 4) + ->save() + ->getId(); + + $point2Id = $this->collection + ->createDocument() + ->setLegacyPoint('point', 50, 40) + ->save() + ->getId(); + + $point = $this->collection + ->find() + ->withinPolygon( + 'point', + array( + array(0, 0), + array(0, 10), + array(10, 10), + array(10, 0), + ) + ) + ->findOne(); + + $this->assertNotEmpty($point); + $this->assertEquals($point1Id, $point->getId()); + } } \ No newline at end of file