Flutter - 从坐标获取地理编码地址

8

我已经在创建的应用程序中实现了一种可靠的获取用户纬度、经度坐标的方法,但似乎无法将这些坐标转化为地标。

我还想知道需要使用什么来打印这些数据。

这是我尝试获取这些数据的方式:

List<Placemark> place = [];

void _getPlace() async {
  List<Placemark> newPlace = await _geolocator.placemarkFromCoordinates(_position.latitude, _position.longitude);
  print(newPlace);
  setState(() {
    place = newPlace;
  });
}

感谢您。

编辑:

CopsOnRoad的回复后,我遇到了这个错误:

[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: 

NoSuchMethodError: The method 'placemarkFromCoordinates' was called on null.
Receiver: null
Tried calling: placemarkFromCoordinates(51.4998, -0.129)
#0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:50:5)
#1      _NearbyPageState._getPlace 
package:tr/pages/nearby.dart:128
<asynchronous suspension>
#2      _NearbyPageState._controlCard.<anonymous closure> 
package:tr/pages/nearby.dart:629
#3      GestureRecognizer.invokeCallback 
package:flutter/…/gestures/recognizer.dart:182
#4      TapGestureRecognizer._checkUp 
package:flutter/…/gestures/tap.dart:365
#5      TapGestureRecognizer.acceptGesture 
package:flutter/…/gestures/tap.dart:312
#6      GestureArenaManager.sweep 
package:flutter/…/gestures/arena.dart:156
#7      _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent 
package:flutter/…/gestures/binding.dart:222
#8      _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (p<…>

你在info.plist中添加了使用iPhone位置的必要权限吗? - Mahendra
是的,我的 plist 文件中有权限。 - Jake
newPlace 打印什么? - CopsOnRoad
类似于[Placemark的实例] - Jake
7个回答

29

更新:使用geocoding

import 'package:geocoding/geocoding.dart';

List<Placemark> placemarks = await placemarkFromCoordinates(52.2165157, 6.9437819);

旧解决方案:

您已经在那里了,您需要的额外材料是:

String _address = ""; // create this variable

void _getPlace() async {
  List<Placemark> newPlace = await _geolocator.placemarkFromCoordinates(_position.latitude, _position.longitude);

  // this is all you need
  Placemark placeMark  = newPlace[0]; 
  String name = placeMark.name;
  String subLocality = placeMark.subLocality;
  String locality = placeMark.locality;
  String administrativeArea = placeMark.administrativeArea;
  String postalCode = placeMark.postalCode;
  String country = placeMark.country;
  String address = "${name}, ${subLocality}, ${locality}, ${administrativeArea} ${postalCode}, ${country}";
  
  print(address);

  setState(() {
    _address = address; // update _address
  });
}

刚刚在执行 flutter clean 后解决了我的问题。 - Jake
1
地理编码只支持英语吗?!我想要用本地语言获得地址结果。我该怎么做? - Mohammad Shamsi
1
有没有免费的服务可以将地图地址转换为经纬度,经纬度转换为地址和提供地点自动完成?请推荐。非常感谢。 - Kamlesh
@Kamlesh 前者是免费的,而后者是付费的。 - CopsOnRoad
这适用于Web应用程序吗? - user20530242
显示剩余3条评论

6

从版本6.0.0开始,geolocator中已删除Placemark,并将其移动到geocoding

从版本6.0.0开始,地理编码功能(placemarkFromAddress和placemarkFromCoordinates)不再是地理定位器插件的一部分。我们已将这些功能移动到它们自己的插件:geocoding。这个新插件是旧方法的改进版。

要使用地理编码将纬度和经度转换为地址,请使用

List<Placemark> placemarks = await placemarkFromCoordinates(52.2165157, 6.9437819);

5

使用pub.dev的flutter_geocoding库

https://pub.dev/packages/flutter_geocoding

或者

我已经在Flutter中使用了Swift的'GMSGeocoder'和Java的'android.location.Geocoder'库。我认为它比pub.dev上的Geocode库更有效率。

我的示例代码:

将Java和Swift的Geocode库自己添加进来。

Java:

 @Override
 public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
        super.configureFlutterEngine(flutterEngine);

        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "samples.flutter.dev/latlng")
                .setMethodCallHandler(
                        (call, result) -> {

                            double lat = call.argument("lat");
                            double lng = call.argument("lng");
                            result.success("return value lat and lng");

                        }
                );
    }

swift

override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/latlng",
                                                  binaryMessenger: controller.binaryMessenger)
        
        batteryChannel.setMethodCallHandler({
            [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
            
            // Note: this method is invoked on the UI thread.
            guard call.method == "latlng" else {
                result(FlutterMethodNotImplemented)
                return
            }
            
            self?.latlng(call,result: result)
        })
        GMSServices.provideAPIKey("")
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }


    private func latlng(_ call: FlutterMethodCall,result:FlutterResult) {
        if let args = call.arguments as? Dictionary<String, Any>,
           let lat = args["lat"] as? Double ,let lng = args["lng"] as? Double  {
            result("return latlng result" )
          } else {
            result(FlutterError.init(code: "bad args", message: nil, details: nil))
          }
    }

flutter

Future<void> _getBatteryLevel(double a, double b) async {
  String latlng;
  try {
    final String result = await const MethodChannel('samples.flutter.dev/latlng').invokeMethod(
        'latlng', <String, dynamic>{"lat": a, "lng": b});
    latlng = result;
  } on PlatformException catch (e) {
    latlng = "Failed to get latlng level: '${e.message}'.";
  }
}

4

首先,在 pubspec.yaml 中包含 lib -geolocator: ^3.0.1。

///Get current location
  Geolocator _geolocator = Geolocator();
  String latitude = "";
  String longitude = "";
  String address = "";

尝试这个解决方案 -

///Call this function
 _fetchLocation() async {
    Position position = await _geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.best);///Here you have choose level of distance
    latitude = position.latitude.toString() ?? '';
    longitude = position.longitude.toString() ?? '';
    var placemarks = await _geolocator.placemarkFromCoordinates(position.latitude, position.longitude);
    address ='${placemarks.first.name.isNotEmpty ? placemarks.first.name + ', ' : ''}${placemarks.first.thoroughfare.isNotEmpty ? placemarks.first.thoroughfare + ', ' : ''}${placemarks.first.subLocality.isNotEmpty ? placemarks.first.subLocality+ ', ' : ''}${placemarks.first.locality.isNotEmpty ? placemarks.first.locality+ ', ' : ''}${placemarks.first.subAdministrativeArea.isNotEmpty ? placemarks.first.subAdministrativeArea + ', ' : ''}${placemarks.first.postalCode.isNotEmpty ? placemarks.first.postalCode + ', ' : ''}${placemarks.first.administrativeArea.isNotEmpty ? placemarks.first.administrativeArea : ''}';
    print("latitude"+latitude);
    print("longitude"+longitude);
    print("adreess"+address);
  }

3
 try {
    await Geolocator()
        .placemarkFromCoordinates(value[0], value[1])
        .then((result) {
      Placemark placeMark = result[0];
      String name = placeMark.name;
      String subLocality = placeMark.subLocality;
      String locality = placeMark.locality;
      String administrativeArea = placeMark.administrativeArea;
      String postalCode = placeMark.postalCode;
      String country = placeMark.country;
      String address =
          "${name}, ${subLocality}, ${locality}, ${administrativeArea} ${postalCode}, ${country}";
      print(address);
      
    });
  } on PlatformException catch (e) {
    print(e);
  }

2

未来的getLatAndlong()异步函数{ cl = await Geolocator.getCurrentPosition().then((value)=>value); }

lat = cl.latitude;
long = cl.longitude;
_kGooglePlex =    CameraPosition(
    target: LatLng(lat,long),
    zoom:14
);
List<Placemark> placemarks = await placemarkFromCoordinates(
    lat, long);
print("country"+placemarks[0].country!);
print("area"+placemarks[0].administrativeArea!);
print("locality"+placemarks[0].locality!);
print("sublocality"+placemarks[0].subLocality!);
print("postlocality"+placemarks[0].postalCode!);
print("street"+placemarks[0].street!);

setState(() {

  countrycurrent = placemarks[0].country!;
  localcurrent = placemarks[0].administrativeArea!;
  madinacurrent = placemarks[0].subLocality!;
  curren=countrycurrent+","+localcurrent+","+madinacurrent;
});

mymarker.add( Marker( infoWindow: InfoWindow( title: placemarks[0].country! + "," + placemarks[0].administrativeArea! + "," + placemarks[0].locality! ), draggable: true,

我标记添加了一个信息窗口,其中包含地点的国家、行政区和城市名称。该标记可以拖动。
  icon:
  BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueOrange),

  markerId: MarkerId("4"),

  position: LatLng(lat, long)),

);}


你的回答可以通过添加额外的支持信息来改进。请编辑以添加进一步的详细信息,例如引用或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心中找到有关编写良好答案的更多信息。 - Community

2

从版本6.0.0开始,Geolocator Plugin的新版本已经发布。地理编码功能(placemarkFromAddressplacemarkFromCoordinates)不再是geolocator插件的一部分。这些功能已经移动到它们自己的插件中:geocoding


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接