|
1 | 1 | package models |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "encoding/json" |
| 5 | + "fmt" |
4 | 6 | "time" |
5 | 7 |
|
6 | 8 | "github.com/golang/geo/s2" |
@@ -72,6 +74,83 @@ type Volume3D struct { |
72 | 74 | Footprint Geometry |
73 | 75 | } |
74 | 76 |
|
| 77 | +type Volume3DJSON struct { |
| 78 | + AltitudeHi *float32 `json:"AltitudeHi,omitempty"` |
| 79 | + AltitudeLo *float32 `json:"AltitudeLo,omitempty"` |
| 80 | + Footprint *geometryJSON `json:"Footprint,omitempty"` |
| 81 | +} |
| 82 | + |
| 83 | +type geometryType string |
| 84 | + |
| 85 | +const ( |
| 86 | + circle geometryType = "circle" |
| 87 | + polygon geometryType = "polygon" |
| 88 | + cells geometryType = "cells" |
| 89 | +) |
| 90 | + |
| 91 | +// geometryJSON is a helper struct for marshaling and unmarshaling Geometry types to/from JSON. |
| 92 | +type geometryJSON struct { |
| 93 | + Type geometryType `json:"type"` |
| 94 | + Polygon *GeoPolygon `json:"polygon,omitempty"` |
| 95 | + Circle *GeoCircle `json:"circle,omitempty"` |
| 96 | + Cells []s2.CellID `json:"cells,omitempty"` |
| 97 | +} |
| 98 | + |
| 99 | +func (v Volume3D) MarshalJSON() ([]byte, error) { |
| 100 | + w := Volume3DJSON{AltitudeHi: v.AltitudeHi, AltitudeLo: v.AltitudeLo} |
| 101 | + if v.Footprint != nil { |
| 102 | + switch f := v.Footprint.(type) { |
| 103 | + case *GeoPolygon: |
| 104 | + w.Footprint = &geometryJSON{Type: polygon, Polygon: f} |
| 105 | + |
| 106 | + case *GeoCircle: |
| 107 | + w.Footprint = &geometryJSON{Type: circle, Circle: f} |
| 108 | + |
| 109 | + case precomputedCellGeometry: |
| 110 | + cellsResult := make([]s2.CellID, 0, len(f)) |
| 111 | + for id := range f { |
| 112 | + cellsResult = append(cellsResult, id) |
| 113 | + } |
| 114 | + w.Footprint = &geometryJSON{Type: cells, Cells: cellsResult} |
| 115 | + |
| 116 | + default: |
| 117 | + return nil, fmt.Errorf("Volume3D: unsupported Footprint type %T for JSON marshaling", v.Footprint) |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + return json.Marshal(w) |
| 122 | +} |
| 123 | + |
| 124 | +func (v *Volume3D) UnmarshalJSON(data []byte) error { |
| 125 | + var w Volume3DJSON |
| 126 | + if err := json.Unmarshal(data, &w); err != nil { |
| 127 | + return err |
| 128 | + } |
| 129 | + v.AltitudeHi = w.AltitudeHi |
| 130 | + v.AltitudeLo = w.AltitudeLo |
| 131 | + if w.Footprint != nil { |
| 132 | + switch w.Footprint.Type { |
| 133 | + case polygon: |
| 134 | + v.Footprint = w.Footprint.Polygon |
| 135 | + |
| 136 | + case circle: |
| 137 | + v.Footprint = w.Footprint.Circle |
| 138 | + |
| 139 | + case cells: |
| 140 | + pcg := make(precomputedCellGeometry, len(w.Footprint.Cells)) |
| 141 | + for _, id := range w.Footprint.Cells { |
| 142 | + pcg[id] = struct{}{} |
| 143 | + } |
| 144 | + |
| 145 | + v.Footprint = pcg |
| 146 | + default: |
| 147 | + return fmt.Errorf("Volume3D: unknown geometry type %q", w.Footprint.Type) |
| 148 | + } |
| 149 | + } |
| 150 | + |
| 151 | + return nil |
| 152 | +} |
| 153 | + |
75 | 154 | // Geometry models a geometry. |
76 | 155 | type Geometry interface { |
77 | 156 | // CalculateCovering returns an s2 cell covering for a geometry. |
|
0 commit comments