iOS
...
Data Objects
地理查询与ParseGeoPoint数据类型在ParseSwift SDK中的应用
8 分
地理查询 介绍 我们使用术语 地理查询 来指代那些条件涉及 parsegeopoint parsegeopoint 类型字段的查询。建议使用 parsegeopoint parsegeopoint 结构在 back4app 数据库中存储地理位置数据。 parseswift sdk parseswift sdk 提供了一组方法,使我们能够根据应用于 parsegeopoint parsegeopoint 数据类型的条件查询数据。 前提条件 要完成本教程,您需要: 一个 在 back4app 上创建的应用 一个基本的 ios 应用来测试查询 目标 了解如何使用地理位置数据的条件查询数据。 1 关于 查询\<u> 类的快速回顾 在 back4app 数据库上执行的任何查询都是通过通用类 查询\<u> 查询\<u> 完成的。通用参数 u u (符合 parseobject parseobject 协议)是我们试图从数据库中检索的对象的数据类型。 给定一个数据类型,如 myobject myobject , 我们以以下方式从 back4app 数据库中检索这些对象 1 import parseswift 2 3 struct myobject parseobject { 4 5 } 6 7 let query = myobject query() 8 9 // executes the query asynchronously 10 query find { result in 11 // handle the result (of type result<\[myobject], parseerror>) 12 } 您可以在官方文档中阅读更多关于 query\<u> query\<u> 类的内容, 在这里查看官方文档 https //github com/parse community/parse swift 2 在 back4app 上保存一些数据 在我们开始执行查询之前,我们应该在 back4app 数据库中存储一些示例数据。通过遵循 快速入门 https //www back4app com/docs/ios/parse swift sdk/install sdk 指南,您可以配置并将您的示例 ios 应用程序链接到您的 back4app 数据库。对于本指南,我们将存储有关城市的信息。我们使用以下结构来组织城市的信息: 1 import parseswift 2 3 struct city parseobject { 4 5 6 var name string? // city's name 7 var location parsegeopoint? // it will store the city's coordinate on earth 8 } 现在,我们开始存储示例数据。此步骤可以使用 swift 或直接从您的应用程序的 控制台 https //www youtube com/watch?v=nvwryrzbcma 在 back4app 平台上。 //after setting up your xcode project, calling the following method should save some sample data on your back4app database 1 import parseswift 2 3 func setupsampledata() { 4 do { 5 // montevideo uruguay 6 = try city( 7 name "montevideo", 8 location parsegeopoint(coordinate cllocationcoordinate2d(latitude 34 85553195363169, longitude 56 207280375137955)) 9 ) save() 10 11 // brasília brazil 12 = try city( 13 name "brasília", 14 location parsegeopoint(coordinate cllocationcoordinate2d(latitude 15 79485821477289, longitude 47 88391074690196)) 15 ) save() 16 17 // bogotá colombia 18 = try city( 19 name "bogotá", 20 location parsegeopoint(coordinate cllocationcoordinate2d(latitude 4 69139880891712, longitude 74 06936691331047)) 21 ) save() 22 23 // mexico city mexico 24 = try city( 25 name "mexico city", 26 location parsegeopoint(coordinate cllocationcoordinate2d(latitude 19 400977162618933, longitude 99 13311378164776)) 27 ) save() 28 29 // washington, d c united states 30 = try city( 31 name "washington, d c ", 32 location parsegeopoint(coordinate cllocationcoordinate2d(latitude 38 930727220189944, longitude 77 04626261880388)) 33 ) save() 34 35 // ottawa canada 36 = try city( 37 name "ottawa", 38 location parsegeopoint(latitude 45 41102167733425, longitude 75 695414598736) 39 ) save() 40 } catch let error as parseerror { 41 print("\[parseswift error]", error message) 42 } catch { 43 print("\[error]", error localizeddescription) 44 } 45 } back4app's console //a quick way to insert elements on your back4app database is via the console located in your app’s api section once you are there, you can start running javascript code to save the sample data 1 // add city objects and create table 2 // note how geopoints are created, passing latitude and longitude as arguments 3 // montevideo 4 city = new parse object('city'); 5 city set('name', 'montevideo uruguay'); 6 city set('location', new parse geopoint( 34 85553195363169, 56 207280375137955)); 7 await city save(); 8 9 // brasília 10 city = new parse object('city'); 11 city set('name', 'brasília brazil'); 12 city set('location', new parse geopoint( 15 79485821477289, 47 88391074690196)); 13 await city save(); 14 15 // bogotá 16 city = new parse object('city'); 17 city set('name', 'bogotá colombia'); 18 city set('location', new parse geopoint(4 69139880891712, 74 06936691331047)); 19 await city save(); 20 21 // mexico city 22 city = new parse object('city'); 23 city set('name', 'mexico city mexico'); 24 city set('location', new parse geopoint(19 400977162618933, 99 13311378164776)); 25 await city save(); 26 27 // washington, d c 28 city = new parse object('city'); 29 city set('name', 'washington, d c usa'); 30 city set('location', new parse geopoint(38 930727220189944, 77 04626261880388)); 31 await city save(); 32 33 // ottawa 34 city = new parse object('city'); 35 city set('name', 'ottawa canada'); 36 city set('location', new parse geopoint(45 41102167733425, 75 695414598736)); 37 await city save(); 3 查询数据 排序结果 保存样本数据后,我们可以开始执行不同类型的查询。 在我们的第一个示例中,我们将选择所有城市,并根据它们距离参考地理点的远近进行排序。我们通过将约束传递给 query\<city> query\<city> 对象来实现此查询。方法 near(key\ geopoint ) near(key\ geopoint ) 可通过 parseswift sdk parseswift sdk 构造这样的约束。作为参数,我们传递字段的名称(通常称为 key key ),该字段包含参考 geopoint geopoint 1 // the reference geopoint will be kingston city jamaica 2 guard let kingstongeopoint = try? parsegeopoint(latitude 18 018086950599134, longitude 76 79894232253473) else { return } 3 4 let query = city query(near(key "location", geopoint kingstongeopoint)) // the method near(key\ geopoint ) returns the constraint needed to sort the query 5 6 let sortedcities \[city]? = try? query find() // executes the query synchronosuly and returns an array containing the cities properly sorted 7 8 query find { result in // executes the query asynchronosuly and returns a result<\[city], parseerror> type object to handle the results 9 switch result { 10 case success(let cities) 11 // cities = \[bogotá, washington dc, mexico city, ottawa, brasília, montevideo] 12 case failure(let error) 13 // handle the error if something happened 14 } 15 } 在给定区域内选择结果 假设我们想选择某个区域内的城市。我们可以通过方法 withinkilometers(key\ geopoint\ distance ) withinkilometers(key\ geopoint\ distance ) 创建的约束来实现这一点。作为参数,我们传递包含城市位置的字段名称、区域中心(一个 parsegeopoint parsegeopoint 数据类型)和城市距离该区域中心的最大距离(以 km ) 计算。要选择距离牙买加金斯敦最多 3000km 的所有城市,我们可以通过以下方式实现 1 let distance double = 3000 // km 2 guard let kingstongeopoint = try? parsegeopoint(latitude 18 018086950599134, longitude 76 79894232253473) else { return } 3 4 let query = city query(withinkilometers(key "location", geopoint kingstongeopoint, distance distance)) 5 // the method withinkilometers(key\ geopoint\ distance ) returns the constraint we need for this case 6 7 let sortedcities \[city]? = try? query find() // executes the query synchronosuly and returns an array containing the cities we are looking for (bogotá, washington dc and mexico city in this case) 8 9 query find { result in // executes the query asynchronosuly and returns a result<\[city], parseerror> type object to handle the results 10 switch result { 11 case success(let cities) 12 // cities = \[bogotá, washington dc, mexico city] 13 case failure(let error) 14 // handle the error if something happened 15 } 16 } 此外,当距离以英里而不是公里给出时,我们可以使用 withinmiles(key\ geopoint\ distance\ sorted ) withinmiles(key\ geopoint\ distance\ sorted ) 方法。 一种不太常见的方法, withinradians(key\ geopoint\ distance\ sorted ) withinradians(key\ geopoint\ distance\ sorted ) ,如果距离以弧度给出,也可以使用。它的使用与前面的方法非常相似。 在给定多边形内选择结果 在前面的例子中,我们选择了一个区域内的城市,该区域由一个圆形区域表示。如果我们需要一个非圆形的区域形状, parseswift sdk parseswift sdk 确实允许我们从其顶点构建这样的区域。 现在,这个例子的目标是选择一个五个顶点的多边形内的城市。这些顶点使用 parsegeopoint parsegeopoint 结构表示。一旦我们创建了顶点,我们就实例化一个 parsepolygon parsepolygon 。然后将这个多边形传递给 withinpolygon(key\ polygon ) withinpolygon(key\ polygon ) 方法(由 parseswift sdk parseswift sdk 提供)来构建约束,以便我们可以选择这个多边形内的城市。 1 // the polygon where the selected cities are 2 let polygon parsepolygon? = { 3 do { 4 // we first instantiate the polygon vertices 5 let geopoint1 = try parsegeopoint(latitude 15 822238344514378, longitude 72 42845934415942) 6 let geopoint2 = try parsegeopoint(latitude 0 7433770196268968, longitude 97 44765968406668) 7 let geopoint3 = try parsegeopoint(latitude 59 997149373299166, longitude 76 52969196322749) 8 let geopoint4 = try parsegeopoint(latitude 9 488786415007201, longitude 18 346101586021952) 9 let geopoint5 = try parsegeopoint(latitude 15 414859532811047, longitude 60 00625459569375) 10 11 // next we compose the polygon 12 return try parsepolygon(\[geopoint1, geopoint2, geopoint3, geopoint4, geopoint5]) 13 } catch let error as parseerror { 14 print("failed to instantiate vertices \\(error message)") 15 return nil 16 } catch { 17 print("failed to instantiate vertices \\(error localizeddescription)") 18 return nil 19 } 20 }() 21 22 guard let safepolygon = polygon else { return } 23 24 let query = city query(withinpolygon(key "location", polygon safepolygon)) 25 // withinpolygon(key\ polygon ) returns the required constraint to apply on the query 26 27 let cities = try? query find() // executes the query synchronously 28 29 query find { result in // executes the query asynchronously and returns a result of type result<\[], parseerror> 30 // handle the result 31 } 结论 如今,对位置数据进行操作以提供定制服务非常重要。back4app 与 parseswift sdk parseswift sdk 一起使得实现这些操作变得简单。