preview_contract.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package service
  2. import "strings"
  3. type MapPreviewView struct {
  4. Mode string `json:"mode"`
  5. BaseTiles *PreviewBaseTiles `json:"baseTiles,omitempty"`
  6. Viewport *PreviewViewport `json:"viewport,omitempty"`
  7. Variants []PreviewVariantView `json:"variants,omitempty"`
  8. SelectedVariantID *string `json:"selectedVariantId,omitempty"`
  9. }
  10. type PreviewBaseTiles struct {
  11. TileBaseURL string `json:"tileBaseUrl"`
  12. Zoom *int `json:"zoom,omitempty"`
  13. TileSize *int `json:"tileSize,omitempty"`
  14. }
  15. type PreviewViewport struct {
  16. Width *int `json:"width,omitempty"`
  17. Height *int `json:"height,omitempty"`
  18. MinLon *float64 `json:"minLon,omitempty"`
  19. MinLat *float64 `json:"minLat,omitempty"`
  20. MaxLon *float64 `json:"maxLon,omitempty"`
  21. MaxLat *float64 `json:"maxLat,omitempty"`
  22. }
  23. type PreviewVariantView struct {
  24. VariantID string `json:"variantId"`
  25. Name *string `json:"name,omitempty"`
  26. RouteCode *string `json:"routeCode,omitempty"`
  27. Controls []PreviewControlView `json:"controls,omitempty"`
  28. Legs []PreviewLegView `json:"legs,omitempty"`
  29. }
  30. type PreviewControlView struct {
  31. ID string `json:"id"`
  32. Kind *string `json:"kind,omitempty"`
  33. Lon *float64 `json:"lon,omitempty"`
  34. Lat *float64 `json:"lat,omitempty"`
  35. Label *string `json:"label,omitempty"`
  36. }
  37. type PreviewLegView struct {
  38. From string `json:"from"`
  39. To string `json:"to"`
  40. }
  41. func buildPreviewFromPayload(payloadJSON *string) (*MapPreviewView, error) {
  42. if payloadJSON == nil || strings.TrimSpace(*payloadJSON) == "" {
  43. return nil, nil
  44. }
  45. payload, err := decodeJSONObject(*payloadJSON)
  46. if err != nil {
  47. return nil, err
  48. }
  49. rawPreview, _ := payload["preview"].(map[string]any)
  50. if len(rawPreview) == 0 {
  51. return nil, nil
  52. }
  53. view := &MapPreviewView{}
  54. if mode := readStringField(rawPreview, "mode"); mode != nil {
  55. view.Mode = *mode
  56. }
  57. if view.Mode == "" {
  58. view.Mode = "readonly"
  59. }
  60. if rawBaseTiles, ok := rawPreview["baseTiles"].(map[string]any); ok && len(rawBaseTiles) > 0 {
  61. baseTiles := &PreviewBaseTiles{}
  62. if tileBaseURL := readStringField(rawBaseTiles, "tileBaseUrl"); tileBaseURL != nil {
  63. baseTiles.TileBaseURL = *tileBaseURL
  64. }
  65. baseTiles.Zoom = readIntField(rawBaseTiles, "zoom")
  66. baseTiles.TileSize = readIntField(rawBaseTiles, "tileSize")
  67. if strings.TrimSpace(baseTiles.TileBaseURL) != "" {
  68. view.BaseTiles = baseTiles
  69. }
  70. }
  71. if rawViewport, ok := rawPreview["viewport"].(map[string]any); ok && len(rawViewport) > 0 {
  72. viewport := &PreviewViewport{
  73. Width: readIntField(rawViewport, "width"),
  74. Height: readIntField(rawViewport, "height"),
  75. MinLon: readFloatField(rawViewport, "minLon"),
  76. MinLat: readFloatField(rawViewport, "minLat"),
  77. MaxLon: readFloatField(rawViewport, "maxLon"),
  78. MaxLat: readFloatField(rawViewport, "maxLat"),
  79. }
  80. view.Viewport = viewport
  81. }
  82. if selectedVariantID := readStringField(rawPreview, "selectedVariantId"); selectedVariantID != nil {
  83. view.SelectedVariantID = selectedVariantID
  84. }
  85. rawVariants, _ := rawPreview["variants"].([]any)
  86. if len(rawVariants) > 0 {
  87. view.Variants = make([]PreviewVariantView, 0, len(rawVariants))
  88. for _, raw := range rawVariants {
  89. item, ok := raw.(map[string]any)
  90. if !ok {
  91. continue
  92. }
  93. variantID := readStringField(item, "variantId")
  94. if variantID == nil || strings.TrimSpace(*variantID) == "" {
  95. variantID = readStringField(item, "id")
  96. }
  97. if variantID == nil || strings.TrimSpace(*variantID) == "" {
  98. continue
  99. }
  100. variant := PreviewVariantView{
  101. VariantID: *variantID,
  102. Name: readStringField(item, "name"),
  103. RouteCode: readStringField(item, "routeCode"),
  104. }
  105. rawControls, _ := item["controls"].([]any)
  106. if len(rawControls) > 0 {
  107. variant.Controls = make([]PreviewControlView, 0, len(rawControls))
  108. for _, rawControl := range rawControls {
  109. controlMap, ok := rawControl.(map[string]any)
  110. if !ok {
  111. continue
  112. }
  113. controlID := readStringField(controlMap, "id")
  114. if controlID == nil || strings.TrimSpace(*controlID) == "" {
  115. continue
  116. }
  117. variant.Controls = append(variant.Controls, PreviewControlView{
  118. ID: *controlID,
  119. Kind: readStringField(controlMap, "kind"),
  120. Lon: readFloatField(controlMap, "lon"),
  121. Lat: readFloatField(controlMap, "lat"),
  122. Label: readStringField(controlMap, "label"),
  123. })
  124. }
  125. }
  126. rawLegs, _ := item["legs"].([]any)
  127. if len(rawLegs) > 0 {
  128. variant.Legs = make([]PreviewLegView, 0, len(rawLegs))
  129. for _, rawLeg := range rawLegs {
  130. legMap, ok := rawLeg.(map[string]any)
  131. if !ok {
  132. continue
  133. }
  134. from := readStringField(legMap, "from")
  135. to := readStringField(legMap, "to")
  136. if from == nil || to == nil || strings.TrimSpace(*from) == "" || strings.TrimSpace(*to) == "" {
  137. continue
  138. }
  139. variant.Legs = append(variant.Legs, PreviewLegView{
  140. From: *from,
  141. To: *to,
  142. })
  143. }
  144. }
  145. view.Variants = append(view.Variants, variant)
  146. }
  147. }
  148. if view.BaseTiles == nil && view.Viewport == nil && len(view.Variants) == 0 {
  149. return nil, nil
  150. }
  151. return view, nil
  152. }
  153. func readIntField(object map[string]any, key string) *int {
  154. if object == nil {
  155. return nil
  156. }
  157. value, ok := object[key]
  158. if !ok {
  159. return nil
  160. }
  161. switch v := value.(type) {
  162. case int:
  163. result := v
  164. return &result
  165. case int32:
  166. result := int(v)
  167. return &result
  168. case int64:
  169. result := int(v)
  170. return &result
  171. case float64:
  172. result := int(v)
  173. return &result
  174. default:
  175. return nil
  176. }
  177. }
  178. func readFloatField(object map[string]any, key string) *float64 {
  179. if object == nil {
  180. return nil
  181. }
  182. value, ok := object[key]
  183. if !ok {
  184. return nil
  185. }
  186. switch v := value.(type) {
  187. case float64:
  188. result := v
  189. return &result
  190. case float32:
  191. result := float64(v)
  192. return &result
  193. case int:
  194. result := float64(v)
  195. return &result
  196. case int32:
  197. result := float64(v)
  198. return &result
  199. case int64:
  200. result := float64(v)
  201. return &result
  202. default:
  203. return nil
  204. }
  205. }