Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: adds configurable query parameters to tile endpoints #867

Closed
10 changes: 9 additions & 1 deletion atlas/atlas.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func (a *Atlas) SeedMapTile(ctx context.Context, m Map, z, x, y uint) error {
return defaultAtlas.SeedMapTile(ctx, m, z, x, y)
}

if len(m.Params) > 0 {
return nil
}

ctx = context.WithValue(ctx, observability.ObserveVarMapName, m.Name)
// confirm we have a cache backend
if a.cacher == nil {
Expand All @@ -130,7 +134,7 @@ func (a *Atlas) SeedMapTile(ctx context.Context, m Map, z, x, y uint) error {
tile := slippy.NewTile(z, x, y)

// encode the tile
b, err := m.Encode(ctx, tile)
b, err := m.Encode(ctx, tile, nil)
if err != nil {
return err
}
Expand All @@ -154,6 +158,10 @@ func (a *Atlas) PurgeMapTile(m Map, tile *tegola.Tile) error {
return defaultAtlas.PurgeMapTile(m, tile)
}

if len(m.Params) > 0 {
return nil
}

if a.cacher == nil {
return ErrMissingCache
}
Expand Down
26 changes: 16 additions & 10 deletions atlas/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"github.com/go-spatial/tegola/provider/debug"
)

// NewMap creates a new map with the necessary default values
// NewWebMercatorMap creates a new map with the necessary default values
func NewWebMercatorMap(name string) Map {
return Map{
Name: name,
Expand All @@ -40,6 +40,7 @@ func NewWebMercatorMap(name string) Map {
}
}

// Map defines a Web Mercator map
type Map struct {
Name string
// Contains an attribution to be displayed when the map is shown to a user.
Expand All @@ -53,6 +54,8 @@ type Map struct {
// WGS:84 values), the third value is the zoom level.
Center [3]float64
Layers []Layer
// Params holds configured query parameters
Params []provider.QueryParameter

SRID uint64
// MVT output values
Expand Down Expand Up @@ -116,7 +119,7 @@ func (m Map) AddDebugLayers() Map {
m.Layers = layers

// setup a debug provider
debugProvider, _ := debug.NewTileProvider(dict.Dict{})
debugProvider, _ := debug.NewTileProvider(dict.Dict{}, nil)

m.Layers = append(layers, []Layer{
{
Expand Down Expand Up @@ -179,7 +182,7 @@ func (m Map) FilterLayersByName(names ...string) Map {
return m
}

func (m Map) encodeMVTProviderTile(ctx context.Context, tile *slippy.Tile) ([]byte, error) {
func (m Map) encodeMVTProviderTile(ctx context.Context, tile *slippy.Tile, params provider.Params) ([]byte, error) {
// get the list of our layers
ptile := provider.NewTile(tile.Z, tile.X, tile.Y, uint(m.TileBuffer), uint(m.SRID))

Expand All @@ -190,13 +193,13 @@ func (m Map) encodeMVTProviderTile(ctx context.Context, tile *slippy.Tile) ([]by
MVTName: m.Layers[i].MVTName(),
}
}
return m.mvtProvider.MVTForLayers(ctx, ptile, layers)
return m.mvtProvider.MVTForLayers(ctx, ptile, params, layers)

}

// encodeMVTTile will encode the given tile into mvt format
// TODO (arolek): support for max zoom
func (m Map) encodeMVTTile(ctx context.Context, tile *slippy.Tile) ([]byte, error) {
func (m Map) encodeMVTTile(ctx context.Context, tile *slippy.Tile, params provider.Params) ([]byte, error) {

// tile container
var mvtTile mvt.Tile
Expand Down Expand Up @@ -225,7 +228,7 @@ func (m Map) encodeMVTTile(ctx context.Context, tile *slippy.Tile) ([]byte, erro
uint(m.TileBuffer), uint(m.SRID))

// fetch layer from data provider
err := l.Provider.TileFeatures(ctx, l.ProviderLayerName, ptile, func(f *provider.Feature) error {
err := l.Provider.TileFeatures(ctx, l.ProviderLayerName, ptile, params, func(f *provider.Feature) error {
// skip row if geometry collection empty.
g, ok := f.Geometry.(geom.Collection)
if ok && len(g.Geometries()) == 0 {
Expand Down Expand Up @@ -360,7 +363,10 @@ func (m Map) encodeMVTTile(ctx context.Context, tile *slippy.Tile) ([]byte, erro
}

// add layers to our tile
mvtTile.AddLayers(mvtLayers...)
err := mvtTile.AddLayers(mvtLayers...)
if err != nil {
return nil, err
}

// generate the MVT tile
vtile, err := mvtTile.VTile(ctx)
Expand All @@ -373,15 +379,15 @@ func (m Map) encodeMVTTile(ctx context.Context, tile *slippy.Tile) ([]byte, erro
}

// Encode will encode the given tile into mvt format
func (m Map) Encode(ctx context.Context, tile *slippy.Tile) ([]byte, error) {
func (m Map) Encode(ctx context.Context, tile *slippy.Tile, params provider.Params) ([]byte, error) {
var (
tileBytes []byte
err error
)
if m.HasMVTProvider() {
tileBytes, err = m.encodeMVTProviderTile(ctx, tile)
tileBytes, err = m.encodeMVTProviderTile(ctx, tile, params)
} else {
tileBytes, err = m.encodeMVTTile(ctx, tile)
tileBytes, err = m.encodeMVTTile(ctx, tile, params)
}
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion atlas/map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func TestEncode(t *testing.T) {

fn := func(tc tcase) func(t *testing.T) {
return func(t *testing.T) {
out, err := tc.grid.Encode(context.Background(), tc.tile)
out, err := tc.grid.Encode(context.Background(), tc.tile, nil)
if err != nil {
t.Errorf("err: %v", err)
return
Expand Down
1 change: 1 addition & 0 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func ParseKey(str string) (*Key, error) {

// remove the base-path and the first slash, then split the parts
keyParts := strings.Split(strings.TrimLeft(str, "/"), "/")

// we're expecting a z/x/y scheme
if len(keyParts) < 3 || len(keyParts) > 5 {
err = ErrInvalidFileKeyParts{
Expand Down
8 changes: 5 additions & 3 deletions cmd/internal/register/maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (
"github.com/go-spatial/tegola/provider"
)

func webMercatorMapFromConfigMap(cfg config.Map) (newMap atlas.Map) {
func webMercatorMapFromConfigMap(cfg provider.Map) (newMap atlas.Map) {
newMap = atlas.NewWebMercatorMap(string(cfg.Name))
newMap.Attribution = SanitizeAttribution(string(cfg.Attribution))
newMap.Params = cfg.Parameters

// convert from env package
for i, v := range cfg.Center {
Expand Down Expand Up @@ -46,7 +47,7 @@ func layerInfosFindByName(infos []provider.LayerInfo, name string) provider.Laye
return nil
}

func atlasLayerFromConfigLayer(cfg *config.MapLayer, mapName string, layerProvider provider.Layerer) (layer atlas.Layer, err error) {
func atlasLayerFromConfigLayer(cfg *provider.MapLayer, mapName string, layerProvider provider.Layerer) (layer atlas.Layer, err error) {
var (
// providerLayer is primary used for error reporting.
providerLayer = string(cfg.ProviderLayer)
Expand Down Expand Up @@ -123,7 +124,7 @@ func selectProvider(name string, mapName string, newMap *atlas.Map, providers ma
}

// Maps registers maps with with atlas
func Maps(a *atlas.Atlas, maps []config.Map, providers map[string]provider.TilerUnion) error {
func Maps(a *atlas.Atlas, maps []provider.Map, providers map[string]provider.TilerUnion) error {

var (
layerer provider.Layerer
Expand Down Expand Up @@ -155,6 +156,7 @@ func Maps(a *atlas.Atlas, maps []config.Map, providers map[string]provider.Tiler
}
newMap.Layers = append(newMap.Layers, layer)
}

a.AddMap(newMap)
}
return nil
Expand Down
24 changes: 12 additions & 12 deletions cmd/internal/register/maps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import (

"github.com/go-spatial/tegola/atlas"
"github.com/go-spatial/tegola/cmd/internal/register"
"github.com/go-spatial/tegola/config"
"github.com/go-spatial/tegola/dict"
"github.com/go-spatial/tegola/internal/env"
"github.com/go-spatial/tegola/provider"
)

func TestMaps(t *testing.T) {
type tcase struct {
atlas atlas.Atlas
maps []config.Map
maps []provider.Map
providers []dict.Dict
expectedErr error
}
Expand All @@ -29,7 +29,7 @@ func TestMaps(t *testing.T) {
provArr[i] = tc.providers[i]
}

providers, err := register.Providers(provArr)
providers, err := register.Providers(provArr, tc.maps)
if err != nil {
t.Errorf("unexpected err: %v", err)
return
Expand All @@ -45,10 +45,10 @@ func TestMaps(t *testing.T) {

tests := map[string]tcase{
"provider layer invalid": {
maps: []config.Map{
maps: []provider.Map{
{
Name: "foo",
Layers: []config.MapLayer{
Layers: []provider.MapLayer{
{
ProviderLayer: "bar",
},
Expand All @@ -67,10 +67,10 @@ func TestMaps(t *testing.T) {
},
},
"provider not found": {
maps: []config.Map{
maps: []provider.Map{
{
Name: "foo",
Layers: []config.MapLayer{
Layers: []provider.MapLayer{
{
ProviderLayer: "bar.baz",
},
Expand All @@ -82,10 +82,10 @@ func TestMaps(t *testing.T) {
},
},
"provider layer not registered with provider": {
maps: []config.Map{
maps: []provider.Map{
{
Name: "foo",
Layers: []config.MapLayer{
Layers: []provider.MapLayer{
{
ProviderLayer: "test.bar",
},
Expand All @@ -105,10 +105,10 @@ func TestMaps(t *testing.T) {
},
},
"default tags": {
maps: []config.Map{
maps: []provider.Map{
{
Name: "foo",
Layers: []config.MapLayer{
Layers: []provider.MapLayer{
{
ProviderLayer: "test.debug-tile-outline",
DefaultTags: env.Dict{
Expand All @@ -126,7 +126,7 @@ func TestMaps(t *testing.T) {
},
},
"success": {
maps: []config.Map{},
maps: []provider.Map{},
providers: []dict.Dict{
{
"name": "test",
Expand Down
4 changes: 2 additions & 2 deletions cmd/internal/register/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (e ErrProviderTypeInvalid) Error() string {
}

// Providers registers data provider backends
func Providers(providers []dict.Dicter) (map[string]provider.TilerUnion, error) {
func Providers(providers []dict.Dicter, maps []provider.Map) (map[string]provider.TilerUnion, error) {
// holder for registered providers
registeredProviders := map[string]provider.TilerUnion{}

Expand Down Expand Up @@ -72,7 +72,7 @@ func Providers(providers []dict.Dicter) (map[string]provider.TilerUnion, error)
}

// register the provider
prov, err := provider.For(ptype, p)
prov, err := provider.For(ptype, p, maps)
if err != nil {
return registeredProviders, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/internal/register/providers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestProviders(t *testing.T) {
provArr[i] = tc.config[i]
}

_, err = register.Providers(provArr)
_, err = register.Providers(provArr, nil)
if tc.expectedErr != nil {
if err.Error() != tc.expectedErr.Error() {
t.Errorf("invalid error. expected: %v, got %v", tc.expectedErr, err.Error())
Expand Down
15 changes: 12 additions & 3 deletions cmd/tegola/cmd/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,20 @@ func doWork(ctx context.Context, tileChannel *TileChannel, maps []atlas.Map, con
}(i)
}

nonParamMaps := make([]atlas.Map, 0)

for _, m := range maps {
// we don't support caching for maps with custom parameters
if m.Params != nil || len(m.Params) > 0 {
log.Warnf("caching is disabled for map %s as it has custom parameters configures", m.Name)
}
nonParamMaps = append(nonParamMaps, m)
}

// run through the incoming tiles, and generate the mapTiles as needed.
TileChannelLoop:
for tile := range tileChannel.Channel() {
for m := range maps {

for _, m := range nonParamMaps {
if ctx.Err() != nil {
cleanup = true
break
Expand All @@ -180,7 +189,7 @@ TileChannelLoop:
}

mapTile := MapTile{
MapName: maps[m].Name,
MapName: m.Name,
Tile: tile,
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/tegola/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ var RootCmd = &cobra.Command{
Use: "tegola",
Short: "tegola is a vector tile server",
Long: fmt.Sprintf(`tegola is a vector tile server
Version: %v`, build.Version),
Version: %v`, build.Version),
PersistentPreRunE: rootCmdValidatePersistent,
}

Expand Down Expand Up @@ -121,7 +121,7 @@ func initConfig(configFile string, cacheRequired bool, logLevel string, logger s
provArr[i] = conf.Providers[i]
}

providers, err := register.Providers(provArr)
providers, err := register.Providers(provArr, conf.Maps)
if err != nil {
return fmt.Errorf("could not register providers: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/tegola_lambda/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func init() {
}

// register the providers
providers, err := register.Providers(provArr)
providers, err := register.Providers(provArr, nil)
if err != nil {
log.Fatal(err)
}
Expand Down
Loading