按照距离firebase的用户位置附近的距离排序数组 [英] Sort array by distance near user location from firebase

查看:118
本文介绍了按照距离firebase的用户位置附近的距离排序数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无法弄清楚如何在用户附近自动排序地址。我无法理解从哪里开始以及如何编写代码。

Can't figure out how to do automatic sorting addresses near the user. I can not understand where to start and how to write code.

我的 firebase 中有地址。地址具有类型字符串(不是纬度/经度)。示例:

I have addresses in my firebase. Addresses have type string (not latitude / longitude). Example:

"Москва, Электрозаводская, 21"
"Москва, Арбат, Староконюшенный переулок, дом 43"
"Москва, улица 1-я Бухвостова, дом 12/11, корпус 53"

我知道什么需要使用来自firebase的查询,但如何使用查询,我现在不明白。

I know what need use query from firebase, but how use query, i don't understand now.

这是我的代码:

class PhotoStudiosViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    var theStudios: [Studio] = []

    var studiosRef: DatabaseReference!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        tableView.estimatedRowHeight = 475
        tableView.rowHeight = UITableViewAutomaticDimension

        loadDataFromFirebase()

    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return theStudios.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! PhotoStudiosTableViewCell

        cell.addressLabel.text = theStudios[indexPath.row].studioAddress

        return cell
    }

    func loadDataFromFirebase() {

        studiosRef = Database.database().reference(withPath: "Addresses")

        let time = DispatchTime.now() + 0.5 

        studiosRef.observe(.value, with: { (snapshot) in

        DispatchQueue.main.asyncAfter(deadline: time) {

            for imageSnap in snapshot.children {

                let studioObj = Studio(snapshot: imageSnap as! DataSnapshot)

                self.theStudios.append(studioObj)

            }

            self.tableView.reloadData()

        }

    })

}



class Studio {

    var ref: DatabaseReference! 
    var studioAddress: String = ""

    init(snapshot: DataSnapshot) {

        ref = snapshot.ref
        studioName = snapshot.key

        let value = snapshot.value as! NSDictionary 

        studioAddress = value["address"] as? String ?? "---"

    }
}

如何使用 firebase 中的数据在用户附近设置自动排序地址?

How to make an automatic sorting addresses near the user using data from firebase?

推荐答案

这是一个复杂的过程,需要多个步骤。我会尝试解释这些步骤,但你必须做一些工作才能把它变成一个有效的解决方案。

This is a complex process, requiring multiple steps. I'll try to explain the steps, but you'll have to do quite some work to turn it into a functioning solution.

首先:你所拥有的地址字符串不是一个位置。计算机无法比较两个这样的字符串并可靠地知道它们之间的距离。

First up: an address string like the one you have is not a location. There is no way for a computer to compare two of such strings and reliably know how far apart they are.

所以你要做的第一件事就是把地址变成一个更可靠的位置指示,即经纬度(也就是纬度和经度) )。将地址转换为lat / lon的过程称为地理编码。这不是一个真正的科学,但是有很多服务在这个地理编码位上相当不错。

So the first thing you'll have to do is to turn the addresses into a more reliable indication of a location, i.e. into a latitude and longitude (a.k.a. lat/lon). The process of turning an address into lat/lon is known as geocoding. It is not really an exact science, but there are plenty of services that are quite good at this geocoding bit.

在这个地理编码过程结束时你将有一个lat每个地址的/ lon组合。这将问题重新纳入数学,这是一门更精确的科学。

At the end of this geocoding process you will have a lat/lon combination for each address. That puts the problem back into mathematics, which is a much more exact science.

接下来你我需要比较每个地址的纬度/经度和计算它们之间的距离。如果您愿意忽略极点附近的不准确等等,那么 是一个相对精确的科学。

Next up you'll need to compare the lat/lon of each address and calculate the distance between them. This is a relatively exact science, if you're willing to ignore inaccuracies near the poles and things like that.

不幸的是Firebase实时数据库本地只能对单个属性进行排序/过滤。由于某个位置包含两个属性(纬度和经度),因此无法在没有魔法的情况下对位置进行过滤。

Unfortunately the Firebase Realtime Database can natively only order/filter on a single property. Since a location consists of two properties (latitude and longitude) it can't filter on location without some magic.

幸运的是有人想出了一种翻译lat / lon的方法将信息转换为单个字符串,称为 geohash 。例如:旧金山的Google办公室位于lat / lon 37.7900515,-122.3923805 ,转换为geohash 9q8yyz 。 Mountain View中的Googleplex位于纬度/经度 37.4219999,-122.0862515 ,转换为geohash 9q9hvu

Luckily somebody came up with a way to translate lat/lon information into a single string, known as a geohash. For example: the Google office in San Francisco is at lat/lon 37.7900515,-122.3923805, which translate to geohash 9q8yyz. The Googleplex in Mountain View is at lat/lon 37.4219999,-122.0862515, which translates to geohash 9q9hvu.

与你开始使用的地址不同,geohashes具有很好的可比性。引用(链接)维基百科的解释:

Unlike the addresses you started with, geohashes are very nicely comparable. To quote the (linked) wikipedia explanation:


附近的地方[有]类似的前缀。共享前缀越长,两个位置越近。

nearby places [have] similar prefixes. The longer a shared prefix is, the closer the two places are.

在上面的两个示例中,您可以看到这两个位置彼此相对接近,因为它们都以 9q开头

In our two examples above, you can see the the two locations are relatively close to each other because they both start with 9q

有一个用于Firebase的开源库被调用GeoFire:

There is an open-source library for Firebase called GeoFire that:


  1. 可以很容易地将Firebase中的位置(必须有lat / lon)存储为geohashes。

  2. 提供查询功能,以便您可以获得与指定位置的最大距离之内的节点。

我建议您查看 iOS版GeoFire

这篇关于按照距离firebase的用户位置附近的距离排序数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆