-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
postmap.go
114 lines (90 loc) · 2.72 KB
/
postmap.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
package main
import (
"crypto/sha256"
"fmt"
"strings"
staticMap "github.com/Luzifer/go-staticmaps"
"github.com/golang/geo/s2"
"github.com/pkg/errors"
)
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 {
return generateMapConfig{}, errors.Errorf("map size exceeds allowed bounds of %dx%d", mapMaxX, mapMaxY)
}
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) {
return nil, errors.Errorf("placeholder %q not found in pattern %q", v, pat)
}
}
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))),
TileSize: 256, //nolint:gomnd
URLPattern: pat,
})
}
return result, nil
}