首页 > 解决方案 > Xamarin 中 CLGeocoder.ReverseGeocodeLocationAsync 的问题

问题描述

我目前正在研究 Xamarin 下 iOS 的(现有)解决方案。我有一张带有以下代码的地图:

public override async Task<string> ResolveLatLngToAddress(double lat, double lng, MapAddressFormat addressFormat) 
        {
            var geocoder = new CLGeocoder();

            try 
            {
                var placemarks = await geocoder.ReverseGeocodeLocationAsync(new CLLocation(lat, lng));

                if (placemarks.Length > 0)
                {
                    var placemark = placemarks[0];

                    switch (addressFormat) 
                    {
                        case MapAddressFormat.AddressFormatFull: 
                            {
                            return FormatUtils.Join(true, placemark.Name, placemark.Locality, placemark.SubLocality);
                            }
                        case MapAddressFormat.AddressFormatNoNumber: 
                            {
                                return FormatUtils.Join(true, placemark.Thoroughfare, placemark.Locality, placemark.SubLocality);
                            }
                    }
                }
            } 
            catch (Foundation.NSErrorException e) 
            {
                // Unable to find a location with the supplied latitude and longitude

            }

            return null;
        }
    }

当用户移动图钉时,代码运行得非常好,有一个文本框控件显示当前选择的地址。但是,一旦用户开始放大和缩小,应用程序就会中断并且功能停止工作。

我已经进行了一些研究,并且我了解 CLGeocoder 类的工作方式是,如果用户启动太多请求,响应会减慢然后完全停止(https://developer.apple.com/documentation/corelocation/clgeocoder)。

我可以看到问题在于该事件在缩放期间被多次触发,例如放大触发器,例如 20 个位置解析请求。

我只想在用户完成缩放后触发位置分辨率,是否有可能以某种方式实现,例如延迟绑定?

请注意,我是 iOS 开发和 Xamarin 的新手。

非常感谢您的帮助。

标签: ios.netxamarinmaps

解决方案


谢谢您的意见。我最终通过缓存先前查询的位置并仅在 lat/lng 坐标更改了我估计为 1 米的一定余量(对我的目的来说非常好)时才重新查询来解决它。

private double _cached_lat = 999;
    private double _cached_lng = 9999;
    private string _cached_location = "";

    public override async Task<string> ResolveLatLngToAddress(double lat, double lng, MapAddressFormat addressFormat) 
    {
        double latDif = System.Math.Abs(_cached_lat - lat);
        double lngDif = System.Math.Abs(_cached_lng - lng);

        //precission - around 1m
        double geo_precission = 0.000005;

        if (((System.Math.Abs (_cached_lat - lat) < geo_precission) && (System.Math.Abs (_cached_lng - lng) < geo_precission)) && (!string.IsNullOrEmpty(_cached_location))) 
        {
            return _cached_location;
        }

        var geocoder = new CLGeocoder();

推荐阅读