Skip to content

Commit 75f1199

Browse files
dplewisBenjamin Wilson Friedman
authored and
Benjamin Wilson Friedman
committed
Add ParsePolygon Type and polygonContains query (#327)
* Add ParsePolygon Type and polygonContains query * test class fix * error handling for polygon * Update PHP_CodeSniffer (#328) * Add lint * update travis * coding style * add coverage to gitignore * removed ignore lines * nit * Updated parse-php-sdk to version 1.2.9 * Corrects and updates phpdoc references/errors (#329) * Corrects and updates phpdoc references/errors * Lint fixes * Added 'Getting Started' to README.md Adds a **Getting Started** section to README.md to direct newcomers to the [official guide](http://docs.parseplatform.org/php/guide/) and [API reference](http://parseplatform.org/parse-php-sdk/namespaces/Parse.html). * Remove Default API (#332) * Removed default api and added appropriate checking * lint * Pages autodeploy and phpdoc style enforcing (#335) * Added 'document-check' to add phpdoc checking during tests and added deploy for api ref on gh-pages * Wrapping filename in quotes * Moved bash out of package.json * Unescaping strings * Testing missing block comment * Fixing lint exception to expose phpdoc style issue * Restored class summary * removed comment * fix documentation * Pinned jms/serializer to 1.7.1 (#336) * Pinned jms/serializer to 1.7.1 * Checking to update jms/serializer to 1.8.0 ONLY on php 5.4 for travis-ci * Added comment, and added graphviz for class diagrams in generated api docs
1 parent fb0b352 commit 75f1199

File tree

4 files changed

+289
-0
lines changed

4 files changed

+289
-0
lines changed

src/Parse/ParseClient.php

+4
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ public static function _decode($data)
345345
return new ParseGeoPoint($data['latitude'], $data['longitude']);
346346
}
347347

348+
if ($typeString === 'Polygon') {
349+
return new ParsePolygon($data['coordinates']);
350+
}
351+
348352
if ($typeString === 'Object') {
349353
$output = ParseObject::create($data['className']);
350354
$output->_mergeAfterFetch($data);

src/Parse/ParsePolygon.php

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
/**
3+
* Class ParsePolygon | Parse/ParsePolygon.php
4+
*/
5+
6+
namespace Parse;
7+
8+
use Parse\Internal\Encodable;
9+
use Parse\ParseGeoPoint;
10+
11+
/**
12+
* ParsePolygon - Representation of a Parse Polygon object.
13+
*
14+
* @author Diamond Lewis <[email protected]>
15+
* @package Parse
16+
*/
17+
class ParsePolygon implements Encodable
18+
{
19+
/**
20+
* The coordinates.
21+
*
22+
* @var array
23+
*/
24+
private $coordinates;
25+
26+
/**
27+
* Create a Parse Polygon object.
28+
*
29+
* @param array $coords GeoPoints or Coordinates.
30+
*/
31+
public function __construct($coords)
32+
{
33+
$this->setCoordinates($coords);
34+
}
35+
36+
/**
37+
* Set the Coordinates value for this Polygon.
38+
*
39+
* @param array $coords GeoPoints or Coordinates.
40+
*
41+
* @throws ParseException
42+
*/
43+
public function setCoordinates($coords)
44+
{
45+
if (!is_array($coords)) {
46+
throw new ParseException('Coordinates must be an Array');
47+
}
48+
if (count($coords) < 3) {
49+
throw new ParseException('Polygon must have at least 3 GeoPoints or Points');
50+
}
51+
$points = [];
52+
foreach ($coords as $coord) {
53+
$geoPoint;
54+
if ($coord instanceof ParseGeoPoint) {
55+
$geoPoint = $coord;
56+
} elseif (is_array($coord) && count($coord) === 2) {
57+
$geoPoint = new ParseGeoPoint($coord[0], $coord[1]);
58+
} else {
59+
throw new ParseException('Coordinates must be an Array of GeoPoints or Points');
60+
}
61+
$points[] = [$geoPoint->getLatitude(), $geoPoint->getLongitude()];
62+
}
63+
$this->coordinates = $points;
64+
}
65+
66+
/**
67+
* Returns the Coordinates value for this Polygon.
68+
*
69+
* @return array
70+
*/
71+
public function getCoordinates()
72+
{
73+
return $this->coordinates;
74+
}
75+
76+
/**
77+
* Encode to associative array representation.
78+
*
79+
* @return array
80+
*/
81+
public function _encode()
82+
{
83+
return [
84+
'__type' => 'Polygon',
85+
'coordinates' => $this->coordinates,
86+
];
87+
}
88+
}

src/Parse/ParseQuery.php

+20
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,26 @@ public function withinPolygon($key, $points)
645645
return $this;
646646
}
647647

648+
/**
649+
* Add a constraint to the query that requires a particular key's
650+
* coordinates that contains a ParseGeoPoint
651+
*
652+
* @param string $key The key of the ParsePolygon
653+
* @param ParseGeoPoint $point The point that will be contained.
654+
*
655+
* @return ParseQuery Returns this query, so you can chain this call.
656+
*/
657+
public function polygonContains($key, $point)
658+
{
659+
$this->addCondition(
660+
$key,
661+
'$geoIntersects',
662+
['$point' => $point]
663+
);
664+
665+
return $this;
666+
}
667+
648668
/**
649669
* Add a constraint to the query that requires a particular key's value to
650670
* be contained in the provided list of values.

tests/Parse/ParsePolygonTest.php

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<?php
2+
3+
namespace Parse\Test;
4+
5+
use Parse\ParseGeoPoint;
6+
use Parse\ParsePolygon;
7+
use Parse\ParseObject;
8+
use Parse\ParseQuery;
9+
10+
class ParsePolygonTest extends \PHPUnit_Framework_TestCase
11+
{
12+
public static function setUpBeforeClass()
13+
{
14+
Helper::setUp();
15+
}
16+
17+
public function setUp()
18+
{
19+
Helper::clearClass('TestObject');
20+
}
21+
22+
public function tearDown()
23+
{
24+
Helper::tearDown();
25+
}
26+
27+
public function testPolygonWithPoints()
28+
{
29+
$openPoints = [[0,0],[0,1],[1,1],[1,0]];
30+
$closedPoints = [[0,0],[0,1],[1,1],[1,0],[0,0]];
31+
$polygon = new ParsePolygon($openPoints);
32+
33+
$obj = ParseObject::create('TestObject');
34+
$obj->set('polygon', $polygon);
35+
$obj->save();
36+
37+
// Query by open points
38+
$query = new ParseQuery('TestObject');
39+
$query->equalTo('polygon', $polygon);
40+
41+
$results = $query->find();
42+
$actualPolygon = $results[0]->get('polygon');
43+
44+
$this->assertEquals(1, count($results));
45+
$this->assertEquals($closedPoints, $actualPolygon->getCoordinates());
46+
47+
// Query by closed points
48+
$polygon = new ParsePolygon($closedPoints);
49+
$query = new ParseQuery('TestObject');
50+
$query->equalTo('polygon', $polygon);
51+
52+
$results = $query->find();
53+
$actualPolygon = $results[0]->get('polygon');
54+
55+
$this->assertEquals(1, count($results));
56+
$this->assertEquals($closedPoints, $actualPolygon->getCoordinates());
57+
}
58+
59+
public function testPolygonWithGeoPoints()
60+
{
61+
$p1 = new ParseGeoPoint(0, 0);
62+
$p2 = new ParseGeoPoint(0, 1);
63+
$p3 = new ParseGeoPoint(1, 1);
64+
$p4 = new ParseGeoPoint(1, 0);
65+
$p5 = new ParseGeoPoint(0, 0);
66+
67+
$points = [$p1, $p2, $p3, $p4];
68+
$openPoints = [[0,0],[0,1],[1,1],[1,0]];
69+
$closedPoints = [[0,0],[0,1],[1,1],[1,0],[0,0]];
70+
$polygon = new ParsePolygon($points);
71+
72+
$obj = ParseObject::create('TestObject');
73+
$obj->set('polygon', $polygon);
74+
$obj->save();
75+
76+
// Query by open points
77+
$query = new ParseQuery('TestObject');
78+
$query->equalTo('polygon', $polygon);
79+
80+
$results = $query->find();
81+
$actualPolygon = $results[0]->get('polygon');
82+
83+
$this->assertEquals(1, count($results));
84+
$this->assertEquals($closedPoints, $actualPolygon->getCoordinates());
85+
86+
// Query by closed points
87+
$polygon = new ParsePolygon($closedPoints);
88+
$query = new ParseQuery('TestObject');
89+
$query->equalTo('polygon', $polygon);
90+
91+
$results = $query->find();
92+
$actualPolygon = $results[0]->get('polygon');
93+
94+
$this->assertEquals(1, count($results));
95+
$this->assertEquals($closedPoints, $actualPolygon->getCoordinates());
96+
}
97+
98+
public function testPolygonMinimum()
99+
{
100+
$this->setExpectedException(
101+
'\Parse\ParseException',
102+
'Polygon must have at least 3 GeoPoints or Points'
103+
);
104+
$polygon = new ParsePolygon([[0,0]]);
105+
$obj = ParseObject::create('TestObject');
106+
$obj->set('polygon', $polygon);
107+
$obj->save();
108+
}
109+
110+
public function testPolygonInvalidInput()
111+
{
112+
$this->setExpectedException(
113+
'\Parse\ParseException',
114+
'Coordinates must be an Array'
115+
);
116+
$polygon = new ParsePolygon(1234);
117+
$obj = ParseObject::create('TestObject');
118+
$obj->set('polygon', $polygon);
119+
$obj->save();
120+
}
121+
122+
public function testPolygonInvalidArray()
123+
{
124+
$this->setExpectedException(
125+
'\Parse\ParseException',
126+
'Coordinates must be an Array of GeoPoints or Points'
127+
);
128+
$polygon = new ParsePolygon([['str1'],['str2'],['str3']]);
129+
$obj = ParseObject::create('TestObject');
130+
$obj->set('polygon', $polygon);
131+
$obj->save();
132+
}
133+
134+
public function testPolygonContains()
135+
{
136+
$points1 = [[0,0],[0,1],[1,1],[1,0]];
137+
$points2 = [[0,0],[0,2],[2,2],[2,0]];
138+
$points3 = [[10,10],[10,15],[15,15],[15,10],[10,10]];
139+
140+
$polygon1 = new ParsePolygon($points1);
141+
$polygon2 = new ParsePolygon($points2);
142+
$polygon3 = new ParsePolygon($points3);
143+
144+
$obj1 = ParseObject::create('TestObject');
145+
$obj2 = ParseObject::create('TestObject');
146+
$obj3 = ParseObject::create('TestObject');
147+
148+
$obj1->set('polygon', $polygon1);
149+
$obj2->set('polygon', $polygon2);
150+
$obj3->set('polygon', $polygon3);
151+
152+
ParseObject::saveAll([$obj1, $obj2, $obj3]);
153+
154+
$point = new ParseGeoPoint(0.5, 0.5);
155+
$query = new ParseQuery('TestObject');
156+
$query->polygonContains('polygon', $point);
157+
$results = $query->find();
158+
$this->assertEquals(2, count($results));
159+
}
160+
161+
public function testPolygonContainsInvalidInput()
162+
{
163+
$this->setExpectedException(
164+
'\Parse\ParseException',
165+
'bad $geoIntersect value; $point should be GeoPoint'
166+
);
167+
$points = [[0,0],[0,1],[1,1],[1,0]];
168+
$polygon = new ParsePolygon($points);
169+
$obj = ParseObject::create('TestObject');
170+
$obj->set('polygon', $polygon);
171+
$obj->save();
172+
173+
$query = new ParseQuery('TestObject');
174+
$query->polygonContains('polygon', 1234);
175+
$results = $query->find();
176+
}
177+
}

0 commit comments

Comments
 (0)