【问题标题】:"object reference not set to an instance of an object" when trying to get lat, lng from a KML-layer to Google Maps [Xamarin Android]尝试从 KML 层获取 lat、lng 到 Google Maps [Xamarin Android] 时,“对象引用未设置为对象的实例”
【发布时间】:2017-08-18 01:04:20
【问题描述】:

我目前正在通过此插件处理 KML 文件:https://github.com/sushihangover/SushiHangover.Android.Maps.Utils

我正在使用的 KML 文件已通过此 coden-p 成功添加:

var kmlLayer = new KmlLayer(googleMap, Resource.Raw.campus, Android.App.Application.Context);
kmlLayer.AddLayerToMap();
MoveCameraToKml(kmlLayer);

添加后,我运行MoveCameraToKml函数,尝试获取每个点的经纬度,但我在foreach (LatLng latLng in ((KmlLineString)geo).GeometryObject);这一行发生崩溃,错误消息为:object reference not set to an instance of an object

void MoveCameraToKml(KmlLayer kmlLayer)
{
  //Retrieve the first container in the KML layer
  var container = (KmlContainer)kmlLayer.Containers.Iterator().Next();

  //Retrieve a nested container within the first container
  container = (KmlContainer)container.Containers.Iterator().Next();

  //Retrieve the first placemark in the nested container
  var placemark = (KmlPlacemark)container.Placemarks.Iterator().Next();
  var geo = placemark.Geometry;
  if (geo is KmlLineString)
  {
      foreach (LatLng latLng in ((KmlLineString)geo).GeometryObject) //object reference not set to an instance of an object
      {
         System.Diagnostics.Debug.WriteLine(latLng); 
      }
   }

}

知道为什么这会让我崩溃吗?我正在按照上面下载的 nuget 示例进行操作。

这个想法是将 lat、lngs 存储在一个列表中,并使用 PolylineOptions 创建路由。

【问题讨论】:

    标签: google-maps xamarin xamarin.android


    【解决方案1】:

    该 Google 示例 (MoveCameraToKml) 假设您使用的是他们的 Campus KML 示例。由于您使用的 KML 对您的应用来说是独一无二的,因此您需要检查您的 KML/XML 元素并编写代码以适应您的使用情况。

    这是一个使用他们的 Grand Canyon KML LineString 远足路径的示例:

    因此,查看 KML,我们需要:

    1. 获取第一个Container
    2. 在该容器中获取第一个 Placemark
    3. 检查它是否有几何图形并且是 KML LineString
    4. 通过GeometryJavaObject()获取LatLng数组
    5. 使用这些 Latlng 构建相机视口并移动到该视口。
    6. 沿着这些单独的点“驱动”相机

    大峡谷 KmlLineString 示例:

    void MoveCameraToKml(KmlLayer kmlLayer)
    {
        var container = (KmlContainer)kmlLayer.Containers.Iterator().Next();
        var placemark = (KmlPlacemark)container.Placemarks.Iterator().Next();
        if (placemark.HasGeometry && placemark.Geometry is KmlLineString)
        {
            var lineString = placemark.Geometry as KmlLineString;
            var latlngArray = lineString.GeometryJavaObject() as Java.Util.ArrayList;
            using (var builder = new LatLngBounds.Builder())
            {
                foreach (LatLng latLng in latlngArray.ToEnumerable())
                {
                    builder.Include(latLng);
                }
                googleMap.MoveCamera(CameraUpdateFactory.NewLatLngBounds(
                    builder.Build(), mapFragment.View.Width, mapFragment.View.Height, 1)
                );
            }
            Task.Run(async () => // run camera along KmlLineString
            {
                foreach (LatLng latLng in latlngArray.ToEnumerable())
                {
                    await Task.Delay(2000);
                    RunOnUiThread(() => googleMap.MoveCamera(CameraUpdateFactory.NewLatLng(latLng)));
    
                }
            });
        }
    }
    

    【讨论】:

    • 非常感谢!我现在得到坐标,并用折线构建它。现在我还剩下最后一件事,就是移除我在添加 kmllayer 时得到的引脚。应该很有趣:)
    • @CarlosRodrigez np,很高兴它有帮助
    • 我解决了这个问题,只是在RemoveLayerFromMap之后删除了图层,因为我已经得到了我需要的坐标。我注意到,当该 KML 文件中应该有两条路线时,代码只创建一条路线。可能 KML 文件设置错误。我需要看看那个。
    【解决方案2】:

    Geometry 可以是 KmlPoint、KmlLineString、KmlPolygon 或 KmlMultiGeometry。

    var geo = placemark.Geometry;
    if (geo is KmlPolygon) then {
      var poly = (KmlPolygon)geo;
    }
    

    【讨论】:

    • 我尝试用 KmlLineString 替换 KmlPolygin 并像这样循环它 foreach (LatLng latLng in polygon.GeometryObject) 但这给了我 object reference not set to an instance of an object 我现在正在使用 KmlPoint 但我不确定如何循环出所有那个点。
    • 除非你知道它是哪种类型,否则你不能转换它。您需要在投射前检查类型。
    • 好的,我取得了一些进展,我用你的例子更新了代码,它显然是我正在使用的“KmlLineString”。当我尝试退出 lat,lng 时,我得到一个 object reference not set to an instance of an object
    • 如果我这样做:var locations = ((KmlLineString)geo).GeometryObject; System.Diagnostics.Debug.WriteLine(locations.Count());Error: value cannot be null
    • 您确实需要使用调试器来检查您正在使用的数据,而不是对其外观做出假设
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2018-07-28
    • 2019-11-02
    相关资源
    最近更新 更多