Go 适用于geojson解组的结构类型
我想将geojson字符串解组为合适的结构类型。 我想将三个不同的geojson字符串解组到同一个结构中:Go 适用于geojson解组的结构类型,go,Go,我想将geojson字符串解组为合适的结构类型。 我想将三个不同的geojson字符串解组到同一个结构中: var jsonBlobPointString = []byte(`{"Type":"Point", "Coordinates":[1.1,2.0]}`) var jsonBlobLineString = []byte(`{"Type":"LineString", "Coordinates":[[1.1,2.0],[3.0,6.3]]}`) var jsonBlobPolygonStrin
var jsonBlobPointString = []byte(`{"Type":"Point", "Coordinates":[1.1,2.0]}`)
var jsonBlobLineString = []byte(`{"Type":"LineString", "Coordinates":[[1.1,2.0],[3.0,6.3]]}`)
var jsonBlobPolygonString = []byte(`{"Type":"Polygon", "Coordinates":[[[1.1,2.0],[3.0,6.3],[5.1,7.0],[1.1,2.0]]]}`)
我提出了一种我并不完全满意的结构类型:
type GeojsonType struct {
Type string
Coordinates interface{}
}
有关完整示例,请参见此链接:
我宁愿不使用接口{}作为坐标。
相反,我会使用一些可以给我一些验证的东西,例如点的坐标[]float64
和坐标[][]表示LineString
是否可以创建一个结构类型,使点、线字符串和多边形都可以在坐标中表示,而无需使用接口?您需要的是从同一个json字典创建3种不同类型的对象 据我所知,这是不可能的,但是您可以使用类型来延迟json解码,并使用一些预处理 哪张照片
&{Type:Point Coordinates:[91 49 46 49 44 50 46 48 93] Point:{Coordinates:[1.1 2]} Line:{Points:[]} Polygon:{Lines:[]}}
&{Type:LineString Coordinates:[91 91 49 46 49 44 50 46 48 93 44 91 51 46 48 44 54 46 51 93 93] Point:{Coordinates:[]} Line:{Points:[[1.1 2] [3 6.3]]} Polygon:{Lines:[]}}
&{Type:Polygon Coordinates:[91 91 91 49 46 49 44 50 46 48 93 44 91 51 46 48 44 54 46 51 93 44 91 53 46 49 44 55 46 48 93 44 91 49 46 49 44 50 46 48 93 93 93] Point:{Coordinates:[]} Line:{Points:[]} Polygon:{Lines:[[[1.1 2] [3 6.3] [5.1 7] [1.1 2]]]}}
基于Nick Craig Wood answer,我构建了以下Marshal/UnMarshal函数
package geojson
//https://stackoverflow.com/questions/15719532/suitable-struct-type-for-unmarshal-of-geojson
import (
"encoding/json"
)
type Point struct {
Coordinates []float64
}
type Line struct {
Points [][]float64
}
type Polygon struct {
Lines [][][]float64
}
type Geojson struct {
Type string `json:"type"`
Coordinates json.RawMessage `json:"coordinates"`
Point Point `json:"-"`
Line Line `json:"-"`
Polygon Polygon `json:"-"`
}
func (g *Geojson) UnmarshalJSON(b []byte) error {
type Alias Geojson
aux := (*Alias)(g)
err := json.Unmarshal(b, &aux)
if err != nil {
return err
}
switch g.Type {
case "Point":
err = json.Unmarshal(g.Coordinates, &g.Point.Coordinates)
case "LineString":
err = json.Unmarshal(g.Coordinates, &g.Line.Points)
case "Polygon":
err = json.Unmarshal(g.Coordinates, &g.Polygon.Lines)
}
g.Coordinates = []byte(nil)
return err
}
func (g Geojson) MarshalJSON() ([]byte, error) {
var raw json.RawMessage
var err error
switch g.Type {
case "Point":
raw, err = json.Marshal(&g.Point.Coordinates)
case "LineString":
raw, err = json.Marshal(&g.Line.Points)
case "Polygon":
raw, err = json.Marshal(&g.Polygon.Lines)
}
if err != nil {
return nil, err
}
g.Coordinates = raw
type Alias Geojson
aux := (*Alias)(&g)
return json.Marshal(aux)
}
您是否尝试过实现解组器接口?非常感谢!我想这正是我所需要的。如何将这个对象序列化回geojson?
package geojson
//https://stackoverflow.com/questions/15719532/suitable-struct-type-for-unmarshal-of-geojson
import (
"encoding/json"
)
type Point struct {
Coordinates []float64
}
type Line struct {
Points [][]float64
}
type Polygon struct {
Lines [][][]float64
}
type Geojson struct {
Type string `json:"type"`
Coordinates json.RawMessage `json:"coordinates"`
Point Point `json:"-"`
Line Line `json:"-"`
Polygon Polygon `json:"-"`
}
func (g *Geojson) UnmarshalJSON(b []byte) error {
type Alias Geojson
aux := (*Alias)(g)
err := json.Unmarshal(b, &aux)
if err != nil {
return err
}
switch g.Type {
case "Point":
err = json.Unmarshal(g.Coordinates, &g.Point.Coordinates)
case "LineString":
err = json.Unmarshal(g.Coordinates, &g.Line.Points)
case "Polygon":
err = json.Unmarshal(g.Coordinates, &g.Polygon.Lines)
}
g.Coordinates = []byte(nil)
return err
}
func (g Geojson) MarshalJSON() ([]byte, error) {
var raw json.RawMessage
var err error
switch g.Type {
case "Point":
raw, err = json.Marshal(&g.Point.Coordinates)
case "LineString":
raw, err = json.Marshal(&g.Line.Points)
case "Polygon":
raw, err = json.Marshal(&g.Polygon.Lines)
}
if err != nil {
return nil, err
}
g.Coordinates = raw
type Alias Geojson
aux := (*Alias)(&g)
return json.Marshal(aux)
}