iOS -GeoFire ExceptionThrown 'Precision must be less than 23!'当搜索半径变宽时

Posted

技术标签:

【中文标题】iOS -GeoFire ExceptionThrown \'Precision must be less than 23!\'当搜索半径变宽时【英文标题】:iOS -GeoFire ExceptionThrown 'Precision must be less than 23!' when Search Radius is to WideiOS -GeoFire ExceptionThrown 'Precision must be less than 23!'当搜索半径变宽时 【发布时间】:2018-11-03 12:55:43 【问题描述】:

我有一个 mapView,用户可以选择 1 英里、10 英里、20 英里和 30 英里的缩放半径来从他们的设备所在的任何位置搜索餐厅。我将餐厅的所有经纬度都保存在 GeoFire 路径中。

当用户决定搜索时,首先我获取用户的位置,然后让用户选择一个英里半径,然后让 mapView 缩放到该半径:

var selectedRadius = 0.0
let milesToMeters = 1609.344
let doubleDistance = 2  // according to this https://***.com/a/5025970/4833705 to get a mapView radius of x miles, the distance needs to be doubled
var circleQuery: GFCircleQuery?
var queryHandle: UInt?

// 1. get the user's current location
guard let currentLocation = locationManager.location else  return 
let lat = currentLocation.coordinate.latitude
let lon = currentLocation.coordinate.longitude
let center = CLLocation(latitude: lat, longitude: lon)

// 2. user picks 10 mile radius
selectedRadius = (10 * doubleDistance) * milesToMeters

// 3. get the region I want to use for zoom in the mapView
let coordinateRegion = MKCoordinateRegionMakeWithDistance(center.coordinate, selectedRadius, selectedRadius)
mapView.setRegion(coordinateRegion, animated: true)

然后我想从 GeoFire 获得 10 英里半径内的所有餐馆,然后我跑了:

// 4. geoFire ref
let geofireRef = Database.database().reference().child("restaurant_locations")
let geoFire = GeoFire(firebaseRef: geofireRef)

// 5. since I had doubled the selectedRadius for the MKCoordinateRegionMakeWithDistance I now cut it in half to get the regular 10 mile radius in meters
let initialRadius = (selectedRadius / doubleDistance)

// 6. this is the radius I want to run the geoFire query on
circleQuery = geoFire?.query(at: center, withRadius: initialRadius)

// 7. observe .keyEntered at that query
queryHandle = circleQuery?.observe(.keyEntered, with:  (key: String!, location: CLLocation!) in ...

在第 7 步,尝试观察 .keyEntered 时出现异常:

'精度必须小于23!

然后我尝试使用 GeoFire 的区域查询 query(with:) 设置跨度,但我得到了完全相同的异常抛出

let span = MKCoordinateSpanMake(initialRadius, initialRadius)
let region = MKCoordinateRegionMake(center.coordinate, span)
geoFire.query(with: region).observe(.keyEntered, with:  (key: String!, location: CLLocation!) in ...

选择MapView缩放半径为10 mi,20或30 mi,如何运行Geofire查询以匹配该半径?

【问题讨论】:

【参考方案1】:

我用海里给出的旧答案显示地图上的距离不正确。

正确的方法是 double the number of miles you want to span then multiple that by 1609.344(1 英里是 1609.344 米)并将结果设置为 CLLocationDistances 以及您在 MKCoordinateRegionMakeWithDistance() 中的位置(下面的第 3 步)

使用GFRegionQuery(下面的第6步)而不是GFCircleQuery来使用geoFire区域

基本上只需在下面的步骤 2 中进行转换,使用下面步骤 3 中的区域,并将其设置为下面步骤 6 中使用的区域。

var radiusConversion = 0.0
let milesToMeters = 1609.344
let doubleDistance = 2
var regionQuery: GFRegionQuery?
var queryHandle: UInt?

// 1. get the user's current location
guard let currentLocation = locationManager.location else  return 
let lat = currentLocation.coordinate.latitude
let lon = currentLocation.coordinate.longitude
let center = CLLocation(latitude: lat, longitude: lon)

// 2. user picks 10 mile radius and do the conversion based on this link https://***.com/a/5025970/4833705
radiusConversion = (10 * doubleDistance) * milesToMeters

// 3. set the region I want to use for zoom in the mapView
let region = MKCoordinateRegionMakeWithDistance(center.coordinate, radiusConversion, radiusConversion)
mapView.setRegion(region, animated: true) // zoom

// 4. geoFire ref
let geoFireRef = Database.database().reference().child("restaurant_locations")
let geoFire = GeoFire(firebaseRef: geoFireRef)

// 6. use GeoFire's query(with: region) and this is the radius I want to run the geoFire query on
regionQuery = geoFire.query(with: region)

// 7. observe.keyEntered at that region query
queryHandle = regionQuery?.observe(.keyEntered, with: .observe(.keyEntered, with:  (key: String!, location: CLLocation!) in ...

// 8.
regionQuery?.observeReady 
    // do something when the observer from step 7 is finished

【讨论】:

以上是关于iOS -GeoFire ExceptionThrown 'Precision must be less than 23!'当搜索半径变宽时的主要内容,如果未能解决你的问题,请参考以下文章

IO模型--阻塞IO,非阻塞IO,IO多路复用,异步IO

IO复用阻塞IO非阻塞IO同步IO异步IO

四种IO模型‘阻塞IO/非阻塞IO/信号驱动IO/异步IO‘

5种IO模型阻塞IO和非阻塞IO同步IO和异步IO

网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

同步IO异步IO阻塞IO非阻塞IO之间的联系与区别