iOS -GeoFire ExceptionThrown 'Точность должна быть меньше 23!' когда радиус поиска слишком велик

У меня есть mapView, и пользователи могут выбрать радиус масштабирования 1, 10, 20 или 30 миль для поиска ресторанов, где бы они ни находились. Я сохранил все широты ресторана в пути GeoFire.

Когда пользователь решает выполнить поиск, сначала я получаю местоположение пользователя / ов, затем позволяю пользователю выбрать радиус в миле, затем я получаю mapView для увеличения до этого радиуса:

var selectedRadius = 0.0
let milesToMeters = 1609.344
let doubleDistance = 2  // according to this https://stackoverflow.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)

Затем я хочу найти все рестораны в радиусе 10 миль от GeoFire и бегу:

// 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 Region 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, 20 или 30 миль, как я могу выполнить запрос GeoFire, чтобы он соответствовал этому радиусу?


person Lance Samaria    schedule 03.11.2018    source источник


Ответы (1)


Старый ответ, который я дал с морскими милями, показал неправильное расстояние на карте.

Правильный способ - удвоить количество миль, которое вы хотите преодолеть, а затем умножить это на 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://stackoverflow.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
}
person Lance Samaria    schedule 03.11.2018