diff --git a/composer.json b/composer.json index fba31d4..c71d6a6 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ "php": ">=5.5", "illuminate/database": "~5.0", "bosnadev/database": "~0.1", - "geo-io/wkb-parser": "~1.0" + "geo-io/wkb-parser": "~1.0", + "jmikola/geojson": "~1.0" }, "require-dev": { "phpunit/phpunit": "~4.5", diff --git a/src/Geometries/Geometry.php b/src/Geometries/Geometry.php index 09ada18..22316d2 100644 --- a/src/Geometries/Geometry.php +++ b/src/Geometries/Geometry.php @@ -3,7 +3,7 @@ use GeoIO\WKB\Parser\Parser; use Phaza\LaravelPostgis\Exceptions\UnknownWKTTypeException; -abstract class Geometry implements GeometryInterface +abstract class Geometry implements GeometryInterface, \JsonSerializable { protected static $wkb_types = [ 1 => Point::class, diff --git a/src/Geometries/GeometryCollection.php b/src/Geometries/GeometryCollection.php index 214d5dd..92bb3ec 100644 --- a/src/Geometries/GeometryCollection.php +++ b/src/Geometries/GeometryCollection.php @@ -1,6 +1,7 @@ geometries); } + + /** + * Convert to GeoJson GeometryCollection that is jsonable to GeoJSON + * + * @return \GeoJson\Geometry\GeometryCollection + */ + public function jsonSerialize() + { + $geometries = []; + foreach ($this->geometries as $geometry) { + $geometries[] = $geometry->jsonSerialize(); + } + + return new \GeoJson\Geometry\GeometryCollection($geometries); + } } diff --git a/src/Geometries/LineString.php b/src/Geometries/LineString.php index e2bb86e..3871866 100644 --- a/src/Geometries/LineString.php +++ b/src/Geometries/LineString.php @@ -28,4 +28,19 @@ public function __toString() { return $this->toPairList(); } + + /** + * Convert to GeoJson LineString that is jsonable to GeoJSON + * + * @return \GeoJson\Geometry\LineString + */ + public function jsonSerialize() + { + $points = []; + foreach ($this->points as $point) { + $points[] = $point->jsonSerialize(); + } + + return new \GeoJson\Geometry\LineString($points); + } } diff --git a/src/Geometries/MultiLineString.php b/src/Geometries/MultiLineString.php index 5a4ebfc..75ee891 100644 --- a/src/Geometries/MultiLineString.php +++ b/src/Geometries/MultiLineString.php @@ -62,4 +62,20 @@ public function count() { return count($this->linestrings); } + + /** + * Convert to GeoJson Point that is jsonable to GeoJSON + * + * @return \GeoJson\Geometry\MultiLineString + */ + public function jsonSerialize() + { + $linestrings = []; + + foreach ($this->linestrings as $linestring) { + $linestrings[] = $linestring->jsonSerialize(); + } + + return new \GeoJson\Geometry\MultiLineString($linestrings); + } } diff --git a/src/Geometries/MultiPoint.php b/src/Geometries/MultiPoint.php index cd34827..ff07291 100644 --- a/src/Geometries/MultiPoint.php +++ b/src/Geometries/MultiPoint.php @@ -1,6 +1,6 @@ toPair()); }, $this->points)); } + + /** + * Convert to GeoJson MultiPoint that is jsonable to GeoJSON + * + * @return \GeoJson\Geometry\MultiPoint + */ + public function jsonSerialize() + { + $points = []; + foreach ($this->points as $point) { + $points[] = $point->jsonSerialize(); + } + + return new \GeoJson\Geometry\MultiPoint($points); + } } diff --git a/src/Geometries/MultiPolygon.php b/src/Geometries/MultiPolygon.php index 2cef183..9621d65 100644 --- a/src/Geometries/MultiPolygon.php +++ b/src/Geometries/MultiPolygon.php @@ -99,4 +99,19 @@ protected static function assembleParts(array $parts) return $polygons; } + + /** + * Convert to GeoJson MultiPolygon that is jsonable to GeoJSON + * + * @return \GeoJson\Geometry\MultiPolygon + */ + public function jsonSerialize() + { + $polygons = []; + foreach ($this->polygons as $polygon) { + $polygons[] = $polygon->jsonSerialize(); + } + + return new \GeoJson\Geometry\MultiPolygon($polygons); + } } diff --git a/src/Geometries/Point.php b/src/Geometries/Point.php index be7f9b3..6ed062c 100644 --- a/src/Geometries/Point.php +++ b/src/Geometries/Point.php @@ -1,5 +1,7 @@ getLng() . ' ' . $this->getLat(); } + + /** + * Convert to GeoJson Point that is jsonable to GeoJSON + * + * @return \GeoJson\Geometry\Point + */ + public function jsonSerialize() + { + // !!! This will convert LngLat from PostGIS to ISO 6709 LatLng !!! + return new \GeoJson\Geometry\Point([$this->getLat(), $this->getLng()]); + } } diff --git a/src/Geometries/PointCollection.php b/src/Geometries/PointCollection.php index 664dae8..b0aed6f 100644 --- a/src/Geometries/PointCollection.php +++ b/src/Geometries/PointCollection.php @@ -6,8 +6,9 @@ use Illuminate\Contracts\Support\Arrayable; use InvalidArgumentException; use IteratorAggregate; +use JsonSerializable; -class PointCollection implements IteratorAggregate, Arrayable, ArrayAccess, Countable +abstract class PointCollection implements IteratorAggregate, Arrayable, ArrayAccess, Countable, JsonSerializable { /** * @var Point[] diff --git a/src/Geometries/Polygon.php b/src/Geometries/Polygon.php index 4fdb1e8..2169d3d 100644 --- a/src/Geometries/Polygon.php +++ b/src/Geometries/Polygon.php @@ -9,4 +9,19 @@ public function toWKT() { return sprintf('POLYGON(%s)', (string)$this); } + + /** + * Convert to GeoJson Polygon that is jsonable to GeoJSON + * + * @return \GeoJson\Geometry\Polygon + */ + public function jsonSerialize() + { + $linearrings = []; + foreach ($this->linestrings as $linestring) { + $linearrings[] = new \GeoJson\Geometry\LinearRing($linestring->jsonSerialize()->getCoordinates()); + } + + return new \GeoJson\Geometry\Polygon($linearrings); + } } diff --git a/tests/Geometries/GeometryCollectionTest.php b/tests/Geometries/GeometryCollectionTest.php index 2398613..9c765ba 100644 --- a/tests/Geometries/GeometryCollectionTest.php +++ b/tests/Geometries/GeometryCollectionTest.php @@ -6,6 +6,29 @@ class GeometryCollectionTest extends BaseTestCase { + /** + * @var GeometryCollection + */ + private $collection; + + protected function setUp() + { + $collection = new LineString( + [ + new Point(0, 0), + new Point(0, 1), + new Point(1, 1), + new Point(1, 0), + new Point(0, 0) + ] + ); + + $point = new Point(100, 200); + + $this->collection = new GeometryCollection([$collection, $point]); + } + + public function testFromWKT() { /** @@ -21,20 +44,23 @@ public function testFromWKT() public function testToWKT() { - $collection = new LineString( - [ - new Point(0, 0), - new Point(0, 1), - new Point(1, 1), - new Point(1, 0), - new Point(0, 0) - ] + $this->assertEquals( + 'GEOMETRYCOLLECTION(LINESTRING(0 0,1 0,1 1,0 1,0 0),POINT(200 100))', + $this->collection->toWKT() ); + } - $point = new Point(100, 200); + public function testJsonSerialize() + { + $this->assertInstanceOf( + \GeoJson\Geometry\GeometryCollection::class, + $this->collection->jsonSerialize() + ); - $polygon = new GeometryCollection([$collection, $point]); + $this->assertSame( + '{"type":"GeometryCollection","geometries":[{"type":"LineString","coordinates":[[0,0],[0,1],[1,1],[1,0],[0,0]]},{"type":"Point","coordinates":[100,200]}]}', + json_encode($this->collection->jsonSerialize()) + ); - $this->assertEquals('GEOMETRYCOLLECTION(LINESTRING(0 0,1 0,1 1,0 1,0 0),POINT(200 100))', $polygon->toWKT()); } } diff --git a/tests/Geometries/LineStringTest.php b/tests/Geometries/LineStringTest.php index 5f53952..28e0833 100644 --- a/tests/Geometries/LineStringTest.php +++ b/tests/Geometries/LineStringTest.php @@ -5,6 +5,20 @@ class LineStringTest extends BaseTestCase { + private $points; + + protected function setUp() + { + $this->points = [new Point(0, 0), new Point(1, 1), new Point(2, 2)]; + } + + public function testToWKT() + { + $linestring = new LineString($this->points); + + $this->assertEquals('LINESTRING(0 0,1 1,2 2)', $linestring->toWKT()); + } + public function testFromWKT() { $linestring = LineString::fromWKT('LINESTRING(0 0, 1 1, 2 2)'); @@ -13,20 +27,18 @@ public function testFromWKT() $this->assertEquals(3, $linestring->count()); } - public function testToWKT() + public function testToString() { + $linestring = new LineString($this->points); - $points = [new Point(0, 0), new Point(1, 1), new Point(2, 2)]; - $linestring = new LineString($points); - - $this->assertEquals('LINESTRING(0 0,1 1,2 2)', $linestring->toWKT()); + $this->assertEquals('0 0,1 1,2 2', (string)$linestring); } - public function testToString() + public function testJsonSerialize() { - $points = [new Point(0, 0), new Point(1, 1), new Point(2, 2)]; - $linestring = new LineString($points); + $lineString = new LineString($this->points); - $this->assertEquals('0 0,1 1,2 2', (string)$linestring); + $this->assertInstanceOf(\GeoJson\Geometry\LineString::class, $lineString->jsonSerialize()); + $this->assertSame('{"type":"LineString","coordinates":[[0,0],[1,1],[2,2]]}', json_encode($lineString)); } } diff --git a/tests/Geometries/MultiLineStringTest.php b/tests/Geometries/MultiLineStringTest.php index c3538da..f20c180 100644 --- a/tests/Geometries/MultiLineStringTest.php +++ b/tests/Geometries/MultiLineStringTest.php @@ -11,7 +11,7 @@ public function testFromWKT() $multilinestring = MultiLineString::fromWKT('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))'); $this->assertInstanceOf(MultiLineString::class, $multilinestring); - $this->assertEquals(2, $multilinestring->count()); + $this->assertSame(2, $multilinestring->count()); } public function testToWKT() @@ -28,6 +28,17 @@ public function testToWKT() $multilinestring = new MultiLineString([$collection]); - $this->assertEquals('MULTILINESTRING((0 0,1 0,1 1,0 1,0 0))', $multilinestring->toWKT()); + $this->assertSame('MULTILINESTRING((0 0,1 0,1 1,0 1,0 0))', $multilinestring->toWKT()); + } + + public function testJsonSerialize() + { + $multilinestring = MultiLineString::fromWKT('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))'); + + $this->assertInstanceOf(\GeoJson\Geometry\MultiLineString::class, $multilinestring->jsonSerialize()); + $this->assertSame( + '{"type":"MultiLineString","coordinates":[[[0,0],[1,1],[2,1]],[[3,2],[2,3],[4,5]]]}', + json_encode($multilinestring) + ); } } diff --git a/tests/Geometries/MultiPointTest.php b/tests/Geometries/MultiPointTest.php index cd66f05..0427246 100644 --- a/tests/Geometries/MultiPointTest.php +++ b/tests/Geometries/MultiPointTest.php @@ -21,4 +21,14 @@ public function testToWKT() $this->assertEquals('MULTIPOINT((0 0),(1 0),(1 1))', $multipoint->toWKT()); } + + public function testJsonSerialize() + { + $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; + + $multipoint = new MultiPoint($collection); + + $this->assertInstanceOf(\GeoJson\Geometry\MultiPoint::class, $multipoint->jsonSerialize()); + $this->assertSame('{"type":"MultiPoint","coordinates":[[0,0],[0,1],[1,1]]}', json_encode($multipoint)); + } } diff --git a/tests/Geometries/MultiPolygonTest.php b/tests/Geometries/MultiPolygonTest.php index c64f433..c0b326e 100644 --- a/tests/Geometries/MultiPolygonTest.php +++ b/tests/Geometries/MultiPolygonTest.php @@ -7,17 +7,12 @@ class MultiPolygonTest extends BaseTestCase { - public function testFromWKT() - { - $polygon = MultiPolygon::fromWKT( - 'MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))' - ); - $this->assertInstanceOf(MultiPolygon::class, $polygon); - - $this->assertEquals(2, $polygon->count()); - } + /** + * @var MultiPolygon + */ + private $multiPolygon; - public function testToWKT() + protected function setUp() { $collection1 = new LineString( [ @@ -54,11 +49,34 @@ public function testToWKT() $polygon2 = new Polygon([$collection3]); - $multipolygon = new MultiPolygon([$polygon1, $polygon2]); + $this->multiPolygon = new MultiPolygon([$polygon1, $polygon2]); + } + + public function testFromWKT() + { + $polygon = MultiPolygon::fromWKT( + 'MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))' + ); + $this->assertInstanceOf(MultiPolygon::class, $polygon); + + $this->assertEquals(2, $polygon->count()); + } + + public function testToWKT() + { $this->assertEquals( 'MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0),(10 10,20 10,20 20,10 20,10 10)),((100 100,200 100,200 200,100 200,100 100)))', - $multipolygon->toWKT() + $this->multiPolygon->toWKT() + ); + } + + public function testJsonSerialize() + { + $this->assertInstanceOf(\GeoJson\Geometry\MultiPolygon::class, $this->multiPolygon->jsonSerialize()); + $this->assertSame( + '{"type":"MultiPolygon","coordinates":[[[[0,0],[0,1],[1,1],[1,0],[0,0]],[[10,10],[10,20],[20,20],[20,10],[10,10]]],[[[100,100],[100,200],[200,200],[200,100],[100,100]]]]}', + json_encode($this->multiPolygon) ); } } diff --git a/tests/Geometries/PointTest.php b/tests/Geometries/PointTest.php index f749042..173e3c7 100644 --- a/tests/Geometries/PointTest.php +++ b/tests/Geometries/PointTest.php @@ -52,4 +52,12 @@ public function testToString() $this->assertEquals('1.3 2', (string)$point); } + + public function testJsonSerialize() + { + $point = new Point(1.2, 3.4); + + $this->assertInstanceOf(\GeoJson\Geometry\Point::class, $point->jsonSerialize()); + $this->assertSame('{"type":"Point","coordinates":[1.2,3.4]}', json_encode($point)); + } } diff --git a/tests/Geometries/PolygonTest.php b/tests/Geometries/PolygonTest.php index e06d3f4..f822414 100644 --- a/tests/Geometries/PolygonTest.php +++ b/tests/Geometries/PolygonTest.php @@ -6,15 +6,9 @@ class PolygonTest extends BaseTestCase { - public function testFromWKT() - { - $polygon = Polygon::fromWKT('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))'); - $this->assertInstanceOf(Polygon::class, $polygon); - - $this->assertEquals(2, $polygon->count()); - } + private $polygon; - public function testToWKT() + protected function setUp() { $collection = new LineString( [ @@ -26,8 +20,30 @@ public function testToWKT() ] ); - $polygon = new Polygon([$collection]); + $this->polygon = new Polygon([$collection]); + } + + + public function testFromWKT() + { + $polygon = Polygon::fromWKT('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))'); + $this->assertInstanceOf(Polygon::class, $polygon); + + $this->assertEquals(2, $polygon->count()); + } + + public function testToWKT() + { + $this->assertEquals('POLYGON((0 0,1 0,1 1,0 1,0 0))', $this->polygon->toWKT()); + } + + public function testJsonSerialize() + { + $this->assertInstanceOf(\GeoJson\Geometry\Polygon::class, $this->polygon->jsonSerialize()); + $this->assertSame( + '{"type":"Polygon","coordinates":[[[0,0],[0,1],[1,1],[1,0],[0,0]]]}', + json_encode($this->polygon) + ); - $this->assertEquals('POLYGON((0 0,1 0,1 1,0 1,0 0))', $polygon->toWKT()); } }