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

查看:21
本文介绍了按距 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 的 query,但是如何使用 query,我现在不明白.

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.

因此,您要做的第一件事就是将地址转换为更可靠的位置指示,即转换为纬度和经度(又名纬度/经度).将地址转换为纬度/经度的过程称为地理编码.这并不是一门精确的科学,但是有很多服务在这个地理编码位方面做得很好.

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.

在此地理编码过程结束时,您将获得每个地址的纬度/经度组合.这又将问题带回了数学,这是一门更精确的科学.

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.

幸运的是,有人想出了一种将纬度/经度信息转换为单个字符串的方法,称为 地理散列.例如:Google 旧金山办公室位于纬度/经度 37.7900515,-122.3923805,转换为 geohash 9q8yy/代码>.山景城的 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.

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

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

有一个名为 GeoFire 的 Firebase 开源库:

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

  1. 可以轻松地在 Firebase 中将位置(必须具有纬度/经度)存储为 geohashes.
  2. 提供查询功能,以便您可以获取在您指定位置的最大距离内的节点.

我建议您查看 iOS 版本的 GeoFire.

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

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