Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在Firebase中将坐标保存为字符串后,如何以CLLLoationDegrees获取坐标以计算用户之间的距离?_Ios_Swift_Firebase_Firebase Realtime Database - Fatal编程技术网

Ios 在Firebase中将坐标保存为字符串后,如何以CLLLoationDegrees获取坐标以计算用户之间的距离?

Ios 在Firebase中将坐标保存为字符串后,如何以CLLLoationDegrees获取坐标以计算用户之间的距离?,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,我认为应该这样做: 1在Firebase中对所有用户的坐标经度和纬度条目进行快照-在输出框中打印这些条目以选中此步骤 2.1命名func,用于计算登录用户与所有其他用户之间的距离 2.2在该函数中,使let协调₀ = 登录用户的坐标。数据库具有坐标的字符串值,因此需要将其设置为CLLLoationDegrees 2.3对coordinate1进行循环,直到coordinateX(即数据库中的所有用户)获得其坐标 2.4使用let distanceInMeters=坐标₀.距离(从:坐标)₁) 并

我认为应该这样做:

1在Firebase中对所有用户的坐标经度和纬度条目进行快照-在输出框中打印这些条目以选中此步骤

2.1命名func,用于计算登录用户与所有其他用户之间的距离

2.2在该函数中,使let协调₀ = 登录用户的坐标。数据库具有坐标的字符串值,因此需要将其设置为CLLLoationDegrees

2.3对coordinate1进行循环,直到coordinateX(即数据库中的所有用户)获得其坐标

2.4使用let distanceInMeters=坐标₀.距离(从:坐标)₁) 并循环所有距离,直到坐标(数据库中的最后一个)

2.5在输出框中打印所有距离。(我不需要在应用程序上打印它们,我只是获取距离,以便我可以按距离对用户进行排名)

///乙部

   let thisUsersUid = Auth.auth().currentUser?.uid //Mr. Dunn's uid
refArtists = Database.database().reference().child("people");

refArtists.observe(DataEventType.value,  with: {snapshot in
if snapshot.childrenCount>0{
self.people.removeAll()
   for people in snapshot.children.allObjects as! [DataSnapshot] {
   if people.key != thisUsersUid { //do not add this users info to the array
   let peopleObject = people.value as? [String: AnyObject]
   let peopleCoordinates = peopleObject?["Coordinates"]  as? String
   let peopl = Userx(Coordinates: peopleCoordinates)
   self.people.append(peopl)  
        }
        self.table.reloadData()
        print(snapshot)
        }
    }

})
///丙部

func distance (){
    let databaseRef = Database.database().reference()
    let uid = Auth.auth().currentUser!.uid
    let coordinate₀ = CLLocation(latitude: databaseRef.child("people").child(uid).child("Coordinates").child("latitude"), longitude: databaseRef.child("people").child(uid).child("Coordinates").child("longitude")) //////I think this is incorrect even w/o string to CLL conversion because I don’t think longitude and latitude and technically children of Coordinates
        …..
        let distanceInMeters = coordinate₀.distance(from: coordinate₁)
        let distanceInMeters2 = coordinate₀.distance(from: coordinate2)
        ….
Print …
Print …
///////代码基于Jay的回答

 let uid = Auth.auth().currentUser!.uid

    let ref = Database.database().reference().child("people").child(uid).child("Coordinates")

ref.observeSingleEvent(of: .value, with: { snapshot in
    let allCoordinates = snapshot.children.allObjects as! [DataSnapshot]
    for Coordinates in allCoordinates {
        let lat = Coordinates.childSnapshot(forPath: "latitude").value as! CLLocationDegrees
        let lon = Coordinates.childSnapshot(forPath: "longitude").value as! CLLocationDegrees
        let userId = Coordinates.key
        let locCoord = CLLocationCoordinate2DMake(lat, lon)
        let bcoordinates  = CLLocationCoordinate2D(latitude: lat, longitude: lon)
    }
})
///第二次更新代码:

    let uid = Auth.auth().currentUser!.uid

refArtists = Database.database().reference().child("people");

let ref = self.refArtists.child(uid).child("Coordinates")


ref.observeSingleEvent(of: .value, with: { snapshot in
    let allLocations = snapshot.children.allObjects as! [DataSnapshot]
    for location in allLocations {
        let userId = location.key
        let coordSnap = location.childSnapshot(forPath: "Coordinates")
        let lat = coordSnap.childSnapshot(forPath: "latitude").value as! CLLocationDegrees
        let lon = coordSnap.childSnapshot(forPath: "longitude").value as! CLLocationDegrees
        let locCoord = CLLocationCoordinate2DMake(lat, lon)
        let coordinates  = CLLocationCoordinate2D(latitude: lat, longitude: lon)
        print("   coords: \(lat)  \(lon)")
    }
})
////这是现在打印的两个坐标的代码:

let ref = self.refArtists.child(uid).child("Coordinates")
ref.observeSingleEvent(of: .value, with: { snapshot in
    let allLocations = snapshot.children.allObjects as! [DataSnapshot]
    for location in allLocations {
        let userId = location.key
        let lat = snapshot.childSnapshot(forPath: "latitude").value as! CLLocationDegrees
        let lon = snapshot.childSnapshot(forPath: "longitude").value as! CLLocationDegrees
        let locCoord = CLLocationCoordinate2DMake(lat, lon)
        let coordinates  = CLLocationCoordinate2D(latitude: lat, longitude: lon)
        print("   coords: \(lat)  \(lon)")
    }

在所有这些之后,我希望根据位置对用户进行排名。

有很多方法可以读取您询问的数据。下面是每种方法的摘要

选项1)

如果有一系列直接在节点内存储坐标数据的节点

people
   uid_0
      Latitude: xxxxxxxx
      Longitude: yyyyyyy
   uid_1
      Latitude: aaaaaaaa
      Longitude: bbbbbbbb
您希望迭代每个节点,为每个位置节点(loc_0、loc_1或uid_0、uid_1等)创建一个CoreLocation对象,下面是代码

let ref = self.ref.child("people")
ref.observeSingleEvent(of: .value, with: { snapshot in
    let allUsers = snapshot.children.allObjects as! [DataSnapshot]
    for user in allUsers {
        let lat = user.childSnapshot(forPath: "Latitude").value as! CLLocationDegrees
        let lon = user.childSnapshot(forPath: "Longitude").value as! CLLocationDegrees
        let userId = user.key
        let locCoord = CLLocationCoordinate2DMake(lat, lon)
        let coordinates  = CLLocationCoordinate2D(latitude: lat, longitude: lon)
    }
})
请注意,self.ref指向我的Firebase根目录

选项2)

如果Firebase结构的坐标数据存储在每个父节点下的坐标节点中,则将坐标节点视为其自己的快照,这将使您能够访问其两个子坐标lat和lon

people
   uid_0
      name: "some user"
      coordinates:
         Latitude: 1
         Longitude: 2
   uid_1
      name: "another user"
      coordinates:
         Latitude: 3
         Longitude: 4
注意,我添加了一个名称子节点,这样您也可以看到如何读取它

let ref = self.ref.child("people")
ref.observeSingleEvent(of: .value, with: { snapshot in
    let allUsers = snapshot.children.allObjects as! [DataSnapshot]
    for user in allUsers {
        let userName = user.childSnapshot(forPath: "name").value as! String
        let userId = user.key
        let coordSnap = user.childSnapshot(forPath: "coordinates")
        let lat = coordSnap.childSnapshot(forPath: "Latitude").value as! CLLocationDegrees
        let lon = coordSnap.childSnapshot(forPath: "Longitude").value as! CLLocationDegrees
        let locCoord = CLLocationCoordinate2DMake(lat, lon)
        let coordinates  = CLLocationCoordinate2D(latitude: lat, longitude: lon)
        print("uid: \(userId)  name: \(userName)")
        print("   coords: \(lat)  \(lon)")
    }
})
}
输出结果如下所示

uid: uid_0  name: some name
   coords: 1.0  2.0
uid: uid_1  name: another name
   coords: 3.0  4.0
选项3)

如果您想读取单个特定节点,而不是遍历所有节点,下面是代码。您需要知道父节点的路径,在本例中是当前用户的uid

func readThisUsersCoordinates() {
    let uid = Auth.auth().currentUser!.uid
    let peopleRef = Database.database().reference().child("people");
    let thisPersonRef = peopleRef.child(uid)
    let thisPersonCoordsRef = thisPersonRef.child("Coordinates")
    thisPersonCoordsRef.observeSingleEvent(of: .value, with: { snapshot in
        let lat = snapshot.childSnapshot(forPath: "latitude").value as! CLLocationDegrees
        let lon = snapshot.childSnapshot(forPath: "longitude").value as! CLLocationDegrees
        print("   coords: \(lat)  \(lon)")
    })
}

CLLocationDegrees可能应该存储为双精度,然后您可以读入它们并直接像这样分配它们` let coord=CLLocationCoordinate2DMake(lat,lon)'。有关工作代码,请参见的答案。我不明白问题的其余部分是什么。谢谢。是的,它以双精度存储。您链接的代码有意义,但给出错误:“Any?”不能转换为“[String:AnyObject]”;你想用“as”吗要强制向下播放?“你知道如何修复吗?我假设这是一个Xcode版本的错误。我当然改变了”位置“我在firebase中设置的代码。是的-问题中的代码在这一点上是三年前的,没有更新为swift 5。我贴了一个答案,让你走对了方向。谢谢!我试试看,谢谢。我的数据库看起来有点不同。我试图调整代码以适应数据库的外观,但是我得到了线程1:SIGABRT error,所以它找不到子线程。你看到我没有看到的错误了吗?我的数据库如下所示:人员随机用户ID代码数据点1:数据点2:坐标+纬度:……经度:…。。随机用户ID代码2。。。。。。。我基于你的代码将被放在原来的问题中,因为这里太长了:刚刚达到5分钟的评论限制。问题中的数据库结构比注释中的数据库结构更清晰。@noname87f您需要将坐标节点作为子快照读取。我更新了我的问题来解决这个问题。非常感谢。谢谢你抽出时间。我的数据库中没有“名称”路径,所以我删除了它。我仍然在let lat=。。。线路。但是,前一行让coordSnap工作,因此其形式是正确的。我不知道这是否是因为纬度和经度不是坐标的标准子坐标,而是它的双重列表。你有没有想过为什么会有错误?我已经添加了我现在在问题中使用的代码。@noname87f我从一个可用的现有项目中获取了该代码。我猜您没有指定正确的子密钥名称。我的结构包含子键
纬度
,因此我的代码访问子键
纬度
。您的结构包括
纬度
(小写L),因此您应该访问该子级。我的代码匹配我的结构,因此您可能需要匹配您的结构。我添加了读取
名称
节点作为模板,以便您了解如何访问其他子节点。有道理?
func readThisUsersCoordinates() {
    let uid = Auth.auth().currentUser!.uid
    let peopleRef = Database.database().reference().child("people");
    let thisPersonRef = peopleRef.child(uid)
    let thisPersonCoordsRef = thisPersonRef.child("Coordinates")
    thisPersonCoordsRef.observeSingleEvent(of: .value, with: { snapshot in
        let lat = snapshot.childSnapshot(forPath: "latitude").value as! CLLocationDegrees
        let lon = snapshot.childSnapshot(forPath: "longitude").value as! CLLocationDegrees
        print("   coords: \(lat)  \(lon)")
    })
}