2010-06-08 3 views
18

Mam DB pełne adresy potrzebuję dostać lat i tęsknię za, więc chcę pętli przez nich i używać Google Geocode do aktualizacji mojej bazy danych. Siedzę, jak analizować wynik JSON, aby dostać to, czego potrzebuję:parse google map geokodu json odpowiedź na obiekt przy użyciu 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); 

Myślałem, że mogę po prostu zbudować szybki klasę i używać Json.NET deserializacji wynik, a to niby działa, ale Myślę, że jestem dmuchanie na moim struktury klasowej:

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;} 
} 

Oto próbka tego, co się wrócili z 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 
     } 
     } 
    } 
    } ] 
} 

brakuje mi tu proste znam go ktoś?

Odpowiedz

44

Próbowałem to, wykonany prosty test i to działało (dodane wyniki i inne):

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

Twój struktura danych działa dla mnie, ale ja wolę definiować location.lat i location.lng jako miejsca dziesiętne. Podobnie łatwiej jest wyliczyć stan odpowiedzi, typy wyników i typy lokalizacji. Json.NET deserializuje poprawnie łańcuchy do wyliczeń. – Mart

+0

Ten wiersz "wyniki publiczne [] results {get; set;}" rozwiązał dwugodzinną blokadę. Nigdy nie myślałem o umieszczeniu innej klasy wyżej niż klasa wyników. Dziękuję Ci. – TrueCoke

+0

@antonio Cool i zajmuje tylko sekundę, aby pobrać dane dzięki –

20

Można użyć dynamicznego obiektu zamiast definiowanie obiektu.

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

namespace to -> System.Web.Script.Serialization.JavaScriptSerializer w System.Web.Extensions (w System.Web.Extensions.dll) – JGilmartin

+1

Uwielbiam prostotę tego. –

+1

Piękne prace .. Próbowałem tego, działa dobrze z .NET Framework 4 (Microsoft.Csharp.dll); mając na uwadze, że nie działa w .NET Framework 3.5. Dowolny pomysł? – Praveen

3

C# kodu wynikowego dodałem kilka dodatkowych klas, nie wiem, czy są nowe API, ale myślałem, że to może być pomocne dla kogoś.

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

Dzięki JEuvin powyżej, udało mi się łatwo przełączać się z XML do formatu JSON z kilkoma modami do powyższego kodu (konkretnie zmieniając lat i LNG na dziesiętny lub podwójne) i również musiał zmienić address_components.types do string [], aby uruchomić go dla mnie. Następnie trochę refaktoryzowałem, aby te same klasy mogły być zamienione na szeregowo z XML lub Json.

Może to pomoże ktoś zbyt ...

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; } 
} 

(edycja z dodatkiem postcode_localities i właściwości partial_match)

+1

Upewnij się, że dodajesz również niektóre atrybuty JSON. Pomaga w operacjach js. Osobiście nie lubię używać XML. – JEuvin

0

upewnić, klasa jest Serializable pozwalają 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; } 
    } 
Powiązane problemy