2018-06-17 14:26:57 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
staticMap "github.com/Luzifer/go-staticmaps"
|
|
|
|
"github.com/golang/geo/s2"
|
2023-10-15 11:19:01 +00:00
|
|
|
"github.com/pkg/errors"
|
2018-06-17 14:26:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type postMapEnvelope struct {
|
|
|
|
Center postMapPoint `json:"center"`
|
|
|
|
Zoom int `json:"zoom"`
|
|
|
|
Markers postMapMarkers `json:"markers"`
|
|
|
|
Width int `json:"width"`
|
|
|
|
Height int `json:"height"`
|
|
|
|
DisableAttribution bool `json:"disable_attribution"`
|
|
|
|
Overlays postMapOverlay `json:"overlays"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p postMapEnvelope) toGenerateMapConfig() (generateMapConfig, error) {
|
|
|
|
result := generateMapConfig{
|
|
|
|
Center: p.Center.getPoint(),
|
|
|
|
Zoom: p.Zoom,
|
|
|
|
Width: p.Width,
|
|
|
|
Height: p.Height,
|
|
|
|
DisableAttribution: p.DisableAttribution,
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.Width > mapMaxX || p.Height > mapMaxY {
|
2023-10-15 11:19:01 +00:00
|
|
|
return generateMapConfig{}, errors.Errorf("map size exceeds allowed bounds of %dx%d", mapMaxX, mapMaxY)
|
2018-06-17 14:26:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
|
|
|
if result.Markers, err = p.Markers.toMarkers(); err != nil {
|
|
|
|
return generateMapConfig{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if result.Overlays, err = p.Overlays.toOverlays(); err != nil {
|
|
|
|
return generateMapConfig{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type postMapMarker struct {
|
|
|
|
Size string `json:"size"`
|
|
|
|
Color string `json:"color"`
|
|
|
|
Coord postMapPoint `json:"coord"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p postMapMarker) String() string {
|
|
|
|
parts := []string{}
|
|
|
|
|
|
|
|
if p.Size != "" {
|
|
|
|
parts = append(parts, fmt.Sprintf("size:%s", p.Size))
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.Color != "" {
|
|
|
|
parts = append(parts, fmt.Sprintf("color:%s", p.Color))
|
|
|
|
}
|
|
|
|
|
|
|
|
parts = append(parts, p.Coord.String())
|
|
|
|
return strings.Join(parts, "|")
|
|
|
|
}
|
|
|
|
|
|
|
|
type postMapMarkers []postMapMarker
|
|
|
|
|
|
|
|
func (p postMapMarkers) toMarkers() ([]marker, error) {
|
|
|
|
raw := []string{}
|
|
|
|
for _, pm := range p {
|
|
|
|
raw = append(raw, pm.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
return parseMarkerLocations(raw)
|
|
|
|
}
|
|
|
|
|
|
|
|
type postMapPoint struct {
|
|
|
|
Lat float64 `json:"lat"`
|
|
|
|
Lon float64 `json:"lon"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p postMapPoint) String() string {
|
|
|
|
return fmt.Sprintf("%f,%f", p.Lat, p.Lon)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p postMapPoint) getPoint() s2.LatLng {
|
|
|
|
return s2.LatLngFromDegrees(p.Lat, p.Lon)
|
|
|
|
}
|
|
|
|
|
|
|
|
type postMapOverlay []string
|
|
|
|
|
|
|
|
func (p postMapOverlay) toOverlays() ([]*staticMap.TileProvider, error) {
|
|
|
|
result := []*staticMap.TileProvider{}
|
|
|
|
for _, pat := range p {
|
|
|
|
for _, v := range []string{`{0}`, `{1}`, `{2}`} {
|
|
|
|
if !strings.Contains(pat, v) {
|
2023-10-15 11:19:01 +00:00
|
|
|
return nil, errors.Errorf("placeholder %q not found in pattern %q", v, pat)
|
2018-06-17 14:26:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pat = strings.NewReplacer(`{0}`, `%[2]d`, `{1}`, `%[3]d`, `{2}`, `%[4]d`).Replace(pat)
|
|
|
|
|
|
|
|
result = append(result, &staticMap.TileProvider{
|
|
|
|
Name: fmt.Sprintf("%x", sha256.Sum256([]byte(pat))),
|
2023-10-15 11:19:01 +00:00
|
|
|
TileSize: 256, //nolint:gomnd
|
2018-06-17 14:26:57 +00:00
|
|
|
URLPattern: pat,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|