diff --git a/cmd/tegola/cmd/cache/seed_purge.go b/cmd/tegola/cmd/cache/seed_purge.go index 46d8ee9e..7e0383df 100644 --- a/cmd/tegola/cmd/cache/seed_purge.go +++ b/cmd/tegola/cmd/cache/seed_purge.go @@ -9,6 +9,7 @@ import ( "github.com/go-spatial/cobra" "github.com/go-spatial/geom" "github.com/go-spatial/geom/slippy" + "github.com/go-spatial/proj" "github.com/go-spatial/tegola/atlas" "github.com/go-spatial/tegola/internal/build" gdcmd "github.com/go-spatial/tegola/internal/cmd" @@ -51,6 +52,8 @@ var ( cacheMap string // while seeding, on log output for tiles that take longer than this (in milliseconds) to render cacheLogThreshold int64 + // the grid system that the bounds is at. If set then we should use WGS84, otherwise assume it's in Pseudo-Mercator + cacheBoundsWGS84 bool ) // variables that are not flags but set by the command. @@ -76,6 +79,7 @@ func init() { SeedPurgeCmd.PersistentFlags().Int64VarP(&cacheLogThreshold, "log-threshold", "", 0, "during seeding, only log tiles that take this number of milliseconds or longer to render (default all tiles)") SeedPurgeCmd.Flags().StringVarP(&cacheBounds, "bounds", "", "-180,-85.0511,180,85.0511", "lng/lat bounds to seed the cache with in the format: minx, miny, maxx, maxy") + SeedPurgeCmd.PersistentFlags().BoolVarP(&cacheBoundsWGS84, "wgs84", "", false, "the grid system for bounds. This flag indicates that the grid is WGS 84; otherwise it's assumed to be in Pseudo-Mercator") SeedPurgeCmd.PersistentPreRunE = seedPurgeCmdValidatePersistent SeedPurgeCmd.PreRunE = seedPurgeCmdValidate @@ -191,19 +195,27 @@ func seedPurgeCommand(_ *cobra.Command, _ []string) (err error) { } }() + srid := proj.EPSGCode(proj.EPSG3857) + if cacheBoundsWGS84 { + srid = proj.EPSG4326 + } + grid := slippy.NewGrid(srid, 0) + log.Info("zoom list: ", zooms) - tileChannel := generateTilesForBounds(ctx, seedPurgeBounds, zooms) + tileChannel := generateTilesForBounds(ctx, seedPurgeBounds, zooms, grid) return doWork(ctx, tileChannel, seedPurgeMaps, cacheConcurrency, seedPurgeWorker) } -func generateTilesForBounds(ctx context.Context, bounds [4]float64, zooms []uint) *TileChannel { +func generateTilesForBounds(ctx context.Context, bounds [4]float64, zooms []uint, grid slippy.TileGridder) *TileChannel { tce := &TileChannel{ channel: make(chan slippy.Tile), } - webmercatorGrid := slippy.NewGrid(3857, 0) + if grid == nil { + grid = slippy.NewGrid(proj.EPSG3857, 0) + } go func() { defer tce.Close() @@ -211,7 +223,7 @@ func generateTilesForBounds(ctx context.Context, bounds [4]float64, zooms []uint var extent geom.Extent = bounds for _, z := range zooms { - tiles, err := slippy.FromBounds(webmercatorGrid, &extent, slippy.Zoom(z)) + tiles, err := slippy.FromBounds(grid, &extent, slippy.Zoom(z)) if err != nil { tce.setError(fmt.Errorf("got error trying to get tiles: %w", err)) tce.Close() diff --git a/cmd/tegola/cmd/cache/seed_purge_generator_test.go b/cmd/tegola/cmd/cache/seed_purge_generator_test.go index 6973769f..8fd8f36d 100644 --- a/cmd/tegola/cmd/cache/seed_purge_generator_test.go +++ b/cmd/tegola/cmd/cache/seed_purge_generator_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/go-spatial/geom/slippy" + "github.com/go-spatial/proj" ) type sTiles []slippy.Tile @@ -70,6 +71,7 @@ func TestGenerateTilesForBounds(t *testing.T) { zooms []uint bounds [4]float64 tiles sTiles + grid slippy.TileGridder err error } @@ -77,7 +79,7 @@ func TestGenerateTilesForBounds(t *testing.T) { return func(t *testing.T) { // Setup up the generator. - tilechannel := generateTilesForBounds(context.Background(), tc.bounds, tc.zooms) + tilechannel := generateTilesForBounds(context.Background(), tc.bounds, tc.zooms, tc.grid) tiles := make(sTiles, 0, len(tc.tiles)) for tile := range tilechannel.Channel() { tiles = append(tiles, tile) @@ -127,6 +129,28 @@ func TestGenerateTilesForBounds(t *testing.T) { slippy.Tile{Z: 1, X: 1, Y: 1}, }, }, + "min_zoom=1 max_zoom=1 bounds=5.9,45.8,10.5,47.8 WSG84": { + // see: https://github.com/go-spatial/tegola/issues/880#issuecomment-2556563251 + zooms: []uint{10}, + bounds: [4]float64{5.9, 45.8, 10.5, 47.8}, + grid: slippy.NewGrid(proj.EPSG4326, 0), + tiles: sTiles{ + slippy.Tile{Z: 10, X: 528, Y: 356}, slippy.Tile{Z: 10, X: 528, Y: 357}, slippy.Tile{Z: 10, X: 528, Y: 358}, slippy.Tile{Z: 10, X: 528, Y: 359}, slippy.Tile{Z: 10, X: 528, Y: 360}, slippy.Tile{Z: 10, X: 528, Y: 361}, slippy.Tile{Z: 10, X: 528, Y: 362}, slippy.Tile{Z: 10, X: 528, Y: 363}, slippy.Tile{Z: 10, X: 528, Y: 364}, slippy.Tile{Z: 10, X: 528, Y: 365}, + slippy.Tile{Z: 10, X: 529, Y: 356}, slippy.Tile{Z: 10, X: 529, Y: 357}, slippy.Tile{Z: 10, X: 529, Y: 358}, slippy.Tile{Z: 10, X: 529, Y: 359}, slippy.Tile{Z: 10, X: 529, Y: 360}, slippy.Tile{Z: 10, X: 529, Y: 361}, slippy.Tile{Z: 10, X: 529, Y: 362}, slippy.Tile{Z: 10, X: 529, Y: 363}, slippy.Tile{Z: 10, X: 529, Y: 364}, slippy.Tile{Z: 10, X: 529, Y: 365}, + slippy.Tile{Z: 10, X: 530, Y: 356}, slippy.Tile{Z: 10, X: 530, Y: 357}, slippy.Tile{Z: 10, X: 530, Y: 358}, slippy.Tile{Z: 10, X: 530, Y: 359}, slippy.Tile{Z: 10, X: 530, Y: 360}, slippy.Tile{Z: 10, X: 530, Y: 361}, slippy.Tile{Z: 10, X: 530, Y: 362}, slippy.Tile{Z: 10, X: 530, Y: 363}, slippy.Tile{Z: 10, X: 530, Y: 364}, slippy.Tile{Z: 10, X: 530, Y: 365}, + slippy.Tile{Z: 10, X: 531, Y: 356}, slippy.Tile{Z: 10, X: 531, Y: 357}, slippy.Tile{Z: 10, X: 531, Y: 358}, slippy.Tile{Z: 10, X: 531, Y: 359}, slippy.Tile{Z: 10, X: 531, Y: 360}, slippy.Tile{Z: 10, X: 531, Y: 361}, slippy.Tile{Z: 10, X: 531, Y: 362}, slippy.Tile{Z: 10, X: 531, Y: 363}, slippy.Tile{Z: 10, X: 531, Y: 364}, slippy.Tile{Z: 10, X: 531, Y: 365}, + slippy.Tile{Z: 10, X: 532, Y: 356}, slippy.Tile{Z: 10, X: 532, Y: 357}, slippy.Tile{Z: 10, X: 532, Y: 358}, slippy.Tile{Z: 10, X: 532, Y: 359}, slippy.Tile{Z: 10, X: 532, Y: 360}, slippy.Tile{Z: 10, X: 532, Y: 361}, slippy.Tile{Z: 10, X: 532, Y: 362}, slippy.Tile{Z: 10, X: 532, Y: 363}, slippy.Tile{Z: 10, X: 532, Y: 364}, slippy.Tile{Z: 10, X: 532, Y: 365}, + slippy.Tile{Z: 10, X: 533, Y: 356}, slippy.Tile{Z: 10, X: 533, Y: 357}, slippy.Tile{Z: 10, X: 533, Y: 358}, slippy.Tile{Z: 10, X: 533, Y: 359}, slippy.Tile{Z: 10, X: 533, Y: 360}, slippy.Tile{Z: 10, X: 533, Y: 361}, slippy.Tile{Z: 10, X: 533, Y: 362}, slippy.Tile{Z: 10, X: 533, Y: 363}, slippy.Tile{Z: 10, X: 533, Y: 364}, slippy.Tile{Z: 10, X: 533, Y: 365}, + slippy.Tile{Z: 10, X: 534, Y: 356}, slippy.Tile{Z: 10, X: 534, Y: 357}, slippy.Tile{Z: 10, X: 534, Y: 358}, slippy.Tile{Z: 10, X: 534, Y: 359}, slippy.Tile{Z: 10, X: 534, Y: 360}, slippy.Tile{Z: 10, X: 534, Y: 361}, slippy.Tile{Z: 10, X: 534, Y: 362}, slippy.Tile{Z: 10, X: 534, Y: 363}, slippy.Tile{Z: 10, X: 534, Y: 364}, slippy.Tile{Z: 10, X: 534, Y: 365}, + slippy.Tile{Z: 10, X: 535, Y: 356}, slippy.Tile{Z: 10, X: 535, Y: 357}, slippy.Tile{Z: 10, X: 535, Y: 358}, slippy.Tile{Z: 10, X: 535, Y: 359}, slippy.Tile{Z: 10, X: 535, Y: 360}, slippy.Tile{Z: 10, X: 535, Y: 361}, slippy.Tile{Z: 10, X: 535, Y: 362}, slippy.Tile{Z: 10, X: 535, Y: 363}, slippy.Tile{Z: 10, X: 535, Y: 364}, slippy.Tile{Z: 10, X: 535, Y: 365}, + slippy.Tile{Z: 10, X: 536, Y: 356}, slippy.Tile{Z: 10, X: 536, Y: 357}, slippy.Tile{Z: 10, X: 536, Y: 358}, slippy.Tile{Z: 10, X: 536, Y: 359}, slippy.Tile{Z: 10, X: 536, Y: 360}, slippy.Tile{Z: 10, X: 536, Y: 361}, slippy.Tile{Z: 10, X: 536, Y: 362}, slippy.Tile{Z: 10, X: 536, Y: 363}, slippy.Tile{Z: 10, X: 536, Y: 364}, slippy.Tile{Z: 10, X: 536, Y: 365}, + slippy.Tile{Z: 10, X: 537, Y: 356}, slippy.Tile{Z: 10, X: 537, Y: 357}, slippy.Tile{Z: 10, X: 537, Y: 358}, slippy.Tile{Z: 10, X: 537, Y: 359}, slippy.Tile{Z: 10, X: 537, Y: 360}, slippy.Tile{Z: 10, X: 537, Y: 361}, slippy.Tile{Z: 10, X: 537, Y: 362}, slippy.Tile{Z: 10, X: 537, Y: 363}, slippy.Tile{Z: 10, X: 537, Y: 364}, slippy.Tile{Z: 10, X: 537, Y: 365}, + slippy.Tile{Z: 10, X: 538, Y: 356}, slippy.Tile{Z: 10, X: 538, Y: 357}, slippy.Tile{Z: 10, X: 538, Y: 358}, slippy.Tile{Z: 10, X: 538, Y: 359}, slippy.Tile{Z: 10, X: 538, Y: 360}, slippy.Tile{Z: 10, X: 538, Y: 361}, slippy.Tile{Z: 10, X: 538, Y: 362}, slippy.Tile{Z: 10, X: 538, Y: 363}, slippy.Tile{Z: 10, X: 538, Y: 364}, slippy.Tile{Z: 10, X: 538, Y: 365}, + slippy.Tile{Z: 10, X: 539, Y: 356}, slippy.Tile{Z: 10, X: 539, Y: 357}, slippy.Tile{Z: 10, X: 539, Y: 358}, slippy.Tile{Z: 10, X: 539, Y: 359}, slippy.Tile{Z: 10, X: 539, Y: 360}, slippy.Tile{Z: 10, X: 539, Y: 361}, slippy.Tile{Z: 10, X: 539, Y: 362}, slippy.Tile{Z: 10, X: 539, Y: 363}, slippy.Tile{Z: 10, X: 539, Y: 364}, slippy.Tile{Z: 10, X: 539, Y: 365}, + slippy.Tile{Z: 10, X: 540, Y: 356}, slippy.Tile{Z: 10, X: 540, Y: 357}, slippy.Tile{Z: 10, X: 540, Y: 358}, slippy.Tile{Z: 10, X: 540, Y: 359}, slippy.Tile{Z: 10, X: 540, Y: 360}, slippy.Tile{Z: 10, X: 540, Y: 361}, slippy.Tile{Z: 10, X: 540, Y: 362}, slippy.Tile{Z: 10, X: 540, Y: 363}, slippy.Tile{Z: 10, X: 540, Y: 364}, slippy.Tile{Z: 10, X: 540, Y: 365}, + slippy.Tile{Z: 10, X: 541, Y: 356}, slippy.Tile{Z: 10, X: 541, Y: 357}, slippy.Tile{Z: 10, X: 541, Y: 358}, slippy.Tile{Z: 10, X: 541, Y: 359}, slippy.Tile{Z: 10, X: 541, Y: 360}, slippy.Tile{Z: 10, X: 541, Y: 361}, slippy.Tile{Z: 10, X: 541, Y: 362}, slippy.Tile{Z: 10, X: 541, Y: 363}, slippy.Tile{Z: 10, X: 541, Y: 364}, slippy.Tile{Z: 10, X: 541, Y: 365}, + }, + }, } for name, tc := range tests {