Ios 在Firebase中将坐标保存为字符串后,如何以CLLLoationDegrees获取坐标以计算用户之间的距离?
我认为应该这样做: 1在Firebase中对所有用户的坐标经度和纬度条目进行快照-在输出框中打印这些条目以选中此步骤 2.1命名func,用于计算登录用户与所有其他用户之间的距离 2.2在该函数中,使let协调₀ = 登录用户的坐标。数据库具有坐标的字符串值,因此需要将其设置为CLLLoationDegrees 2.3对coordinate1进行循环,直到coordinateX(即数据库中的所有用户)获得其坐标 2.4使用let distanceInMeters=坐标₀.距离(从:坐标)₁) 并循环所有距离,直到坐标(数据库中的最后一个) 2.5在输出框中打印所有距离。(我不需要在应用程序上打印它们,我只是获取距离,以便我可以按距离对用户进行排名) ///乙部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=坐标₀.距离(从:坐标)₁) 并
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)")
})
}