1

Тема: GoogleMaps API та десеріалізація JSon відповіді

Даю запит до googlemaps API з адресою об'єкту, назад отримаю в JSon форматі відповідь:

Прихований текст
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "8",
               "short_name" : "8",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "проспект Пушкіна",
               "short_name" : "проспект Пушкіна",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Чечелівський район",
               "short_name" : "Чечелівський район",
               "types" : [ "political", "sublocality", "sublocality_level_1" ]
            },
            {
               "long_name" : "Дніпро́",
               "short_name" : "Дніпро́",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Дніпропетровська міськрада",
               "short_name" : "Дніпропетровська міськрада",
               "types" : [ "administrative_area_level_3", "political" ]
            },
            {
               "long_name" : "Дніпропетровська область",
               "short_name" : "Дніпропетровська область",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Україна",
               "short_name" : "UA",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "проспект Пушкіна, 8, Дніпро́, Дніпропетровська область, Україна",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 48.4674756,
                  "lng" : 35.0202435
               },
               "southwest" : {
                  "lat" : 48.4674638,
                  "lng" : 35.0202373
               }
            },
            "location" : {
               "lat" : 48.4674638,
               "lng" : 35.0202373
            },
            "location_type" : "RANGE_INTERPOLATED",
            "viewport" : {
               "northeast" : {
                  "lat" : 48.4688186802915,
                  "lng" : 35.02158938029149
               },
               "southwest" : {
                  "lat" : 48.46612071970851,
                  "lng" : 35.0188914197085
               }
            }
         },
         "place_id" : "EnPQv9GA0L7RgdC_0LXQutGCINCf0YPRiNC60ZbQvdCwLCA4LCDQlNC90ZbQv9GA0L7MgSwg0JTQvdGW0L_RgNC-0L_QtdGC0YDQvtCy0YHRjNC60LAg0L7QsdC70LDRgdGC0YwsINCj0LrRgNCw0ZfQvdCw",
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}

Маю класи:

Прихований текст
public class AddressComponent
    {
        public string Long_name { get; set; }
        public string Short_name { get; set; }
        public List<string> Types { get; set; }
    }

    public class Northeast
    {
        public double Lat { get; set; }
        public double Lng { get; set; }
    }

    public class Southwest
    {
        public double Lat { get; set; }
        public double Lng { get; set; }
    }

    public class Bounds
    {
        public Northeast Northeast { get; set; }
        public Southwest Southwest { get; set; }
    }

    public class Location
    {
        public double Lat { get; set; }
        public double Lng { get; set; }
    }

    public class Northeast2
    {
        public double Lat { get; set; }
        public double Lng { get; set; }
    }

    public class Southwest2
    {
        public double Lat { get; set; }
        public double Lng { get; set; }
    }

    public class Viewport
    {
        public Northeast2 Northeast { get; set; }
        public Southwest2 Southwest { 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 Result
    {
        public List<AddressComponent> Address_components { get; set; }
        public string Formatted_address { get; set; }
        public Geometry Geometry { get; set; }
        public string Place_id { get; set; }
        public List<string> Types { get; set; }
    }

    public class RootObject
    {
        public List<Result> Results { get; set; }
        public string Status { get; set; }
    }

Маю метод який розпіхує елементи адрес та координати по відповідним textbox:

private void JSonDeserialize(string json)
        {
            RootObject root = JsonConvert.DeserializeObject<RootObject>(json);

            foreach(var item in root.Results)
            {                                                            
                buildingTextBox.Text     = Convert.ToString(item.Address_components[0].Long_name);
                streetTextBox.Text       = Convert.ToString(item.Address_components[1].Long_name);
                sityTextBox.Text         = Convert.ToString(item.Address_components[3].Long_name);
                regionTextBox.Text       = Convert.ToString(item.Address_components[5].Long_name);
                geoLatitudeTextBox.Text  = Convert.ToString(item.Geometry.Location.Lat);
                geoLongitudeTextBox.Text = Convert.ToString(item.Geometry.Location.Lng);                
            }
        }

Отримую доступ до елементів list "Address_components" по індексу. В прикладі їх 7 (0-6). Все наче добре. Але якщо ввести таку адресу:

Прихований текст
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "36A",
               "short_name" : "36A",
               "types" : [ "premise" ]
            },
            {
               "long_name" : "36А",
               "short_name" : "36А",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "проспект Пушкіна",
               "short_name" : "проспект Пушкіна",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Чечелівський район",
               "short_name" : "Чечелівський район",
               "types" : [ "political", "sublocality", "sublocality_level_1" ]
            },
            {
               "long_name" : "Дніпро́",
               "short_name" : "Дніпро́",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Дніпропетровська міськрада",
               "short_name" : "Дніпропетровська міськрада",
               "types" : [ "administrative_area_level_3", "political" ]
            },
            {
               "long_name" : "Дніпропетровська область",
               "short_name" : "Дніпропетровська область",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Україна",
               "short_name" : "UA",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "36A, проспект Пушкіна, 36А, Дніпро́, Дніпропетровська область, Україна",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 48.470062,
                  "lng" : 35.0111311
               },
               "southwest" : {
                  "lat" : 48.469715,
                  "lng" : 35.01062
               }
            },
            "location" : {
               "lat" : 48.4698481,
               "lng" : 35.0108244
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 48.4712374802915,
                  "lng" : 35.0122245302915
               },
               "southwest" : {
                  "lat" : 48.4685395197085,
                  "lng" : 35.0095265697085
               }
            }
         },
         "place_id" : "ChIJhc85E1Xi20ARWFJiT4E4HOI",
         "types" : [ "premise" ]
      }
   ],
   "status" : "OK"
}

То як бачимо, до list "Address_components" додався ще один елемент "premise" і елементів стало вже 8 (0-7). І вся інформація про адресу змістилась на один індекс.

Питання, як взяти значення в list не по індексу, а по типу "street_number", "route", "locality" та "administrative_area_level_1"?

Або як напряму не можна, то як взнати номер індексу типів "street_number", "route", "locality" та "administrative_area_level_1"?

Чи порадьте свій варіант.

2 Востаннє редагувалося FakiNyan (21.06.2017 13:30:46)

Re: GoogleMaps API та десеріалізація JSon відповіді

через LINQ, певно, можна
озьдо я вам приклад накидав
http://ideone.com/oFZWCV

Подякували: taburyak, 0xDADA11C72

3 Востаннє редагувалося taburyak (21.06.2017 14:24:24)

Re: GoogleMaps API та десеріалізація JSon відповіді

FakiNyan написав:

через LINQ, певно, можна
озьдо я вам приклад накидав

Крутяк! Оце так-так! Я б ще довго медитував над цим. Величезне дякую.

Забабахав ось так:

private string GetAddressComponent(Result item, string component)
        {
            string resultComponent = null;
            var neededData = item.Address_components.Select(d => d).Where(AddressComponent => AddressComponent.Types.Contains(component));

            foreach (var data in neededData)
            {
                resultComponent = Convert.ToString(data.Long_name);
            }
            
            return resultComponent;
        }

        private void JSonDeserialize(string json)
        {
            RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
            
            foreach(var item in root.Results)
            {
                buildingTextBox.Text = GetAddressComponent(item, "street_number");
                streetTextBox.Text = GetAddressComponent(item, "route");
                sityTextBox.Text = GetAddressComponent(item, "locality");
                regionTextBox.Text = GetAddressComponent(item, "administrative_area_level_1");
                
                geoLatitudeTextBox.Text  = Convert.ToString(item.Geometry.Location.Lat);
                geoLongitudeTextBox.Text = Convert.ToString(item.Geometry.Location.Lng);
                
            }
        }

Працює чітко по плану. Як будуть зауваження - приймаю.

4 Востаннє редагувалося taburyak (21.06.2017 14:30:21)

Re: GoogleMaps API та десеріалізація JSon відповіді

Роздивився що у JSon є простір імен Newtonsoft.Json.Linq;
Може можна через Json.Linq якось простіше мати доступ до полів "Address_components" по назвам types?

5

Re: GoogleMaps API та десеріалізація JSon відповіді

може й простіше, я не пробував, озьдо тут є інфа про це
http://www.newtonsoft.com/json/help/htm … toJSON.htm

private string GetAddressComponent(Result item, string component)
        {
            string resultComponent = null;
            var neededData = item.Address_components.Select(d => d).Where(AddressComponent => AddressComponent.Types.Contains(component)); //повертає список елементів, котрі містять component в своїх Types
 
            foreach (var data in neededData)
            {
                resultComponent = Convert.ToString(data.Long_name);
            }
            
            return resultComponent; //отут ви повертаєте data.Long_name останнього елемента зі списку
        }

якщо вам треба повернути останній елемент зі списку Address_components, котрий місить в своєму Types значення component, то мона просто через FindLast
http://ideone.com/IZLoJd

Подякували: taburyak1

6

Re: GoogleMaps API та десеріалізація JSon відповіді

FakiNyan написав:

може й простіше, я не пробував, озьдо тут є інфа про це
http://www.newtonsoft.com/json/help/htm … toJSON.htm

Добре, ще раз дякую. Помедитую над цим, може просвітлення надійде  *SCRATCH*

Подякували: FakiNyan1