switch to new coord tools

master
Thomas Rudin 2018-12-18 11:12:31 +01:00
parent e14e7388fc
commit 27d2dbddad
10 changed files with 90 additions and 541 deletions

View File

@ -1,97 +0,0 @@
package io.rudin.minetest.tileserver;
import static io.rudin.minetest.tileserver.blockdb.tables.Blocks.BLOCKS;
import io.rudin.minetest.tileserver.config.Layer;
import io.rudin.minetest.tileserver.config.LayerConfig;
import io.rudin.minetest.tileserver.config.TileServerConfig;
import io.rudin.minetest.tileserver.query.YQueryBuilder;
import org.aeonbits.owner.ConfigFactory;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Record2;
import org.jooq.impl.DSL;
import com.google.inject.Guice;
import com.google.inject.Injector;
import io.rudin.minetest.tileserver.module.ConfigModule;
import io.rudin.minetest.tileserver.module.DBModule;
import io.rudin.minetest.tileserver.module.ServiceModule;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
import io.rudin.minetest.tileserver.util.CoordinateResolver.TileInfo;
public class StaticTileGen {
public static void main(String[] args) throws Exception {
// TODO create tiles in directory with static html index file
TileServerConfig cfg = ConfigFactory.create(TileServerConfig.class);
Injector injector = Guice.createInjector(
new ConfigModule(cfg),
new DBModule(cfg),
new ServiceModule(cfg)
);
DSLContext ctx = injector.getInstance(DSLContext.class);
TileRenderer tileRenderer = injector.getInstance(TileRenderer.class);
YQueryBuilder yQueryBuilder = injector.getInstance(YQueryBuilder.class);
LayerConfig layerConfig = injector.getInstance(LayerConfig.class);
Layer layer = layerConfig.layers.get(0);
Condition yCondition = yQueryBuilder.getCondition(layer);
Record2<Integer, Integer> result = ctx
.select(DSL.max(BLOCKS.POSX), DSL.min(BLOCKS.POSX))
.from(BLOCKS)
.where(yCondition)
.fetchOne();
Integer maxX = result.get(DSL.max(BLOCKS.POSX));
Integer minX = result.get(DSL.min(BLOCKS.POSX));
System.out.println("Max-X " + maxX + " Min-X: " + minX);
for (int zoom=CoordinateResolver.MAX_ZOOM; zoom>=CoordinateResolver.MIN_ZOOM; zoom--) {
int factor = (int)Math.pow(2, CoordinateResolver.ONE_TO_ONE_ZOOM - zoom);
int step = 16 * factor;
for (int x=minX; x<=maxX; x+=step) {
Record2<Integer, Integer> zrange = ctx
.select(DSL.max(BLOCKS.POSZ), DSL.min(BLOCKS.POSZ))
.from(BLOCKS)
.where(BLOCKS.POSX.eq(x))
.and(yCondition)
.fetchOne();
Integer maxZ = zrange.get(DSL.max(BLOCKS.POSZ));
Integer minZ = zrange.get(DSL.min(BLOCKS.POSZ));
if (maxZ == null || minZ == null)
continue;
for (int z=minZ; z<=maxZ; z+=step) {
TileInfo tileInfo = CoordinateResolver.fromCoordinates(x, z).toZoom(zoom);
//TileInfo minZoom = tileInfo.toZoom(CoordinateResolver.MIN_ZOOM);
long start = System.currentTimeMillis();
tileRenderer.render(layer, tileInfo.x, tileInfo.y, tileInfo.zoom);
long diff = System.currentTimeMillis() - start;
System.out.println("Tile: " + tileInfo.x + "/" + tileInfo.y + " @ " + tileInfo.zoom + " took " + diff + " ms");
}
}
}
}
}

View File

@ -20,6 +20,7 @@ import io.rudin.minetest.tileserver.config.TileServerConfig;
import io.rudin.minetest.tileserver.qualifier.MapDB;
import io.rudin.minetest.tileserver.query.YQueryBuilder;
import io.rudin.minetest.tileserver.service.MapBlockRenderService;
import io.rudin.minetest.tileserver.util.coordinate.*;
import org.jooq.DSLContext;
import org.jooq.Result;
import org.slf4j.Logger;
@ -27,15 +28,15 @@ import org.slf4j.LoggerFactory;
import io.rudin.minetest.tileserver.blockdb.tables.records.BlocksRecord;
import io.rudin.minetest.tileserver.service.TileCache;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
import io.rudin.minetest.tileserver.util.CoordinateResolver.MapBlockCoordinateInfo;
import io.rudin.minetest.tileserver.util.WhiteTile;
@Singleton
public class TileRenderer {
private static final Logger logger = LoggerFactory.getLogger(TileRenderer.class);
public static final int TILE_PIXEL_SIZE = 256;
@Inject
public TileRenderer(@MapDB DSLContext ctx, TileCache cache, MapBlockRenderService blockRenderer, TileServerConfig cfg, YQueryBuilder yQueryBuilder) {
this.ctx = ctx;
@ -61,7 +62,7 @@ public class TileRenderer {
.name("tileserver_render_time_seconds").help("Render time in seconds.").register();
public BufferedImage createTile() {
return new BufferedImage(CoordinateResolver.TILE_PIXEL_SIZE, CoordinateResolver.TILE_PIXEL_SIZE, BufferedImage.TYPE_INT_RGB);
return new BufferedImage(TILE_PIXEL_SIZE, TILE_PIXEL_SIZE, BufferedImage.TYPE_INT_RGB);
}
private final int DEFAULT_BLOCK_ZOOM = 13;
@ -81,30 +82,35 @@ public class TileRenderer {
}
}
MapBlockCoordinateInfo mapblockInfo = CoordinateResolver.fromTile(tileX, tileY, zoom);
Range<MapBlockCoordinate> mapBlocksRange = CoordinateFactory.getMapBlocksInTile(new TileCoordinate(tileX, tileY, zoom));
if (mapblockInfo.x > 2048 || mapblockInfo.x < -2048 || mapblockInfo.z > 2048 || mapblockInfo.z < -2048)
int max = Math.max(
Math.max(mapBlocksRange.pos1.x, mapBlocksRange.pos1.z),
Math.max(mapBlocksRange.pos2.x, mapBlocksRange.pos2.x)
);
int min = Math.min(
Math.min(mapBlocksRange.pos1.x, mapBlocksRange.pos1.z),
Math.min(mapBlocksRange.pos2.x, mapBlocksRange.pos2.x)
);
if (max > 2048 || min < -2048)
//Out of range...
return WhiteTile.getPNG();
if (zoom < DEFAULT_BLOCK_ZOOM) {
//TODO: fail-fast for regions without map-blocks -> white
int x1 = mapblockInfo.x;
int x2 = mapblockInfo.x + (int)mapblockInfo.width;
int z1 = mapblockInfo.z;
int z2 = (mapblockInfo.z *-1) + ((int)mapblockInfo.height);
long start = System.currentTimeMillis();
Result<BlocksRecord> firstResult = ctx
.selectFrom(BLOCKS)
.where(
BLOCKS.POSX.ge(Math.min(x1, x2))
.and(BLOCKS.POSX.le(Math.max(x1, x2)))
.and(BLOCKS.POSZ.ge(Math.min(z1, z2)))
.and(BLOCKS.POSZ.le(Math.max(z1, z2)))
BLOCKS.POSX.ge(Math.min(mapBlocksRange.pos1.x, mapBlocksRange.pos2.x))
.and(BLOCKS.POSX.le(Math.max(mapBlocksRange.pos1.x, mapBlocksRange.pos2.x)))
.and(BLOCKS.POSZ.ge(Math.min(mapBlocksRange.pos1.z, mapBlocksRange.pos2.z)))
.and(BLOCKS.POSZ.le(Math.max(mapBlocksRange.pos1.z, mapBlocksRange.pos2.z)))
.and(yQueryBuilder.getCondition(layer))
)
.limit(1)
@ -117,7 +123,9 @@ public class TileRenderer {
}
if (firstResult.isEmpty()) {
logger.debug("Fail-fast, got zero mapblock count for x=({})-({}) z=({})-({})", x1,x2, z1,z2);
logger.debug("Fail-fast, got zero mapblock count for x=({})-({}) z=({})-({})",
mapBlocksRange.pos1.x, mapBlocksRange.pos2.x,
mapBlocksRange.pos1.z, mapBlocksRange.pos2.z);
byte[] data = WhiteTile.getPNG();
@ -173,69 +181,26 @@ public class TileRenderer {
try {
final int HALF_TILE_PIXEL_SIZE = CoordinateResolver.TILE_PIXEL_SIZE / 2;
final int HALF_TILE_PIXEL_SIZE = TILE_PIXEL_SIZE / 2;
if (zoom > DEFAULT_BLOCK_ZOOM) {
//TODO: needed anymore?
//Zoom in
int nextZoom = zoom - 1;
int offsetNextZoomX = Math.abs(tileX % 2);
int offsetNextZoomY = Math.abs(tileY % 2);
int nextZoomX = (tileX - offsetNextZoomX) / 2;
int nextZoomY = (tileY - offsetNextZoomY) / 2;
BufferedImage tile = createTile();
Graphics2D graphics = tile.createGraphics();
//Get all quadrants
BufferedImage image = renderImage(layer, nextZoomX, nextZoomY, nextZoom);
BufferedImage quadrant = image.getSubimage(
HALF_TILE_PIXEL_SIZE * offsetNextZoomX,
HALF_TILE_PIXEL_SIZE * offsetNextZoomY,
HALF_TILE_PIXEL_SIZE,
HALF_TILE_PIXEL_SIZE
);
Image scaledInstance = quadrant.getScaledInstance(
CoordinateResolver.TILE_PIXEL_SIZE,
CoordinateResolver.TILE_PIXEL_SIZE,
Image.SCALE_FAST
);
graphics.drawImage(scaledInstance, 0, 0, CoordinateResolver.TILE_PIXEL_SIZE, CoordinateResolver.TILE_PIXEL_SIZE, null);
ByteArrayOutputStream output = new ByteArrayOutputStream(12000);
ImageIO.write(tile, "png", output);
//binary cache
byte[] data = output.toByteArray();
cache.put(layer.id, tileX, tileY, zoom, data);
if (tile == null)
logger.error("Got a null-tile @ {}/{}/{}", tileX, tileY, data);
return tile;
} else if (zoom < DEFAULT_BLOCK_ZOOM) {
if (zoom < DEFAULT_BLOCK_ZOOM) {
//Zoom out
BufferedImage tile = createTile();
//Pack 4 tiles from higher zoom into 1 tile
TileQuadrants quadrants = CoordinateFactory.getZoomedQuadrantsFromTile(new TileCoordinate(tileX, tileY, zoom));
int nextZoom = zoom + 1;
int nextZoomX = tileX * 2;
int nextZoomY = tileY * 2;
BufferedImage upperLeft = renderImage(layer, nextZoomX, nextZoomY, nextZoom);
BufferedImage upperRightImage = renderImage(layer, nextZoomX + 1, nextZoomY, nextZoom);
BufferedImage lowerLeftImage = renderImage(layer, nextZoomX, nextZoomY + 1, nextZoom);
BufferedImage lowerRightImage = renderImage(layer, nextZoomX + 1, nextZoomY + 1, nextZoom);
BufferedImage upperLeft = renderImage(layer, quadrants.upperLeft.x, quadrants.upperLeft.y, quadrants.upperLeft.zoom);
BufferedImage upperRightImage = renderImage(layer, quadrants.upperRight.x, quadrants.upperRight.y, quadrants.upperRight.zoom);
BufferedImage lowerLeftImage = renderImage(layer, quadrants.lowerLeft.x, quadrants.lowerLeft.y, quadrants.lowerLeft.zoom);
BufferedImage lowerRightImage = renderImage(layer, quadrants.lowerRight.x, quadrants.lowerRight.y, quadrants.lowerRight.zoom);
long start = System.currentTimeMillis();
@ -274,18 +239,18 @@ public class TileRenderer {
//Default zoom (13 == 1 mapblock with 16px wide blocks)
long start = System.currentTimeMillis();
MapBlockCoordinateInfo coordinateInfo = CoordinateResolver.fromTile(tileX, tileY, zoom);
Range<MapBlockCoordinate> coordinateRange = CoordinateFactory.getMapBlocksInTile(new TileCoordinate(tileX, tileY, zoom));
//16x16 mapblocks on a tile
BufferedImage image = createTile();
Graphics2D graphics = image.createGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, CoordinateResolver.TILE_PIXEL_SIZE, CoordinateResolver.TILE_PIXEL_SIZE);
graphics.fillRect(0, 0, TILE_PIXEL_SIZE, TILE_PIXEL_SIZE);
int mapblockX = coordinateInfo.x;
int mapblockZ = coordinateInfo.z;
int mapblockX = coordinateRange.pos1.x;
int mapblockZ = coordinateRange.pos1.z;
long now = System.currentTimeMillis();
long timingImageSetup = now - start;

View File

@ -1,13 +1,14 @@
package io.rudin.minetest.tileserver.job;
import com.google.common.util.concurrent.Striped;
import io.rudin.minetest.tileserver.TileRenderer;
import io.rudin.minetest.tileserver.config.Layer;
import io.rudin.minetest.tileserver.config.LayerConfig;
import io.rudin.minetest.tileserver.config.TileServerConfig;
import io.rudin.minetest.tileserver.qualifier.MapDB;
import io.rudin.minetest.tileserver.query.YQueryBuilder;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
import io.rudin.minetest.tileserver.util.coordinate.CoordinateFactory;
import io.rudin.minetest.tileserver.util.coordinate.MapBlockCoordinate;
import io.rudin.minetest.tileserver.util.coordinate.TileCoordinate;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Record2;
@ -18,8 +19,6 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.concurrent.locks.ReadWriteLock;
import static io.rudin.minetest.tileserver.blockdb.tables.Blocks.BLOCKS;
@Singleton
@ -96,10 +95,10 @@ public class InitialTileRendererJob implements Runnable {
double zProgress = (posz - minZ) / (double) zCount;
CoordinateResolver.TileInfo tileInfo = CoordinateResolver.fromCoordinates(posx, posz);
TileCoordinate tileCoordinate = CoordinateFactory.getTileCoordinateFromMapBlock(new MapBlockCoordinate(posx, posz));
try {
byte[] data = renderer.render(layer, tileInfo.x, tileInfo.y, CoordinateResolver.ONE_TO_ONE_ZOOM);
byte[] data = renderer.render(layer, tileCoordinate.x, tileCoordinate.y, tileCoordinate.zoom);
byteCount += data.length;
tileCount++;

View File

@ -19,11 +19,12 @@ import io.rudin.minetest.tileserver.qualifier.MapDB;
import io.rudin.minetest.tileserver.query.YQueryBuilder;
import io.rudin.minetest.tileserver.service.BlocksRecordService;
import io.rudin.minetest.tileserver.service.EventBus;
import io.rudin.minetest.tileserver.util.coordinate.CoordinateFactory;
import io.rudin.minetest.tileserver.util.coordinate.MapBlockCoordinate;
import io.rudin.minetest.tileserver.util.coordinate.TileCoordinate;
import org.jooq.*;
import io.rudin.minetest.tileserver.service.TileCache;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
import io.rudin.minetest.tileserver.util.CoordinateResolver.TileInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -97,7 +98,7 @@ public class UpdateChangedTilesJob implements Runnable {
private boolean running = false;
private String getTileKey(TileInfo tile){
private String getTileKey(TileCoordinate tile){
return "Tile:" + tile.x + "/" + tile.y + "/" + tile.zoom;
}
@ -256,25 +257,25 @@ public class UpdateChangedTilesJob implements Runnable {
Integer x = record.getPosx();
Integer z = record.getPosz();
TileInfo tileInfo = CoordinateResolver.fromCoordinates(x, z);
TileCoordinate tileCoordinate = CoordinateFactory.getTileCoordinateFromMapBlock(new MapBlockCoordinate(x, z));
for (int i = CoordinateResolver.MAX_ZOOM; i >= CoordinateResolver.MIN_ZOOM+2; i--) {
TileInfo zoomedTile = tileInfo.toZoom(i);
String tileKey = getTileKey(zoomedTile);
for (int i = CoordinateFactory.MAX_ZOOM; i >= 3; i--) {
String tileKey = getTileKey(tileCoordinate);
if (!updatedTileKeys.contains(tileKey)) {
//Generate tiles now
logger.debug("Rendering tile x={} y={} zoom={}", zoomedTile.x, zoomedTile.y, zoomedTile.zoom);
tileRenderer.render(layer, zoomedTile.x, zoomedTile.y, zoomedTile.zoom);
logger.debug("Rendering tile x={} y={} zoom={}", tileCoordinate.x, tileCoordinate.y, tileCoordinate.zoom);
tileRenderer.render(layer, tileCoordinate.x, tileCoordinate.y, tileCoordinate.zoom);
logger.debug("Dispatching tile-changed-event for tile: {}/{}", zoomedTile.x, zoomedTile.y);
logger.debug("Dispatching tile-changed-event for tile: {}/{}", tileCoordinate.x, tileCoordinate.y);
EventBus.TileChangedEvent event = new EventBus.TileChangedEvent();
event.layerId = layer.id;
event.x = zoomedTile.x;
event.y = zoomedTile.y;
event.zoom = zoomedTile.zoom;
event.x = tileCoordinate.x;
event.y = tileCoordinate.y;
event.zoom = tileCoordinate.zoom;
event.mapblockX = x;
event.mapblockZ = z;
eventBus.post(event);
@ -287,6 +288,9 @@ public class UpdateChangedTilesJob implements Runnable {
}
//zom out
tileCoordinate = CoordinateFactory.getZoomedOutTile(tileCoordinate);
}
}

View File

@ -4,7 +4,6 @@ import io.rudin.minetest.tileserver.blockdb.tables.pojos.Protector;
import io.rudin.minetest.tileserver.config.LayerConfig;
import io.rudin.minetest.tileserver.config.Layer;
import io.rudin.minetest.tileserver.qualifier.MapDB;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
import org.jooq.DSLContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -1,142 +0,0 @@
package io.rudin.minetest.tileserver.util;
public class CoordinateResolver {
public static final int TILE_PIXEL_SIZE = 256;
public static final int MAPBLOCK_PIXEL_SIZE = 16;
public static final int MAX_ZOOM = 13;
public static final int MIN_ZOOM = 1;
public static final int ONE_TO_ONE_ZOOM = 13; // 1 tile == 1 mapblock
/**
* Tile information
*/
public static class TileInfo {
public int x, y;
public int zoom;
public double width, height; //in tiles
public TileInfo toZoom(int zoom) {
TileInfo info = new TileInfo();
double deltaFactor = Math.pow(2, zoom - this.zoom);
info.zoom = zoom;
//info.x = (int)(this.x * deltaFactor) + (int)((this.x * deltaFactor) % 2);
//info.y = (int)(this.y * deltaFactor) + (int)((this.y * deltaFactor) % 2);
info.x = (int)Math.floor((double)this.x * deltaFactor);
info.y = (int)Math.floor((double)this.y * deltaFactor);
info.height = this.height / deltaFactor;
info.width = this.width / deltaFactor;
return info;
}
@Override
public String toString() {
return "TileInfo{" +
"x=" + x +
", y=" + y +
", zoom=" + zoom +
", width=" + width +
", height=" + height +
'}';
}
}
/**
* Get tile coordinates from mapblock coords
* @param x
* @param z
* @return
*/
public static TileInfo fromCoordinates(int x, int z) {
TileInfo info = new TileInfo();
info.zoom = ONE_TO_ONE_ZOOM;
info.x = x;
info.y = (z * -1) + 1;
info.height = 1;
info.width = 1;
return info;
}
public static class MapBlockCoordinateInfo {
public int x, z;
@Deprecated //area
public double width, height; //in map-blocks
@Override
public String toString() {
return "MapBlockCoordinateInfo{" +
"x=" + x +
", z=" + z +
", width=" + width +
", height=" + height +
'}';
}
}
/**
* An area defined by two mapblock "points"
*/
public static class MapBlockArea {
public MapBlockCoordinateInfo pos1, pos2;
}
public static MapBlockArea getMapBlockArea(int x, int y, int zoom){
MapBlockArea area = new MapBlockArea();
MapBlockCoordinateInfo pos1 = new MapBlockCoordinateInfo();
MapBlockCoordinateInfo pos2 = new MapBlockCoordinateInfo();
double factor = Math.pow(2, ONE_TO_ONE_ZOOM - zoom);
pos1.x = (int)(x * factor);
pos1.z = (int)((y-1) * factor * -1);
//TODOs
area.pos1 = pos1;
area.pos2 = pos2;
return area;
}
@Deprecated
public static MapBlockCoordinateInfo fromTile(int x, int y, int zoom) {
MapBlockCoordinateInfo info = new MapBlockCoordinateInfo();
/*
* Leaflet:
* Y
* X -> ||
* \/
*
* Minetest:
* Z
* X -> /\
* ||
*
*/
double factor = Math.pow(2, ONE_TO_ONE_ZOOM - zoom);
// tile with 1:1 map resolution
info.x = (int)(x * factor);
info.z = (int)((y-1) * factor * -1);
info.height = factor;
info.width = factor;
return info;
}
}

View File

@ -38,6 +38,22 @@ public class CoordinateFactory {
);
}
public static TileCoordinate getZoomedOutTile(TileCoordinate tile){
if (tile.zoom <= 1)
throw new IllegalArgumentException("invalid zoom: " + tile.zoom);
return new TileCoordinate(
(int)Math.floor(tile.x / 2.0),
(int)Math.floor(tile.y / 2.0),
tile.zoom - 1
);
}
/**
* Returns the zoomed in tile-quadrants
* @param tile
* @return
*/
public static TileQuadrants getZoomedQuadrantsFromTile(TileCoordinate tile){
if (tile.zoom >= MAX_ZOOM || tile.zoom < 1)
throw new IllegalArgumentException("invalid zoom: " + tile.zoom);

View File

@ -1,7 +1,5 @@
package io.rudin.minetest.tileserver.util.coordinate;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
public class TileCoordinate {
public TileCoordinate(int x, int y, int zoom){
this.x = x;

View File

@ -1,191 +0,0 @@
package io.rudin.minetest.tileserver;
import org.junit.Assert;
import org.junit.Test;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
import io.rudin.minetest.tileserver.util.CoordinateResolver.MapBlockCoordinateInfo;
import io.rudin.minetest.tileserver.util.CoordinateResolver.TileInfo;
public class CoordinateResolverTest {
@Test
public void testSimpleTiletoBlock() {
MapBlockCoordinateInfo blockInfo = CoordinateResolver.fromTile(1, 2, 9);
Assert.assertEquals(16, blockInfo.x);
Assert.assertEquals(-33, blockInfo.z);
Assert.assertEquals(16, blockInfo.height, 0.1);
Assert.assertEquals(16, blockInfo.width, 0.1);
blockInfo = CoordinateResolver.fromTile(2, 2, 9);
Assert.assertEquals(32, blockInfo.x);
Assert.assertEquals(-33, blockInfo.z);
Assert.assertEquals(16, blockInfo.height, 0.1);
Assert.assertEquals(16, blockInfo.width, 0.1);
}
@Test
public void testZoomedTile() {
MapBlockCoordinateInfo blockInfo = CoordinateResolver.fromTile(0, 0, 13);
Assert.assertEquals(0, blockInfo.x);
Assert.assertEquals(-1, blockInfo.z);
Assert.assertEquals(1, blockInfo.height, 0.1);
Assert.assertEquals(1, blockInfo.width, 0.1);
blockInfo = CoordinateResolver.fromTile(1, 2, 13);
Assert.assertEquals(1, blockInfo.x);
Assert.assertEquals(-3, blockInfo.z);
Assert.assertEquals(1, blockInfo.height, 0.1);
Assert.assertEquals(1, blockInfo.width, 0.1);
}
@Test
public void testSimpleBlockToTile() {
TileInfo tileInfo = CoordinateResolver.fromCoordinates(16, -32);
Assert.assertEquals(13, tileInfo.zoom);
Assert.assertEquals(1, tileInfo.width, 0.1);
Assert.assertEquals(1, tileInfo.height, 0.1);
Assert.assertEquals(16, tileInfo.x);
Assert.assertEquals(33, tileInfo.y);
tileInfo = CoordinateResolver.fromCoordinates(32, -32);
Assert.assertEquals(13, tileInfo.zoom);
Assert.assertEquals(1, tileInfo.width, 0.1);
Assert.assertEquals(1, tileInfo.height, 0.1);
Assert.assertEquals(32, tileInfo.x);
Assert.assertEquals(33, tileInfo.y);
tileInfo = CoordinateResolver.fromCoordinates(33, -32);
Assert.assertEquals(13, tileInfo.zoom);
Assert.assertEquals(1, tileInfo.width, 0.1);
Assert.assertEquals(1, tileInfo.height, 0.1);
Assert.assertEquals(33, tileInfo.x);
Assert.assertEquals(33, tileInfo.y);
}
@Test
public void testTileZoomOut() {
TileInfo tileInfo = CoordinateResolver.fromCoordinates(32, -32);
Assert.assertEquals(13, tileInfo.zoom);
Assert.assertEquals(1, tileInfo.width, 0.1);
Assert.assertEquals(1, tileInfo.height, 0.1);
Assert.assertEquals(32, tileInfo.x);
Assert.assertEquals(33, tileInfo.y);
tileInfo = tileInfo.toZoom(12); //zoom out
Assert.assertEquals(12, tileInfo.zoom);
Assert.assertEquals(2, tileInfo.width, 0.1);
Assert.assertEquals(2, tileInfo.height, 0.1);
Assert.assertEquals(16, tileInfo.x);
Assert.assertEquals(16, tileInfo.y);
tileInfo = tileInfo.toZoom(11); //zoom out
Assert.assertEquals(11, tileInfo.zoom);
Assert.assertEquals(4, tileInfo.width, 0.1);
Assert.assertEquals(4, tileInfo.height, 0.1);
Assert.assertEquals(8, tileInfo.x);
Assert.assertEquals(8, tileInfo.y);
tileInfo = tileInfo.toZoom(10); //zoom out
Assert.assertEquals(10, tileInfo.zoom);
Assert.assertEquals(8, tileInfo.width, 0.1);
Assert.assertEquals(8, tileInfo.height, 0.1);
Assert.assertEquals(4, tileInfo.x);
Assert.assertEquals(4, tileInfo.y);
tileInfo = tileInfo.toZoom(9); //zoom out
Assert.assertEquals(9, tileInfo.zoom);
Assert.assertEquals(16, tileInfo.width, 0.1);
Assert.assertEquals(16, tileInfo.height, 0.1);
Assert.assertEquals(2, tileInfo.x);
Assert.assertEquals(2, tileInfo.y);
}
@Test
public void testTileZoomIn() {
TileInfo tileInfo = CoordinateResolver.fromCoordinates(32, -32).toZoom(9);
Assert.assertEquals(9, tileInfo.zoom);
Assert.assertEquals(16, tileInfo.width, 0.1);
Assert.assertEquals(16, tileInfo.height, 0.1);
Assert.assertEquals(2, tileInfo.x);
Assert.assertEquals(2, tileInfo.y);
tileInfo = tileInfo.toZoom(10); //zoom in
Assert.assertEquals(10, tileInfo.zoom);
Assert.assertEquals(8, tileInfo.width, 0.1);
Assert.assertEquals(8, tileInfo.height, 0.1);
Assert.assertEquals(4, tileInfo.x);
Assert.assertEquals(4, tileInfo.y);
}
/*
Zoom: 9
__ __ __ __
|0 |1 |2 |3 |
|_0|_0|_0|_0|
|0 |1 |2 |3 |
|_1|_1|_1|_1|
Zoom: 8
_____ _____
|0 |1 |
| | |
| | |
|____0|____0|
*/
@Test
public void testTileZoomIn2() {
TileInfo tileInfo = CoordinateResolver.fromCoordinates(16, -16).toZoom(9);
Assert.assertEquals(9, tileInfo.zoom);
Assert.assertEquals(16, tileInfo.width, 0.1);
Assert.assertEquals(16, tileInfo.height, 0.1);
Assert.assertEquals(1, tileInfo.x);
Assert.assertEquals(1, tileInfo.y);
tileInfo = tileInfo.toZoom(10); //zoom in
Assert.assertEquals(10, tileInfo.zoom);
Assert.assertEquals(8, tileInfo.width, 0.1);
Assert.assertEquals(8, tileInfo.height, 0.1);
Assert.assertEquals(2, tileInfo.x);
Assert.assertEquals(2, tileInfo.y);
tileInfo = tileInfo.toZoom(10); //zoom in
Assert.assertEquals(10, tileInfo.zoom);
Assert.assertEquals(8, tileInfo.width, 0.1);
Assert.assertEquals(8, tileInfo.height, 0.1);
Assert.assertEquals(2, tileInfo.x);
Assert.assertEquals(2, tileInfo.y);
}
@Test
public void dumpTileInfo(){
TileInfo tileInfo = CoordinateResolver.fromCoordinates(6, -10);//96/-160
System.out.println("Tile x=" + tileInfo.x + " y=" + tileInfo.y + " zoom=" + tileInfo.zoom);
}
@Test
public void testTileZoomIterate() {
TileInfo tileInfo = CoordinateResolver.fromCoordinates(32, -32);
for (int i=CoordinateResolver.MAX_ZOOM; i>=CoordinateResolver.MIN_ZOOM; i--) {
TileInfo zoomedTile = tileInfo.toZoom(i);
MapBlockCoordinateInfo coordinateInfo = CoordinateResolver.fromTile(zoomedTile.x, zoomedTile.y, zoomedTile.zoom);
System.out.println("Zoom: " + i);
System.out.println("+Tile: " + zoomedTile);
System.out.println("+MapBlock: " + coordinateInfo);
}
}
}

View File

@ -1,14 +1,13 @@
package io.rudin.minetest.tileserver;
import io.rudin.minetest.tileserver.accessor.Coordinate;
import io.rudin.minetest.tileserver.base.TileServerTest;
import io.rudin.minetest.tileserver.blockdb.tables.Blocks;
import io.rudin.minetest.tileserver.blockdb.tables.records.BlocksRecord;
import io.rudin.minetest.tileserver.job.UpdateChangedTilesJob;
import io.rudin.minetest.tileserver.qualifier.MapDB;
import io.rudin.minetest.tileserver.service.BlocksRecordService;
import io.rudin.minetest.tileserver.service.TileCache;
import io.rudin.minetest.tileserver.util.CoordinateResolver;
import io.rudin.minetest.tileserver.util.coordinate.CoordinateFactory;
import io.rudin.minetest.tileserver.util.coordinate.MapBlockCoordinate;
import io.rudin.minetest.tileserver.util.coordinate.TileCoordinate;
import org.jooq.DSLContext;
import org.junit.Assert;
import org.junit.Test;
@ -17,7 +16,6 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.util.List;
import static io.rudin.minetest.tileserver.blockdb.tables.Blocks.BLOCKS;
@ -33,26 +31,26 @@ public class UpdateChangedTilesTest extends TileServerTest {
@Test
public void test() throws IOException {
final int mapblockX = 0;
final int mapblockZ = 0;
CoordinateResolver.TileInfo coordinates = CoordinateResolver.fromCoordinates(mapblockX, mapblockZ);
logger.debug("Mapblock X={} Z={} / Tile X={} Y={} Zoom={} Width={} Height={}",
mapblockX, mapblockZ,
coordinates.x, coordinates.y, coordinates.zoom, coordinates.width, coordinates.height);
byte[] tile = tileCache.get(0, coordinates.x, coordinates.y, 13);
MapBlockCoordinate mapBlockCoordinate = new MapBlockCoordinate(0, 0);
TileCoordinate tileCoordinate = CoordinateFactory.getTileCoordinateFromMapBlock(mapBlockCoordinate);
logger.debug("Mapblock X={} Z={} / Tile X={} Y={} Zoom={}",
mapBlockCoordinate.x, mapBlockCoordinate.z,
tileCoordinate.x, tileCoordinate.y, tileCoordinate.zoom);
byte[] tile = tileCache.get(0, tileCoordinate.x, tileCoordinate.y, tileCoordinate.zoom);
Assert.assertNull(tile);
logger.debug("First result: {}", changedTilesJob.updateChangedTiles());
tile = tileCache.get(0, coordinates.x, coordinates.y, 13);
tile = tileCache.get(0, tileCoordinate.x, tileCoordinate.y, tileCoordinate.zoom);
Assert.assertNotNull(tile);
BlocksRecord block = ctx.selectFrom(BLOCKS)
.where(BLOCKS.POSX.eq(mapblockX).and(BLOCKS.POSY.eq(0).and(BLOCKS.POSZ.eq(mapblockZ))))
.where(BLOCKS.POSX.eq(mapBlockCoordinate.x).and(BLOCKS.POSY.eq(0).and(BLOCKS.POSZ.eq(mapBlockCoordinate.z))))
.fetchOne();
block.setMtime(System.currentTimeMillis());
@ -60,7 +58,7 @@ public class UpdateChangedTilesTest extends TileServerTest {
logger.debug("Second result: {}", changedTilesJob.updateChangedTiles());
tile = tileCache.get(0, coordinates.x, coordinates.y, 13);
tile = tileCache.get(0, tileCoordinate.x, tileCoordinate.y, tileCoordinate.zoom);
Assert.assertNotNull(tile);