sort tiles by zoom ascending

pull/1/head
Mike Barry 2021-07-17 15:50:00 -04:00
rodzic 5660ee8f3f
commit c092afd184
3 zmienionych plików z 38 dodań i 12 usunięć

Wyświetl plik

@ -36,8 +36,7 @@ public record TileCoord(int encoded, int x, int y, int z) implements Comparable<
}
public static int decodeZ(int key) {
int result = key >> 28;
return result < 0 ? 16 + result : result;
return (key >> 28) + 8;
}
public static int decodeX(int key) {
@ -62,6 +61,15 @@ public record TileCoord(int encoded, int x, int y, int z) implements Comparable<
if (y >= max) {
y = max;
}
// since most significant bit is treated as the sign bit, make:
// z0-7 get encoded from 8 (0b1000) to 15 (0b1111)
// z8-14 get encoded from 0 (0b0000) to 6 (0b0110)
// so that encoded tile coordinates are ordered by zoom level
if (z < 8) {
z += 8;
} else {
z -= 8;
}
return (z << 28) | (x << 14) | y;
}

Wyświetl plik

@ -146,12 +146,18 @@ public class MbtilesWriter {
.setMaxzoom(config.maxzoom())
.setJson(layerStats.getTileStats());
int currentZoom = Integer.MIN_VALUE;
try (var batchedWriter = db.newBatchedTileWriter()) {
Mbtiles.TileEntry tile;
while ((tile = tiles.get()) != null) {
int z = tile.tile().z();
if (z > currentZoom) {
LOGGER.info("[mbtiles] Starting z" + z);
currentZoom = z;
}
batchedWriter.write(tile.tile(), tile.bytes());
stats.wroteTile(tile.tile().z(), tile.bytes().length);
tilesByZoom[tile.tile().z()].inc();
stats.wroteTile(z, tile.bytes().length);
tilesByZoom[z].inc();
}
}

Wyświetl plik

@ -2,6 +2,7 @@ package com.onthegomap.flatmap.geo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@ -11,22 +12,33 @@ public class TileCoordTest {
@ParameterizedTest
@CsvSource({
"0,0,0,0",
"0,0,1,268435456",
"0,1,1,268435457",
"1,1,1,268451841",
"100,100,14,-535232412",
"0,0,0",
"0,0,1",
"0,1,1",
"1,1,1",
"100,100,14",
})
public void testTileCoord(int x, int y, int z, int encoded) {
public void testTileCoord(int x, int y, int z) {
TileCoord coord1 = TileCoord.ofXYZ(x, y, z);
assertEquals(encoded, coord1.encoded());
TileCoord coord2 = TileCoord.decode(encoded);
TileCoord coord2 = TileCoord.decode(coord1.encoded());
assertEquals(coord1.x(), coord2.x());
assertEquals(coord1.y(), coord2.y());
assertEquals(coord1.z(), coord2.z());
assertEquals(coord1, coord2);
}
@Test
public void testTileSortOrder() {
int last = Integer.MIN_VALUE;
for (int z = 0; z <= 14; z++) {
int encoded = TileCoord.ofXYZ(0, 0, z).encoded();
if (encoded < last) {
fail("encoded value for z" + (z - 1) + " (" + last + ") is not less than z" + z + " (" + encoded + ")");
}
last = encoded;
}
}
@Test
public void testThrowsPastZ14() {
assertThrows(AssertionError.class, () -> TileCoord.ofXYZ(0, 0, 15));