Odczytywanie współrzędnych geograficznych

Ostatnio musiałem odczytać współrzędne geograficzne na podstawie nazwy lokalizacji.

Pierwszą opcją, którą sprawdziłem był pakiet “GoogleMaps.LocationServices”. Po instalacji NuGet, odczytanie współrzędnych było bardzo proste:

            var gls = new GoogleLocationService();
            var location = gls.GetLatLongFromAddress("Warsaw, Poland");

            Console.WriteLine("{0}, {1}", location.Latitude,location.Longitude);

Wynik:
1

Rozwiązanie bardzo proste. Biblioteka korzysta z Google Maps, ale niestety ma limity na liczbę zapytań w ciągu dnia. Co gorsza, nie istnieje możliwość zwiększenia tego limitu.

Z tego względu zdecydowałem się na bezpośrednie połączenie z Google API, a konkretnie z Geocoding API. Co prawda, rozwiązanie też ma limity dzienne, ale po darmowej rejestracji uzyskamy limit 100k dziennie, co w moim w wypadku było wystarczające. API jest w formie REST:
“https://maps.googleapis.com/maps/api/geocode/json?address=Warsaw,Poland&key=YOUR_API_KEY”

Oczywiście należy najpierw uzyskać klucz, rejestrując konto na Console Google. Przykładowa odpowiedź przychodzi w następującym formacie:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Warsaw",
               "short_name" : "Warsaw",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Warszawa",
               "short_name" : "Warszawa",
               "types" : [ "administrative_area_level_3", "political" ]
            },
            {
               "long_name" : "Warszawa",
               "short_name" : "Warszawa",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Masovian Voivodeship",
               "short_name" : "Masovian Voivodeship",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Poland",
               "short_name" : "PL",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Warsaw, Poland",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 52.3679992,
                  "lng" : 21.2710983
               },
               "southwest" : {
                  "lat" : 52.0978767,
                  "lng" : 20.8512898
               }
            },
            "location" : {
               "lat" : 52.2296756,
               "lng" : 21.0122287
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 52.3679992,
                  "lng" : 21.2710983
               },
               "southwest" : {
                  "lat" : 52.0978767,
                  "lng" : 20.8512898
               }
            }
         },
         "place_id" : "ChIJAZ-GmmbMHkcR_NPqiCq-8HI",
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

Generując automatycznie klasy C# w Visual Studio na podstawie JSON uzyskamy:

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

    public class Result
    {
        public Address_Components[] address_components { get; set; }
        public string formatted_address { get; set; }
        public Geometry geometry { get; set; }
        public string place_id { get; set; }
        public 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 Bounds
    {
        public Northeast northeast { get; set; }
        public Southwest southwest { get; set; }
    }

    public class Northeast
    {
        public float lat { get; set; }
        public float lng { get; set; }
    }

    public class Southwest
    {
        public float lat { get; set; }
        public float lng { get; set; }
    }

    public class Location
    {
        public float lat { get; set; }
        public float lng { get; set; }
    }

    public class Viewport
    {
        public Northeast1 northeast { get; set; }
        public Southwest1 southwest { get; set; }
    }

    public class Northeast1
    {
        public float lat { get; set; }
        public float lng { get; set; }
    }

    public class Southwest1
    {
        public float lat { get; set; }
        public float lng { get; set; }
    }

    public class Address_Components
    {
        public string long_name { get; set; }
        public string short_name { get; set; }
        public string[] types { get; set; }
    }

W przypadku usług REST, standardowo używam RestSharp+JSON.NET:

           var query = "https://maps.googleapis.com/maps/api/geocode/json?address=Warsaw,Poland&key=API_KEY";

            var client = new RestClient(query);
            var response = client.Get<dynamic>(new RestRequest());

            Rootobject data = JsonConvert.DeserializeObject<Rootobject>(response.Content);
            
            Console.WriteLine("{0}, {1}", data.results[0].geometry.location.lat, data.results[0].geometry.location.lng);

W praktyce, automatycznie wygenerowane klasy zostałyby zastąpione czytelniejszą strukturą. Tyle jednak wystarczy na szybkie sprawdzenie możliwości API.

Leave a Reply

Your email address will not be published.