当前位置: 首页 > 面试题库 >

按距离Firebase用户位置附近的距离对数组进行排序

濮金鑫
2023-03-14
问题内容

无法弄清楚如何对用户附近的 地址 进行自动 排序 。我不明白从哪里开始以及如何编写代码。

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

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

我知道需要从firebase 使用 查询 ,但是如何使用 query ,我现在不明白。

这是我的代码

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中的* 数据在用户附近自动 排序 地址? *


问题答案:

这是一个复杂的过程,需要多个步骤。我将尝试解释这些步骤,但是您必须做一些工作才能将其转变为可运行的解决方案。

地理编码

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

因此,您要做的第一件事就是将地址转换为更可靠的位置指示,即转换为纬度和经度(也就是经/纬度)。将地址转换为经/纬度的过程称为地址解析。这确实不是一门精确的科学,但是有很多服务都可以很好地利用此地理编码位。

在此地址解析过程结束时,您将为每个地址输入经纬度组合。这使问题重新回到数学上,这是一门更为精确的科学。

地理查询

接下来,您需要比较每个地址的经纬度,并计算它们之间的距离。如果您愿意忽略两极附近的错误以及诸如此类的事情,这 一门相对精确的科学。

不幸的是,Firebase实时数据库本身只能对单个属性进行排序/过滤。由于位置由两个属性(纬度和经度)组成,因此如果没有魔法,就无法过滤位置。

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

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

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

在上面的两个示例中,您可以看到两个位置相对靠近,因为它们都以 9q

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

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

我建议您签出iOS版本的GeoFire。



 类似资料:
  • 问题内容: 我有以下模型: 我应如何查询以距离排序(距离为无穷大)? 如果需要,可以在PosgreSQL,GeoDjango上工作。 问题答案: 首先,最好使一个点字段而不是使lat和lnt分开: 然后,你可以像这样过滤它:

  • 正如我们之前所说,有很多不同类型的 ChannelHandler 。每个 ChannelHandler 做什么取决于其超类。 Netty 提供了一些默认的处理程序实现形式的“adapter(适配器)”类。这些旨在简化开发处理逻辑。我们已经看到,在 pipeline 中每个的 ChannelHandler 负责转发事件到链中的下一个处理器。这些适配器类(及其子类)会自动帮你实现,所以你只需要实现该特

  • 我需要计算汽车行驶的距离!不是距离,不是距离到否。如果我们通过谷歌提供的API计算,距离可以完全不同。谷歌可以提供从一个点到另一个点的1公里距离,但汽车可以按照骑手想要的方式行驶800米。使用加速计没有帮助。它适用于步行,但绝不适用于更快的速度。 我尝试过使用Google的位置API:距离到或距离之间根本不是一个选项。它可以给出与IN REAL截然不同的结果。在真实的汽车中,可以通过非常短的地方并

  • 我正在学习CLR中的一节,它描述了使用分而治之的方法,使用两点之间的欧几里德距离来找到最近的点对。 有一个问题,要求找到最近的点对之间的manhatten距离,使用类似的方法。但是,我不能把握两者之间的区别。以下是我能想到的: 3)递归到我们的点子集<=3为止(在这种情况下使用蛮力) 4)最小距离可以是从任何一个递归调用返回的距离--称它为D。 5)找到线“L”周围2D宽度内所有点,然后对于每个这

  • 我正在搜索半径3公里内的用户,基于用户的长/拉特。我正在比较auth long/lat和附近的用户long/lat。它返回具有距离的用户集合。 现在我很难按距离排序。 如果我添加orderBy('距离','desc')当然会导致一个错误,因为我的DB上没有距离列。 这是一种排序和分页的方法。

  • 问题内容: 所以我有一个随机的javascript名称数组… [@ larry,@ nicholas,@ notch]等 它们都以@符号开头。我想按Levenshtein距离对它们进行排序,以使列表顶部的那些最接近搜索词。目前,我有一些使用jQuery的javascript,它使用javascript 方法在按键时输入的搜索词周围: (自首次发布以来编辑的代码) 它还具有一些if语句,用于检测数组