Skip to content

Commit

Permalink
GeoJSONReader: Fix 2D empty geometry creation
Browse files Browse the repository at this point in the history
  • Loading branch information
mwtoews committed May 15, 2023
1 parent 25316e9 commit 1f11986
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- LargestEmptyCircle: enhance boundary to allow any polygonal geometry (GH-859, Martin Davis)
- Build issues with RH (GH-860)
- OffsetCurve: fix EndCap parameter handling (GH-899, Martin Davis)
- GeoJSONReader: Fix 2D empty geometry creation (GH-???, Mike Taves)

## Changes in 3.11.2
2023-03-16
Expand Down
6 changes: 3 additions & 3 deletions src/io/GeoJSONReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ std::unique_ptr<geom::LineString> GeoJSONReader::readLineString(
const geom::Coordinate& c = readCoordinate(coord);
coordinates.push_back(c);
}
auto coordinateSequence = geometryFactory.getCoordinateSequenceFactory()->create(std::move(coordinates));
auto coordinateSequence = geometryFactory.getCoordinateSequenceFactory()->create(std::move(coordinates), 2u);
return geometryFactory.createLineString(std::move(coordinateSequence));
}

Expand All @@ -264,7 +264,7 @@ std::unique_ptr<geom::Polygon> GeoJSONReader::readPolygon(
const geom::Coordinate& c = readCoordinate(coord);
coordinates.push_back(c);
}
auto coordinateSequence = geometryFactory.getCoordinateSequenceFactory()->create(std::move(coordinates));
auto coordinateSequence = geometryFactory.getCoordinateSequenceFactory()->create(std::move(coordinates), 2u);
if (!shell) {
shell = geometryFactory.createLinearRing(std::move(coordinateSequence));
}
Expand Down Expand Up @@ -309,7 +309,7 @@ std::unique_ptr<geom::MultiLineString> GeoJSONReader::readMultiLineString(
const geom::Coordinate& c = readCoordinate(coord);
coordinates.push_back(geom::Coordinate{c.x, c.y});
}
auto coordinateSequence = geometryFactory.getCoordinateSequenceFactory()->create(std::move(coordinates));
auto coordinateSequence = geometryFactory.getCoordinateSequenceFactory()->create(std::move(coordinates), 2u);
lines.push_back(geometryFactory.createLineString(std::move(coordinateSequence)));
}
return geometryFactory.createMultiLineString(std::move(lines));
Expand Down
25 changes: 23 additions & 2 deletions tests/unit/io/GeoJSONReaderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void object::test<1>
std::string geojson { "{\"type\":\"Point\",\"coordinates\":[-117.0,33.0]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POINT (-117.000 33.000)", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON LineString
Expand All @@ -65,6 +66,7 @@ void object::test<2>
std::string geojson { "{\"type\":\"LineString\",\"coordinates\":[[102.0,0.0],[103.0,1.0],[104.0,0.0],[105.0,1.0]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("LINESTRING (102.000 0.000, 103.000 1.000, 104.000 0.000, 105.000 1.000)", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON Polygon with only an outer ring
Expand All @@ -76,6 +78,7 @@ void object::test<3>
std::string geojson { "{\"type\":\"Polygon\",\"coordinates\":[[[30,10],[40,40],[20,40],[10,20],[30,10]]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POLYGON ((30.000 10.000, 40.000 40.000, 20.000 40.000, 10.000 20.000, 30.000 10.000))", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON Point with an outer ring and an inner ring
Expand All @@ -87,6 +90,7 @@ void object::test<4>
std::string geojson { "{\"type\":\"Polygon\",\"coordinates\":[[[35,10],[45,45],[15,40],[10,20],[35,10]],[[20,30],[35,35],[30,20],[20,30]]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POLYGON ((35.000 10.000, 45.000 45.000, 15.000 40.000, 10.000 20.000, 35.000 10.000), (20.000 30.000, 35.000 35.000, 30.000 20.000, 20.000 30.000))", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON MultiPoint
Expand All @@ -98,6 +102,7 @@ void object::test<5>
std::string geojson { "{\"type\":\"MultiPoint\",\"coordinates\":[[10, 40], [40, 30], [20, 20], [30, 10]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("MULTIPOINT (10.000 40.000, 40.000 30.000, 20.000 20.000, 30.000 10.000)", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON MultiLineString
Expand All @@ -109,6 +114,7 @@ void object::test<6>
std::string geojson { "{\"type\":\"MultiLineString\",\"coordinates\":[[[10, 10], [20, 20], [10, 40]],[[40, 40], [30, 30], [40, 20], [30, 10]]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("MULTILINESTRING ((10.000 10.000, 20.000 20.000, 10.000 40.000), (40.000 40.000, 30.000 30.000, 40.000 20.000, 30.000 10.000))", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON MultiPolygon
Expand All @@ -120,6 +126,7 @@ void object::test<7>
std::string geojson { "{\"type\": \"MultiPolygon\", \"coordinates\": [[[[40, 40], [20, 45], [45, 30], [40, 40]]], [[[20, 35], [10, 30], [10, 10], [30, 5], [45, 20], [20, 35]], [[30, 20], [20, 15], [20, 25], [30, 20]]]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("MULTIPOLYGON (((40.000 40.000, 20.000 45.000, 45.000 30.000, 40.000 40.000)), ((20.000 35.000, 10.000 30.000, 10.000 10.000, 30.000 5.000, 45.000 20.000, 20.000 35.000), (30.000 20.000, 20.000 15.000, 20.000 25.000, 30.000 20.000)))", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON GeometryCollection
Expand All @@ -131,6 +138,7 @@ void object::test<8>
std::string geojson { "{\"type\": \"GeometryCollection\",\"geometries\": [{\"type\": \"Point\",\"coordinates\": [40, 10]},{\"type\": \"LineString\",\"coordinates\": [[10, 10], [20, 20], [10, 40]]},{\"type\": \"Polygon\",\"coordinates\": [[[40, 40], [20, 45], [45, 30], [40, 40]]]}]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("GEOMETRYCOLLECTION (POINT (40.000 10.000), LINESTRING (10.000 10.000, 20.000 20.000, 10.000 40.000), POLYGON ((40.000 40.000, 20.000 45.000, 45.000 30.000, 40.000 40.000)))", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON Feature with a Point and no properties
Expand All @@ -142,7 +150,7 @@ void object::test<9>
std::string geojson { "{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-117.0,33.0]}}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POINT (-117.000 33.000)", geom->toText());

ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON FeatureCollection with two Feature with Points and no properties
Expand All @@ -154,7 +162,7 @@ void object::test<10>
std::string geojson { "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-117.0,33.0]}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-122.0,45.0]}}]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("GEOMETRYCOLLECTION (POINT (-117.000 33.000), POINT (-122.000 45.000))", geom->toText());

ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON empty Point
Expand All @@ -166,6 +174,7 @@ void object::test<11>
std::string geojson { "{\"type\":\"Point\",\"coordinates\":[]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POINT EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON empty LineString
Expand All @@ -177,6 +186,7 @@ void object::test<12>
std::string geojson { "{\"type\":\"LineString\",\"coordinates\":[]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("LINESTRING EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON empty Polygon
Expand All @@ -188,6 +198,7 @@ void object::test<13>
std::string geojson { "{\"type\":\"Polygon\",\"coordinates\":[]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POLYGON EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON empty MultiPoint
Expand All @@ -199,6 +210,7 @@ void object::test<14>
std::string geojson { "{\"type\":\"MultiPoint\",\"coordinates\":[]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("MULTIPOINT EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON empty MultiLineString
Expand All @@ -210,6 +222,7 @@ void object::test<15>
std::string geojson { "{\"type\":\"MultiLineString\",\"coordinates\":[]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("MULTILINESTRING EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON empty MultiPolygon
Expand All @@ -221,6 +234,7 @@ void object::test<16>
std::string geojson { "{\"type\": \"MultiPolygon\", \"coordinates\": []}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("MULTIPOLYGON EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read an empty GeometryCollection
Expand All @@ -232,6 +246,7 @@ void object::test<17>
std::string geojson { "{\"type\": \"GeometryCollection\",\"geometries\": []}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("GEOMETRYCOLLECTION EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a Simple Feature
Expand All @@ -243,6 +258,7 @@ void object::test<18>
std::string geojson { "{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-117.0,33.0]}, \"properties\": {\"id\": 1, \"name\": \"one\", \"required\": true} }" };
geos::io::GeoJSONFeatureCollection features(geojsonreader.readFeatures(geojson));
ensure_equals(static_cast<size_t>(1), features.getFeatures().size());
ensure_equals(static_cast<size_t>(features.getFeatures()[0].getGeometry()->getCoordinateDimension()), 2u);
ensure_equals("POINT (-117.000 33.000)", features.getFeatures()[0].getGeometry()->toText());
ensure_equals(1.0, features.getFeatures()[0].getProperties().at("id").getNumber());
ensure_equals("one", features.getFeatures()[0].getProperties().at("name").getString());
Expand All @@ -258,6 +274,7 @@ void object::test<19>
std::string geojson { "{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-117.0,33.0]}, \"properties\": {\"id\": 1, \"name\": \"one\", \"items\": [1,2,3,4], \"nested\": {\"id\":2, \"name\":\"two\"}}}" };
geos::io::GeoJSONFeatureCollection features(geojsonreader.readFeatures(geojson));
ensure_equals(static_cast<size_t>(1), features.getFeatures().size());
ensure_equals(static_cast<size_t>(features.getFeatures()[0].getGeometry()->getCoordinateDimension()), 2u);
ensure_equals("POINT (-117.000 33.000)", features.getFeatures()[0].getGeometry()->toText());
ensure_equals(1.0, features.getFeatures()[0].getProperties().at("id").getNumber());
ensure_equals("one", features.getFeatures()[0].getProperties().at("name").getString());
Expand All @@ -282,6 +299,7 @@ void object::test<20>
"]}" };
geos::io::GeoJSONFeatureCollection features(geojsonreader.readFeatures(geojson));
ensure_equals(static_cast<size_t>(3), features.getFeatures().size());
ensure_equals(static_cast<size_t>(features.getFeatures()[0].getGeometry()->getCoordinateDimension()), 2u);
ensure_equals("POLYGON ((87.890 64.923, 76.992 55.178, 102.656 46.558, 115.312 60.413, 94.570 58.447, 87.890 64.923))", features.getFeatures()[0].getGeometry()->toText());
ensure_equals(1.0, features.getFeatures()[0].getProperties().at("id").getNumber());
ensure_equals("LINESTRING (1.406 48.690, 41.835 34.016, 22.500 13.923)", features.getFeatures()[1].getGeometry()->toText());
Expand All @@ -299,6 +317,7 @@ void object::test<21>
std::string geojson { "{\"type\":\"Polygon\",\"coordinates\":[[]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POLYGON EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON Point with only one coordinate
Expand Down Expand Up @@ -405,6 +424,7 @@ void object::test<27>
std::string geojson { "{\"type\":\"Polygon\",\"coordinates\":[[],[]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("POLYGON EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON empty MultiLineString with empty LineStrings
Expand All @@ -416,6 +436,7 @@ void object::test<28>
std::string geojson { "{\"type\":\"MultiLineString\",\"coordinates\":[[],[],[]]}" };
GeomPtr geom(geojsonreader.read(geojson));
ensure_equals("MULTILINESTRING EMPTY", geom->toText());
ensure_equals(static_cast<size_t>(geom->getCoordinateDimension()), 2u);
}

// Read a GeoJSON Point with too many coordinates
Expand Down

0 comments on commit 1f11986

Please sign in to comment.