forked from go-spatial/tegola
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handle_capabilities.go
120 lines (99 loc) · 3.21 KB
/
handle_capabilities.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package server
import (
"encoding/json"
"fmt"
"net/http"
"github.com/go-spatial/tegola/atlas"
)
type Capabilities struct {
Version string `json:"version"`
Maps []CapabilitiesMap `json:"maps"`
}
type CapabilitiesMap struct {
Name string `json:"name"`
Attribution string `json:"attribution"`
Bounds [4]float64 `json:"bounds"`
Center [3]float64 `json:"center"`
Tiles []string `json:"tiles"`
Capabilities string `json:"capabilities"`
Layers []CapabilitiesLayer `json:"layers"`
}
type CapabilitiesLayer struct {
Name string `json:"name"`
Tiles []string `json:"tiles"`
MinZoom int `json:"minzoom"`
MaxZoom int `json:"maxzoom"`
}
type HandleCapabilities struct{}
func (req HandleCapabilities) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// new capabilities struct
capabilities := Capabilities{
Version: Version,
}
// parse our query string
var query = r.URL.Query()
// iterate our registered maps
for _, m := range atlas.AllMaps() {
var debugQuery string
// if we have a debug param add it to our URLs
if query.Get("debug") == "true" {
debugQuery = "?debug=true"
// update our map to include the debug layers
m = m.AddDebugLayers()
}
// build the map details
cMap := CapabilitiesMap{
Name: m.Name,
Attribution: m.Attribution,
Bounds: m.Bounds,
Center: m.Center,
Tiles: []string{
fmt.Sprintf("%v://%v/maps/%v/{z}/{x}/{y}.pbf%v", scheme(r), hostName(r), m.Name, debugQuery),
},
Capabilities: fmt.Sprintf("%v://%v/capabilities/%v.json%v", scheme(r), hostName(r), m.Name, debugQuery),
}
for i := range m.Layers {
// check if the layer already exists in our slice. this can happen if the config
// is using the "name" param for a layer to override the providerLayerName
var skip bool
for j := range cMap.Layers {
if cMap.Layers[j].Name == m.Layers[i].MVTName() {
// we need to use the min and max of all layers with this name
if cMap.Layers[j].MinZoom > m.Layers[i].MinZoom {
cMap.Layers[j].MinZoom = m.Layers[i].MinZoom
}
if cMap.Layers[j].MaxZoom < m.Layers[i].MaxZoom {
cMap.Layers[j].MaxZoom = m.Layers[i].MaxZoom
}
skip = true
break
}
}
// entry for layer already exists. move on
if skip {
continue
}
// build the layer details
cLayer := CapabilitiesLayer{
Name: m.Layers[i].MVTName(),
Tiles: []string{
fmt.Sprintf("%v://%v/maps/%v/%v/{z}/{x}/{y}.pbf%v", scheme(r), hostName(r), m.Name, m.Layers[i].MVTName(), debugQuery),
},
MinZoom: m.Layers[i].MinZoom,
MaxZoom: m.Layers[i].MaxZoom,
}
// add the layer to the map
cMap.Layers = append(cMap.Layers, cLayer)
}
// add the map to the capabilities struct
capabilities.Maps = append(capabilities.Maps, cMap)
// content type
w.Header().Add("Content-Type", "application/json")
// cache control headers (no-cache)
w.Header().Add("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Add("Pragma", "no-cache")
w.Header().Add("Expires", "0")
}
// setup a new json encoder and encode our capabilities
json.NewEncoder(w).Encode(capabilities)
}