Flutter
...
Data Queries
Geoqueries en Flutter: Queries geográficas en Parse SDK
13 min
usando la geolocalización de flutter para realizar geo consultas en parse introducción en esta guía, aprenderás sobre el tipo de dato geopoint en parse y cómo realizar consultas geográficas en parse utilizando la geolocalización de flutter crearás una aplicación que realizará consultas geográficas y recuperará registros utilizando parse geopoints parse geopoints no explicaremos el código de la aplicación flutter ya que el enfoque principal de esta guía es sobre flutter con parse requisitos previos para completar este tutorial, necesitarás una aplicación creada en back4app nota sigue el tutorial de nueva aplicación parse para aprender cómo crear una aplicación parse en back4app una aplicación flutter conectada a back4app nota sigue el instalar sdk de parse en el proyecto flutter para crear un proyecto flutter conectado a back4app un dispositivo (o dispositivo virtual) que ejecute android o ios para ejecutar este ejemplo de guía, debes configurar el plugin geolocator correctamente no olvides agregar permisos para android e ios para acceder a la ubicación del dispositivo { btn target=” blank” rel=”nofollow noreferer noopener”} en el proyecto lee cuidadosamente las instrucciones para configurar el proyecto de android e ios objetivo realizar geoqueries utilizando geopuntos almacenados en back4app y geolocalización de flutter el tipo de dato geopoint parse te permite asociar coordenadas de latitud y longitud del mundo real con un objeto agregar un parsegeopoint parsegeopoint a un parseobject parseobject permitirá que las consultas consideren la proximidad de un objeto a un punto de referencia esta característica te permite hacer cosas fácilmente, como averiguar qué usuario está más cerca de otro usuario o qué lugares están más cerca de un usuario para asociar un punto con un objeto, primero necesitas crear un parsegeopoint parsegeopoint a continuación, puedes encontrar un geopunto con una latitud de 40 0 grados y 30 0 grados de longitud este punto se almacena en el objeto como un campo regular, como cualquier otro tipo de dato (cadena, número, fecha, etc ) nota actualmente solo una clave en una clase puede ser un parsegeopoint 1 la clase querybuilder cualquier operación de consulta de parse utiliza el querybuilder querybuilder tipo de objeto, que te ayudará a recuperar datos específicos de tu base de datos a lo largo de tu aplicación para crear un nuevo querybuilder querybuilder , necesitas pasar como parámetro la subclase parseobject subclase parseobject deseada, que es la que contendrá los resultados de tu consulta es crucial saber que un querybuilder querybuilder solo se resolverá después de llamar a un método de recuperación query query , por lo que se puede configurar una consulta y encadenar varios modificadores antes de ser realmente llamada puedes leer más sobre la querybuilder querybuilder clase aquí en la documentación oficial usando la consola de javascript en back4app dentro del panel de control de tu aplicación back4app, encontrarás una consola api muy útil en la que puedes ejecutar código javascript directamente en esta guía usarás para almacenar objetos de datos en back4app en el panel principal de tu aplicación ve a core >api console >javascript core >api console >javascript 2 guardar datos en back4app para ejecutar las consultas en esta guía primero necesitarás poblar tu aplicación con algunos datos vamos a crear una ciudad ciudad clase, que será el objetivo de nuestras consultas en esta guía aquí está el parse object parse object código de creación de clases, así que adelante y ejecútalo en tu consola api 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(); 38 39 // tokyo 40 city = new parse object('city'); 41 city set('name', 'tokyo japan'); 42 city set('location', new parse geopoint(35 6897, 139 6922)); 43 await city save(); 44 45 // mumbai 46 city = new parse object('city'); 47 city set('name', 'mumbai india'); 48 city set('location', new parse geopoint(18 9667, 72 8333)); 49 await city save(); 50 51 // shanghai 52 city = new parse object('city'); 53 city set('name', 'shanghai china'); 54 city set('location', new parse geopoint(31 1667, 121 4667)); 55 await city save(); 56 57 // new york 58 city = new parse object('city'); 59 city set('name', 'new york usa'); 60 city set('location', new parse geopoint(40 6943, 73 9249)); 61 await city save(); 62 63 // moscow 64 city = new parse object('city'); 65 city set('name', 'moscow russia'); 66 city set('location', new parse geopoint(55 7558, 37 6178)); 67 await city save(); 68 69 // paris 70 city = new parse object('city'); 71 city set('name', 'paris france'); 72 city set('location', new parse geopoint(48 8566, 2 3522)); 73 await city save(); 74 75 // paris 76 city = new parse object('city'); 77 city set('name', 'london united kingdom'); 78 city set('location', new parse geopoint(51 5072, 0 1275)); 79 await city save(); 80 81 // luanda 82 city = new parse object('city'); 83 city set('name', 'luanda angola'); 84 city set('location', new parse geopoint( 8 8383, 13 2344)); 85 await city save(); 86 87 // johannesburg 88 city = new parse object('city'); 89 city set('name', 'johannesburg south africa'); 90 city set('location', new parse geopoint( 26 2044, 28 0416)); 91 await city save(); 92 93 console log('success!'); después de ejecutar este código, ahora deberías tener una ciudad ciudad clase en tu base de datos tu nueva clase debería verse así ahora echemos un vistazo a ejemplos de cada querybuilder querybuilder método, junto con breves explicaciones sobre lo que hacen 3 consultar los datos ahora que tienes una clase poblada, podemos realizar algunas consultas de geopoint en ella comencemos ordenando ciudad ciudad resultados por el más cercano desde dallas en ee uu (latitud 32 779167, y longitud 96 808891), utilizando el wherenear wherenear método 1 // create your query 2 final querybuilder\<parseobject> parsequery = 3 querybuilder\<parseobject>(parseobject('city')); 4 5 // create our geopoint for the query 6 final dallasgeopoint = 7 parsegeopoint(latitude 32 779167, longitude 96 808891); 8 9 // `wherenear` will order results based on distance between the geopoint 10 // type field from the class and the geopoint argument 11 parsequery wherenear('location', dallasgeopoint); 12 13 // the query will resolve only after calling this method, retrieving 14 // an array of `parseobjects`, if success 15 final parseresponse apiresponse = await parsequery query(); 16 17 if (apiresponse success && apiresponse results != null) { 18 // let's show the results 19 for (var o in apiresponse results! as list\<parseobject>) { 20 print( 21 'city ${o get\<string>('name')} location ${o get\<parsegeopoint>('location')! latitude}, ${o get\<parsegeopoint>('location')! longitude}'); 22 } 23 } ahora consultemos utilizando el método wherewithinkilometers wherewithinkilometers , que recuperará todos los resultados cuyo campo geopoint se encuentre dentro de la distancia máxima en kilómetros dallas se utilizará una vez más como referencia y el límite de distancia será de 3000 km 1 // create your query 2 final querybuilder\<parseobject> parsequery = 3 querybuilder\<parseobject>(parseobject('city')); 4 5 // create our geopoint for the query 6 final dallasgeopoint = 7 parsegeopoint(latitude 32 779167, longitude 96 808891); 8 9 // you can also use `withinmiles` and `withinradians` the same way, 10 // but with different measuring unities 11 parsequery wherewithinkilometers('location', dallasgeopoint, 3000); 12 //parsequery wherewithinmiles('location', dallasgeopoint, 3000); 13 14 // the query will resolve only after calling this method, retrieving 15 // an array of `parseobjects`, if success 16 final parseresponse apiresponse = await parsequery query(); 17 18 if (apiresponse success && apiresponse results != null) { 19 // let's show the results 20 for (var o in apiresponse results! as list\<parseobject>) { 21 print( 22 'city ${o get\<string>('name')} location ${o get\<parsegeopoint>('location')! latitude}, ${o get\<parsegeopoint>('location')! longitude}'); 23 } 24 } ahora consultemos usando el método wherewithinmiles wherewithinmiles , que recuperará todos los resultados cuyo campo geopoint se encuentre dentro de la distancia máxima en millas dallas se utilizará una vez más como referencia y el límite de distancia será de 3000 millas 1 // create your query 2 final querybuilder\<parseobject> parsequery = 3 querybuilder\<parseobject>(parseobject('city')); 4 5 // create our geopoint for the query 6 final dallasgeopoint = 7 parsegeopoint(latitude 32 779167, longitude 96 808891); 8 9 // you can also use `wherewithinkilometers` and `wherewithinradians` the same way, 10 parsequery wherewithinmiles('location', dallasgeopoint, 3000); 11 12 // the query will resolve only after calling this method, retrieving 13 // an array of `parseobjects`, if success 14 final parseresponse apiresponse = await parsequery query(); 15 16 if (apiresponse success && apiresponse results != null) { 17 // let's show the results 18 for (var o in apiresponse results! as list\<parseobject>) { 19 print( 20 'city ${o get\<string>('name')} location ${o get\<parsegeopoint>('location')! latitude}, ${o get\<parsegeopoint>('location')! longitude}'); 21 } 22 } 4 consulta desde flutter ahora usemos nuestras consultas de ejemplo dentro de una aplicación flutter, con una interfaz simple que tiene una lista que muestra resultados y también 3 botones para llamar a las consultas la aplicación también recupera la ubicación actual del dispositivo utilizando geolocator plugin (siga las instrucciones), por lo que las consultas utilizarán datos reales abre tu proyecto de flutter, ve al main dart main dart archivo, limpia todo el código y reemplázalo con 1 import 'package\ flutter/cupertino dart'; 2 import 'package\ flutter/material dart'; 3 import 'package\ geolocator/geolocator dart'; 4 import 'package\ parse server sdk flutter/parse server sdk dart'; 5 6 void main() async { 7 widgetsflutterbinding ensureinitialized(); 8 9 final keyapplicationid = 'your app id here'; 10 final keyclientkey = 'your client key here'; 11 12 final keyparseserverurl = 'https //parseapi back4app com'; 13 14 await parse() initialize(keyapplicationid, keyparseserverurl, 15 clientkey keyclientkey, debug true); 16 17 runapp(materialapp( 18 title 'flutter geopoint', 19 debugshowcheckedmodebanner false, 20 home homepage(), 21 )); 22 } 23 24 class homepage extends statefulwidget { 25 @override 26 homepagestate createstate() => homepagestate(); 27 } 28 29 class homepagestate extends state\<homepage> { 30 list\<parseobject> results = \<parseobject>\[]; 31 double selecteddistance = 3000; 32 33 future\<position> getcurrentposition() async { 34 bool serviceenabled; 35 locationpermission permission; 36 37 // test if location services are enabled 38 serviceenabled = await geolocator islocationserviceenabled(); 39 if (!serviceenabled) { 40 return future error('location services are disabled '); 41 } 42 43 permission = await geolocator checkpermission(); 44 if (permission == locationpermission denied) { 45 permission = await geolocator requestpermission(); 46 if (permission == locationpermission denied) { 47 return future error('location permissions are denied'); 48 } 49 } 50 51 if (permission == locationpermission deniedforever) { 52 return future error( 53 'location permissions are permanently denied, we cannot request permissions '); 54 } 55 56 // when we reach here, permissions are granted and we can 57 // continue accessing the position of the device 58 return await geolocator getcurrentposition(); 59 } 60 61 void doquerynear() async { 62 // create your query 63 final querybuilder\<parseobject> parsequery = 64 querybuilder\<parseobject>(parseobject('city')); 65 66 // get current position from device 67 final position = await getcurrentposition(); 68 69 final currentgeopoint = parsegeopoint( 70 latitude position latitude, longitude position longitude); 71 72 // `wherenear` will order results based on distance between the geopoint 73 // type field from the class and the geopoint argument 74 parsequery wherenear('location', currentgeopoint); 75 76 // the query will resolve only after calling this method, retrieving 77 // an array of `parseobjects`, if success 78 final parseresponse apiresponse = await parsequery query(); 79 80 if (apiresponse success && apiresponse results != null) { 81 // let's show the results 82 for (var o in apiresponse results! as list\<parseobject>) { 83 print( 84 'city ${o get\<string>('name')} location ${o get\<parsegeopoint>('location')! latitude}, ${o get\<parsegeopoint>('location')! longitude}'); 85 } 86 87 setstate(() { 88 results = apiresponse results as list\<parseobject>; 89 }); 90 } else { 91 setstate(() { 92 results clear(); 93 }); 94 } 95 } 96 97 void doqueryinkilometers() async { 98 // create your query 99 final querybuilder\<parseobject> parsequery = 100 querybuilder\<parseobject>(parseobject('city')); 101 102 // get current position from device 103 final position = await getcurrentposition(); 104 105 final currentgeopoint = parsegeopoint( 106 latitude position latitude, longitude position longitude); 107 108 // you can also use `wherewithinmiles` and `wherewithinradians` the same way, 109 // but with different measuring unities 110 parsequery wherewithinkilometers( 111 'location', currentgeopoint, selecteddistance); 112 113 // the query will resolve only after calling this method, retrieving 114 // an array of `parseobjects`, if success 115 final parseresponse apiresponse = await parsequery query(); 116 117 if (apiresponse success && apiresponse results != null) { 118 // let's show the results 119 for (var o in apiresponse results! as list\<parseobject>) { 120 print( 121 'city ${o get\<string>('name')} location ${o get\<parsegeopoint>('location')! latitude}, ${o get\<parsegeopoint>('location')! longitude}'); 122 } 123 124 setstate(() { 125 results = apiresponse results as list\<parseobject>; 126 }); 127 } else { 128 setstate(() { 129 results clear(); 130 }); 131 } 132 } 133 134 void doqueryinmiles() async { 135 // create your query 136 final querybuilder\<parseobject> parsequery = 137 querybuilder\<parseobject>(parseobject('city')); 138 139 // get current position from device 140 final position = await getcurrentposition(); 141 142 final currentgeopoint = parsegeopoint( 143 latitude position latitude, longitude position longitude); 144 145 // you can also use `wherewithinkilometers` and `wherewithinradians` the same way, 146 parsequery wherewithinmiles('location', currentgeopoint, selecteddistance); 147 148 // the query will resolve only after calling this method, retrieving 149 // an array of `parseobjects`, if success 150 final parseresponse apiresponse = await parsequery query(); 151 152 if (apiresponse success && apiresponse results != null) { 153 // let's show the results 154 for (var o in apiresponse results! as list\<parseobject>) { 155 print( 156 'city ${o get\<string>('name')} location ${o get\<parsegeopoint>('location')! latitude}, ${o get\<parsegeopoint>('location')! longitude}'); 157 } 158 159 setstate(() { 160 results = apiresponse results as list\<parseobject>; 161 }); 162 } else { 163 setstate(() { 164 results clear(); 165 }); 166 } 167 } 168 169 void doclearresults() async { 170 setstate(() { 171 results = \[]; 172 }); 173 } 174 175 @override 176 widget build(buildcontext context) { 177 return scaffold( 178 body padding( 179 padding const edgeinsets all(16 0), 180 child column( 181 crossaxisalignment crossaxisalignment stretch, 182 children \[ 183 container( 184 height 200, 185 child image network( 186 'https //blog back4app com/wp content/uploads/2017/11/logo b4a 1 768x175 1 png'), 187 ), 188 center( 189 child const text('flutter on back4app geopoint', 190 style textstyle(fontsize 18, fontweight fontweight bold)), 191 ), 192 sizedbox( 193 height 8, 194 ), 195 container( 196 height 50, 197 child elevatedbutton( 198 onpressed doquerynear, 199 child text('query near'), 200 style elevatedbutton stylefrom(primary colors blue)), 201 ), 202 sizedbox( 203 height 16, 204 ), 205 center(child text('distance')), 206 slider( 207 value selecteddistance, 208 min 0, 209 max 10000, 210 divisions 10, 211 onchanged (value) { 212 setstate(() { 213 selecteddistance = value; 214 }); 215 }, 216 label selecteddistance tostringasfixed(0), 217 ), 218 sizedbox( 219 height 8, 220 ), 221 container( 222 height 50, 223 child elevatedbutton( 224 onpressed doqueryinkilometers, 225 child text('query in kilometers'), 226 style elevatedbutton stylefrom(primary colors blue)), 227 ), 228 sizedbox( 229 height 8, 230 ), 231 container( 232 height 50, 233 child elevatedbutton( 234 onpressed doqueryinmiles, 235 child text('query miles'), 236 style elevatedbutton stylefrom(primary colors blue)), 237 ), 238 sizedbox( 239 height 8, 240 ), 241 container( 242 height 50, 243 child elevatedbutton( 244 onpressed doclearresults, 245 child text('clear results'), 246 style elevatedbutton stylefrom(primary colors blue)), 247 ), 248 sizedbox( 249 height 8, 250 ), 251 text( 252 'result list ${results length}', 253 ), 254 expanded( 255 child listview\ builder( 256 itemcount results length, 257 itembuilder (context, index) { 258 final o = results\[index]; 259 return container( 260 padding const edgeinsets all(4), 261 decoration 262 boxdecoration(border border all(color colors black)), 263 child text( 264 '${o get\<string>('name')} \nlocation ${o get\<parsegeopoint>('location')! latitude}, ${o get\<parsegeopoint>('location')! longitude}'), 265 ); 266 }), 267 ) 268 ], 269 ), 270 )); 271 } 272 } encuentra tu id de aplicación y las credenciales de clave de cliente navegando a tu panel de control de la aplicación en sitio web de back4app https //www back4app com/ actualiza tu código en main dart main dart con los valores de applicationid y clientkey de tu proyecto en back4app keyapplicationid = id de la aplicación keyclientkey = clave del cliente ejecuta el proyecto, y la aplicación se cargará como se muestra en la imagen conclusión al final de esta guía, aprendiste cómo funcionan las consultas de datos geopoint en parse y cómo realizarlas en back4app desde una aplicación flutter