Skip to content

Commit

Permalink
Fix non vectorized LineString decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
mactrem committed Jun 15, 2024
1 parent 8e5cc19 commit 53665d3
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
32 changes: 24 additions & 8 deletions java/src/main/java/com/mlt/decoder/GeometryDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public static GeometryColumn decodeGeometryColumn(
List<Integer> numParts = null;
List<Integer> numRings = null;
List<Integer> vertexOffsets = null;
List<Integer> mortonVertexBuffer = null;
List<Integer> vertexList = null;
for (var i = 0; i < numStreams - 1; i++) {
var geometryStreamMetadata = StreamMetadataDecoder.decode(tile, offset);
Expand Down Expand Up @@ -109,6 +108,12 @@ public static Geometry[] decodeGeometry(GeometryColumn geometryColumn) {

var vertexBuffer = geometryColumn.vertexList.stream().mapToInt(i -> i).toArray();

var containsPolygon =
geometryColumn.geometryTypes.stream()
.anyMatch(
g ->
g == GeometryType.POLYGON.ordinal()
|| g == GeometryType.MULTIPOLYGON.ordinal());
// TODO: refactor redundant code
for (var geometryType : geometryTypes) {
if (geometryType.equals(GeometryType.POINT.ordinal())) {
Expand Down Expand Up @@ -146,17 +151,21 @@ public static Geometry[] decodeGeometry(GeometryColumn geometryColumn) {
geometries[geometryCounter++] = geometryFactory.createMultiPoint(points);
}
} else if (geometryType.equals(GeometryType.LINESTRING.ordinal())) {
var numVertices =
containsPolygon
? ringOffsets.get(ringOffsetsCounter++)
: partOffsets.get(partOffsetCounter++);

if (vertexOffsets == null || vertexOffsets.length == 0) {
var numVertices = partOffsets.get(partOffsetCounter++);
var vertices = getLineString(vertexBuffer, vertexBufferOffset, numVertices, false);
vertexBufferOffset += numVertices * 2;
geometries[geometryCounter++] = geometryFactory.createLineString(vertices);
} else {
var numVertices = partOffsets.get(partOffsetCounter++);
var vertices =
decodeDictionaryEncodedLineString(
vertexBuffer, vertexOffsets, vertexOffsetsOffset, numVertices, false);
vertexOffsetsOffset += numVertices;

geometries[geometryCounter++] = geometryFactory.createLineString(vertices);
}
} else if (geometryType.equals(GeometryType.POLYGON.ordinal())) {
Expand Down Expand Up @@ -193,15 +202,23 @@ public static Geometry[] decodeGeometry(GeometryColumn geometryColumn) {
var lineStrings = new LineString[numLineStrings];
if (vertexOffsets == null || vertexOffsets.length == 0) {
for (var i = 0; i < numLineStrings; i++) {
var numVertices = partOffsets.get(partOffsetCounter++);
var numVertices =
containsPolygon
? ringOffsets.get(ringOffsetsCounter++)
: partOffsets.get(partOffsetCounter++);

var vertices = getLineString(vertexBuffer, vertexBufferOffset, numVertices, false);
lineStrings[i] = geometryFactory.createLineString(vertices);
vertexBufferOffset += numVertices * 2;
}
geometries[geometryCounter++] = geometryFactory.createMultiLineString(lineStrings);
} else {
for (var i = 0; i < numLineStrings; i++) {
var numVertices = partOffsets.get(partOffsetCounter++);
var numVertices =
containsPolygon
? ringOffsets.get(ringOffsetsCounter++)
: partOffsets.get(partOffsetCounter++);

var vertices =
decodeDictionaryEncodedLineString(
vertexBuffer, vertexOffsets, vertexOffsetsOffset, numVertices, false);
Expand Down Expand Up @@ -275,8 +292,7 @@ public static Geometry[] decodeGeometryVectorized(GeometryVector geometryVector)
var vertexBufferOffset = 0;
var vertexOffsetsOffset = 0;

GeometryVector.MortonSettings mortonSettings =
geometryVector.mortonSettings.isPresent() ? geometryVector.mortonSettings.get() : null;
GeometryVector.MortonSettings mortonSettings = geometryVector.mortonSettings.orElse(null);
var topologyVector = geometryVector.topologyVector;
var geometryOffsets = topologyVector.geometryOffsets();
var partOffsets = topologyVector.partOffsets();
Expand Down Expand Up @@ -362,7 +378,7 @@ public static Geometry[] decodeGeometryVectorized(GeometryVector geometryVector)
vertices = getLineString(vertexBuffer, vertexBufferOffset, numVertices, false);
vertexBufferOffset += numVertices * 2;
} else {
/** Currently only 2D coordinates are supported in this implementation */
/* Currently only 2D coordinates are supported in this implementation */
vertices =
geometryVector.vertexBufferType == GeometryVector.VertexBufferType.VEC_2
? decodeDictionaryEncodedLineString(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.nio.IntBuffer;
import java.util.Iterator;
import java.util.Optional;
import org.jetbrains.annotations.NotNull;
import org.locationtech.jts.geom.Geometry;

public class GeometryVector implements Iterable<Geometry> {
Expand Down Expand Up @@ -134,6 +135,7 @@ public int getGeometryType(int index) {
}

public boolean containsPolygonGeometry() {
// TODO: get rid of this by only checking for the presence of partOffsets and ringOffsets?
if (geometryTypes != null) {
for (int i = 0; i < numGeometries; i++) {
if (geometryTypes.get(i) == GeometryType.POLYGON.ordinal()
Expand All @@ -149,7 +151,7 @@ public boolean containsPolygonGeometry() {
}

@Override
public Iterator<Geometry> iterator() {
public @NotNull Iterator<Geometry> iterator() {
return new Iterator<>() {
private int index = 0;
private Geometry[] geometries;
Expand All @@ -162,7 +164,7 @@ public boolean hasNext() {
@Override
public Geometry next() {
if (geometries == null) {
// TODO: implement lazy decoding
// TODO: implement lazy materialization
geometries = GeometryDecoder.decodeGeometryVectorized(GeometryVector.this);
}
return geometries[index++];
Expand Down
12 changes: 12 additions & 0 deletions java/src/test/java/com/mlt/decoder/MltDecoderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ public void decodeMlTile_Z6() throws IOException {
testTileSequential(tileId, TestSettings.OMT_MVT_PATH);
}

@Test
public void decodeMlTile_Z10() throws IOException {
var tileId = String.format("%s_%s_%s", 10, 532, 684);
testTileSequential(tileId, TestSettings.OMT_MVT_PATH);
}

@Test
public void decodeMlTile_Z13() throws IOException {
var tileId = String.format("%s_%s_%s", 13, 4265, 5467);
testTileSequential(tileId, TestSettings.OMT_MVT_PATH);
}

@Test
@Disabled
// java.lang.IllegalArgumentException: Invalid number of points in LineString (found 1 - must be 0
Expand Down

0 comments on commit 53665d3

Please sign in to comment.