diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 35f093f7..15bdeb38 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -7,6 +7,7 @@ use Countable; use GeoJson\Feature\FeatureCollection; use GeoJson\GeoJson; +use GeoJson\Geometry\GeometryCollection as GeometryGeometryCollection; use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; use Illuminate\Contracts\Support\Arrayable; use InvalidArgumentException; @@ -129,10 +130,19 @@ public static function fromJson($geoJson) $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if (!is_a($geoJson, FeatureCollection::class)) { - throw new InvalidGeoJsonException('Expected '.FeatureCollection::class.', got '.get_class($geoJson)); + if (is_a($geoJson, FeatureCollection::class)) { + return self::featureCollectionFromJson($geoJson); } + if (is_a($geoJson, GeometryGeometryCollection::class)) { + return self::geometryCollectionFromJson($geoJson); + } + + throw new InvalidGeoJsonException('Expected '.FeatureCollection::class.' or '.GeometryGeometryCollection::class.', got '.get_class($geoJson)); + } + + protected static function featureCollectionFromJson(FeatureCollection $geoJson) + { $set = []; foreach ($geoJson->getFeatures() as $feature) { $set[] = parent::fromJson($feature); @@ -141,6 +151,16 @@ public static function fromJson($geoJson) return new self($set); } + protected static function geometryCollectionFromJson(GeometryGeometryCollection $geoJson) + { + $set = []; + foreach ($geoJson->getGeometries() as $feature) { + $set[] = parent::fromJson($feature); + } + + return new self($set); + } + /** * Convert to GeoJson GeometryCollection that is jsonable to GeoJSON. * diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index a0d6f016..ea2f57f4 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -117,7 +117,7 @@ public function testArrayAccess() $geometryCollection[] = 1; } - public function testFromJson() + public function testFeatureCollectionFromJson() { $geometryCollection = GeometryCollection::fromJson('{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[3,4]}}]}'); $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); @@ -131,11 +131,22 @@ public function testInvalidGeoJsonException() { $this->assertException( \Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class, - sprintf('Expected %s, got %s', GeoJson\Feature\FeatureCollection::class, GeoJson\Geometry\Point::class) + sprintf('Expected %s or %s, got %s', GeoJson\Feature\FeatureCollection::class, GeoJson\Geometry\GeometryCollection::class, GeoJson\Geometry\Point::class) ); GeometryCollection::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); } + public function testGeometryCollectionFromJson() + { + $geometryCollection = GeometryCollection::fromJson('{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[30,30]},{"type":"LineString","coordinates":[[0,0],[10,10],[20,20]]}]}'); + $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); + $geometryCollectionPoints = $geometryCollection->getGeometries(); + $this->assertEquals(2, count($geometryCollectionPoints)); + $this->assertEquals(new Point(30, 30), $geometryCollectionPoints[0]); + $this->assertEquals(new LineString([new Point(0, 0), new Point(10, 10), new Point(20, 20)]), $geometryCollectionPoints[1]); + $this->assertJsonStringEqualsJsonString('{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[30,30]},{"type":"LineString","coordinates":[[0,0],[10,10],[20,20]]}]}', $geometryCollection->toJson()); + } + private function getGeometryCollection() { return new GeometryCollection([$this->getLineString(), $this->getPoint()]);