Skip to content
Open
Show file tree
Hide file tree
Changes from 16 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
5 changes: 0 additions & 5 deletions atlas/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ type Map struct {

mvtProviderName string
mvtProvider provider.MVTTiler

observer observability.Interface
}

// HasMVTProvider indicates if map is a mvt provider based map
Expand Down Expand Up @@ -194,13 +192,11 @@ func (m Map) encodeMVTProviderTile(ctx context.Context, tile slippy.Tile, params
}
}
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, params provider.Params) ([]byte, error) {

// tile container
var mvtTile mvt.Tile
// wait group for concurrent layer fetching
Expand All @@ -214,7 +210,6 @@ func (m Map) encodeMVTTile(ctx context.Context, tile slippy.Tile, params provide

// iterate our layers
for i, layer := range m.Layers {

// go routine for fetching the layer concurrently
go func(i int, l Layer) {
mvtLayer := mvt.Layer{
Expand Down
27 changes: 17 additions & 10 deletions cmd/internal/register/maps.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package register

import (
"fmt"
"html"
"regexp"
"strings"

"github.com/go-spatial/geom"
"github.com/go-spatial/tegola/atlas"
"github.com/go-spatial/tegola/config"
"github.com/go-spatial/tegola/mapbox/tilejson"
"github.com/go-spatial/tegola/provider"
)

Expand All @@ -32,7 +34,6 @@ func webMercatorMapFromConfigMap(cfg provider.Map) (newMap atlas.Map) {
newMap.TileBuffer = uint64(*cfg.TileBuffer)
}
return newMap

}

func layerInfosFindByName(infos []provider.LayerInfo, name string) provider.LayerInfo {
Expand All @@ -48,10 +49,8 @@ func layerInfosFindByName(infos []provider.LayerInfo, name string) provider.Laye
}

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)
)
// providerLayer is primary used for error reporting.
providerLayer := string(cfg.ProviderLayer)
// read the provider's layer names
// don't care about the error.
providerName, layerName, _ := cfg.ProviderLayerName()
Expand Down Expand Up @@ -123,12 +122,9 @@ func selectProvider(name string, mapName string, newMap *atlas.Map, providers ma
return nil, ErrProviderNotFound{name}
}

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

var (
layerer provider.Layerer
)
var layerer provider.Layerer

// iterate our maps
for _, m := range maps {
Expand All @@ -144,6 +140,17 @@ func Maps(a *atlas.Atlas, maps []provider.Map, providers map[string]provider.Til
}
}

// if our map requests TileJSON v3 specifically
// we have to validate that the provider supports it.
// if m.TileJSONVersion is not being provided tegola determines
// the TileJSON version for the user.
if m.TileJSONVersion == tilejson.Version3 {
p := providers[providerName]
if ok, err := p.IsTileJSONV3Compatible(); !ok {
return fmt.Errorf("%w: %s", err, providerName)
}
}

// find our layer provider
layerer, err = selectProvider(providerName, string(m.Name), &newMap, providers)
if err != nil {
Expand Down
22 changes: 21 additions & 1 deletion cmd/internal/register/maps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/go-spatial/tegola/cmd/internal/register"
"github.com/go-spatial/tegola/dict"
"github.com/go-spatial/tegola/internal/env"
"github.com/go-spatial/tegola/mapbox/tilejson"
"github.com/go-spatial/tegola/provider"
)

Expand Down Expand Up @@ -39,7 +40,6 @@ func TestMaps(t *testing.T) {
if !errors.Is(err, tc.expectedErr) {
t.Errorf("invalid error, expected %v got %v", tc.expectedErr, err)
}
return
}
}

Expand Down Expand Up @@ -125,6 +125,26 @@ func TestMaps(t *testing.T) {
},
},
},
"fails when map requires TileJSON v3 but provider does not implement": {
maps: []provider.Map{
{
Name: "test",
TileJSONVersion: tilejson.Version3,
Layers: []provider.MapLayer{
{
ProviderLayer: "foo.bar",
},
},
},
},
providers: []dict.Dict{
{
"name": "foo",
"type": "debug",
},
},
expectedErr: provider.ErrNotTileJSONV3Compatible,
},
"success": {
maps: []provider.Map{},
providers: []dict.Dict{
Expand Down
14 changes: 11 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import (
"io"
"net/http"
"os"
"slices"
"strings"
"time"

"github.com/BurntSushi/toml"
"github.com/go-spatial/tegola"
"github.com/go-spatial/tegola/internal/env"
"github.com/go-spatial/tegola/internal/log"
"github.com/go-spatial/tegola/mapbox/tilejson"
"github.com/go-spatial/tegola/provider"
)

Expand Down Expand Up @@ -157,7 +159,6 @@ func ValidateAndRegisterParams(mapName string, params []provider.QueryParameter)

// Validate checks the config for issues
func (c *Config) Validate() error {

var knownTypes []string
drivers := make(map[string]int)
for _, name := range provider.Drivers(provider.TypeStd) {
Expand Down Expand Up @@ -200,7 +201,6 @@ func (c *Config) Validate() error {
// maps with configured parameters for logging
mapsWithCustomParams := []string{}
for mapKey, m := range c.Maps {

// validate any declared query parameters
if err := ValidateAndRegisterParams(string(m.Name), m.Parameters); err != nil {
return err
Expand All @@ -214,6 +214,14 @@ func (c *Config) Validate() error {
mapLayers[string(m.Name)] = map[string]provider.MapLayer{}
}

if m.TileJSONVersion != "" &&
!slices.Contains(
[]string{tilejson.Version3, tilejson.Version2},
m.TileJSONVersion,
) {
return ErrUnknownTileJSONVersion
}

// Set current provider to empty, for MVT providers
// we can only have the same provider for all layers.
// This allow us to track what the first found provider
Expand Down Expand Up @@ -387,7 +395,7 @@ func Load(location string) (conf Config, err error) {
log.Infof("loading remote config (%v)", location)

// setup http client with a timeout
var httpClient = &http.Client{
httpClient := &http.Client{
Timeout: time.Second * 10,
}

Expand Down
50 changes: 46 additions & 4 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/go-spatial/tegola/config"
"github.com/go-spatial/tegola/internal/env"
"github.com/go-spatial/tegola/mapbox/tilejson"
"github.com/go-spatial/tegola/provider"
_ "github.com/go-spatial/tegola/provider/debug"
_ "github.com/go-spatial/tegola/provider/postgis"
Expand Down Expand Up @@ -61,7 +62,6 @@ func TestParse(t *testing.T) {

fn := func(tc tcase) func(*testing.T) {
return func(t *testing.T) {

f, err := os.Open(tc.configPath)
if err != nil {
t.Fatalf("unexpected error: %s", err)
Expand Down Expand Up @@ -388,7 +388,6 @@ func TestParse(t *testing.T) {
}

func TestValidateMutateZoom(t *testing.T) {

type tcase struct {
config *config.Config
expectedMinZoom int
Expand Down Expand Up @@ -511,7 +510,6 @@ func TestValidateMutateZoom(t *testing.T) {
for name, tc := range tests {
t.Run(name, fn(tc))
}

}

func TestValidate(t *testing.T) {
Expand Down Expand Up @@ -1318,12 +1316,56 @@ func TestValidate(t *testing.T) {
},
},
},
"invalid tilejson version": {
expectedErr: config.ErrUnknownTileJSONVersion,
config: config.Config{
Providers: []env.Dict{
{
"name": "some_provider",
"type": "mvt_test",
},
},
Maps: []provider.Map{
{
Name: "some_map",
Attribution: "Test Attribution",
TileJSONVersion: "foobar",
Layers: []provider.MapLayer{
{
ProviderLayer: "some_provider.some_layer",
},
},
},
},
},
},
"valid tilejson version": {
config: config.Config{
Providers: []env.Dict{
{
"name": "some_provider",
"type": "mvt_test",
},
},
Maps: []provider.Map{
{
Name: "some_map",
Attribution: "Test Attribution",
TileJSONVersion: tilejson.Version3,
Layers: []provider.MapLayer{
{
ProviderLayer: "some_provider.some_layer",
},
},
},
},
},
},
}

for name, tc := range tests {
t.Run(name, fn(tc))
}

}

func TestConfigureTileBuffers(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions config/errors.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package config

import (
"errors"
"fmt"
"strings"

"github.com/go-spatial/tegola/mapbox/tilejson"
"github.com/go-spatial/tegola/provider"
)

var ErrUnknownTileJSONVersion = errors.New("tilejson_version invalid. can either be " + tilejson.Version2 + " or " + tilejson.Version3)

type ErrMapNotFound struct {
MapName string
}
Expand Down
8 changes: 7 additions & 1 deletion mapbox/tilejson/tilejson.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// https://github.com/mapbox/tilejson-spec
package tilejson

const Version = "2.1.0"
const (
Version2 = "2.0.0"
Version3 = "3.0.0"
)

type GeomType string

Expand Down Expand Up @@ -135,4 +138,7 @@ type VectorLayer struct {
MaxZoom uint `json:"maxzoom"`
// Tegola supports individual layer tiles.
Tiles []string `json:"tiles"`
// REQUIRED in TileJSON 3.0.0. An object whose keys and values are the names
// and descriptions of attributes available in this layer.
Fields map[string]any `json:"fields,omitempty"`
}
8 changes: 5 additions & 3 deletions provider/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import (

var (
// ErrCanceled is returned when cancel was requested
ErrCanceled = fmt.Errorf("provider: %v", context.Canceled)
ErrUnsupported = errors.New("provider: unsupported")
ErrNilInitFunc = errors.New("init function can not be nil")
ErrCanceled = fmt.Errorf("provider: %v", context.Canceled)
ErrUnsupported = errors.New("provider: unsupported")
ErrNilInitFunc = errors.New("init function can not be nil")
ErrNotTileJSONV3Compatible = errors.New("provider is not TileJSON version 3 compatible")
ErrNoProvider = errors.New("no provider provided")
)

type ErrUnableToConvertFeatureID struct {
Expand Down
15 changes: 8 additions & 7 deletions provider/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import "github.com/go-spatial/tegola/internal/env"

// A Map represents a map in the Tegola Config file.
type Map struct {
Name env.String `toml:"name"`
Attribution env.String `toml:"attribution"`
Bounds []env.Float `toml:"bounds"`
Center [3]env.Float `toml:"center"`
Layers []MapLayer `toml:"layers"`
Parameters []QueryParameter `toml:"params"`
TileBuffer *env.Int `toml:"tile_buffer"`
Name env.String `toml:"name"`
Attribution env.String `toml:"attribution"`
Bounds []env.Float `toml:"bounds"`
Center [3]env.Float `toml:"center"`
Layers []MapLayer `toml:"layers"`
Parameters []QueryParameter `toml:"params"`
TileBuffer *env.Int `toml:"tile_buffer"`
TileJSONVersion string `toml:"tilejson_version"`
}
Loading
Loading