ReactJS
Data objects
ReactアプリでParseのGeoPointクエリを実装する手法
9 分
reactのジオロケーションを使用してparseでジオクエリを実行する はじめに このガイドでは、reactのジオロケーションを使用してparseでジオクエリを実行します。これらのクエリを使用してreactコンポーネントを実装し、back4appとreactを使用して現実的なデータを設定し、クエリを実行する方法を学びます。 前提条件 このチュートリアルを完了するには、次のものが必要です 作成されたreactアプリと back4appに接続された このガイドのサンプルプロジェクトを実行したい場合は、 ant design ant design ライブラリを設定する必要があります。 目標 back4appに保存されたgeopointsとreactのジオロケーションを使用してジオクエリを実行します。 1 parse queryクラスの理解 すべてのparseクエリ操作は、 parse query parse query オブジェクトタイプを使用し、アプリ全体でデータベースから特定のデータを取得するのに役立ちます。 parse query parse query は、リトリーブメソッド(例えば、 parse query find parse query find または parse query get parse query get )を呼び出した後にのみ解決されるため、クエリを設定し、実際に呼び出される前にいくつかの修飾子をチェーンすることができます。 新しい parse query parse query を作成するには、クエリ結果を含むサブクラスとして希望する parse object parse object をパラメータとして渡す必要があります。以下に例として、架空の profile profile サブクラスがクエリされています。 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(); 次の parse query parse query クラスについては、 公式ドキュメントでこちらをご覧ください https //parseplatform org/parse sdk js/api/master/parse query html 。 2 back4appにデータを保存する このガイドのクエリのターゲットとなる city city クラスを作成しましょう。parse js consoleでは、javascriptコードを直接実行し、js sdkコマンドを使用してアプリケーションデータベースの内容をクエリおよび更新することができます。以下のコードをjs consoleから実行し、back4appにデータを挿入してください。 ダッシュボードのjsコンソールの見た目は次のようになります 次の例の内容で city city クラスを作成してください 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 データをクエリする クラスが populated されたので、geopoint クエリを実行できます。ジャマイカのキングストンから最も近い結果を並べ替えましょう(緯度 18 01808695059913、経度 76 79894232253473)。 city city を使用して、 parse query near parse query near メソッドを使用します 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 }; 次に、 parse query withinkilometers parse query withinkilometers メソッドを使用してクエリを実行します。これは、geopoint フィールドが最大距離内にあるすべての結果を取得します。再びキングストンを参照として使用し、距離制限は 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 }; 別の便利なクエリメソッドは parse query withinpolygon parse query withinpolygon , これは指定されたポリゴン内にあるgeopointフィールドの値を持つ結果をクエリします。このポリゴンは、少なくとも3つのgeopointsの配列で構成されています。ポリゴンのパスが開いている場合、parseは最後の点と最初の点を接続して自動的に閉じます。 この例では、南アメリカ大陸を大まかに含む単純なポリゴンを使用します。これは、海にある5つの遠く離れたgeopointsで構成されています。 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 reactコンポーネントからのクエリ では、reactのコンポーネント内で例のクエリを使用し、結果を表示するリストとクエリを呼び出すための3つのボタンを持つシンプルなインターフェースを作成しましょう。このコンポーネントは、 navigator geolocation navigator geolocation javascript apiを使用してデバイスの現在の位置を取得するため、ユーザーがブラウザで位置情報のアクセスを無効にしていない限り、クエリは実際のデータを使用します。 コンポーネントのコードはこのように配置されています。「 doquery doquery 」関数に、以前の例のコードが含まれています。 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 }; これらのクラスも追加してください app css app css ファイルに、コンポーネントのレイアウトを完全にレンダリングするために 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 } コンポーネントがレンダリングされ、クエリ関数の1つをクエリした後の見た目は次のようになります 結論 このガイドの最後に、geopointデータクエリがparseでどのように機能するか、そしてreactアプリケーションからback4appでそれをどのように実行するかを学びました。次のガイドでは、parseでユーザーを作成および管理する方法を確認します。