如何从 Flutter 中的 Geocoder 响应中提取城市和国家/地区

How to extract city locality and country from Geocoder response in Flutter

我已经收到地理编码器的回复,其中包含完整的可读地址。我想要一个从这个地址检索城市和国家/地区的好方法

这个方法我试过了,没用

print(json.decode(response.body)['results'][0].getLocality());//didnt work

这是我的代码:


  final url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lng&key=$GOOGLE_API_KEY';
  final response = await http.get(url);
  print(response.body);
  print(json.decode(response.body)['results'][0].getLocality());//didnt work
  return  json.decode(response.body)['results'][0]['formatted_address'];

}```

问题是在这种情况下 json.decode(response.body) 只能像 Map 一样使用,所以您不能调用没有的方法,例如 getLocality()

要做到这一点,您应该将 JSON 解析为具有该方法的对象。我向您推荐这篇文章以了解有关解析的更多信息 JSON:Parsing complex JSON in Flutter


如果您想在不解析 JSON 的情况下访问 countrylocality,您可以这样做:

String body = '{"results":[{"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":"Santa Clara County","short_name":"Santa Clara County","types":["administrative_area_level_2","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"]}],"formatted_address":"1600 Amphitheatre Parkway, Mountain View, CA 94043, USA","geometry":{"location":{"lat":37.4224764,"lng":-122.0842499},"location_type":"ROOFTOP","viewport":{"northeast":{"lat":37.4238253802915,"lng":-122.0829009197085},"southwest":{"lat":37.4211274197085,"lng":-122.0855988802915}}},"place_id":"ChIJ2eUgeAK6j4ARbn5u_wAGqWA","types":["street_address"]}],"status":"OK"}';
List<dynamic> addressComponents =
    json.decode(body)['results'][0]['address_components'];
String country = addressComponents
    .firstWhere((entry) => entry['types'].contains('country'))['long_name'];
String locality = addressComponents.firstWhere(
    (entry) => entry['types'].contains('locality'))['long_name'];
print('country: $country');
print('locality: $locality');

如果可以有多个 countrylocality,您可以这样做:

List<dynamic> countries = addressComponents
    .where((entry) => entry['types'].contains('country'))
    .toList()
    .map((entry) => entry['long_name'])
    .toList();
List<dynamic> localities = addressComponents
    .where((entry) => entry['types'].contains('locality'))
    .toList()
    .map((entry) => entry['long_name'])
    .toList();
print('countries: $countries');
print('localities: $localities');

在我的例子中,我在 class(空安全)

的帮助下成功提取了
class Place {
  String? address;
  String? street;
  String? postcode ;
  String? neighborhood;
  String? city;
  String? formattedAddress;

  Place({
      this.address,
      this.street,
      this.postcode,
      this.neighborhood,
      this.city,
      this.formattedAddress});

  Place.fromJson(Map<String, dynamic> json) {
    for (var component in json['address_components']) {
      var componentType = component["types"][0];
      switch (componentType) {
        case "street_number":
          address = component['long_name'];
          break;
        case "route":
          street = component['long_name'];
          break;
        case "neighborhood":
          neighborhood = component['long_name'];
          break;
        case "postal_town":
          city = component['long_name'];
          break;
        case "postal_code":
          postcode = component['long_name'];
          break;
        case "formatted_address":
          formattedAddress = component['long_name'];
          break;
      }
    }
  }
}

如何使用class


Future<Place> getPlace(String placeId) async {
    try {
      var url = 'https://maps.googleapis.com/maps/api/place/details/json?place_id=$placeId&key=$key';
      var response = await http.get(Uri.parse(url));
      var json = convert.jsonDecode(response.body);
      return Place.fromJson(json['result']);
    } catch (e) {
      throw e;
    }
  }