forked from go-spatial/tegola
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request go-spatial#202 from terranodo/issue-64
Issue 64 LGTM+2
- Loading branch information
Showing
89 changed files
with
9,093 additions
and
910 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
.DS_Store | ||
.idea | ||
*.toml | ||
tegola |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
package atlas | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
|
||
"github.com/terranodo/tegola" | ||
"github.com/terranodo/tegola/cache" | ||
) | ||
|
||
// DefaultAtlas is instanitated for convenience | ||
var DefaultAtlas = &Atlas{} | ||
|
||
const ( | ||
// MaxZoom will not render tile beyond this zoom level | ||
MaxZoom = 22 | ||
) | ||
|
||
type Atlas struct { | ||
// for managing current access to the map container | ||
sync.RWMutex | ||
// hold maps | ||
maps map[string]Map | ||
// holds a reference to the cache backend | ||
cacher cache.Interface | ||
} | ||
|
||
func (a *Atlas) AllMaps() []Map { | ||
a.RLock() | ||
defer a.RUnlock() | ||
|
||
var maps []Map | ||
for i := range a.maps { | ||
m := a.maps[i] | ||
// make an explict copy of the layers | ||
layers := make([]Layer, len(m.Layers)) | ||
copy(layers, m.Layers) | ||
m.Layers = layers | ||
|
||
maps = append(maps, m) | ||
} | ||
|
||
return maps | ||
} | ||
|
||
// SeedMapTile will generate a tile and persist it to the | ||
// configured cache backend | ||
func (a *Atlas) SeedMapTile(m Map, tile tegola.Tile) error { | ||
// confirm we have a cache backend | ||
if a.cacher == nil { | ||
return ErrMissingCache | ||
} | ||
|
||
// encode the tile | ||
b, err := m.Encode(context.Background(), tile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// cache key | ||
key := cache.Key{ | ||
MapName: m.Name, | ||
Z: tile.Z, | ||
X: tile.X, | ||
Y: tile.Y, | ||
} | ||
|
||
return a.cacher.Set(&key, b) | ||
} | ||
|
||
// PurgeMapTile will purge a map tile from the configured cache backend | ||
func (a *Atlas) PurgeMapTile(m Map, tile tegola.Tile) error { | ||
if a.cacher == nil { | ||
return ErrMissingCache | ||
} | ||
|
||
// cache key | ||
key := cache.Key{ | ||
MapName: m.Name, | ||
Z: tile.Z, | ||
X: tile.X, | ||
Y: tile.Y, | ||
} | ||
|
||
return a.cacher.Purge(&key) | ||
} | ||
|
||
// Map looks up a Map by name and returns a copy of the Map | ||
func (a *Atlas) Map(mapName string) (Map, error) { | ||
a.RLock() | ||
defer a.RUnlock() | ||
|
||
m, ok := a.maps[mapName] | ||
if !ok { | ||
return Map{}, ErrMapNotFound{ | ||
Name: mapName, | ||
} | ||
} | ||
|
||
// make an explict copy of the layers | ||
layers := make([]Layer, len(m.Layers)) | ||
copy(layers, m.Layers) | ||
m.Layers = layers | ||
|
||
return m, nil | ||
} | ||
|
||
// AddMap registers a map by name. if the map already exists it will be overwritten | ||
func (a *Atlas) AddMap(m Map) { | ||
a.Lock() | ||
defer a.Unlock() | ||
|
||
if a.maps == nil { | ||
a.maps = map[string]Map{} | ||
} | ||
|
||
a.maps[m.Name] = m | ||
} | ||
|
||
// GetCache returns the registered cache if one is registered, otherwise nil | ||
func (a *Atlas) GetCache() cache.Interface { | ||
return a.cacher | ||
} | ||
|
||
// SetCache sets the cache backend | ||
func (a *Atlas) SetCache(c cache.Interface) { | ||
a.cacher = c | ||
} | ||
|
||
// AllMaps returns all registered maps in DefaultAtlas | ||
func AllMaps() []Map { | ||
return DefaultAtlas.AllMaps() | ||
} | ||
|
||
// GetMap returns a copy of the a map by name from DefaultAtlas. if the map does not exist it will return an error | ||
func GetMap(mapName string) (Map, error) { | ||
return DefaultAtlas.Map(mapName) | ||
} | ||
|
||
// AddMap registers a map by name with DefaultAtlas. if the map already exists it will be overwritten | ||
func AddMap(m Map) { | ||
DefaultAtlas.AddMap(m) | ||
} | ||
|
||
// GetCache returns the registered cache for DefaultAtlas, if one is registered, otherwise nil | ||
func GetCache() cache.Interface { | ||
return DefaultAtlas.GetCache() | ||
} | ||
|
||
// SetCache sets the cache backend for DefaultAtlas | ||
func SetCache(c cache.Interface) { | ||
DefaultAtlas.SetCache(c) | ||
} | ||
|
||
// SeedMapTile will generate a tile and persist it to the | ||
// configured cache backend for the DefaultAtlas | ||
func SeedMapTile(m Map, tile tegola.Tile) error { | ||
return DefaultAtlas.SeedMapTile(m, tile) | ||
} | ||
|
||
// PurgeMapTile will purge a map tile from the configured cache backend | ||
// for the DefaultAtlas | ||
func PurgeMapTile(m Map, tile tegola.Tile) error { | ||
return DefaultAtlas.PurgeMapTile(m, tile) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package atlas_test | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/terranodo/tegola" | ||
"github.com/terranodo/tegola/atlas" | ||
"github.com/terranodo/tegola/basic" | ||
"github.com/terranodo/tegola/mvt" | ||
) | ||
|
||
type testMVTProvider struct{} | ||
|
||
func (tp *testMVTProvider) MVTLayer(ctx context.Context, layerName string, tile tegola.Tile, tags map[string]interface{}) (*mvt.Layer, error) { | ||
var layer mvt.Layer | ||
|
||
return &layer, nil | ||
} | ||
|
||
func (tp *testMVTProvider) Layers() ([]mvt.LayerInfo, error) { | ||
return []mvt.LayerInfo{ | ||
layer{ | ||
name: "test-layer", | ||
geomType: basic.Polygon{}, | ||
srid: tegola.WebMercator, | ||
}, | ||
}, nil | ||
} | ||
|
||
var testLayer1 = atlas.Layer{ | ||
Name: "test-layer", | ||
ProviderLayerName: "test-layer-1", | ||
MinZoom: 4, | ||
MaxZoom: 9, | ||
Provider: &testMVTProvider{}, | ||
GeomType: basic.Point{}, | ||
DefaultTags: map[string]interface{}{ | ||
"foo": "bar", | ||
}, | ||
} | ||
|
||
var testLayer2 = atlas.Layer{ | ||
Name: "test-layer-2-name", | ||
ProviderLayerName: "test-layer-2-provider-layer-name", | ||
MinZoom: 10, | ||
MaxZoom: 20, | ||
Provider: &testMVTProvider{}, | ||
GeomType: basic.Line{}, | ||
DefaultTags: map[string]interface{}{ | ||
"foo": "bar", | ||
}, | ||
} | ||
|
||
var testLayer3 = atlas.Layer{ | ||
Name: "test-layer", | ||
ProviderLayerName: "test-layer-3", | ||
MinZoom: 10, | ||
MaxZoom: 20, | ||
Provider: &testMVTProvider{}, | ||
GeomType: basic.Point{}, | ||
DefaultTags: map[string]interface{}{}, | ||
} | ||
|
||
var testMap = atlas.Map{ | ||
Name: "test-map", | ||
Attribution: "test attribution", | ||
Center: [3]float64{1.0, 2.0, 3.0}, | ||
Layers: []atlas.Layer{ | ||
testLayer1, | ||
testLayer2, | ||
testLayer3, | ||
}, | ||
} | ||
|
||
type layer struct { | ||
name string | ||
geomType tegola.Geometry | ||
srid int | ||
} | ||
|
||
func (l layer) Name() string { | ||
return l.name | ||
} | ||
|
||
func (l layer) GeomType() tegola.Geometry { | ||
return l.geomType | ||
} | ||
|
||
func (l layer) SRID() int { | ||
return l.srid | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package atlas | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
) | ||
|
||
var ( | ||
ErrMissingCache = errors.New("atlas: missing cache") | ||
) | ||
|
||
type ErrMapNotFound struct { | ||
Name string | ||
} | ||
|
||
func (e ErrMapNotFound) Error() string { | ||
return fmt.Sprintf("atlas: map (%v) not found", e.Name) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.