ReactJS
Data objects
Geoqueries en React con Parse: Aplicaciones y Ejemplos
10 min
usando la geolocalización de react para realizar geoqueries con parse introducción en esta guía, realizarás geoqueries en parse utilizando la geolocalización de react implementarás un componente de react utilizando estas consultas y aprenderás cómo configurar y consultar datos realistas utilizando back4app y react requisitos previos para completar este tutorial, necesitarás una aplicación de react creada y conectada a back4app si deseas ejecutar el proyecto de ejemplo de esta guía, deberías configurar la ant design ant design biblioteca objetivo realizar geoqueries utilizando geopoints almacenados en back4app y la geolocalización de react 1 entendiendo la clase parse query cualquier operación de consulta de parse utiliza el parse query parse query tipo de objeto, que te ayudará a recuperar datos específicos de tu base de datos a lo largo de tu aplicación es crucial saber que un parse query parse query solo se resolverá después de llamar a un método de recuperación (como parse query find parse query find o parse query get parse query get ), por lo que se puede configurar una consulta y encadenar varios modificadores antes de ser realmente llamada para crear un nuevo parse query parse query , necesitas pasar como parámetro la deseada parse object parse object subclase, que es la que contendrá los resultados de tu consulta un ejemplo de consulta se puede ver a continuación, en la que se está consultando una profile profile subclase ficticia 1 // this will create your query 2 let parsequery = new parse query("profile"); 3 // the query will resolve only after calling this method 4 let queryresult = await parsequery find(); puedes leer más sobre la parse query parse query clase aquí en la documentación oficial https //parseplatform org/parse sdk js/api/master/parse query html 2 guarda algunos datos en back4app vamos a crear una city city clase, que será el objetivo de nuestras consultas en esta guía en la consola js de parse es posible ejecutar código javascript directamente, consultando y actualizando el contenido de la base de datos de tu aplicación utilizando los comandos del sdk de js ejecuta el código a continuación desde tu consola js e inserta los datos en back4app aquí está cómo se ve la consola js en tu panel adelante y crea la ciudad ciudad clase con el siguiente contenido de ejemplo 1 // add city objects and create table 2 // note how geopoints are created, passing latitude and longitude as arguments 3 // montevideo 4 var 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 console log('success!'); 3 consultar los datos ahora que tienes una clase poblada, podemos realizar algunas consultas de geopoint en ella comencemos ordenando ciudad ciudad los resultados por los más cercanos desde kingston en jamaica (latitud 18 01808695059913 y longitud 76 79894232253473), utilizando el parse query near parse query near método 1 // create your query 2 let parsequery = new parse query('city'); 3	 4 // create our geopoint for the query 5 let kingstongeopoint = new parse geopoint(18 018086950599134, 76 79894232253473); 6	 7 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 8 parsequery near('location', kingstongeopoint); 9	 10 // the query will resolve only after calling this method, retrieving 11 // an array of `parse objects` 12 let queryresults = await parsequery find(); 13	 14 // let's show the results 15 for (let result of queryresults) { 16 // you access `parse objects` attributes by using ` get` 17 console log(result get('name')); 18 }; ahora consultemos usando el método parse query withinkilometers parse query withinkilometers , que recuperará todos los resultados cuyo campo geopoint se encuentre dentro de la distancia máxima kingston se usará una vez más como referencia y el límite de distancia será de 3000 km 1 // create your query 2 let parsequery = new parse query('city'); 3	 4 // create our geopoint for the query 5 let kingstongeopoint = new parse geopoint(18 018086950599134, 76 79894232253473); 6	 7 // you can also use `withinmiles` and `withinradians` the same way, 8 // but with different measuring unities 9 parsequery withinkilometers('location', kingstongeopoint, 3000); 10	 11 // the query will resolve only after calling this method, retrieving 12 // an array of `parse objects` 13 let queryresults = await parsequery find(); 14	 15 // let's show the results 16 for (let result of queryresults) { 17 // you access `parse objects` attributes by using ` get` 18 console log(result get('name')); 19 }; otro método de consulta útil es parse query withinpolygon parse query withinpolygon , que consultará resultados cuyo valor del campo geopoint esté dentro del polígono especificado, compuesto por un arreglo de geopoints (al menos tres) si la ruta del polígono está abierta, se cerrará automáticamente por parse conectando los últimos y primeros puntos para este ejemplo, utilizarás un polígono simple que contiene aproximadamente el continente sudamericano, compuesto por 5 geopoints distantes en el océano 1 // create your query 2 let parsequery = new parse query('city'); 3	 4 // create our geopoint polygon for the query 5 let geopoint1 = new parse geopoint(15 822238344514378, 72 42845934415942); 6 let geopoint2 = new parse geopoint( 0 7433770196268968, 97 44765968406668); 7 let geopoint3 = new parse geopoint( 59 997149373299166, 76 52969196322749); 8 let geopoint4 = new parse geopoint( 9 488786415007201, 18 346101586021952); 9 let geopoint5 = new parse geopoint(15 414859532811047, 60 00625459569375); 10	 11 // note that the polygon is merely an array of geopoint objects and that the first and last are not connected, so parse connects them for you 12 parsequery withinpolygon('location', \[geopoint1, geopoint2, geopoint3, geopoint4, geopoint5]); 13	 14 // the query will resolve only after calling this method, retrieving 15 // an array of `parse objects` 16 let queryresults = await parsequery find(); 17	 18 // let's show the results 19 for (let result of queryresults) { 20 // you access `parse objects` attributes by using ` get` 21 console log(result get('name')); 22 }; 4 consulta desde un componente react ahora usemos nuestras consultas de ejemplo dentro de un componente en react, con una interfaz simple que tiene una lista que muestra resultados y también 3 botones para llamar a las consultas el componente también recupera la ubicación actual del dispositivo utilizando el navigator geolocation navigator geolocation api de javascript, por lo que las consultas utilizarán datos reales, siempre que el usuario no haya deshabilitado el acceso a la ubicación en el navegador así es como se organiza el código del componente, note las doquery doquery funciones, que contienen el código de ejemplo de antes javascript 1 import react, { usestate } from 'react'; 2 import parse from 'parse/dist/parse min js'; 3 import ' /app css'; 4 import { button, divider } from 'antd'; 5 import { closeoutlined, searchoutlined } from '@ant design/icons'; 6	 7 export const querygeo = () => { 8 // state variable 9 const \[queryresults, setqueryresults] = usestate(); 10	 11 const doquerynear = async function () { 12 // check if geolocation api is available in the browser 13 if ('geolocation' in navigator) { 14 // get current location and create the geopoint for the query 15 navigator geolocation getcurrentposition( 16 async function (position) { 17 const currentposition = { 18 latitude position coords latitude, 19 longitude position coords longitude, 20 }; 21 // create our geopoint 22 let currentlocationgeopoint = new parse geopoint( 23 currentposition latitude, 24 currentposition longitude 25 ); 26	 27 // create our query 28 let parsequery = new parse query('city'); 29	 30 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 31 parsequery near('location', currentlocationgeopoint); 32	 33 try { 34 let results = await parsequery find(); 35 // set query results to state variable 36 setqueryresults(results); 37 return true; 38 } catch (error) { 39 // error can be caused by lack of internet connection 40 alert(`error! ${error message}`); 41 } 42 }, 43 function ( error) { 44 alert( 45 'you need to allow geolocation to retrieve your location on the browser to test this if you are on an apple os, enable it on your system preferences ' 46 ); 47 } 48 ); 49 } else { 50 alert('geolocation services are not supported by your browser '); 51 } 52 return false; 53 }; 54	 55 const doquerywithinkilometers = async function () { 56 // check if geolocation api is available in the browser 57 if ('geolocation' in navigator) { 58 // get current location and create the geopoint for the query 59 navigator geolocation getcurrentposition( 60 async function (position) { 61 const currentposition = { 62 latitude position coords latitude, 63 longitude position coords longitude, 64 }; 65 // create our geopoint 66 let currentlocationgeopoint = new parse geopoint( 67 currentposition latitude, 68 currentposition longitude 69 ); 70	 71 // create our query 72 let parsequery = new parse query('city'); 73	 74 // you can also use `withinmiles` and `withinradians` the same way, 75 // but with different measuring unities 76 parsequery withinkilometers( 77 'location', 78 currentlocationgeopoint, 79 3000 80 ); 81	 82 try { 83 let results = await parsequery find(); 84 // set query results to state variable 85 setqueryresults(results); 86 } catch (error) { 87 // error can be caused by lack of internet connection 88 alert(`error! ${error message}`); 89 } 90 }, 91 function ( error) { 92 alert( 93 'you need to allow geolocation to retrieve your location on the browser to test this if you are on an apple os, enable it on your system preferences ' 94 ); 95 } 96 ); 97 } else { 98 alert('geolocation services are not supported by your browser '); 99 } 100 return false; 101 }; 102	 103 const doquerywithinpolygon = async function () { 104 // create our geopoint polygon points 105 let geopoint1 = new parse geopoint(15 822238344514378, 72 42845934415942); 106 let geopoint2 = new parse geopoint( 0 7433770196268968, 97 44765968406668); 107 let geopoint3 = new parse geopoint( 59 997149373299166, 76 52969196322749); 108 let geopoint4 = new parse geopoint( 9 488786415007201, 18 346101586021952); 109 let geopoint5 = new parse geopoint(15 414859532811047, 60 00625459569375); 110	 111 // create our query 112 let parsequery = new parse query('city'); 113	 114 // note that the polygon is merely an array of geopoint objects and that the first and 115 // last are not connected, so parse connects them for you 116 parsequery withinpolygon('location', \[ 117 geopoint1, 118 geopoint2, 119 geopoint3, 120 geopoint4, 121 geopoint5, 122 ]); 123	 124 try { 125 let results = await parsequery find(); 126 // set query results to state variable 127 setqueryresults(results); 128 } catch (error) { 129 // error can be caused by lack of internet connection 130 alert(`error! ${error}`); 131 return false; 132 } 133 return true; 134 }; 135	 136 const clearqueryresults = async function () { 137 setqueryresults(undefined); 138 return true; 139 }; 140	 141 return ( 142 \<div> 143 \<div classname="header"> 144 \<img 145 classname="header logo" 146 alt="back4app logo" 147 src={ 148 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 149 } 150 /> 151 \<p classname="header text bold">{'react on back4app'}\</p> 152 \<p classname="header text">{'geopoint queries'}\</p> 153 \</div> 154 \<div classname="container"> 155 \<div classname="flex between"> 156 \<h2 classname="heading">{'query list'}\</h2> 157 \<div classname="flex"> 158 \<button 159 onclick={() => doquerynear()} 160 type="primary" 161 classname="heading button" 162 color={'#208aec'} 163 icon={\<searchoutlined />} 164 > 165 query near 166 \</button> 167 \<button 168 onclick={() => doquerywithinkilometers()} 169 type="primary" 170 classname="heading button" 171 color={'#208aec'} 172 icon={\<searchoutlined />} 173 > 174 query within km 175 \</button> 176 \<button 177 onclick={() => doquerywithinpolygon()} 178 type="primary" 179 classname="heading button" 180 color={'#208aec'} 181 icon={\<searchoutlined />} 182 > 183 query within polygon 184 \</button> 185 \<button 186 onclick={() => clearqueryresults()} 187 type="primary" 188 classname="heading button" 189 color={'#208aec'} 190 icon={\<closeoutlined />} 191 > 192 clear results 193 \</button> 194 \</div> 195 \</div> 196 \<divider /> 197 \<div classname="flex between"> 198 \<div classname="flex child"> 199 {/ query list /} 200 {queryresults !== undefined && 201 queryresults map((result, index) => ( 202 \<div classname="list item" key={`${index}`}> 203 \<p classname="list item title">{`${result get('name')}`}\</p> 204 \</div> 205 ))} 206 {queryresults !== undefined && queryresults length <= 0 ? ( 207 \<p>{'no results here!'}\</p> 208 ) null} 209 \</div> 210 \</div> 211 \</div> 212 \</div> 213 ); 214 }; typescript 1 import react, { usestate, fc, reactelement } from 'react'; 2 import ' /app css'; 3 import { button, divider } from 'antd'; 4 import { closeoutlined, searchoutlined } from '@ant design/icons'; 5 const parse = require('parse/dist/parse min js'); 6	 7 type locationobject = {latitude number, longitude number}; 8	 9 export const querygeo fc<{}> = () reactelement => { 10 // state variable 11 const \[queryresults, setqueryresults] = usestate\<parse object\[]>(); 12	 13 const doquerynear = async function () promise\<boolean> { 14 // check if geolocation api is available in the browser 15 if ("geolocation" in navigator) { 16 // get current location and create the geopoint for the query 17 navigator geolocation getcurrentposition(async function (position) { 18 const currentposition locationobject = { latitude position coords latitude, longitude position coords longitude }; 19 // create our geopoint 20 let currentlocationgeopoint parse geopoint = new parse geopoint( 21 currentposition latitude, 22 currentposition longitude, 23 ); 24	 25 // create our query 26 let parsequery parse query = new parse query('city'); 27	 28 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 29 parsequery near('location', currentlocationgeopoint); 30	 31 try { 32 let results parse object\[] = await parsequery find(); 33 // set query results to state variable 34 setqueryresults(results); 35 return true; 36 } catch (error) { 37 // error can be caused by lack of internet connection 38 alert(`error! ${error message}`); 39 } 40 }, function ( error any) { 41 alert("you need to allow geolocation to retrieve your location on the browser to test this if you are on an apple os, enable it on your system preferences "); 42 }); 43 } else { 44 alert("geolocation services are not supported by your browser "); 45 } 46 return false; 47 }; 48	 49 const doquerywithinkilometers = async function () promise\<boolean> { 50 // check if geolocation api is available in the browser 51 if ("geolocation" in navigator) { 52 // get current location and create the geopoint for the query 53 navigator geolocation getcurrentposition(async function (position) { 54 const currentposition locationobject = { latitude position coords latitude, longitude position coords longitude }; 55 // create our geopoint 56 let currentlocationgeopoint parse geopoint = new parse geopoint( 57 currentposition latitude, 58 currentposition longitude, 59 ); 60	 61 // create our query 62 let parsequery parse query = new parse query('city'); 63	 64 // you can also use `withinmiles` and `withinradians` the same way, 65 // but with different measuring unities 66 parsequery withinkilometers('location', currentlocationgeopoint, 3000); 67	 68 try { 69 let results parse object\[] = await parsequery find(); 70 // set query results to state variable 71 setqueryresults(results); 72 } catch (error) { 73 // error can be caused by lack of internet connection 74 alert(`error! ${error message}`); 75 } 76 }, function ( error any) { 77 alert("you need to allow geolocation to retrieve your location on the browser to test this if you are on an apple os, enable it on your system preferences "); 78 }); 79 } else { 80 alert("geolocation services are not supported by your browser "); 81 } 82 return false; 83 }; 84	 85 const doquerywithinpolygon = async function () promise\<boolean> { 86 // create our geopoint polygon points 87 // in react typescript types ('@types/parse'), parse query withinpolygon expects 88 // an array of number arrays, so you need to change the declarations 89 let geopoint1 number\[] = \[ 90 7 242 845 934 415 940,00 91 15 822 238 344 514 300,00 92 ]; 93 let geopoint2 number\[] = \[ 94 9 744 765 968 406 660,00 95 0 7433770196268968, 96 ]; 97 let geopoint3 number\[] = \[ 98 7 652 969 196 322 740,00 99 59 997 149 373 299 100,00 100 ]; 101 let geopoint4 number\[] = \[ 102 18 346 101 586 021 900,00 103 9 488 786 415 007 200,00 104 ]; 105 let geopoint5 number\[] = \[ 106 6 000 625 459 569 370,00 107 15 414 859 532 811 000,00 108 ]; 109	 110 // create our query 111 let parsequery parse query = new parse query('city'); 112	 113 // note that the polygon is merely an array of geopoint objects and that the first and 114 // last are not connected, so parse connects them for you 115 parsequery withinpolygon('location', \[ 116 geopoint1, 117 geopoint2, 118 geopoint3, 119 geopoint4, 120 geopoint5, 121 ]); 122	 123 try { 124 let results parse object\[] = await parsequery find(); 125 // set query results to state variable 126 setqueryresults(results); 127 } catch (error) { 128 // error can be caused by lack of internet connection 129 alert(`error! ${error}`); 130 return false; 131 } 132 return true; 133 }; 134	 135 const clearqueryresults = async function () promise\<boolean> { 136 setqueryresults(undefined); 137 return true; 138 }; 139	 140 return ( 141 \<div> 142 \<div classname="header"> 143 \<img 144 classname="header logo" 145 alt="back4app logo" 146 src={ 147 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 148 } 149 /> 150 \<p classname="header text bold">{'react on back4app'}\</p> 151 \<p classname="header text">{'geopoint queries'}\</p> 152 \</div> 153 \<div classname="container"> 154 \<div classname="flex between"> 155 \<h2 classname="heading">{'query list'}\</h2> 156 \<div classname="flex"> 157 \<button 158 onclick={() => doquerynear()} 159 type="primary" 160 classname="heading button" 161 color={'#208aec'} 162 icon={\<searchoutlined />} 163 > 164 query near 165 \</button> 166 \<button 167 onclick={() => doquerywithinkilometers()} 168 type="primary" 169 classname="heading button" 170 color={'#208aec'} 171 icon={\<searchoutlined />} 172 > 173 query within km 174 \</button> 175 \<button 176 onclick={() => doquerywithinpolygon()} 177 type="primary" 178 classname="heading button" 179 color={'#208aec'} 180 icon={\<searchoutlined />} 181 > 182 query within polygon 183 \</button> 184 \<button 185 onclick={() => clearqueryresults()} 186 type="primary" 187 classname="heading button" 188 color={'#208aec'} 189 icon={\<closeoutlined />} 190 > 191 clear results 192 \</button> 193 \</div> 194 \</div> 195 \<divider /> 196 \<div classname="flex between"> 197 \<div classname="flex child"> 198 {/ query list /} 199 {queryresults !== undefined && 200 queryresults map((result parse object, index number) => ( 201 \<div classname="list item" key={`${index}`}> 202 \<p classname="list item title">{`${result get('name')}`}\</p> 203 \</div> 204 ))} 205 {queryresults !== undefined && 206 queryresults length <= 0 ? ( 207 \<p>{'no results here!'}\</p> 208 ) null} 209 \</div> 210 \</div> 211 \</div> 212 \</div> 213 ); 214 }; también agrega estas clases a tu app css app css archivo para renderizar completamente el diseño del componente app css 1 html { 2 box sizing border box; 3 outline none; 4 overflow auto; 5 } 6	 7 , 8 before, 9 after { 10 margin 0; 11 padding 0; 12 box sizing inherit; 13 } 14	 15 h1, 16 h2, 17 h3, 18 h4, 19 h5, 20 h6 { 21 margin 0; 22 font weight bold; 23 } 24	 25 p { 26 margin 0; 27 } 28	 29 body { 30 margin 0; 31 background color #fff; 32 } 33	 34 container { 35 width 100%; 36 max width 900px; 37 margin auto; 38 padding 20px 0; 39 text align left; 40 } 41	 42 header { 43 align items center; 44 padding 25px 0; 45 background color #208aec; 46 } 47	 48 header logo { 49 height 55px; 50 margin bottom 20px; 51 object fit contain; 52 } 53	 54 header text bold { 55 margin bottom 3px; 56 color rgba(255, 255, 255, 0 9); 57 font size 16px; 58 font weight bold; 59 } 60	 61 header text { 62 color rgba(255, 255, 255, 0 9); 63 font size 15px; 64 } 65	 66 heading { 67 font size 22px; 68 } 69	 70 flex { 71 display flex; 72 } 73	 74 flex between { 75 display flex; 76 justify content space between; 77 } 78	 79 flex child { 80 flex 0 0 45%; 81 } 82	 83 heading button { 84 margin left 12px; 85 } 86	 87 list item { 88 padding bottom 15px; 89 margin bottom 15px; 90 border bottom 1px solid rgba(0,0,0,0 06); 91 text align left; 92 } 93	 94 list item title { 95 color rgba(0,0,0,0 87); 96 font size 17px; 97 } así es como debería verse el componente después de renderizar y consultar una de las funciones de consulta 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 react en la próxima guía, verás cómo crear y gestionar usuarios en parse