diff --git a/src/Exception/GeometryIOException.php b/src/Exception/GeometryIOException.php index 024fe32c..e3abb157 100644 --- a/src/Exception/GeometryIOException.php +++ b/src/Exception/GeometryIOException.php @@ -35,6 +35,18 @@ public static function invalidEWKT() : GeometryIOException return new self('Invalid EWKT.'); } + /** + * @param string $context + * + * @return GeometryIOException + */ + public static function invalidGeoJSON(string $context) : GeometryIOException + { + $message = sprintf('Invalid GeoJSON: %s.', $context); + + return new static($message); + } + /** * @param int $wkbType * @@ -47,6 +59,18 @@ public static function unsupportedWKBType(int $wkbType) : GeometryIOException return new self($message); } + /** + * @param string $geojsonType + * + * @return GeometryIOException + */ + public static function unsupportedGeoJSONType(string $geojsonType) : GeometryIOException + { + $message = sprintf('Unsupported GeoJSON type: %s.', $geojsonType); + + return new static($message); + } + /** * @param string $geometryType * diff --git a/src/IO/GeoJSONReader.php b/src/IO/GeoJSONReader.php new file mode 100644 index 00000000..c238dd16 --- /dev/null +++ b/src/IO/GeoJSONReader.php @@ -0,0 +1,309 @@ +readGeoJSON($geojsonArray); + + return $geometry; + } + + /** + * @param array $geojson + * + * @return Geometry + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function readGeoJSON(array $geojson) : Geometry + { + if (! isset($geojson['type']) || ! is_string($geojson['type'])) { + throw GeometryIOException::invalidGeoJSON('Missing or Malformed "type" attribute.'); + } + + switch ($geojson['type']) { + case 'Feature': + return $this->readFeature($geojson); + + case 'FeatureCollection': + if (! isset($geojson['features']) || ! is_array($geojson['features'])) { + throw GeometryIOException::invalidGeoJSON('Missing or Malformed "FeatureCollection.features" attribute.'); + } + + $geometries = []; + + foreach ($geojson['features'] as $feature) { + $geometries[] = $this->readFeature($feature); + } + + return GeometryCollection::of(...$geometries); + + case 'Point': + case 'MultiPoint': + case 'LineString': + case 'MultiLineString': + case 'Polygon': + case 'MultiPolygon': + return $this->readGeometry($geojson); + + default: + throw GeometryIOException::unsupportedGeoJSONType($geojson['type']); + } + } + + /** + * @param array $feature + * + * @return Geometry + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function readFeature(array $feature) : Geometry + { + // Verify Type 'Feature' + if (! isset($feature['type']) || 'Feature' !== $feature['type']) { + throw GeometryIOException::invalidGeoJSON('Missing or Malformed "Feature.type" attribute.'); + } + + // Verify Geometry exists and is array + if (! isset($feature['geometry']) || ! is_array($feature['geometry'])) { + throw GeometryIOException::invalidGeoJSON('Missing or Malformed "Feature.geometry" attribute.'); + } + + return $this->readGeometry($feature['geometry']); + } + + /** + * @param array $geometry + * + * @return Geometry + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function readGeometry(array $geometry) : Geometry + { + // Verify Geometry `type` + if (! isset($geometry['type']) || ! is_string($geometry['type'])) { + throw GeometryIOException::invalidGeoJSON('Missing or Malformed "Geometry.type" attribute.'); + } + + $geoType = $geometry['type']; + + // Verify Geometry `coordinates` + if (! isset($geometry['coordinates']) || ! array($geometry['coordinates'])) { + throw GeometryIOException::invalidGeoJSON('Missing or Malformed "Geometry.coordinates" attribute.'); + } + + $geoCoords = $geometry['coordinates']; + + $hasZ = $this->hasZ($geoCoords); + $hasM = false; + $srid = 4326; + + $cs = new CoordinateSystem($hasZ, $hasM, $srid); + + switch ($geoType) { + case 'Point': + return $this->genPoint($cs, $geoCoords); + + case 'MultiPoint': + return $this->genMultiPoint($cs, $geoCoords); + + case 'LineString': + return $this->genLineString($cs, $geoCoords); + + case 'MultiLineString': + return $this->genMultiLineString($cs, $geoCoords); + + case 'Polygon': + return $this->genPolygon($cs, $geoCoords); + + case 'MultiPolygon': + return $this->genMultiPolygon($cs, $geoCoords); + } + + throw GeometryIOException::unsupportedGeoJSONType($geoType); + } + + /** + * [x, y] + * + * @param CoordinateSystem $cs + * @param array $coords + * + * @return Point + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function genPoint(CoordinateSystem $cs, array $coords) : Point + { + return new Point($cs, ...$coords); + } + + /** + * [[x, y], ...] + * + * @param CoordinateSystem $cs + * @param array $coords + * + * @return MultiPoint + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function genMultiPoint(CoordinateSystem $cs, array $coords) : MultiPoint + { + $points = []; + + foreach ($coords as $pointCoords) { + $points[] = $this->genPoint($cs, $pointCoords); + } + + return new MultiPoint($cs, ...$points); + } + + /** + * [[x, y], ...] + * + * @param CoordinateSystem $cs + * @param array $coords + * + * @return LineString + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function genLineString(CoordinateSystem $cs, array $coords) : LineString + { + $points = []; + + foreach ($coords as $pointCoords) { + $points[] = $this->genPoint($cs, $pointCoords); + } + + return new LineString($cs, ...$points); + } + + /** + * [[[x, y], ...], ...] + * + * @param CoordinateSystem $cs + * @param array $coords + * + * @return MultiLineString + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function genMultiLineString(CoordinateSystem $cs, array $coords) : MultiLineString + { + $lineStrings = []; + + foreach ($coords as $lineStringCoords) { + $lineStrings[] = $this->genLineString($cs, $lineStringCoords); + } + + return new MultiLineString($cs, ...$lineStrings); + } + + /** + * [[[x, y], ...], ...] + * + * @param CoordinateSystem $cs + * @param array $coords + * + * @return Polygon + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function genPolygon(CoordinateSystem $cs, array $coords) : Polygon + { + $lineStrings = []; + + foreach ($coords as $lineStringCoords) { + $lineStrings[] = $this->genLineString($cs, $lineStringCoords); + } + + return new Polygon($cs, ...$lineStrings); + } + + /** + * [[[x, y], ...], ...] + * + * @param CoordinateSystem $cs + * @param array $coords + * + * @return MultiPolygon + * + * @throws GeometryException If the GeoJSON file is invalid. + */ + private function genMultiPolygon(CoordinateSystem $cs, array $coords) : MultiPolygon + { + $polygons = []; + + foreach ($coords as $polygonCoords) { + $polygons[] = $this->genPolygon($cs, $polygonCoords); + } + + return new MultiPolygon($cs, ...$polygons); + } + + /** + * @param $coords + * + * @return bool + */ + private function hasZ(array $coords) + { + if (empty($coords)) { + return false; + } + + // At least one Geometry hasZ + if (! is_array($coords[0])) { + return 3 === count($coords); + } + + foreach ($coords as $coord) { + if ($this->hasZ($coord)) { + return true; + } + } + + return false; + } +} diff --git a/src/IO/GeoJSONWriter.php b/src/IO/GeoJSONWriter.php new file mode 100644 index 00000000..4f99851e --- /dev/null +++ b/src/IO/GeoJSONWriter.php @@ -0,0 +1,96 @@ +geometryType() === 'GeometryCollection') { + return $this->writeFeatureCollection($geometry); + } + + return $this->genGeoJSONString($this->formatGeoJSONGeometry($geometry)); + } + + /** + * @param Geometry $geometry + * + * @return array + * + * @throws GeometryIOException + */ + private function formatGeoJSONGeometry(Geometry $geometry) : array + { + $geometryType = $geometry->geometryType(); + $validGeometries = [ + 'Point', + 'MultiPoint', + 'LineString', + 'MultiLineString', + 'Polygon', + 'MultiPolygon' + ]; + + if (! in_array($geometryType, $validGeometries)) { + throw GeometryIOException::unsupportedGeometryType($geometry->geometryType()); + } + + return [ + 'type' => $geometryType, + 'coordinates' => $geometry->toArray() + ]; + } + + /** + * @param GeometryCollection $geometryCollection + * + * @return string + * + * @throws GeometryIOException + */ + private function writeFeatureCollection(GeometryCollection $geometryCollection) : string + { + $geojsonArray = [ + 'type' => 'FeatureCollection', + 'features' => [] + ]; + + foreach ($geometryCollection->geometries() as $geometry) { + $geojsonArray['features'][] = [ + 'type' => 'Feature', + 'geometry' => $this->formatGeoJSONGeometry($geometry) + ]; + } + + return $this->genGeoJSONString($geojsonArray); + } + + /** + * @param array $geojsonArray + * + * @return string + */ + private function genGeoJSONString(array $geojsonArray) : string + { + return json_encode($geojsonArray); + } +} \ No newline at end of file diff --git a/tests/IO/GeoJSONAbstractTest.php b/tests/IO/GeoJSONAbstractTest.php new file mode 100644 index 00000000..cad10e44 --- /dev/null +++ b/tests/IO/GeoJSONAbstractTest.php @@ -0,0 +1,407 @@ +providerGeometryPointGeoJSON(), + $this->providerGeometryMultiPointGeoJSON(), + $this->providerGeometryLineStringGeoJSON(), + $this->providerGeometryMultiLineStringGeoJSON(), + $this->providerGeometryPolygonGeoJSON(), + $this->providerGeometryMultiPolygonGeoJSON() + ); + } + + /** + * @return array + */ + public function providerFeatureGeoJSON() : array + { + return array_merge( + $this->providerFeaturePointGeoJSON(), + $this->providerFeatureMultiPointGeoJSON(), + $this->providerFeatureLineStringGeoJSON(), + $this->providerFeatureMultiLineStringGeoJSON(), + $this->providerFeaturePolygonGeoJSON(), + $this->providerFeatureMultiPolygonGeoJSON() + ); + } + + /** + * @return array + */ + public function providerFeatureCollectionGeoJSON() : array + { + return [ + [ + '{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[1,1]}},{"type":"Feature","geometry":{"type":"Point","coordinates":[1,3]}}]}', + [[1, 1], [1, 3]], + [false, false] + ], + [ + '{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[1,1,1]}},{"type":"Feature","geometry":{"type":"Point","coordinates":[1,3,2]}}]}', + [[1, 1, 1], [1, 3, 2]], + [true, true] + ] + ]; + } + + /** + * @return array + */ + public function providerGeometryPointGeoJSON() : array + { + return [ + [ + '{"type":"Point","coordinates":[]}', + [], + false + ], + [ + '{"type":"Point","coordinates":[1,2]}', + [1, 2], + false + ], + [ + '{"type":"Point","coordinates":[1,2,0]}', + [1, 2, 0], + true + ] + ]; + } + + /** + * @return array + */ + public function providerFeaturePointGeoJSON() : array + { + return [ + [ + '{"type":"Feature","geometry":{"type":"Point","coordinates":[]}}', + [], + false + ], + [ + '{"type":"Feature","geometry":{"type":"Point","coordinates":[1,2]}}', + [1, 2], + false + ], + [ + '{"type":"Feature","geometry":{"type":"Point","coordinates":[1,2,0]}}', + [1, 2, 0], + true + ] + ]; + } + + /** + * @return array + */ + public function providerGeometryMultiPointGeoJSON() : array + { + return [ + [ + '{"type":"MultiPoint","coordinates":[]}', + [], + false + ], + [ + '{"type":"MultiPoint","coordinates":[[1,0],[1,1]]}', + [[1, 0], [1, 1]], + false + ], + [ + '{"type":"MultiPoint","coordinates":[[1,0,1],[1,1,0]]}', + [[1, 0, 1], [1, 1, 0]], + true + ] + ]; + } + + /** + * @return array + */ + public function providerFeatureMultiPointGeoJSON() : array + { + return [ + [ + '{"type":"Feature","geometry":{"type":"MultiPoint","coordinates":[]}}', + [], + false + ], + [ + '{"type":"Feature","geometry":{"type":"MultiPoint","coordinates":[[1,0],[1,1]]}}', + [[1, 0], [1, 1]], + false + ], + [ + '{"type":"Feature","geometry":{"type":"MultiPoint","coordinates":[[1,0,1],[1,1,0]]}}', + [[1, 0, 1], [1, 1, 0]], + true + ] + ]; + } + + /** + * @return array + */ + public function providerGeometryLineStringGeoJSON() : array + { + return [ + [ + '{"type":"LineString","coordinates":[]}', + [], + false + ], + [ + '{"type":"LineString","coordinates":[[1,2],[3,4]]}', + [[1, 2], [3, 4]], + false + ], + [ + '{"type":"LineString","coordinates":[[1,2,1],[3,4,1]]}', + [[1, 2, 1], [3, 4, 1]], + true + ] + ]; + } + + /** + * @return array + */ + public function providerFeatureLineStringGeoJSON() : array + { + return [ + [ + '{"type":"Feature","geometry":{"type":"LineString","coordinates":[]}}', + [], + false + ], + [ + '{"type":"Feature","geometry":{"type":"LineString","coordinates":[[1,2],[3,4]]}}', + [[1, 2], [3, 4]], + false + ], + [ + '{"type":"Feature","geometry":{"type":"LineString","coordinates":[[1,2,1],[3,4,1]]}}', + [[1, 2, 1], [3, 4, 1]], + true + ] + ]; + } + + /** + * @return array + */ + public function providerGeometryMultiLineStringGeoJSON() : array + { + return [ + [ + '{"type":"MultiLineString","coordinates":[]}', + [], + false + ], + [ + '{"type":"MultiLineString","coordinates":[[[1,0],[1,1]],[[2,2],[1,3]]]}', + [[[1, 0], [1, 1]], [[2, 2], [1, 3]]], + false + ], + [ + '{"type":"MultiLineString","coordinates":[[[1,0,1],[1,1,1]],[[2,2,2],[1,3,3]]]}', + [[[1, 0, 1], [1, 1, 1]], [[2, 2, 2], [1, 3, 3]]], + true + ] + ]; + } + + /** + * @return array + */ + public function providerFeatureMultiLineStringGeoJSON() : array + { + return [ + [ + '{"type":"Feature","geometry":{"type":"MultiLineString","coordinates":[]}}', + [], + false + ], + [ + '{"type":"Feature","geometry":{"type":"MultiLineString","coordinates":[[[1,0,1],[1,1,1]],[[2,2,2],[1,3,3]]]}}', + [[[1, 0, 1], [1, 1, 1]], [[2, 2, 2], [1, 3, 3]]], + true + ] + ]; + } + + /** + * @return array + */ + public function providerGeometryPolygonGeoJSON() : array + { + return [ + [ + '{"type":"Polygon","coordinates":[]}', + [], + false + ], + [ + '{"type":"Polygon","coordinates":[[[0,0],[1,2],[3,4],[0,0]]]}', + [[[0, 0], [1, 2], [3, 4], [0, 0]]], + false + ], + [ + '{"type":"Polygon","coordinates":[[[1000,0],[1010,0],[1010,10],[1000,10],[1000,0]],[[1002,2],[1008,2],[1008,8],[1002,8],[1002,2]]]}', + [ + [[1000, 0], [1010, 0], [1010, 10], [1000, 10], [1000, 0]], + [[1002, 2], [1008, 2], [1008, 8], [1002, 8], [1002, 2]] + ], + false + ], + [ + '{"type":"Polygon","coordinates":[[[0,0,1],[1,2,1],[3,4,1],[0,0,1]]]}', + [[[0, 0, 1], [1, 2, 1], [3, 4, 1], [0, 0, 1]]], + true + ], + [ + '{"type":"Polygon","coordinates":[[[1000,0,1],[1010,0,1],[1010,10,1],[1000,10,1],[1000,0,1]],[[1002,2,2],[1008,2,2],[1008,8,2],[1002,8,2],[1002,2,2]]]}', + [ + [[1000, 0, 1], [1010, 0, 1], [1010, 10, 1], [1000, 10, 1], [1000, 0, 1]], + [[1002, 2, 2], [1008, 2, 2], [1008, 8, 2], [1002, 8, 2], [1002, 2, 2]] + ], + true + ], + ]; + } + + /** + * @return array + */ + public function providerFeaturePolygonGeoJSON() : array + { + return [ + [ + '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[]}}', + [], + false + ], + [ + '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[0,0],[1,2],[3,4],[0,0]]]}}', + [[[0, 0], [1, 2], [3, 4], [0, 0]]], + false + ], + [ + '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[1000,0],[1010,0],[1010,10],[1000,10],[1000,0]],[[1002,2],[1008,2],[1008,8],[1002,8],[1002,2]]]}}', + [ + [[1000, 0], [1010, 0], [1010, 10], [1000, 10], [1000, 0]], + [[1002, 2], [1008, 2], [1008, 8], [1002, 8], [1002, 2]] + ], + false + ], + [ + '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[0,0,1],[1,2,1],[3,4,1],[0,0,1]]]}}', + [[[0, 0, 1], [1, 2, 1], [3, 4, 1], [0, 0, 1]]], + true + ], + [ + '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[1000,0,1],[1010,0,1],[1010,10,1],[1000,10,1],[1000,0,1]],[[1002,2,2],[1008,2,2],[1008,8,2],[1002,8,2],[1002,2,2]]]}}', + [ + [[1000, 0, 1], [1010, 0, 1], [1010, 10, 1], [1000, 10, 1], [1000, 0, 1]], + [[1002, 2, 2], [1008, 2, 2], [1008, 8, 2], [1002, 8, 2], [1002, 2, 2]] + ], + true + ] + ]; + } + + /** + * @return array + */ + public function providerGeometryMultiPolygonGeoJSON() : array + { + return [ + [ + '{"type":"MultiPolygon","coordinates":[]}', + [], + false + ], + [ + '{"type":"MultiPolygon","coordinates":[[[[1,2],[1,2],[1,3],[1,2]]],[[[1000,0],[1010,0],[1010,10],[1000,10],[1000,0]],[[1002,2],[1008,2],[1008,8],[1002,8],[1002,2]]]]}', + [ + [ + [[1, 2], [1, 2], [1, 3], [1, 2]] + ], + [ + [[1000, 0], [1010, 0], [1010, 10], [1000, 10], [1000, 0]], + [[1002, 2], [1008, 2], [1008, 8], [1002, 8], [1002, 2]] + ] + ], + false + ], + [ + '{"type":"MultiPolygon","coordinates":[[[[1,2,1],[1,2,1],[1,3,1],[1,2,1]]],[[[1000,0,2],[1010,0,2],[1010,10,2],[1000,10,2],[1000,0,2]],[[1002,2,3],[1008,2,3],[1008,8,3],[1002,8,3],[1002,2,3]]]]}', + [ + [ + [[1, 2, 1], [1, 2, 1], [1, 3, 1], [1, 2, 1]] + ], + [ + [[1000, 0, 2], [1010, 0, 2], [1010, 10, 2], [1000, 10, 2], [1000, 0, 2]], + [[1002, 2, 3], [1008, 2, 3], [1008, 8, 3], [1002, 8, 3], [1002, 2, 3]] + ] + ], + true + ] + ]; + } + + /** + * @return array + */ + public function providerFeatureMultiPolygonGeoJSON() : array + { + return [ + [ + '{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[]}}', + [], + false + ], + [ + '{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[1,2],[1,2],[1,3],[1,2]]],[[[1000,0],[1010,0],[1010,10],[1000,10],[1000,0]],[[1002,2],[1008,2],[1008,8],[1002,8],[1002,2]]]]}}', + [ + [ + [[1, 2], [1, 2], [1, 3], [1, 2]] + ], + [ + [[1000, 0], [1010, 0], [1010, 10], [1000, 10], [1000, 0]], + [[1002, 2], [1008, 2], [1008, 8], [1002, 8], [1002, 2]] + ] + ], + false + ], + [ + '{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[1,2,1],[1,2,1],[1,3,1],[1,2,1]]],[[[1000,0,2],[1010,0,2],[1010,10,2],[1000,10,2],[1000,0,2]],[[1002,2,3],[1008,2,3],[1008,8,3],[1002,8,3],[1002,2,3]]]]}}', + [ + [ + [[1, 2, 1], [1, 2, 1], [1, 3, 1], [1, 2, 1]] + ], + [ + [[1000, 0, 2], [1010, 0, 2], [1010, 10, 2], [1000, 10, 2], [1000, 0, 2]], + [[1002, 2, 3], [1008, 2, 3], [1008, 8, 3], [1002, 8, 3], [1002, 2, 3]] + ] + ], + true + ] + ]; + } +} diff --git a/tests/IO/GeoJSONReaderTest.php b/tests/IO/GeoJSONReaderTest.php new file mode 100644 index 00000000..673a03c5 --- /dev/null +++ b/tests/IO/GeoJSONReaderTest.php @@ -0,0 +1,124 @@ +read($geojson); + $this->assertGeometryContents($geometry, $coords, $is3D, false, 4326); + } + + /** + * @return \Generator + */ + public function providerReadGeometry(): \Generator + { + foreach ($this->providerGeometryGeoJSON() as [$geojson, $coords, $is3D]) { + yield [$geojson, $coords, $is3D]; + yield [$this->alter($geojson), $coords, $is3D]; + } + } + + /** + * @dataProvider providerReadFeature + * + * @param string $geojson The GeoJSON to read. + * @param array $coords The expected Geometry coordinates. + * @param bool $is3D Whether the resulting Geometry has a Z coordinate. + * + * @return void + * + * @throws \Brick\Geo\Exception\GeometryException + */ + public function testReadFeature(string $geojson, array $coords, bool $is3D): void + { + $geometry = (new GeoJSONReader())->read($geojson); + $this->assertGeometryContents($geometry, $coords, $is3D, false, 4326); + } + + /** + * @return \Generator + */ + public function providerReadFeature(): \Generator + { + foreach ($this->providerFeatureGeoJSON() as [$geojson, $coords, $is3D]) { + yield [$geojson, $coords, $is3D]; + yield [$this->alter($geojson), $coords, $is3D]; + } + } + + /** + * @dataProvider providerReadFeatureCollection + * + * @param string $geojson The GeoJSON to read. + * @param array[] $coords The expected Point coordinates. + * @param bool[] $is3D Whether the resulting Point has a Z coordinate. + * + * @return void + * + * @throws \Brick\Geo\Exception\GeometryException + */ + public function testReadFeatureCollection( + string $geojson, + array $coords, + array $is3D + ): void { + $geometryCollection = (new GeoJSONReader())->read($geojson); + + $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); + + foreach ($geometryCollection->geometries() as $key => $geometry) { + $this->assertGeometryContents($geometry, $coords[$key], $is3D[$key], false, 4326); + } + } + + /** + * @return \Generator + */ + public function providerReadFeatureCollection(): \Generator + { + foreach ($this->providerFeatureCollectionGeoJSON() as [$geojson, $coords, $is3D]) { + yield [$geojson, $coords, $is3D]; + yield [$this->alter($geojson), $coords, $is3D]; + } + } + + /** + * Adds extra spaces to a GeoJSON string. + * + * The result is still a valid GeoJSON string, that the reader should be able to handle. + * + * @param string $geojson + * + * @return string + */ + private function alter(string $geojson): string + { + $search = [' ', '{', '}', ',']; + $replace = []; + + foreach ($search as $char) { + $replace[] = " $char "; + } + + $geojson = str_replace($search, $replace, $geojson); + + return $geojson; + } +} \ No newline at end of file diff --git a/tests/IO/GeoJSONWriterTest.php b/tests/IO/GeoJSONWriterTest.php new file mode 100644 index 00000000..50cac100 --- /dev/null +++ b/tests/IO/GeoJSONWriterTest.php @@ -0,0 +1,47 @@ +read($geojson); + $geometryGeoJSON = (new GeoJSONWriter())->write($geometry); + + $this->assertEquals($geojson, $geometryGeoJSON); + } + + /** + * @return \Generator + */ + public function providerWriteGeometry() : \Generator + { + foreach ($this->providerGeometryGeoJSON() as [$geojson, $coords, $is3D]) { + yield [$geojson]; + } + } + + /** + * @return \Generator + */ + public function providerWriteFeatureCollection() : \Generator + { + foreach ($this->providerFeatureCollectionGeoJSON() as [$geojson, $coords, $is3D]) { + yield [$geojson]; + } + } +} \ No newline at end of file