-
Notifications
You must be signed in to change notification settings - Fork 475
Fix WKTWriter invalid dimensional EMPTY tokens for nested empty geometries #1225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -731,6 +731,17 @@ private void appendOrdinateText(EnumSet<Ordinate> outputOrdinates, Writer writer | |
| writer.append(WKTConstants.M); | ||
| } | ||
|
|
||
| /** | ||
| * Appends the {@code EMPTY} token, inserting a separator after any dimensional | ||
| * marker written by {@link #appendOrdinateText}. | ||
| */ | ||
| private void appendEmptyText(EnumSet<Ordinate> outputOrdinates, Writer writer) throws IOException { | ||
| if (outputOrdinates.contains(Ordinate.Z) || outputOrdinates.contains(Ordinate.M)) { | ||
| writer.write(" "); | ||
| } | ||
| writer.write(WKTConstants.EMPTY); | ||
| } | ||
|
|
||
| /** | ||
| * Appends all members of a <code>CoordinateSequence</code> to the stream. Each {@code Coordinate} is separated from | ||
| * another using a colon, the ordinates of a {@code Coordinate} are separated by a space. | ||
|
|
@@ -748,7 +759,7 @@ private void appendSequenceText(CoordinateSequence seq, EnumSet<Ordinate> output | |
| throws IOException | ||
| { | ||
| if (seq.size() == 0) { | ||
| writer.write(WKTConstants.EMPTY); | ||
| appendEmptyText(outputOrdinates, writer); | ||
| } | ||
| else { | ||
| if (indentFirst) indent(useFormatting, level, writer); | ||
|
|
@@ -785,7 +796,7 @@ private void appendPolygonText( | |
| throws IOException | ||
| { | ||
| if (polygon.isEmpty()) { | ||
| writer.write(WKTConstants.EMPTY); | ||
| appendEmptyText(outputOrdinates, writer); | ||
| } | ||
| else { | ||
| if (indentFirst) indent(useFormatting, level, writer); | ||
|
|
@@ -817,7 +828,7 @@ private void appendMultiPointText( | |
| throws IOException | ||
| { | ||
| if (multiPoint.getNumGeometries() == 0) { | ||
| writer.write(WKTConstants.EMPTY); | ||
| appendEmptyText(outputOrdinates, writer); | ||
| } | ||
| else { | ||
| writer.write("("); | ||
|
|
@@ -850,7 +861,7 @@ private void appendMultiLineStringText(MultiLineString multiLineString, EnumSet< | |
| throws IOException | ||
| { | ||
| if (multiLineString.getNumGeometries() == 0) { | ||
| writer.write(WKTConstants.EMPTY); | ||
| appendEmptyText(outputOrdinates, writer); | ||
| } | ||
| else { | ||
| int level2 = level; | ||
|
|
@@ -885,7 +896,7 @@ private void appendMultiPolygonText( | |
| throws IOException | ||
| { | ||
| if (multiPolygon.getNumGeometries() == 0) { | ||
| writer.write(WKTConstants.EMPTY); | ||
| appendEmptyText(outputOrdinates, writer); | ||
| } | ||
| else { | ||
| int level2 = level; | ||
|
|
@@ -920,7 +931,7 @@ private void appendGeometryCollectionText( | |
| throws IOException | ||
| { | ||
| if (geometryCollection.getNumGeometries() == 0) { | ||
| writer.write(WKTConstants.EMPTY); | ||
| appendEmptyText(outputOrdinates, writer); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All six instance |
||
| } | ||
| else { | ||
| int level2 = level; | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dimensional EMPTY belongs here, not in |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -199,4 +199,42 @@ public void testWktLineStringZM() throws ParseException { | |
| assertEquals(7.0, lineZM.getPointN(1).getCoordinate().getZ()); | ||
| assertEquals(8.0, lineZM.getPointN(1).getCoordinate().getM()); | ||
| } | ||
|
|
||
| /** | ||
| * Nested empty geometries with dimensional markers must keep the marker and | ||
| * {@code EMPTY} as separate tokens so that {@link WKTReader} can parse the output. | ||
| */ | ||
| public void testWriteNestedEmptyDimensionalGeometry() throws ParseException { | ||
| WKTReader reader = new WKTReader(); | ||
| WKTWriter writer4 = new WKTWriter(4); | ||
|
|
||
| Geometry geometryZ = reader.read( | ||
| "GEOMETRYCOLLECTION Z (" | ||
| + "LINESTRING Z (0 0 1, 1 1 2), " | ||
| + "MULTILINESTRING Z EMPTY)"); | ||
| String writtenZ = writer4.write(geometryZ); | ||
| assertTrue(writtenZ.contains("MULTILINESTRING Z EMPTY")); | ||
| assertFalse(writtenZ.contains("ZEMPTY")); | ||
| reader.read(writtenZ); | ||
|
Comment on lines
+211
to
+218
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exact #1223 repro for Z (and the M / ZM siblings below), plus a
Optional, non-blocking: one top-level |
||
|
|
||
| WKTWriter writerM = new WKTWriter(3); | ||
| writerM.setOutputOrdinates(Ordinate.createXYM()); | ||
| Geometry geometryM = reader.read( | ||
| "GEOMETRYCOLLECTION M (" | ||
| + "LINESTRING M (0 0 1, 1 1 2), " | ||
| + "MULTILINESTRING M EMPTY)"); | ||
| String writtenM = writerM.write(geometryM); | ||
| assertTrue(writtenM.contains("MULTILINESTRING M EMPTY")); | ||
| assertFalse(writtenM.contains("MEMPTY")); | ||
| reader.read(writtenM); | ||
|
|
||
| Geometry geometryZM = reader.read( | ||
| "GEOMETRYCOLLECTION ZM (" | ||
| + "LINESTRING ZM (0 0 1 2, 1 1 2 3), " | ||
| + "MULTILINESTRING ZM EMPTY)"); | ||
| String writtenZM = writer4.write(geometryZM); | ||
| assertTrue(writtenZM.contains("MULTILINESTRING ZM EMPTY")); | ||
| assertFalse(writtenZM.contains("ZMEMPTY")); | ||
| reader.read(writtenZM); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right cut.
appendOrdinateTextwritesZ/M/ZMwith no trailing space, and existing goldens pin non-empty WKT asPOINT Z(1 1 1), notZ (. Do not “fix” this by adding a trailing space on the ordinate marker — that would change every dimensional token.Spacing only before
EMPTYwhen Z or M is present also keeps XY asPOINT EMPTY: the tagged writer already wrote the space after the type, so this helper must not add a second one.