【问题标题】:Compass True Heading in iPhone/iPadiPhone/iPad 中的指南针真航向
【发布时间】:2011-09-12 05:19:21
【问题描述】:

我在 iPhone/iPad 指南针开发上遇到了一些问题。

从 CLHeading 获取的 trueHeading 总是给我“-1”值,我被困在这里。这是我的代码:

self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
self.locationManager.headingFilter = 0.5; //1 degrees
[self.locationManager startUpdatingHeading];

我还发现了一件事,那就是当我在地图应用程序或指南针应用程序上使用了位置信息时,trueHeading 值突然读取正确。我想知道是什么原因,有什么想法吗?它发生在 iPhone4 和 iPad 上。

每当我在设置中关闭定位服务并重新启用它时也会发生这种情况,它将无法读取正确的 trueHeading 值,我想知道是因为我创建的应用程序无法启用定位服务吗?

还是先谢谢了

---我的解决方案---

见下文。

【问题讨论】:

  • 您是在有指南针的设备(例如 iPhone 4)上执行此操作吗?
  • 如果你勾选[CLLocationManager headingAvailable],它会返回什么?

标签: iphone ios ipad compass-geolocation


【解决方案1】:

为了避免标题不断返回 -1.000000,不只是运行 startUpdatingHeading 而是一起运行 startUpdatingLocation,这会有所帮助。

【讨论】:

  • 你的意思是同时调用两者吗?
【解决方案2】:

尝试使用这个...

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate=self;
    locationManager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
    // Start heading updates. 
    if (locationManager.headingAvailable && locationManager.locationServicesEnabled) 
    {
        locationManager.headingFilter = kCLHeadingFilterNone; 
        [locationManager startUpdatingHeading];
    }

并在执行此操作后调用 CLLocationManager 委托方法

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {

    // Use the true heading if it is valid. 
    [lblAccuracy setText:[NSString stringWithFormat:@"%.1fmi",newHeading.headingAccuracy]]; 
}

但是这种编码适用于设备而不是模拟器......

编码愉快..

【讨论】:

  • 仍然不能,我怀疑是我目前正在使用的应用程序无法从设备本身读取位置服务,因为每当我关闭并重新启用位置服务时,它都会变成 -1 读数对于 trueHeading,但如果我使用其他应用程序(地图、指南针),它能够正确显示 trueHeading
  • 'headingAvailable' 已弃用:在 iOS 4.0 中首次弃用
  • 'locationServicesEnabled' 已弃用:首先在 iOS 4.0 中弃用
【解决方案3】:

---我的解决方案---

我所做的是,将[self.locationManager startUpdatingLocation] 添加到[self.locationManager startUpdatingHeading]; 之前或之后(当位置服务关闭并从设置重新启用时)。我不确定这是一个好的解决方案,但这是我为使其工作所做的工作,如果您有任何更好的解决方案,请分享。

【讨论】:

【解决方案4】:

我自己在位置管理器上遇到了一些问题,发现对我来说,在测试时从计算机上拔下 iPhone 是有帮助的。不知何故,只有在拔掉 iPhone 后才会弹出校准警报。

【讨论】:

    【解决方案5】:

    我遇到了同样的问题。我将 startUpdatingHeading 移到按钮操作中,然后将其移回分配 CLLocationManager 的位置——它一直工作正常——它开始只返回 -1。

    我重新启动了我的 iPad,它又开始工作了。希望它保持这种状态。

    编辑:不,它并没有保持这种状态。我也不得不使用 startUpdatingLocation 。这不会耗尽电池吗?我将 desiredAccuracy 设置为 kCLLocationAccuracyThreeKilometers,因为无论如何我都没有使用位置数据。

    【讨论】:

      【解决方案6】:

      真正的读数需要知道您使用指南针的地方的磁场变化。从前面的讨论来看,从磁场方向校正真实方向的功能似乎需要您的位置才能获得变化值。如果您不喜欢在代码中使用位置 GPS 信息,我建议您阅读磁读数并自行更正该值。您需要首先获得所需位置的变化,然后应用以下公式:T=M ± V,其中 T 是真实方向,M 是罗盘磁读数,V 是变化。东用“+”,西用“-”。我发现允许网站为任何需要的位置提供变化(磁偏角):http://www.geomag.nrcan.gc.ca/calc/mdcal-eng.php

      【讨论】:

        【解决方案7】:

        当定位服务关闭时,didUpdateHeading delegate method 只返回磁航向。您可以根据自己的需要使用它。根据苹果文档..

        要开始传递与航向相关的事件,请分配一个委托给 位置管理器对象并调用它的 startUpdatingHeading 方法。 如果还启用了位置更新,则位置管理器返回 真航向和磁航向值。如果位置更新 未启用,位置管理器仅返回磁性 航向值。

        【讨论】:

          【解决方案8】:

          现在正在解决这个问题。当我使用 SpriteKit 时,我可以从 Core Motion 获取更新。它是关于能够像一帧(1/60 秒)或每隔几帧一样连续调用一个函数。在不使用 SpriteKit 的情况下,文档说要在闭包中调用更新,我假设这将在它们自己的线程上并由您来发布。

          有一种算法可以将磁力计读数转换为相对于真北的实际度数。想象一张看起来像交流电的时域函数的图表,您会发现对数据进行插值是应用麦克斯韦方程组的简单事情。 Here's an example on honeywell

          【讨论】:

          • 霍尼韦尔论文详细介绍了如何使用磁力计计算磁北。它只是顺便提到要获得真正的北方,您必须添加当地的赤纬。这是一张粗略的草图,显示了北美的局部偏角,但没有算法或精细的数值。
          猜你喜欢
          • 1970-01-01
          • 2011-05-07
          • 1970-01-01
          • 2011-10-01
          • 2022-09-24
          • 1970-01-01
          相关资源
          最近更新 更多