2013-03-30 2 views
6

Je souhaite démélanger une chaîne geojson dans un type de structure approprié. J'ai trois différentes chaînes de GeoJSON que je veux désorganiser dans le même struct:Type de structure approprié pour unmarshal de 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 jsonBlobPolygonString = []byte(`{"Type":"Polygon", "Coordinates":[[[1.1,2.0],[3.0,6.3],[5.1,7.0],[1.1,2.0]]]}`) 

je suis venu avec un type struct que je ne suis pas totalement satisfait:

type GeojsonType struct { 
    Type string 
    Coordinates interface{} 
} 

Voir ce lien pour l'exemple complet: http://play.golang.org/p/Bt-51BX__A

Je préfère ne pas utiliser l'interface {} pour les coordonnées. J'utiliserais plutôt quelque chose qui me donnerait une certaine validation par exemple Coordinates [] float64 pour Point et Coordinates [] [] float64 pour LineString.

Est-il possible de créer un type struct afin que Point, LineString et Polygon puissent tous être représentés dans Coordinates sans utiliser d'interface?

+0

Avez-vous essayé d'implémenter l'interface Unmarshaler? – Mikke

Répondre

6

Ce que vous voulez, c'est créer 3 types d'objets différents à partir du même dictionnaire json.

Pour autant que je sais que ce n'est pas possible, mais vous pouvez utiliser le type RawMessage pour retarder le décodage JSON et utiliser un peu de pré-traitement like this

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Point struct { 
    Coordinates []float64 
} 

type Line struct { 
    Points [][]float64 
} 

type Polygon struct { 
    Lines [][][]float64 
} 

type GeojsonType struct { 
    Type  string 
    Coordinates json.RawMessage 
    Point  Point 
    Line  Line 
    Polygon  Polygon 
} 

var jsonBlob = []byte(`[ 
{"Type":"Point", "Coordinates":[1.1,2.0]}, 
{"Type":"LineString", "Coordinates":[[1.1,2.0],[3.0,6.3]]}, 
{"Type":"Polygon", "Coordinates":[[[1.1,2.0],[3.0,6.3],[5.1,7.0],[1.1,2.0]]]} 
]`) 

func main() { 
    var geojsonPoints []GeojsonType 
    err := json.Unmarshal(jsonBlob, &geojsonPoints) 
    if err != nil { 
     fmt.Println("error:", err) 
    } 

    // Postprocess the coordinates 

    for i := range geojsonPoints { 
     t := &geojsonPoints[i] 

     switch t.Type { 
     case "Point": 
      err = json.Unmarshal(t.Coordinates, &t.Point.Coordinates) 
     case "LineString": 
      err = json.Unmarshal(t.Coordinates, &t.Line.Points) 
     case "Polygon": 
      err = json.Unmarshal(t.Coordinates, &t.Polygon.Lines) 
     default: 
      panic("Unknown type") 
     } 
     if err != nil { 
      fmt.Printf("Failed to convert %s: %s", t.Type, err) 
     } 
     fmt.Printf("%+v\n", t) 
    } 
} 

qui imprime

&{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]]]}} 
+0

Merci beaucoup! Je pense que c'est exactement ce dont j'ai besoin. – Gunnis

Questions connexes