tests for GeoUtils

pull/1/head
Mike Barry 2021-04-25 16:29:47 -04:00
rodzic b7bfef4ad1
commit 1c6ae5bee2
7 zmienionych plików z 112 dodań i 16 usunięć

Wyświetl plik

@ -32,18 +32,17 @@ public class OsmInputFile {
public double[] getBounds() {
try (var input = new FileInputStream(file)) {
var datinput = new DataInputStream(input);
int headersize = datinput.readInt();
if (headersize > 65536) {
throw new FileFormatException(
"Unexpectedly long header 65536 bytes. Possibly corrupt file " + file);
var dataInput = new DataInputStream(input);
int headerSize = dataInput.readInt();
if (headerSize > 65536) {
throw new FileFormatException("Unexpectedly long header 65536 bytes. Possibly corrupt file " + file);
}
byte[] buf = datinput.readNBytes(headersize);
byte[] buf = dataInput.readNBytes(headerSize);
BlobHeader header = BlobHeader.parseFrom(buf);
if (!header.getType().equals("OSMHeader")) {
throw new IllegalArgumentException("Expecting OSMHeader got " + header.getType());
}
buf = datinput.readNBytes(header.getDatasize());
buf = dataInput.readNBytes(header.getDatasize());
Blob blob = Blob.parseFrom(buf);
ByteString data = null;
if (blob.hasRaw()) {

Wyświetl plik

@ -79,7 +79,8 @@ public class GeoUtils {
}
};
static final double QUANTIZED_WORLD_SIZE = Math.pow(2, 31);
private static final double QUANTIZED_WORLD_SIZE = Math.pow(2, 31);
private static final long LOWER_32_BIT_MASK = (1L << 32) - 1L;
public static long encodeFlatLocation(double lon, double lat) {
double worldX = getWorldX(lon);
@ -88,4 +89,12 @@ public class GeoUtils {
long y = (long) (worldY * QUANTIZED_WORLD_SIZE);
return (x << 32) | y;
}
public static double decodeWorldY(long encoded) {
return ((double) (encoded & LOWER_32_BIT_MASK)) / QUANTIZED_WORLD_SIZE;
}
public static double decodeWorldX(long encoded) {
return ((double) (encoded >> 32)) / QUANTIZED_WORLD_SIZE;
}
}

Wyświetl plik

@ -8,13 +8,14 @@ public class TileCoord {
private final int z;
private TileCoord(int encoded, int x, int y, int z) {
assert z <= 14;
this.encoded = encoded;
this.x = x;
this.y = y;
this.z = z;
}
public static TileCoord of(int x, int y, int z) {
public static TileCoord ofXYZ(int x, int y, int z) {
return new TileCoord(encode(x, y, z), x, y, z);
}

Wyświetl plik

@ -1,5 +0,0 @@
package com.onthegomap.flatmap;
public class GeoUtilsTest {
}

Wyświetl plik

@ -4,6 +4,8 @@ import com.onthegomap.flatmap.geo.GeoUtils;
import java.util.ArrayList;
import java.util.List;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateSequence;
import org.locationtech.jts.geom.CoordinateXY;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.MultiPoint;
@ -11,6 +13,7 @@ import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.geom.util.AffineTransformation;
import org.locationtech.jts.geom.util.GeometryTransformer;
public class TestUtils {
@ -20,7 +23,7 @@ public class TestUtils {
public static List<Coordinate> newCoordinateList(double... coords) {
List<Coordinate> result = new ArrayList<>(coords.length / 2);
for (int i = 0; i < coords.length; i += 2) {
result.add(new Coordinate(coords[i], coords[i + 1]));
result.add(new CoordinateXY(coords[i], coords[i + 1]));
}
return result;
}
@ -30,7 +33,7 @@ public class TestUtils {
}
public static Point newPoint(double x, double y) {
return GeoUtils.gf.createPoint(new Coordinate(x, y));
return GeoUtils.gf.createPoint(new CoordinateXY(x, y));
}
public static MultiPoint newMultiPoint(Point... points) {
@ -44,4 +47,19 @@ public class TestUtils {
public static GeometryCollection newGeometryCollection(Geometry... geoms) {
return GeoUtils.gf.createGeometryCollection(geoms);
}
public static Geometry round(Geometry input) {
return new GeometryTransformer() {
@Override
protected CoordinateSequence transformCoordinates(
CoordinateSequence coords, Geometry parent) {
for (int i = 0; i < coords.size(); i++) {
for (int j = 0; j < coords.getDimension(); j++) {
coords.setOrdinate(i, j, Math.round(coords.getOrdinate(i, j) * 1e5) / 1e5);
}
}
return coords;
}
}.transform(input);
}
}

Wyświetl plik

@ -0,0 +1,40 @@
package com.onthegomap.flatmap.geo;
import static com.onthegomap.flatmap.TestUtils.newPoint;
import static com.onthegomap.flatmap.TestUtils.round;
import static com.onthegomap.flatmap.geo.GeoUtils.ProjectWorldCoords;
import static com.onthegomap.flatmap.geo.GeoUtils.decodeWorldX;
import static com.onthegomap.flatmap.geo.GeoUtils.decodeWorldY;
import static com.onthegomap.flatmap.geo.GeoUtils.encodeFlatLocation;
import static com.onthegomap.flatmap.geo.GeoUtils.getWorldX;
import static com.onthegomap.flatmap.geo.GeoUtils.getWorldY;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
public class GeoUtilsTest {
@ParameterizedTest
@CsvSource({
"0,0, 0.5,0.5",
"0, -180, 0, 0.5",
"0, " + (180 - 1e-7) + ", 1, 0.5",
"45, 0, 0.5, 0.359725",
"-45, 0, 0.5, " + (1 - 0.359725)
})
public void testWorldCoords(double lat, double lon, double worldX, double worldY) {
assertEquals(worldY, getWorldY(lat), 1e-5);
assertEquals(worldX, getWorldX(lon), 1e-5);
long encoded = encodeFlatLocation(lon, lat);
assertEquals(worldY, decodeWorldY(encoded), 1e-5);
assertEquals(worldX, decodeWorldX(encoded), 1e-5);
Point input = newPoint(lon, lat);
Point expected = newPoint(worldX, worldY);
Geometry actual = ProjectWorldCoords.transform(input);
assertEquals(round(expected), round(actual));
}
}

Wyświetl plik

@ -0,0 +1,34 @@
package com.onthegomap.flatmap.geo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
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",
})
public void testTileCoord(int x, int y, int z, int encoded) {
TileCoord coord1 = TileCoord.ofXYZ(x, y, z);
assertEquals(encoded, coord1.encoded());
TileCoord coord2 = TileCoord.decode(encoded);
assertEquals(coord1.x(), coord2.x());
assertEquals(coord1.y(), coord2.y());
assertEquals(coord1.z(), coord2.z());
assertEquals(coord1, coord2);
}
@Test
public void testThrowsPastZ14() {
assertThrows(AssertionError.class, () -> TileCoord.ofXYZ(0, 0, 15));
}
}