223 lines
5.9 KiB
Go
223 lines
5.9 KiB
Go
package service
|
|
|
|
import "strings"
|
|
|
|
type MapPreviewView struct {
|
|
Mode string `json:"mode"`
|
|
BaseTiles *PreviewBaseTiles `json:"baseTiles,omitempty"`
|
|
Viewport *PreviewViewport `json:"viewport,omitempty"`
|
|
Variants []PreviewVariantView `json:"variants,omitempty"`
|
|
SelectedVariantID *string `json:"selectedVariantId,omitempty"`
|
|
}
|
|
|
|
type PreviewBaseTiles struct {
|
|
TileBaseURL string `json:"tileBaseUrl"`
|
|
Zoom *int `json:"zoom,omitempty"`
|
|
TileSize *int `json:"tileSize,omitempty"`
|
|
}
|
|
|
|
type PreviewViewport struct {
|
|
Width *int `json:"width,omitempty"`
|
|
Height *int `json:"height,omitempty"`
|
|
MinLon *float64 `json:"minLon,omitempty"`
|
|
MinLat *float64 `json:"minLat,omitempty"`
|
|
MaxLon *float64 `json:"maxLon,omitempty"`
|
|
MaxLat *float64 `json:"maxLat,omitempty"`
|
|
}
|
|
|
|
type PreviewVariantView struct {
|
|
VariantID string `json:"variantId"`
|
|
Name *string `json:"name,omitempty"`
|
|
RouteCode *string `json:"routeCode,omitempty"`
|
|
Controls []PreviewControlView `json:"controls,omitempty"`
|
|
Legs []PreviewLegView `json:"legs,omitempty"`
|
|
}
|
|
|
|
type PreviewControlView struct {
|
|
ID string `json:"id"`
|
|
Kind *string `json:"kind,omitempty"`
|
|
Lon *float64 `json:"lon,omitempty"`
|
|
Lat *float64 `json:"lat,omitempty"`
|
|
Label *string `json:"label,omitempty"`
|
|
}
|
|
|
|
type PreviewLegView struct {
|
|
From string `json:"from"`
|
|
To string `json:"to"`
|
|
}
|
|
|
|
func buildPreviewFromPayload(payloadJSON *string) (*MapPreviewView, error) {
|
|
if payloadJSON == nil || strings.TrimSpace(*payloadJSON) == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
payload, err := decodeJSONObject(*payloadJSON)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rawPreview, _ := payload["preview"].(map[string]any)
|
|
if len(rawPreview) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
view := &MapPreviewView{}
|
|
if mode := readStringField(rawPreview, "mode"); mode != nil {
|
|
view.Mode = *mode
|
|
}
|
|
if view.Mode == "" {
|
|
view.Mode = "readonly"
|
|
}
|
|
|
|
if rawBaseTiles, ok := rawPreview["baseTiles"].(map[string]any); ok && len(rawBaseTiles) > 0 {
|
|
baseTiles := &PreviewBaseTiles{}
|
|
if tileBaseURL := readStringField(rawBaseTiles, "tileBaseUrl"); tileBaseURL != nil {
|
|
baseTiles.TileBaseURL = *tileBaseURL
|
|
}
|
|
baseTiles.Zoom = readIntField(rawBaseTiles, "zoom")
|
|
baseTiles.TileSize = readIntField(rawBaseTiles, "tileSize")
|
|
if strings.TrimSpace(baseTiles.TileBaseURL) != "" {
|
|
view.BaseTiles = baseTiles
|
|
}
|
|
}
|
|
|
|
if rawViewport, ok := rawPreview["viewport"].(map[string]any); ok && len(rawViewport) > 0 {
|
|
viewport := &PreviewViewport{
|
|
Width: readIntField(rawViewport, "width"),
|
|
Height: readIntField(rawViewport, "height"),
|
|
MinLon: readFloatField(rawViewport, "minLon"),
|
|
MinLat: readFloatField(rawViewport, "minLat"),
|
|
MaxLon: readFloatField(rawViewport, "maxLon"),
|
|
MaxLat: readFloatField(rawViewport, "maxLat"),
|
|
}
|
|
view.Viewport = viewport
|
|
}
|
|
|
|
if selectedVariantID := readStringField(rawPreview, "selectedVariantId"); selectedVariantID != nil {
|
|
view.SelectedVariantID = selectedVariantID
|
|
}
|
|
|
|
rawVariants, _ := rawPreview["variants"].([]any)
|
|
if len(rawVariants) > 0 {
|
|
view.Variants = make([]PreviewVariantView, 0, len(rawVariants))
|
|
for _, raw := range rawVariants {
|
|
item, ok := raw.(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
variantID := readStringField(item, "variantId")
|
|
if variantID == nil || strings.TrimSpace(*variantID) == "" {
|
|
variantID = readStringField(item, "id")
|
|
}
|
|
if variantID == nil || strings.TrimSpace(*variantID) == "" {
|
|
continue
|
|
}
|
|
variant := PreviewVariantView{
|
|
VariantID: *variantID,
|
|
Name: readStringField(item, "name"),
|
|
RouteCode: readStringField(item, "routeCode"),
|
|
}
|
|
rawControls, _ := item["controls"].([]any)
|
|
if len(rawControls) > 0 {
|
|
variant.Controls = make([]PreviewControlView, 0, len(rawControls))
|
|
for _, rawControl := range rawControls {
|
|
controlMap, ok := rawControl.(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
controlID := readStringField(controlMap, "id")
|
|
if controlID == nil || strings.TrimSpace(*controlID) == "" {
|
|
continue
|
|
}
|
|
variant.Controls = append(variant.Controls, PreviewControlView{
|
|
ID: *controlID,
|
|
Kind: readStringField(controlMap, "kind"),
|
|
Lon: readFloatField(controlMap, "lon"),
|
|
Lat: readFloatField(controlMap, "lat"),
|
|
Label: readStringField(controlMap, "label"),
|
|
})
|
|
}
|
|
}
|
|
rawLegs, _ := item["legs"].([]any)
|
|
if len(rawLegs) > 0 {
|
|
variant.Legs = make([]PreviewLegView, 0, len(rawLegs))
|
|
for _, rawLeg := range rawLegs {
|
|
legMap, ok := rawLeg.(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
from := readStringField(legMap, "from")
|
|
to := readStringField(legMap, "to")
|
|
if from == nil || to == nil || strings.TrimSpace(*from) == "" || strings.TrimSpace(*to) == "" {
|
|
continue
|
|
}
|
|
variant.Legs = append(variant.Legs, PreviewLegView{
|
|
From: *from,
|
|
To: *to,
|
|
})
|
|
}
|
|
}
|
|
view.Variants = append(view.Variants, variant)
|
|
}
|
|
}
|
|
|
|
if view.BaseTiles == nil && view.Viewport == nil && len(view.Variants) == 0 {
|
|
return nil, nil
|
|
}
|
|
return view, nil
|
|
}
|
|
|
|
func readIntField(object map[string]any, key string) *int {
|
|
if object == nil {
|
|
return nil
|
|
}
|
|
value, ok := object[key]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
switch v := value.(type) {
|
|
case int:
|
|
result := v
|
|
return &result
|
|
case int32:
|
|
result := int(v)
|
|
return &result
|
|
case int64:
|
|
result := int(v)
|
|
return &result
|
|
case float64:
|
|
result := int(v)
|
|
return &result
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func readFloatField(object map[string]any, key string) *float64 {
|
|
if object == nil {
|
|
return nil
|
|
}
|
|
value, ok := object[key]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
switch v := value.(type) {
|
|
case float64:
|
|
result := v
|
|
return &result
|
|
case float32:
|
|
result := float64(v)
|
|
return &result
|
|
case int:
|
|
result := float64(v)
|
|
return &result
|
|
case int32:
|
|
result := float64(v)
|
|
return &result
|
|
case int64:
|
|
result := float64(v)
|
|
return &result
|
|
default:
|
|
return nil
|
|
}
|
|
}
|