From ea973f769b182f768996b44cf18b3e81cc24418f Mon Sep 17 00:00:00 2001 From: Oliver Tonnhofer Date: Wed, 23 Nov 2016 16:05:53 +0100 Subject: [PATCH] add padding around expired tiles --- expire/tilelist.go | 34 ++++++++++++++++++++++------------ expire/tilelist_test.go | 33 +++++++++++++++++++++++++++++++++ test/expire_tiles_test.go | 20 +++++++++++--------- 3 files changed, 66 insertions(+), 21 deletions(-) create mode 100644 expire/tilelist_test.go diff --git a/expire/tilelist.go b/expire/tilelist.go index 33802dd..ec2345b 100644 --- a/expire/tilelist.go +++ b/expire/tilelist.go @@ -2,14 +2,14 @@ package expire import ( "fmt" - "github.com/omniscale/imposm3/element" - "github.com/omniscale/imposm3/proj" "io" - "math" "os" "path/filepath" "sync" "time" + + "github.com/omniscale/imposm3/element" + "github.com/omniscale/imposm3/proj" ) var mercBbox = [4]float64{ @@ -30,15 +30,24 @@ func init() { } } -func TileCoord(long, lat float64, zoom uint32) (uint32, uint32) { +// fraction of a tile that is added as a padding around an expired tile +const tilePadding = 0.1 + +func TileCoords(long, lat float64, zoom uint32) []tileKey { x, y := proj.WgsToMerc(long, lat) res := mercRes[zoom] x = x - mercBbox[0] y = mercBbox[3] - y - tileX := uint32(math.Floor(x / (res * 256))) - tileY := uint32(math.Floor(y / (res * 256))) + tileX := float32(x / (res * 256)) + tileY := float32(y / (res * 256)) - return tileX, tileY + tiles := make([]tileKey, 0, 4) + for x := uint32(tileX - tilePadding); x <= uint32(tileX+tilePadding); x++ { + for y := uint32(tileY - tilePadding); y <= uint32(tileY+tilePadding); y++ { + tiles = append(tiles, tileKey{x, y}) + } + } + return tiles } type TileList struct { @@ -50,8 +59,8 @@ type TileList struct { } type tileKey struct { - x uint32 - y uint32 + X uint32 + Y uint32 } type tile struct { @@ -70,9 +79,10 @@ func NewTileList(zoom int, out string) *TileList { } func (tl *TileList) addCoord(long, lat float64) { - tileX, tileY := TileCoord(long, lat, tl.zoom) tl.mu.Lock() - tl.tiles[tileKey{tileX, tileY}] = struct{}{} + for _, t := range TileCoords(long, lat, tl.zoom) { + tl.tiles[t] = struct{}{} + } tl.mu.Unlock() } @@ -88,7 +98,7 @@ func (tl *TileList) ExpireNodes(nodes []element.Node, closed bool) { func (tl *TileList) writeTiles(w io.Writer) error { for tileKey, _ := range tl.tiles { - _, err := fmt.Fprintf(w, "%d/%d/%d\n", tl.zoom, tileKey.x, tileKey.y) + _, err := fmt.Fprintf(w, "%d/%d/%d\n", tl.zoom, tileKey.X, tileKey.Y) if err != nil { return err } diff --git a/expire/tilelist_test.go b/expire/tilelist_test.go new file mode 100644 index 0000000..be5740f --- /dev/null +++ b/expire/tilelist_test.go @@ -0,0 +1,33 @@ +package expire + +import ( + "testing" +) + +func TestTileCoords(t *testing.T) { + tests := []struct { + long float64 + lat float64 + zoom uint32 + tiles []tileKey + }{ + {0, 0, 14, []tileKey{{8191, 8191}, {8191, 8192}, {8192, 8191}, {8192, 8192}}}, + {0.01, 0, 14, []tileKey{{8192, 8191}, {8192, 8192}}}, + {0, 0.01, 14, []tileKey{{8191, 8191}, {8192, 8191}}}, + {0.01, 0.01, 14, []tileKey{{8192, 8191}}}, + {0.02, 0.01, 14, []tileKey{{8192, 8191}, {8193, 8191}}}, + } + + for _, test := range tests { + actual := TileCoords(test.long, test.lat, test.zoom) + if len(actual) != len(test.tiles) { + t.Errorf("%v != %v", actual, test.tiles) + continue + } + for i := range actual { + if actual[i] != test.tiles[i] { + t.Errorf("%v != %v", actual, test.tiles) + } + } + } +} diff --git a/test/expire_tiles_test.go b/test/expire_tiles_test.go index a27a792..24632e0 100644 --- a/test/expire_tiles_test.go +++ b/test/expire_tiles_test.go @@ -108,16 +108,18 @@ func TestExpireTiles_CheckExpireFile(t *testing.T) { {"modify relation from nodes (old)", 4.0001, 3, true}, {"modify relation from nodes (new)", 4.0001, -3, true}, } { - x, y := expire.TileCoord(test.long, test.lat, 14) - if test.expire { - if _, ok := tiles[tile{x: int(x), y: int(y), z: 14}]; !ok { - t.Errorf("missing expire tile for %s 14/%d/%d for %f %f", test.reason, x, y, test.long, test.lat) + for _, coord := range expire.TileCoords(test.long, test.lat, 14) { + x, y := coord.X, coord.Y + if test.expire { + if _, ok := tiles[tile{x: int(x), y: int(y), z: 14}]; !ok { + t.Errorf("missing expire tile for %s 14/%d/%d for %f %f", test.reason, x, y, test.long, test.lat) + } else { + delete(tiles, tile{x: int(x), y: int(y), z: 14}) + } } else { - delete(tiles, tile{x: int(x), y: int(y), z: 14}) - } - } else { - if _, ok := tiles[tile{x: int(x), y: int(y), z: 14}]; ok { - t.Errorf("found expire tile for %s 14/%d/%d for %f %f", test.reason, x, y, test.long, test.lat) + if _, ok := tiles[tile{x: int(x), y: int(y), z: 14}]; ok { + t.Errorf("found expire tile for %s 14/%d/%d for %f %f", test.reason, x, y, test.long, test.lat) + } } } }