Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,9 @@ class HeatmapTileRenderer(
minY = bounds.minY - padding,
maxY = bounds.maxY + padding,
)
if (!tileBounds.intersects(paddedBounds)) return null
// 日付変更線をまたいだ点も余白ぶんは隣のタイルに掛かる(HeatmapTileBinner が回り込ませる)ので、
// ここで弾くときも 1 周ずらした位置と比べる。
if (!tileBounds.intersectsWrapped(paddedBounds)) return null

val buffers = resetBuffers(gridDim)
timings.let { it.setupMs = msSince(setupStartNs) }
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/mapconductor/heatmap/HeatmapWorld.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ internal data class Bounds(
maxX >= other.minX &&
minY <= other.maxY &&
maxY >= other.minY

/** 日付変更線の向こう側(x を 1 周ずらした位置)にある [other] とも重なるかを見る。 */
fun intersectsWrapped(other: Bounds): Boolean =
intersects(other) ||
intersects(other.copy(minX = other.minX - HeatmapWorld.WORLD_WIDTH, maxX = other.maxX - HeatmapWorld.WORLD_WIDTH)) ||
intersects(other.copy(minX = other.minX + HeatmapWorld.WORLD_WIDTH, maxX = other.maxX + HeatmapWorld.WORLD_WIDTH))
}

/**
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/com/mapconductor/heatmap/BoundsWrapTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.mapconductor.heatmap

import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

/**
* タイルを描く前の「データ範囲と重なるか」の判定が、日付変更線の向こう側も見ることを確かめる。
* 点が経度 179.9 付近にしか無いとき、z1 の西半球タイル (x=0) の左端には
* HeatmapTileBinner が回り込ませた点がにじむので、ここで弾いてはいけない。
* react-sdk の tileRenderer.test.mjs と同じ配置で見る。
*/
class BoundsWrapTest {
@Test
fun dataJustEastOfTheDateLineReachesTheWesternTile() {
val dataX = HeatmapWorld.WORLD_WIDTH * (179.9 + 180.0) / 360.0
val padding = 0.5 * 10.0 / 64.0 // z1 のタイル幅 0.5、半径 10px、64px タイル
val data = Bounds(dataX - padding, dataX + padding, 0.5 - padding, 0.5 + padding)
val westTile = Bounds(0.0 - padding, 0.5 + padding, 0.5 - padding, 1.0 + padding)

assertFalse(westTile.intersects(data))
assertTrue(westTile.intersectsWrapped(data))
}

@Test
fun wrappingDoesNotMatchTilesThatAreFarAway() {
val data = Bounds(0.99, 1.0, 0.5, 0.51)
// 西端から離れたタイル、y の外れたタイルは 1 周ずらしても重ならない。
assertFalse(Bounds(0.2, 0.3, 0.5, 0.51).intersectsWrapped(data))
assertFalse(Bounds(-0.01, 0.01, 0.0, 0.1).intersectsWrapped(data))
}
}
Loading