Skip to content

Commit

Permalink
fixed parsing of PolyhedralSurface to Solid
Browse files Browse the repository at this point in the history
  • Loading branch information
clausnagel committed Dec 3, 2023
1 parent 35fc5c4 commit 1c30186
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ private Geometry<?> read(ByteBuffer buffer) throws GeometryException {
geometry = readMultiLineString(buffer);
break;
case WKBConstants.MULTIPOLYGON:
case WKBConstants.POLYHEDRALSURFACE:
geometry = readMultiPolygon(buffer);
break;
case WKBConstants.POLYHEDRALSURFACE:
geometry = readSolid(buffer);
break;
case WKBConstants.GEOMETRYCOLLECTION:
geometry = readGeometryCollection(buffer);
break;
Expand Down Expand Up @@ -113,6 +115,21 @@ private Polygon readPolygon(ByteBuffer buffer, int dimension) {
return Polygon.of(shell, holes);
}

private Polygon[] readPolygons(ByteBuffer buffer) throws GeometryException {
int size = buffer.getInt();
Polygon[] polygons = new Polygon[size];

for (int i = 0; i < size; i++) {
Geometry<?> geometry = read(buffer);
if (!(geometry instanceof Polygon)) {
throw new GeometryException("Expected Polygon but found " + geometry.getGeometryType() + ".");
}
polygons[i] = (Polygon) geometry;
}

return polygons;
}

private MultiPoint readMultiPoint(ByteBuffer buffer) throws GeometryException {
int size = buffer.getInt();
Point[] points = new Point[size];
Expand Down Expand Up @@ -144,33 +161,26 @@ private MultiLineString readMultiLineString(ByteBuffer buffer) throws GeometryEx
}

private MultiSurface readMultiPolygon(ByteBuffer buffer) throws GeometryException {
int size = buffer.getInt();
Polygon[] polygons = new Polygon[size];

for (int i = 0; i < size; i++) {
Geometry<?> geometry = read(buffer);
if (!(geometry instanceof Polygon)) {
throw new GeometryException("Expected Polygon but found " + geometry.getGeometryType() + ".");
}
polygons[i] = (Polygon) geometry;
}
return MultiSurface.of(readPolygons(buffer));
}

return MultiSurface.of(polygons);
private Solid readSolid(ByteBuffer buffer) throws GeometryException {
return Solid.of(CompositeSurface.of(readPolygons(buffer)));
}

private MultiSurface readGeometryCollection(ByteBuffer buffer) throws GeometryException {
private MultiSolid readGeometryCollection(ByteBuffer buffer) throws GeometryException {
int size = buffer.getInt();
List<Polygon> polygons = new ArrayList<>();
Solid[] solids = new Solid[size];

for (int i = 0; i < size; i++) {
Geometry<?> geometry = read(buffer);
if (!(geometry instanceof MultiSurface)) {
throw new GeometryException("Expected PolyhedralSurface but found " + geometry.getGeometryType() + ".");
if (!(geometry instanceof Solid)) {
throw new GeometryException("Expected Solid but found " + geometry.getGeometryType() + ".");
}
polygons.addAll(((MultiSurface) geometry).getPolygons());
solids[i] = (Solid) geometry;
}

return MultiSurface.of(polygons);
return MultiSolid.of(solids);
}

private List<Coordinate> getCoordinates(ByteBuffer buffer, int size, int dimension) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ private Geometry<?> read(StreamTokenizer tokenizer) throws GeometryException, IO
geometry = readMultiLineString(tokenizer, dimension);
break;
case WKTConstants.MULTIPOLYGON:
case WKTConstants.POLYHEDRALSURFACE:
geometry = readMultiPolygon(tokenizer, dimension);
break;
case WKTConstants.POLYHEDRALSURFACE:
geometry = readSolid(tokenizer, dimension);
break;
case WKTConstants.GEOMETRYCOLLECTION:
geometry = readGeometryCollection(tokenizer);
break;
Expand All @@ -92,10 +94,33 @@ private LineString readLineString(StreamTokenizer tokenizer, int dimension) thro
return LineString.of(getCoordinates(tokenizer, dimension));
}

private LinearRing readLinearRingText(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
private LinearRing readLinearRing(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
return LinearRing.of(getCoordinates(tokenizer, dimension));
}

private Polygon readPolygon(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
if (nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY)) {
return Polygon.empty();
}

LinearRing shell = readLinearRing(tokenizer, dimension);
List<LinearRing> holes = new ArrayList<>();
while (nextCloserOrComma(tokenizer).equals(COMMA)) {
holes.add(readLinearRing(tokenizer, dimension));
}

return Polygon.of(shell, holes);
}

private List<Polygon> readPolygons(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
List<Polygon> polygons = new ArrayList<>();
do {
polygons.add(readPolygon(tokenizer, dimension));
} while (nextCloserOrComma(tokenizer).equals(COMMA));

return polygons;
}

private MultiPoint readMultiPoint(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
if (nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY)) {
return MultiPoint.empty();
Expand All @@ -116,20 +141,6 @@ private MultiPoint readMultiPoint(StreamTokenizer tokenizer, int dimension) thro
return MultiPoint.of(points);
}

private Polygon readPolygon(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
if (nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY)) {
return Polygon.empty();
}

LinearRing shell = readLinearRingText(tokenizer, dimension);
List<LinearRing> holes = new ArrayList<>();
while (nextCloserOrComma(tokenizer).equals(COMMA)) {
holes.add(readLinearRingText(tokenizer, dimension));
}

return Polygon.of(shell, holes);
}

private MultiLineString readMultiLineString(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
if (nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY)) {
return MultiLineString.empty();
Expand All @@ -144,34 +155,32 @@ private MultiLineString readMultiLineString(StreamTokenizer tokenizer, int dimen
}

private MultiSurface readMultiPolygon(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
if (nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY)) {
return MultiSurface.empty();
}

List<Polygon> polygons = new ArrayList<>();
do {
polygons.add(readPolygon(tokenizer, dimension));
} while (nextCloserOrComma(tokenizer).equals(COMMA));

return MultiSurface.of(polygons);
return nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY) ?
MultiSurface.empty() :
MultiSurface.of(readPolygons(tokenizer, dimension));
}

private Solid readSolid(StreamTokenizer tokenizer, int dimension) throws GeometryException, IOException {
return nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY) ?
Solid.empty() :
Solid.of(CompositeSurface.of(readPolygons(tokenizer, dimension)));
}

private MultiSurface readGeometryCollection(StreamTokenizer tokenizer) throws GeometryException, IOException {
private MultiSolid readGeometryCollection(StreamTokenizer tokenizer) throws GeometryException, IOException {
if (nextEmptyOrOpener(tokenizer).equals(WKTConstants.EMPTY)) {
return MultiSurface.empty();
return MultiSolid.empty();
}

List<Polygon> polygons = new ArrayList<>();
List<Solid> solids = new ArrayList<>();
do {
Geometry<?> geometry = read(tokenizer);
if (!(geometry instanceof MultiSurface)) {
throw new GeometryException("Expected PolyhedralSurface but found " + geometry.getGeometryType() + ".");
if (!(geometry instanceof Solid)) {
throw new GeometryException("Expected Solid but found " + geometry.getGeometryType() + ".");
}
polygons.addAll(((MultiSurface) geometry).getPolygons());
solids.add((Solid) geometry);
} while (nextCloserOrComma(tokenizer).equals(COMMA));

return MultiSurface.of(polygons);
return MultiSolid.of(solids);
}

private Integer readSRID(StreamTokenizer tokenizer) throws GeometryException, IOException {
Expand Down Expand Up @@ -312,5 +321,3 @@ private StreamTokenizer createTokenizer(String wkt) {
return tokenizer;
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -119,21 +119,21 @@ void testParse3DMultiPolygon() throws Throwable {
@Test
@DisplayName("Test parse and write 3D PolyhedralSurface")
void testParse3DPolyhedralSurface() throws Throwable {
MultiSurface multiSurface1 = (MultiSurface) wktParser.parse(TEST_POLYHEDRALSURFACE_3D);
MultiSurface multiSurface2 = (MultiSurface) wkbParser.parse(TEST_POLYHEDRALSURFACE_3D_B);
assertEquals(wktWriter.write(Solid.of(CompositeSurface.of(multiSurface1.getPolygons()))), TEST_POLYHEDRALSURFACE_3D);
assertEquals(wktWriter.write(Solid.of(CompositeSurface.of(multiSurface2.getPolygons()))), TEST_POLYHEDRALSURFACE_3D);
assertEquals(wkbWriter.write(Solid.of(CompositeSurface.of(multiSurface2.getPolygons()))), TEST_POLYHEDRALSURFACE_3D_B);
Solid solid1 = (Solid) wktParser.parse(TEST_POLYHEDRALSURFACE_3D);
Solid solid2 = (Solid) wkbParser.parse(TEST_POLYHEDRALSURFACE_3D_B);
assertEquals(wktWriter.write(Solid.of(solid1.getShell())), TEST_POLYHEDRALSURFACE_3D);
assertEquals(wktWriter.write(Solid.of(solid2.getShell())), TEST_POLYHEDRALSURFACE_3D);
assertEquals(wkbWriter.write(Solid.of(solid2.getShell())), TEST_POLYHEDRALSURFACE_3D_B);
}

@Test
@DisplayName("Test parse and write 3D GeometryCollection(PolyhedralSurface)")
void testParse3DGeometryCollection() throws Throwable {
MultiSurface multiSurface1 = (MultiSurface) wktParser.parse(TEST_GEOMETRYCOLLECTION_3D);
MultiSurface multiSurface2 = (MultiSurface) wkbParser.parse(TEST_GEOMETRYCOLLECTION_3D_B);
assertEquals(multiSurface1.getVertexDimension(), 3);
assertEquals(multiSurface1.getPolygons().size(), 4);
assertEquals(multiSurface2.getVertexDimension(), 3);
assertEquals(multiSurface2.getPolygons().size(), 4);
MultiSolid multiSolid1 = (MultiSolid) wktParser.parse(TEST_GEOMETRYCOLLECTION_3D);
MultiSolid multiSolid2 = (MultiSolid) wkbParser.parse(TEST_GEOMETRYCOLLECTION_3D_B);
assertEquals(multiSolid1.getVertexDimension(), 3);
assertEquals(multiSolid1.getSolids().size(), 2);
assertEquals(multiSolid2.getVertexDimension(), 3);
assertEquals(multiSolid2.getSolids().size(), 2);
}
}

0 comments on commit 1c30186

Please sign in to comment.