Skip to content

Commit

Permalink
pr fixups
Browse files Browse the repository at this point in the history
  • Loading branch information
bdon committed Jan 31, 2023
1 parent a2b395d commit 21247da
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.carrotsearch.hppc.ByteArrayList;
import com.carrotsearch.hppc.ObjectArrayList;
import com.onthegomap.planetiler.reader.FileFormatException;
import com.onthegomap.planetiler.util.VarInt;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
Expand All @@ -17,10 +19,10 @@ public final class Pmtiles {
static final int HEADER_LEN = 127;

public static class Entry implements Comparable<Entry> {
long tileId;
long offset;
int length;
public int runLength;
private long tileId;
private long offset;
private int length;
private int runLength;

public Entry(long tileId, long offset, int length, int runLength) {
this.tileId = tileId;
Expand All @@ -29,6 +31,22 @@ public Entry(long tileId, long offset, int length, int runLength) {
this.runLength = runLength;
}

public long getTileId() {
return tileId;
}

public long getOffset() {
return offset;
}

public long getLength() {
return length;
}

public long getRunLength() {
return runLength;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down Expand Up @@ -67,12 +85,22 @@ public int compareTo(Entry that) {
}

public enum Compression {
UNKNOWN,
NONE,
GZIP;
UNKNOWN((byte) 0),
NONE((byte) 1),
GZIP((byte) 2);

public static Compression fromByte(byte val) {
return switch (val) {
private final byte value;

Compression(byte value) {
this.value = value;
}

public byte getValue() {
return this.value;
}

public static Compression fromByte(byte b) {
return switch (b) {
case 1 -> NONE;
case 2 -> GZIP;
default -> UNKNOWN;
Expand All @@ -81,8 +109,18 @@ public static Compression fromByte(byte val) {
}

public enum TileType {
UNKNOWN,
MVT;
UNKNOWN((byte) 0),
MVT((byte) 1);

private final byte value;

TileType(byte value) {
this.value = value;
}

public byte getValue() {
return this.value;
}

public static TileType fromByte(byte val) {
return switch (val) {
Expand Down Expand Up @@ -138,9 +176,9 @@ public byte[] toBytes() {
buf.putLong(numTileEntries);
buf.putLong(numTileContents);
buf.put((byte) (clustered ? 1 : 0));
buf.put((byte) internalCompression.ordinal());
buf.put((byte) tileCompression.ordinal());
buf.put((byte) tileType.ordinal());
buf.put(internalCompression.getValue());
buf.put(tileCompression.getValue());
buf.put(tileType.getValue());
buf.put(minZoom);
buf.put(maxZoom);
buf.putInt(minLonE7);
Expand All @@ -157,34 +195,41 @@ public static Header fromBytes(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
Header header = new Header();
byte[] magic = new byte[7];
buffer.get(magic);
System.out.println(magic);
header.specVersion = buffer.get();
header.rootDirOffset = buffer.getLong();
header.rootDirLength = buffer.getLong();
header.jsonMetadataOffset = buffer.getLong();
header.jsonMetadataLength = buffer.getLong();
header.leafDirectoriesOffset = buffer.getLong();
header.leafDirectoriesLength = buffer.getLong();
header.tileDataOffset = buffer.getLong();
header.tileDataLength = buffer.getLong();
header.numAddressedTiles = buffer.getLong();
header.numTileEntries = buffer.getLong();
header.numTileContents = buffer.getLong();
header.clustered = (buffer.get() == 0x1);
header.internalCompression = Compression.fromByte(buffer.get());
header.tileCompression = Compression.fromByte(buffer.get());
header.tileType = TileType.fromByte(buffer.get());
header.minZoom = buffer.get();
header.maxZoom = buffer.get();
header.minLonE7 = buffer.getInt();
header.minLatE7 = buffer.getInt();
header.maxLonE7 = buffer.getInt();
header.maxLatE7 = buffer.getInt();
header.centerZoom = buffer.get();
header.centerLonE7 = buffer.getInt();
header.centerLatE7 = buffer.getInt();
return header;

try {
buffer.get(magic);
if (!(new String(magic, StandardCharsets.UTF_8).equals("PMTiles"))) {
throw new FileFormatException("Incorrect magic number for PMTiles archive.");
}
header.specVersion = buffer.get();
header.rootDirOffset = buffer.getLong();
header.rootDirLength = buffer.getLong();
header.jsonMetadataOffset = buffer.getLong();
header.jsonMetadataLength = buffer.getLong();
header.leafDirectoriesOffset = buffer.getLong();
header.leafDirectoriesLength = buffer.getLong();
header.tileDataOffset = buffer.getLong();
header.tileDataLength = buffer.getLong();
header.numAddressedTiles = buffer.getLong();
header.numTileEntries = buffer.getLong();
header.numTileContents = buffer.getLong();
header.clustered = (buffer.get() == 0x1);
header.internalCompression = Compression.fromByte(buffer.get());
header.tileCompression = Compression.fromByte(buffer.get());
header.tileType = TileType.fromByte(buffer.get());
header.minZoom = buffer.get();
header.maxZoom = buffer.get();
header.minLonE7 = buffer.getInt();
header.minLatE7 = buffer.getInt();
header.maxLonE7 = buffer.getInt();
header.maxLatE7 = buffer.getInt();
header.centerZoom = buffer.get();
header.centerLonE7 = buffer.getInt();
header.centerLatE7 = buffer.getInt();
return header;
} catch (BufferUnderflowException e) {
throw new FileFormatException("Failed to read enough bytes for PMTiles header.");
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.onthegomap.planetiler.pmtiles;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.carrotsearch.hppc.ObjectArrayList;
import com.onthegomap.planetiler.reader.FileFormatException;
import org.junit.jupiter.api.Test;

class PmtilesTest {
Expand Down Expand Up @@ -63,6 +65,12 @@ void testRoundtripHeader() {
assertEquals(in.centerLatE7, out.centerLatE7);
}

@Test
void testBadHeader() {
assertThrows(FileFormatException.class, () -> Pmtiles.Header.fromBytes(new byte[0]));
assertThrows(FileFormatException.class, () -> Pmtiles.Header.fromBytes(new byte[127]));
}

@Test
void testRoundtripDirectoryMinimal() {
ObjectArrayList<Pmtiles.Entry> in = new ObjectArrayList<>();
Expand Down

0 comments on commit 21247da

Please sign in to comment.