Skip to content

Commit

Permalink
#369 monitor vector tiles poc - update poi location logic
Browse files Browse the repository at this point in the history
  • Loading branch information
vmarc committed Dec 16, 2023
1 parent 0f49a90 commit a0b6517
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 44 deletions.
34 changes: 18 additions & 16 deletions server/src/main/scala/kpn/core/poi/PoiLocation.scala
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package kpn.core.poi

import java.text.DecimalFormat

import kpn.server.analyzer.engine.tiles.domain.CoordinateTransform.worldXtoLon
import kpn.server.analyzer.engine.tiles.domain.CoordinateTransform.worldYtoLat
import kpn.server.analyzer.engine.tiles.domain.Rectangle
import kpn.server.analyzer.engine.tiles.domain.OldTile
import kpn.server.analyzer.engine.tiles.domain.Tile

import java.text.DecimalFormat

object PoiLocation {

val belgiumAndNetherlands: Rectangle = boundsFrom(new OldTile(10, 519, 331), new OldTile(10, 532, 349))
private val germany = boundsFrom(new OldTile(10, 535, 355), new OldTile(10, 536, 356))
private val germanyNorth = boundsFrom(new OldTile(10, 531, 330), new OldTile(10, 536, 338))
private val germanySouth = boundsFrom(new OldTile(10, 528, 338), new OldTile(10, 537, 344))
private val germanyEast = boundsFrom(new OldTile(10, 544, 331), new OldTile(10, 553, 341))
private val austria = boundsFrom(new OldTile(10, 552, 358), new OldTile(10, 555, 360))
private val france = boundsFrom(new OldTile(10, 518, 343), new OldTile(10, 520, 344))
private val spain = boundsFrom(new OldTile(10, 508, 380), new OldTile(10, 509, 381))
val belgiumAndNetherlands: Rectangle = latLonBoundsFrom(Tile(10, 519, 331), Tile(10, 532, 349))
private val germany = latLonBoundsFrom(Tile(10, 535, 355), Tile(10, 536, 356))
private val germanyNorth = latLonBoundsFrom(Tile(10, 531, 330), Tile(10, 536, 338))
private val germanySouth = latLonBoundsFrom(Tile(10, 528, 338), Tile(10, 537, 344))
private val germanyEast = latLonBoundsFrom(Tile(10, 544, 331), Tile(10, 553, 341))
private val austria = latLonBoundsFrom(Tile(10, 552, 358), Tile(10, 555, 360))
private val france = latLonBoundsFrom(Tile(10, 518, 343), Tile(10, 520, 344))
private val spain = latLonBoundsFrom(Tile(10, 508, 380), Tile(10, 509, 381))

val allBoundingBoxes: Seq[Rectangle] = Seq(
belgiumAndNetherlands,
Expand Down Expand Up @@ -48,12 +50,12 @@ object PoiLocation {
}
}

private def boundsFrom(topLeftTile: OldTile, bottomRightTile: OldTile): Rectangle = {
private def latLonBoundsFrom(topLeftTile: Tile, bottomRightTile: Tile): Rectangle = {
Rectangle(
xMin = topLeftTile.bounds.xMin,
xMax = bottomRightTile.bounds.xMax,
yMin = bottomRightTile.bounds.yMin,
yMax = topLeftTile.bounds.yMax
xMin = worldXtoLon(topLeftTile.worldXMin),
xMax = worldXtoLon(bottomRightTile.worldXMax),
yMin = worldYtoLat(bottomRightTile.worldYMax),
yMax = worldYtoLat(topLeftTile.worldYMin)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class MonitorTileTool(config: MonitorTileToolConfig) {
Log.context(s"${index + 1}/${tileDatas.size}") {
try {
val Array(z, x, y) = tileData.name.split("-").map(namePart => java.lang.Integer.parseInt(namePart))
val tile = new Tile(z, x, y)
val tile = Tile(z, x, y)
val tileRelationDatas = tileData.relationIds.flatMap { relationId =>
allRelationDatas.get(relationId)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import scala.math.toRadians

object OldTile {

def apply(z: Int, x: Int, y: Int): OldTile = {
new OldTile(z, x, y)
}

val EXTENT: Int = 4096

val CLIP_BUFFER: ClipBuffer = ClipBuffer(
Expand Down Expand Up @@ -66,14 +70,14 @@ class OldTile(val z: Int, val x: Int, val y: Int) { // TODO MAP make case class
}

val clipBounds: Rectangle = {
buildPoiClipBounds(OldTile.CLIP_BUFFER)
buildClipBounds(OldTile.CLIP_BUFFER)
}

val poiClipBounds: Rectangle = {
buildPoiClipBounds(OldTile.POI_CLIP_BUFFER)
buildClipBounds(OldTile.POI_CLIP_BUFFER)
}

private def buildPoiClipBounds(clipBuffer: ClipBuffer): Rectangle = {
private def buildClipBounds(clipBuffer: ClipBuffer): Rectangle = {
val xMin = bounds.xMin - ((bounds.xMax - bounds.xMin) * clipBuffer.left / OldTile.EXTENT)
val xMax = bounds.xMax + ((bounds.xMax - bounds.xMin) * clipBuffer.right / OldTile.EXTENT)
val yMin = bounds.yMin - ((bounds.yMax - bounds.yMin) * clipBuffer.bottom / OldTile.EXTENT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ class OldTileCache {
}

private def getTile(tileName: String, z: Int, x: Int, y: Int): OldTile = {
tiles.getOrElseUpdate(tileName, new OldTile(z, x, y))
tiles.getOrElseUpdate(tileName, OldTile(z, x, y))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ import org.locationtech.jts.geom.Coordinate

object Tile {

val EXTENT: Int = 256

val CLIP_BUFFER: ClipBuffer = ClipBuffer(
EXTENT * 14 / 256, // assume tile size 256 pixels, radius of node circle 14 pixels
EXTENT * 14 / 256,
EXTENT * 14 / 256,
EXTENT * 14 / 256
)

val POI_CLIP_BUFFER: ClipBuffer = ClipBuffer(
left = EXTENT * 17 / 256, // poi icon width 32 (32 / 2 + 1) -> 17
right = EXTENT * 17 / 256,
top = 0,
bottom = EXTENT * 39 / 256 // poi icon height 37 (37 + 2)
)


def apply(z: Int, x: Int, y: Int): Tile = {
new Tile(z, x, y)
}

// x part of the z-x-y tilename
def tileX(z: Int, worldX: Double): Int = {
val zoomFactor = 1 << z // the number of tiles across the map in each direction
Expand All @@ -27,6 +48,24 @@ class Tile(val z: Int, val x: Int, val y: Int) {
val worldYMin = y.toDouble / zoomFactor
val worldYMax = (y.toDouble + 1) / zoomFactor

val clipBounds: Rectangle = {
buildClipBounds(OldTile.CLIP_BUFFER)
}

val poiClipBounds: Rectangle = {
buildClipBounds(OldTile.POI_CLIP_BUFFER)
}

private def buildClipBounds(clipBuffer: ClipBuffer): Rectangle = {
val xMin = worldXMin - ((worldXMax - worldXMin) * clipBuffer.left / Tile.EXTENT)
val xMax = worldXMax + ((worldXMax - worldXMin) * clipBuffer.right / Tile.EXTENT)
val yMin = worldYMin - ((worldYMax - worldYMin) * clipBuffer.bottom / Tile.EXTENT)
val yMax = worldYMax + ((worldYMax - worldYMin) * clipBuffer.top / Tile.EXTENT)
Rectangle(xMin, xMax, yMin, yMax)
}

override def toString: String = s"${this.getClass.getSimpleName}($name)"

override def equals(obj: Any): Boolean = {
obj.isInstanceOf[OldTile] && obj.asInstanceOf[OldTile].name == name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class PoiChangeAnalyzerTest extends UnitTest with SharedTestObjects {

(t.knownPoiCache.contains _).when(PoiRef("node", 123)).returns(false)
(t.poiScopeAnalyzer.inScope _).when(*).returns(true)
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(new OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(new OldTile(14, 0, 0))
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(OldTile(14, 0, 0))
(t.tileCalculator.poiTiles _).when(*, *).returns(Seq("13-0-0", "14-0-0"))
(t.poiRepository.get _).when(PoiRef("node", 123)).returns(None)

Expand Down Expand Up @@ -133,8 +133,8 @@ class PoiChangeAnalyzerTest extends UnitTest with SharedTestObjects {

(t.knownPoiCache.contains _).when(PoiRef("node", 123)).returns(false)
(t.poiScopeAnalyzer.inScope _).when(*).returns(true)
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(new OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(new OldTile(14, 0, 0))
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(OldTile(14, 0, 0))
(t.tileCalculator.poiTiles _).when(*, *).returns(Seq("13-0-0", "14-0-0"))
(t.poiRepository.get _).when(PoiRef("node", 123)).returns(None)

Expand Down Expand Up @@ -192,8 +192,8 @@ class PoiChangeAnalyzerTest extends UnitTest with SharedTestObjects {
(t.poiRepository.get _).when(PoiRef("node", 123)).returns(Some(existingPoi()))
(t.knownPoiCache.contains _).when(PoiRef("node", 123)).returns(false)
(t.poiScopeAnalyzer.inScope _).when(*).returns(true)
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(new OldTile(13, 1, 1))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(new OldTile(14, 1, 1))
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(OldTile(13, 1, 1))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(OldTile(14, 1, 1))
(t.tileCalculator.poiTiles _).when(*, *).returns(Seq("13-1-1", "14-1-1"))
(t.knownPoiCache.contains _).when(PoiRef("node", 123)).returns(true)

Expand Down Expand Up @@ -453,8 +453,8 @@ class PoiChangeAnalyzerTest extends UnitTest with SharedTestObjects {

(t.knownPoiCache.contains _).when(PoiRef("way", 123)).returns(false)
(t.poiScopeAnalyzer.inScope _).when(*).returns(true)
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(new OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(new OldTile(14, 0, 0))
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(OldTile(14, 0, 0))
(t.tileCalculator.poiTiles _).when(*, *).returns(Seq("13-0-0", "14-0-0"))
(t.poiRepository.get _).when(PoiRef("way", 123)).returns(None)
(t.poiQueryExecutor.centers _).when("way", Seq(123L)).returns(
Expand Down Expand Up @@ -552,8 +552,8 @@ class PoiChangeAnalyzerTest extends UnitTest with SharedTestObjects {

(t.knownPoiCache.contains _).when(PoiRef("relation", 123)).returns(false)
(t.poiScopeAnalyzer.inScope _).when(*).returns(true)
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(new OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(new OldTile(14, 0, 0))
(t.tileCalculator.tileLonLat _).when(13, *, *).returns(OldTile(13, 0, 0))
(t.tileCalculator.tileLonLat _).when(14, *, *).returns(OldTile(14, 0, 0))
(t.tileCalculator.poiTiles _).when(*, *).returns(Seq("13-0-0", "14-0-0"))
(t.poiRepository.get _).when(PoiRef("relation", 123)).returns(None)
(t.poiQueryExecutor.centers _).when("relation", Seq(123L)).returns(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ class TileFileRepositoryTest extends UnitTest {

val repo = new TileFileRepositoryImpl("/tmp/tiles", "png")

repo.saveOrUpdate("cycling/survey", new OldTile(11, 12, 13), Array())
repo.saveOrUpdate("cycling/survey", OldTile(11, 12, 13), Array())
assert(file.exists())

repo.deleteTile("cycling/survey", new OldTile(11, 12, 13))
repo.deleteTile("cycling/survey", OldTile(11, 12, 13))
assert(!file.exists())
}
finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package kpn.server.analyzer.engine.tiles.domain

import kpn.api.common.LatLonImpl
import kpn.core.util.UnitTest
import kpn.server.analyzer.engine.tiles.domain.CoordinateTransform.latToWorldY
import kpn.server.analyzer.engine.tiles.domain.CoordinateTransform.lonToWorldX

class TileTest extends UnitTest {

Expand All @@ -13,19 +15,19 @@ class TileTest extends UnitTest {

val essen = LatLonImpl("51.46774", "4.46839")

OldTile.x(z, essen.lon) should equal(x)
OldTile.y(z, essen.lat) should equal(y)
Tile.tileX(z, lonToWorldX(essen.lon)) should equal(x)
Tile.tileY(z, latToWorldY(essen.lat)) should equal(y)

val tile = new OldTile(z, x, y)
val tile = Tile(z, x, y)

tile.bounds.xMin should equal(4.43847 +- 0.00001)
tile.bounds.xMax should equal(4.48242 +- 0.00001)
tile.bounds.yMin should equal(51.45400 +- 0.00001)
tile.bounds.yMax should equal(51.48138 +- 0.00001)
tile.worldXMin should equal(lonToWorldX(4.43847) +- 0.001)
tile.worldXMax should equal(lonToWorldX(4.48242) +- 0.001)
tile.worldYMin should equal(latToWorldY(51.45400) +- 0.001)
tile.worldYMax should equal(latToWorldY(51.48138) +- 0.001)

tile.clipBounds.xMin should equal(4.43607 +- 0.00001)
tile.clipBounds.xMax should equal(4.48482 +- 0.00001)
tile.clipBounds.yMin should equal(51.45250 +- 0.00001)
tile.clipBounds.yMax should equal(51.48288 +- 0.00001)
tile.clipBounds.xMin should equal(lonToWorldX(4.43607) +- 0.001)
tile.clipBounds.xMax should equal(lonToWorldX(4.48482) +- 0.001)
tile.clipBounds.yMin should equal(latToWorldY(51.45250) +- 0.001)
tile.clipBounds.yMax should equal(latToWorldY(51.48288) +- 0.001)
}
}

0 comments on commit a0b6517

Please sign in to comment.