iOS
...
Data Objects
Consultas Geográficas con ParseSwift SDK en iOS
9 min
geoqueries introducción usamos el término geoqueries para referirnos al tipo de consultas donde sus condiciones involucran parsegeopoint parsegeopoint campos de tipo se recomienda usar la parsegeopoint parsegeopoint estructura para almacenar datos de ubicación geográfica en una base de datos de back4app el parseswift sdk parseswift sdk proporciona un conjunto de métodos que nos permite consultar datos de acuerdo a las condiciones aplicadas sobre parsegeopoint parsegeopoint tipo de datos requisitos previos para completar este tutorial, necesitarás una aplicación creada en back4app una aplicación básica de ios para probar consultas objetivo entender cómo consultar datos utilizando condiciones sobre datos de ubicación geográfica 1 revisión rápida sobre la clase query\<u> cualquier consulta realizada en una base de datos de back4app se hace a través de la clase genérica query\<u> query\<u> el parámetro genérico u u (que conforma al parseobject parseobject protocolo) es el tipo de datos de los objetos que estamos tratando de recuperar de la base de datos dado un tipo de dato como myobject myobject , recuperamos estos objetos de una base de datos de back4app de la siguiente manera 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 } puedes leer más sobre la query\<u> query\<u> clase aquí en la documentación oficial https //github com/parse community/parse swift 2 guarda algunos datos en back4app antes de comenzar a ejecutar consultas, debemos almacenar algunos datos de muestra en una base de datos de back4app siguiendo la guía de inicio rápido https //www back4app com/docs/ios/parse swift sdk/install sdk , puedes configurar y vincular tu aplicación ios de muestra a tu base de datos de back4app para esta guía, almacenaremos información sobre ciudades usamos la siguiente estructura para organizar la información de una ciudad 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 } ahora, procedemos a almacenar los datos de muestra este paso se puede implementar utilizando swift o directamente desde la consola https //www youtube com/watch?v=nvwryrzbcma en la plataforma 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 consultar los datos ordenando los resultados con los datos de muestra guardados, podemos comenzar a realizar diferentes tipos de consultas para nuestro primer ejemplo, seleccionaremos todas las ciudades y las ordenaremos dependiendo de qué tan lejos están de un geopunto de referencia implementamos esta consulta pasando una restricción al query\<city> query\<city> objeto el método near(key\ geopoint ) near(key\ geopoint ) disponible a través del parseswift sdk parseswift sdk nos permite construir tal restricción como argumentos, pasamos el nombre del campo (generalmente referido como key key ) que contiene el geopoint geopoint de referencia 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 } seleccionando resultados dentro de una región dada supongamos que queremos seleccionar ciudades dentro de una cierta región podemos lograr esto con una restricción creada por el método withinkilometers(key\ geopoint\ distance ) withinkilometers(key\ geopoint\ distance ) como argumentos, pasamos el nombre del campo que contiene la ubicación de la ciudad, el centro de la región (un parsegeopoint parsegeopoint tipo de dato) y la distancia máxima (en km ) que una ciudad puede estar desde el centro de esta región para seleccionar todas las ciudades que están a un máximo de 3000km de kingston jamaica, podemos hacerlo de la siguiente manera 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 } además, cuando la distancia se da en millas en lugar de kilómetros, podemos usar el withinmiles(key\ geopoint\ distance\ sorted ) withinmiles(key\ geopoint\ distance\ sorted ) método un método menos común, withinradians(key\ geopoint\ distance\ sorted ) withinradians(key\ geopoint\ distance\ sorted ) , también está disponible si la distancia se da en radianes su uso es muy similar a los métodos anteriores seleccionando resultados dentro de un polígono en el ejemplo anterior, seleccionamos ciudades dentro de una región representada por una región circular en caso de que necesitemos tener una forma no circular para la región, el parseswift sdk parseswift sdk nos permite construir tales regiones a partir de sus vértices ahora, el objetivo de este ejemplo es seleccionar ciudades dentro de un polígono de cinco vértices estos vértices se expresan utilizando el parsegeopoint parsegeopoint struct una vez que hemos creado los vértices, instanciamos un parsepolygon parsepolygon este polígono se pasa luego al withinpolygon(key\ polygon ) withinpolygon(key\ polygon ) método (proporcionado por el parseswift sdk parseswift sdk ) para construir la restricción que nos permitirá seleccionar ciudades dentro de este polígono 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 } conclusión hoy en día, realizar operaciones sobre datos de ubicación para ofrecer servicios personalizados es muy importante back4app junto con el parseswift sdk parseswift sdk facilita la implementación de este tipo de operaciones