mirror of
https://github.com/Luzifer/staticmap.git
synced 2024-12-20 12:51:18 +00:00
Move parameters into struct form
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
9a7a0ec7c9
commit
aa33543af8
4 changed files with 55 additions and 47 deletions
17
cache.go
17
cache.go
|
@ -1,22 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/golang/geo/s2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type cacheFunction func(center s2.LatLng, zoom int, marker []marker, x, y int, disableAttribution bool) (io.ReadCloser, error)
|
type cacheFunction func(generateMapConfig) (io.ReadCloser, error)
|
||||||
|
|
||||||
func cacheKeyHelper(center s2.LatLng, zoom int, marker []marker, x, y int, disableAttribution bool) string {
|
|
||||||
markerString := []string{}
|
|
||||||
for _, m := range marker {
|
|
||||||
markerString = append(markerString, m.String())
|
|
||||||
}
|
|
||||||
hashString := fmt.Sprintf("%s|%d|%s|%dx%d|%v", center.String(), zoom, strings.Join(markerString, "+"), x, y, disableAttribution)
|
|
||||||
|
|
||||||
return fmt.Sprintf("%x", sha256.Sum256([]byte(hashString)))
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,12 +7,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/geo/s2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func filesystemCache(center s2.LatLng, zoom int, marker []marker, x, y int, disableAttribution bool) (io.ReadCloser, error) {
|
func filesystemCache(opts generateMapConfig) (io.ReadCloser, error) {
|
||||||
cacheKey := cacheKeyHelper(center, zoom, marker, x, y, disableAttribution)
|
cacheKey := opts.getCacheKey()
|
||||||
cacheFileName := path.Join(cfg.CacheDir, cacheKey[0:2], cacheKey+".png")
|
cacheFileName := path.Join(cfg.CacheDir, cacheKey[0:2], cacheKey+".png")
|
||||||
|
|
||||||
if info, err := os.Stat(cacheFileName); err == nil && info.ModTime().Add(cfg.ForceCache).After(time.Now()) {
|
if info, err := os.Stat(cacheFileName); err == nil && info.ModTime().Add(cfg.ForceCache).After(time.Now()) {
|
||||||
|
@ -20,7 +18,7 @@ func filesystemCache(center s2.LatLng, zoom int, marker []marker, x, y int, disa
|
||||||
}
|
}
|
||||||
|
|
||||||
// No cache hit, generate a new map
|
// No cache hit, generate a new map
|
||||||
mapReader, err := generateMap(center, zoom, marker, x, y, disableAttribution)
|
mapReader, err := generateMap(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
36
main.go
36
main.go
|
@ -65,36 +65,34 @@ func main() {
|
||||||
|
|
||||||
func handleMapRequest(res http.ResponseWriter, r *http.Request) {
|
func handleMapRequest(res http.ResponseWriter, r *http.Request) {
|
||||||
var (
|
var (
|
||||||
center *s2.LatLng
|
err error
|
||||||
disableAttribution bool = r.URL.Query().Get("no-attribution") == "true"
|
mapReader io.ReadCloser
|
||||||
err error
|
opts = generateMapConfig{
|
||||||
mapReader io.ReadCloser
|
DisableAttribution: r.URL.Query().Get("no-attribution") == "true",
|
||||||
markers []marker
|
}
|
||||||
x, y int
|
|
||||||
zoom int
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if center, err = parseCoordinate(r.URL.Query().Get("center")); err != nil {
|
if opts.Center, err = parseCoordinate(r.URL.Query().Get("center")); err != nil {
|
||||||
http.Error(res, fmt.Sprintf("Unable to parse 'center' parameter: %s", err), http.StatusBadRequest)
|
http.Error(res, fmt.Sprintf("Unable to parse 'center' parameter: %s", err), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if zoom, err = strconv.Atoi(r.URL.Query().Get("zoom")); err != nil {
|
if opts.Zoom, err = strconv.Atoi(r.URL.Query().Get("zoom")); err != nil {
|
||||||
http.Error(res, fmt.Sprintf("Unable to parse 'zoom' parameter: %s", err), http.StatusBadRequest)
|
http.Error(res, fmt.Sprintf("Unable to parse 'zoom' parameter: %s", err), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if x, y, err = parseSize(r.URL.Query().Get("size"), true); err != nil {
|
if opts.Width, opts.Height, err = parseSize(r.URL.Query().Get("size"), true); err != nil {
|
||||||
http.Error(res, fmt.Sprintf("Unable to parse 'size' parameter: %s", err), http.StatusBadRequest)
|
http.Error(res, fmt.Sprintf("Unable to parse 'size' parameter: %s", err), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if markers, err = parseMarkerLocations(r.URL.Query()["markers"]); err != nil {
|
if opts.Markers, err = parseMarkerLocations(r.URL.Query()["markers"]); err != nil {
|
||||||
http.Error(res, fmt.Sprintf("Unable to parse 'markers' parameter: %s", err), http.StatusBadRequest)
|
http.Error(res, fmt.Sprintf("Unable to parse 'markers' parameter: %s", err), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if mapReader, err = cacheFunc(*center, zoom, markers, x, y, disableAttribution); err != nil {
|
if mapReader, err = cacheFunc(opts); err != nil {
|
||||||
log.Errorf("Map render failed: %s (Request: %s)", err, r.URL.String())
|
log.Errorf("Map render failed: %s (Request: %s)", err, r.URL.String())
|
||||||
http.Error(res, fmt.Sprintf("I experienced difficulties rendering your map: %s", err), http.StatusInternalServerError)
|
http.Error(res, fmt.Sprintf("I experienced difficulties rendering your map: %s", err), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -106,14 +104,14 @@ func handleMapRequest(res http.ResponseWriter, r *http.Request) {
|
||||||
io.Copy(res, mapReader)
|
io.Copy(res, mapReader)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseCoordinate(coord string) (*s2.LatLng, error) {
|
func parseCoordinate(coord string) (s2.LatLng, error) {
|
||||||
if coord == "" {
|
if coord == "" {
|
||||||
return nil, errors.New("No coordinate given")
|
return s2.LatLng{}, errors.New("No coordinate given")
|
||||||
}
|
}
|
||||||
|
|
||||||
parts := strings.Split(coord, ",")
|
parts := strings.Split(coord, ",")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
return nil, errors.New("Coordinate not in format lat,lon")
|
return s2.LatLng{}, errors.New("Coordinate not in format lat,lon")
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -122,15 +120,15 @@ func parseCoordinate(coord string) (*s2.LatLng, error) {
|
||||||
)
|
)
|
||||||
|
|
||||||
if lat, err = strconv.ParseFloat(parts[0], 64); err != nil {
|
if lat, err = strconv.ParseFloat(parts[0], 64); err != nil {
|
||||||
return nil, errors.New("Latitude not parseable as float")
|
return s2.LatLng{}, errors.New("Latitude not parseable as float")
|
||||||
}
|
}
|
||||||
|
|
||||||
if lon, err = strconv.ParseFloat(parts[1], 64); err != nil {
|
if lon, err = strconv.ParseFloat(parts[1], 64); err != nil {
|
||||||
return nil, errors.New("Longitude not parseable as float")
|
return s2.LatLng{}, errors.New("Longitude not parseable as float")
|
||||||
}
|
}
|
||||||
|
|
||||||
pt := s2.LatLngFromDegrees(lat, lon)
|
pt := s2.LatLngFromDegrees(lat, lon)
|
||||||
return &pt, nil
|
return pt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSize(size string, validate bool) (x, y int, err error) {
|
func parseSize(size string, validate bool) (x, y int, err error) {
|
||||||
|
@ -203,7 +201,7 @@ func parseMarkerLocations(markers []string) ([]marker, error) {
|
||||||
return nil, fmt.Errorf("Unparsable chunk found in marker: %q", p)
|
return nil, fmt.Errorf("Unparsable chunk found in marker: %q", p)
|
||||||
}
|
}
|
||||||
result = append(result, marker{
|
result = append(result, marker{
|
||||||
pos: *pos,
|
pos: pos,
|
||||||
color: col,
|
color: col,
|
||||||
size: size,
|
size: size,
|
||||||
})
|
})
|
||||||
|
|
41
map.go
41
map.go
|
@ -2,9 +2,11 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
staticMap "github.com/Luzifer/go-staticmaps"
|
staticMap "github.com/Luzifer/go-staticmaps"
|
||||||
"github.com/fogleman/gg"
|
"github.com/fogleman/gg"
|
||||||
|
@ -43,20 +45,45 @@ func (m marker) String() string {
|
||||||
return fmt.Sprintf("%s|%.0f|%d,%d,%d,%d", m.pos.String(), m.size, r, g, b, a)
|
return fmt.Sprintf("%s|%.0f|%d,%d,%d,%d", m.pos.String(), m.size, r, g, b, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateMap(center s2.LatLng, zoom int, marker []marker, x, y int, disableAttribution bool) (io.Reader, error) {
|
type generateMapConfig struct {
|
||||||
|
Center s2.LatLng
|
||||||
|
Zoom int
|
||||||
|
Markers []marker
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
DisableAttribution bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g generateMapConfig) getCacheKey() string {
|
||||||
|
markerString := []string{}
|
||||||
|
for _, m := range g.Markers {
|
||||||
|
markerString = append(markerString, m.String())
|
||||||
|
}
|
||||||
|
hashString := fmt.Sprintf("%s|%d|%s|%dx%d|%v",
|
||||||
|
g.Center.String(),
|
||||||
|
g.Zoom,
|
||||||
|
strings.Join(markerString, "+"),
|
||||||
|
g.Width,
|
||||||
|
g.Height,
|
||||||
|
g.DisableAttribution)
|
||||||
|
|
||||||
|
return fmt.Sprintf("%x", sha256.Sum256([]byte(hashString)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateMap(opts generateMapConfig) (io.Reader, error) {
|
||||||
ctx := staticMap.NewContext()
|
ctx := staticMap.NewContext()
|
||||||
ctx.SetUserAgent(fmt.Sprintf("Mozilla/5.0+(compatible; staticmap/%s; https://github.com/Luzifer/staticmap)", version))
|
ctx.SetUserAgent(fmt.Sprintf("Mozilla/5.0+(compatible; staticmap/%s; https://github.com/Luzifer/staticmap)", version))
|
||||||
|
|
||||||
ctx.SetSize(x, y)
|
ctx.SetSize(opts.Width, opts.Height)
|
||||||
ctx.SetCenter(center)
|
ctx.SetCenter(opts.Center)
|
||||||
ctx.SetZoom(zoom)
|
ctx.SetZoom(opts.Zoom)
|
||||||
|
|
||||||
if disableAttribution {
|
if opts.DisableAttribution {
|
||||||
ctx.OverrideAttribution("")
|
ctx.OverrideAttribution("")
|
||||||
}
|
}
|
||||||
|
|
||||||
if marker != nil {
|
if opts.Markers != nil {
|
||||||
for _, m := range marker {
|
for _, m := range opts.Markers {
|
||||||
ctx.AddMarker(staticMap.NewMarker(m.pos, m.color, float64(m.size)))
|
ctx.AddMarker(staticMap.NewMarker(m.pos, m.color, float64(m.size)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue