2010-06-08 9 views
18

Ho un DB pieno di indirizzi che ho bisogno di ottenere lat e long, quindi voglio collegarli e usare Google Geocode per aggiornare il mio database. Sono bloccato su come analizzare il risultato JSON per ottenere quello che mi serve:parse google maps geocode json risposta all'oggetto utilizzando Json.Net

var address = "http://maps.google.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false"; 
var result = new System.Net.WebClient().DownloadString(address); 
GoogleGeoCodeResponse test = JsonConvert.DeserializeObject<GoogleGeoCodeResponse>(result); 

ho pensato che avrei potuto semplicemente costruire una classe rapido e utilizzare JSON.Net per deserializzare il risultato, ed è tipo di lavorazione, ma Penso che sto soffia sulla mia struttura di classe:

public class GoogleGeoCodeResponse { 

    public string status { get; set; } 
    public geometry geometry { get; set; } 

} 

public class geometry { 
    public string location_type { get; set; } 
    public location location { get; set; } 
} 

public class location { 
    public string lat {get;set;} 
    public string lng {get;set;} 
} 

Ecco un esempio di ciò che ottenere restituito da Google:

{ 
    "status": "OK", 
    "results": [ { 
    "types": [ "street_address" ], 
    "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", 
    "address_components": [ { 
     "long_name": "1600", 
     "short_name": "1600", 
     "types": [ "street_number" ] 
    }, { 
     "long_name": "Amphitheatre Pkwy", 
     "short_name": "Amphitheatre Pkwy", 
     "types": [ "route" ] 
    }, { 
     "long_name": "Mountain View", 
     "short_name": "Mountain View", 
     "types": [ "locality", "political" ] 
    }, { 
     "long_name": "California", 
     "short_name": "CA", 
     "types": [ "administrative_area_level_1", "political" ] 
    }, { 
     "long_name": "United States", 
     "short_name": "US", 
     "types": [ "country", "political" ] 
    }, { 
     "long_name": "94043", 
     "short_name": "94043", 
     "types": [ "postal_code" ] 
    } ], 
    "geometry": { 
     "location": { 
     "lat": 37.4219720, 
     "lng": -122.0841430 
     }, 
     "location_type": "ROOFTOP", 
     "viewport": { 
     "southwest": { 
      "lat": 37.4188244, 
      "lng": -122.0872906 
     }, 
     "northeast": { 
      "lat": 37.4251196, 
      "lng": -122.0809954 
     } 
     } 
    } 
    } ] 
} 

mi manca semplice qui lo so, chiunque?

risposta

44

ho provato questo, ha fatto un semplice test e ha funzionato (aggiunta di risultati e altri):

public class GoogleGeoCodeResponse 
{ 

    public string status { get; set; } 
    public results[] results { get; set; } 

} 

public class results 
{ 
    public string formatted_address { get; set; } 
    public geometry geometry { get; set; } 
    public string[] types { get; set; } 
    public address_component[] address_components { get; set; } 
} 

public class geometry 
{ 
    public string location_type { get; set; } 
    public location location { get; set; } 
} 

public class location 
{ 
    public string lat { get; set; } 
    public string lng { get; set; } 
} 

public class address_component 
{ 
    public string long_name { get; set; } 
    public string short_name { get; set; } 
    public string[] types { get; set; } 
} 
+2

tuo la struttura dei dati funziona per me, ma preferisco definire location.lat e location.lng come decimali. Allo stesso modo è più semplice avere enumerazione per lo stato della risposta, i tipi di risultati e i tipi di posizione. Json.NET deserializzerà correttamente le stringhe in enumerazione. – Mart

+0

Questa riga "risultati pubblici [] risultati {get; set;}" ha risolto un roadblock di due ore. Non ho mai pensato di mettere un altro livello di classe sopra la classe dei risultati. Grazie. – TrueCoke

+0

@antonio Cool ed è solo il secondo a prendere dati grazie –

20

È possibile utilizzare un oggetto dinamico piuttosto che definire l'oggetto.

public static dynamic GEOCodeAddress(String Address) 
    { 
     var address = String.Format("http://maps.google.com/maps/api/geocode/json?address={0}&sensor=false", Address.Replace(" ", "+")); 
     var result = new System.Net.WebClient().DownloadString(address); 
     JavaScriptSerializer jss = new JavaScriptSerializer(); 
     return jss.Deserialize<dynamic>(result); 
    } 
+1

è -> System.Web.Script.Serialization.JavaScriptSerializer in System.Web.Extensions (in System.Web.Extensions.dll) – JGilmartin

+1

Amo la semplicità di questo. –

+1

Bellissimo lavoro .. Ho provato questo, funziona bene con .NET Framework 4 (Microsoft.Csharp.dll); mentre non funziona in .NET Framework 3.5. Qualche idea? – Praveen

3

C# Oggetto Codice ho aggiunto un paio di lezioni extra, non so se sono nuovi alle API, ma ho pensato che questo potrebbe essere utile a qualcuno.

public class GoogleGeoCodeResponse 
    { 
     public results[] results { get; set; } 
     public string status { get; set; } 

    } 

    public class results 
    { 
     public address_component[] address_components { get; set; } 
     public string formatted_address { get; set; } 
     public geometry geometry { get; set; } 
     public string[] types { get; set; } 
    } 

    public class address_component 
    { 
     String long_name { get; set; } 
     String short_name { get; set; } 
     String types { get; set; } 

    } 

    public class geometry 
    { 
     public bounds bounds { get; set; } 
     public location location { get; set; } 
     public string location_type { get; set; } 
     public viewport viewport { get; set; } 
    } 

    public class location 
    { 
     public string lat { get; set; } 
     public string lng { get; set; } 
    } 

    public class viewport 
    { 
     public northeast northeast { get; set; } 
     public southwest southwest { get; set; } 
    } 

    public class bounds 
    { 
     public northeast northeast { get; set; } 
    } 

    public class northeast 
    { 
     public string lat { get; set; } 
     public string lng { get; set; } 
    } 

    public class southwest 
    { 
     public string lat { get; set; } 
     public string lng { get; set; } 
    } 
1

Grazie a JEuvin sopra, sono stato in grado di passare facilmente da XML a JSON con alcuni mods al codice di cui sopra (in particolare la modifica lat e lng in decimale o doppio) e aveva anche cambiare address_components.types a string [] per farlo funzionare per me. Ho quindi refactored un po 'in modo che le stesse classi possano essere deserializzate da XML o Json in modo intercambiabile.

Forse questo aiuterà qualcuno anche ...

using System; 
using System.Xml.Serialization; 

[Serializable] 
[XmlType(AnonymousType = true)] 
[XmlRoot(Namespace = "", IsNullable = false)] 
public class GeocodeResponse 
{ 
    public GeocodeResponse() 
    { 
    } 

    [XmlElement("result")] 

    public results[] results { get; set; } 

    public string status { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class results 
{ 
    public results() 
    { 
    } 

    [XmlElement("address_component")] 

    public address_component[] address_components { get; set; } 

    public string formatted_address { get; set; } 

    public geometry geometry { get; set; } 

    [XmlElement("type")] 
    public string[] types { get; set; } 

    public string[] postcode_localities { get; set; } 

    public bool partial_match { get; set; } 

    public string place_id { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class address_component 
{ 
    public address_component() 
    { 
    } 

    public string long_name { get; set; } 

    public string short_name { get; set; } 

    [XmlElement("type")] 
    public string[] types { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class geometry 
{ 
    public geometry() 
    { 
    } 

    public bounds bounds { get; set; } 

    public location location { get; set; } 

    public string location_type { get; set; } 

    public viewport viewport { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class location 
{ 
    public location() 
    { 
    } 

    public double lat { get; set; } 

    public double lng { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class viewport 
{ 
    public viewport() 
    { 
    } 

    public northeast northeast { get; set; } 

    public southwest southwest { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class bounds 
{ 
    public bounds() 
    { 
    } 

    public northeast northeast { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class northeast 
{ 
    public northeast() 
    { 
    } 

    public double lat { get; set; } 

    public double lng { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class southwest 
{ 
    public southwest() 
    { 
    } 

    public double lat { get; set; } 

    public double lng { get; set; } 
} 

(modificata con l'aggiunta di postcode_localities e proprietà partial_match)

+1

Assicurati di aggiungere anche alcuni attributi JSON. Aiuta per le operazioni js. Personalmente non mi piace usare XML. – JEuvin

0

Assicurarsi che la classe è Serializable, permettono nullables

[Serializable] 
[XmlType(AnonymousType = true)] 
[XmlRoot(Namespace = "", IsNullable = true)] 
public class GeocodeResponse 
{ 
    public GeocodeResponse() 
    { 
     // can be empty or you can initiate the properties here 
    } 

    [XmlElement("location ")] 
    [Display(Name = "location ")] 
    // add json attributes as well 
    public location location { get; set; } 

    public string status { get; set; } 
    } 
Problemi correlati