React Native
...
Data objects
Geoqueries
9 分
react nativeのジオロケーションを使用してparseでジオクエリを実行する はじめに このガイドでは、react nativeのジオロケーションを使用してparseでジオクエリを実行します。これらのクエリを使用してreact nativeコンポーネントを実装し、back4appとreact nativeを使用して現実的なデータを設定し、クエリを実行する方法を学びます。 前提条件 このチュートリアルを完了するには、次のものが必要です: 作成され、 back4app に接続されたreact nativeアプリ。 このガイドで提供される画面レイアウトをテスト/使用したい場合は、 react native paper react native paper を設定する必要があります。 ライブラリ と、さらに react native geolocation service react native geolocation service も必要です。 目標 back4appに保存されたジオポイントとreact nativeのジオロケーションを使用してジオクエリを実行します。 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 consoleの見た目です さあ、次の例の内容で city city クラスを作成してください 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 console log('success!'); 3 データをクエリする クラスが populated したので、geopoint クエリを実行できます。まず、 city city の結果をジャマイカのキングストンから最も近い順に並べ替えます(緯度 18 01808695059913、経度 76 79894232253473)。 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フィールド値を持つ結果をクエリします。ポリゴンはgeopointsの配列(少なくとも3つ)で構成されます。ポリゴンのパスが開いている場合、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 nativeコンポーネントからのクエリ では、react nativeのコンポーネント内で例のクエリを使用し、結果を表示するリストとクエリを呼び出すための3つのボタンを持つシンプルなインターフェースを作成しましょう。このコンポーネントは、 react native geolocation service react native geolocation service を使用してデバイスの現在の位置を取得するため、クエリは実際のデータを使用します。 コンポーネントコードのレイアウトはこのようになっています。 doquery doquery 関数があり、以前の例のコード形式が含まれています。 javascript 1 import react, {usestate} from 'react'; 2 import { 3 alert, 4 image, 5 view, 6 permissionsandroid, 7 platform, 8 scrollview, 9 stylesheet, 10 } from 'react native'; 11 import parse from 'parse/react native'; 12 import { 13 list, 14 title, 15 button as paperbutton, 16 text as papertext, 17 } from 'react native paper'; 18 import geolocation from 'react native geolocation service'; 19	 20 export const querylist = () => { 21 // state variable 22 const \[queryresults, setqueryresults] = usestate(null); 23	 24 // this function asks for location permission on ios and android 25 const requestlocationpermissions = async () => { 26 if (platform os === 'ios') { 27 // ios can be asked always, since the os handles if user already gave permission 28 await geolocation requestauthorization('wheninuse'); 29 } else if (platform os === 'android') { 30 let permissioncheck = await permissionsandroid check( 31 permissionsandroid permissions access fine location, 32 ); 33 // only asks for permission on android if not given before 34 if (permissioncheck !== true) { 35 await permissionsandroid request( 36 permissionsandroid permissions access fine location, 37 { 38 title 'location permission request', 39 message 40 'this app needs you permission for using your location for querying geopoints in parse!', 41 buttonpositive 'ok', 42 }, 43 ); 44 } 45 } 46 }; 47	 48 const doquerynear = async function () { 49 // request location permissions 50 await requestlocationpermissions(); 51 // get current location and create the geopoint for the query 52 geolocation getcurrentposition( 53 async (currentposition) => { 54 // create our geopoint 55 let currentlocationgeopoint = new parse geopoint( 56 currentposition coords latitude, 57 currentposition coords longitude, 58 ); 59	 60 // create our query 61 let parsequery = new parse query('city'); 62	 63 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 64 parsequery near('location', currentlocationgeopoint); 65	 66 try { 67 let results = await parsequery find(); 68 // set query results to state variable 69 setqueryresults(results); 70 } catch (error) { 71 // error can be caused by lack of internet connection 72 alert alert('error!', error message); 73 } 74 }, 75 error => { 76 alert alert( 77 'error!', 78 'this app needs your location permission to query this!', 79 ); 80 }, 81 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 82 ); 83 return true; 84 }; 85	 86 const doquerywithinkilometers = async function () { 87 // request location permissions 88 await requestlocationpermissions(); 89 // get current location and create the geopoint for the query 90 geolocation getcurrentposition( 91 async (currentposition) => { 92 // create our geopoint 93 let currentlocationgeopoint = new parse geopoint( 94 currentposition coords latitude, 95 currentposition coords longitude, 96 ); 97	 98 // create our query 99 let parsequery = new parse query('city'); 100	 101 // you can also use `withinmiles` and `withinradians` the same way, 102 // but with different measuring unities 103 parsequery withinkilometers('location', currentlocationgeopoint, 3000); 104	 105 try { 106 let results = await parsequery find(); 107 // set query results to state variable 108 setqueryresults(results); 109 } catch (error) { 110 // error can be caused by lack of internet connection 111 alert alert('error!', error message); 112 } 113 }, 114 error => { 115 alert alert( 116 'error!', 117 'this app needs your location permission to query this!', 118 ); 119 }, 120 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 121 ); 122 return true; 123 }; 124	 125 const doquerywithinpolygon = async function () { 126 // create our geopoint polygon points 127 let geopoint1 = new parse geopoint(15 822238344514378, 72 42845934415942); 128 let geopoint2 = new parse geopoint( 0 7433770196268968, 97 44765968406668); 129 let geopoint3 = new parse geopoint( 59 997149373299166, 76 52969196322749); 130 let geopoint4 = new parse geopoint( 9 488786415007201, 18 346101586021952); 131 let geopoint5 = new parse geopoint(15 414859532811047, 60 00625459569375); 132	 133 // create our query 134 let parsequery = new parse query('city'); 135	 136 // 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 137 parsequery withinpolygon('location', \[ 138 geopoint1, 139 geopoint2, 140 geopoint3, 141 geopoint4, 142 geopoint5, 143 ]); 144	 145 try { 146 let results = await parsequery find(); 147 // set query results to state variable 148 setqueryresults(results); 149 } catch (error) { 150 // error can be caused by lack of internet connection 151 alert alert('error!', error message); 152 } 153 }; 154	 155 const clearqueryresults = async function () { 156 setqueryresults(null); 157 return true; 158 }; 159	 160 return ( 161 <> 162 \<view style={styles header}> 163 \<image 164 style={styles header logo} 165 source={ { 166 uri 167 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png', 168 } } 169 /> 170 \<papertext style={styles header text}> 171 \<papertext style={styles header text bold}> 172 {'react native on back4app '} 173 \</papertext> 174 {' geopoint queries'} 175 \</papertext> 176 \</view> 177 \<scrollview style={styles wrapper}> 178 \<view> 179 \<title>{'result list'}\</title> 180 {/ query list /} 181 {queryresults !== null && 182 queryresults !== undefined && 183 queryresults map((result) => ( 184 \<list item 185 key={result id} 186 title={result get('name')} 187 titlestyle={styles list text} 188 style={styles list item} 189 /> 190 ))} 191 {queryresults === null || 192 queryresults === undefined || 193 (queryresults !== null && 194 queryresults !== undefined && 195 queryresults length <= 0) ? ( 196 \<papertext>{'no results here!'}\</papertext> 197 ) null} 198 \</view> 199 \<view> 200 \<title>{'query buttons'}\</title> 201 \<paperbutton 202 onpress={() => doquerynear()} 203 mode="contained" 204 icon="search web" 205 color={'#208aec'} 206 style={styles list button}> 207 {'query near'} 208 \</paperbutton> 209 \<paperbutton 210 onpress={() => doquerywithinkilometers()} 211 mode="contained" 212 icon="search web" 213 color={'#208aec'} 214 style={styles list button}> 215 {'query within km'} 216 \</paperbutton> 217 \<paperbutton 218 onpress={() => doquerywithinpolygon()} 219 mode="contained" 220 icon="search web" 221 color={'#208aec'} 222 style={styles list button}> 223 {'query within polygon'} 224 \</paperbutton> 225 \<paperbutton 226 onpress={() => clearqueryresults()} 227 mode="contained" 228 icon="delete" 229 color={'#208aec'} 230 style={styles list button}> 231 {'clear results'} 232 \</paperbutton> 233 \</view> 234 \</scrollview> 235 \</> 236 ); 237 }; 238	 239 // these define the screen component styles 240 const styles = stylesheet create({ 241 header { 242 alignitems 'center', 243 paddingtop 30, 244 paddingbottom 50, 245 backgroundcolor '#208aec', 246 }, 247 header logo { 248 height 50, 249 width 220, 250 resizemode 'contain', 251 }, 252 header text { 253 margintop 15, 254 color '#f0f0f0', 255 fontsize 16, 256 }, 257 header text bold { 258 color '#fff', 259 fontweight 'bold', 260 }, 261 wrapper { 262 width '90%', 263 alignself 'center', 264 }, 265 list button { 266 margintop 6, 267 marginleft 15, 268 height 40, 269 }, 270 list item { 271 borderbottomwidth 1, 272 borderbottomcolor 'rgba(0, 0, 0, 0 12)', 273 }, 274 list text { 275 fontsize 15, 276 }, 277 });1 import react, {fc, reactelement, usestate} from 'react'; 2 import { 3 alert, 4 image, 5 view, 6 permissionsandroid, 7 platform, 8 scrollview, 9 stylesheet, 10 } from 'react native'; 11 import parse from 'parse/react native'; 12 import { 13 list, 14 title, 15 button as paperbutton, 16 text as papertext, 17 } from 'react native paper'; 18 import geolocation from 'react native geolocation service'; 19	 20 export const querylist fc<{}> = ({}) reactelement => { 21 // state variable 22 const \[queryresults, setqueryresults] = usestate(null); 23	 24 // this function asks for location permission on ios and android 25 const requestlocationpermissions = async () => { 26 if (platform os === 'ios') { 27 // ios can be asked always, since the os handles if user already gave permission 28 await geolocation requestauthorization('wheninuse'); 29 } else if (platform os === 'android') { 30 let permissioncheck boolean = await permissionsandroid check( 31 permissionsandroid permissions access fine location, 32 ); 33 // only asks for permission on android if not given before 34 if (permissioncheck !== true) { 35 await permissionsandroid request( 36 permissionsandroid permissions access fine location, 37 { 38 title 'location permission request', 39 message 40 'this app needs you permission for using your location for querying geopoints in parse!', 41 buttonpositive 'ok', 42 }, 43 ); 44 } 45 } 46 }; 47	 48 const doquerynear = async function () promise\<boolean> { 49 // request location permissions 50 await requestlocationpermissions(); 51 // get current location and create the geopoint for the query 52 geolocation getcurrentposition( 53 async (currentposition { 54 coords {latitude number; longitude number}; 55 }) => { 56 // create our geopoint 57 let currentlocationgeopoint parse geopoint = new parse geopoint( 58 currentposition coords latitude, 59 currentposition coords longitude, 60 ); 61	 62 // create our query 63 let parsequery parse query = new parse query('city'); 64	 65 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 66 parsequery near('location', currentlocationgeopoint); 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 alert('error!', error message); 75 } 76 }, 77 error => { 78 alert alert( 79 'error!', 80 'this app needs your location permission to query this!', 81 ); 82 }, 83 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 84 ); 85 return true; 86 }; 87	 88 const doquerywithinkilometers = async function () promise\<boolean> { 89 // request location permissions 90 await requestlocationpermissions(); 91 // get current location and create the geopoint for the query 92 geolocation getcurrentposition( 93 async (currentposition { 94 coords {latitude number; longitude number}; 95 }) => { 96 // create our geopoint 97 let currentlocationgeopoint parse geopoint = new parse geopoint( 98 currentposition coords latitude, 99 currentposition coords longitude, 100 ); 101	 102 // create our query 103 let parsequery parse query = new parse query('city'); 104	 105 // you can also use `withinmiles` and `withinradians` the same way, 106 // but with different measuring unities 107 parsequery withinkilometers('location', currentlocationgeopoint, 3000); 108	 109 try { 110 let results \[parse object] = await parsequery find(); 111 // set query results to state variable 112 setqueryresults(results); 113 } catch (error) { 114 // error can be caused by lack of internet connection 115 alert alert('error!', error message); 116 } 117 }, 118 error => { 119 alert alert( 120 'error!', 121 'this app needs your location permission to query this!', 122 ); 123 }, 124 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 125 ); 126 return true; 127 }; 128	 129 const doquerywithinpolygon = async function () promise\<boolean> { 130 // create our geopoint polygon points 131 let geopoint1 parse geopoint = new parse geopoint( 132 15 822 238 344 514 300,00 133 7 242 845 934 415 940,00 134 ); 135 let geopoint2 parse geopoint = new parse geopoint( 136 0 7433770196268968, 137 9 744 765 968 406 660,00 138 ); 139 let geopoint3 parse geopoint = new parse geopoint( 140 59 997 149 373 299 100,00 141 7 652 969 196 322 740,00 142 ); 143 let geopoint4 parse geopoint = new parse geopoint( 144 9 488 786 415 007 200,00 145 18 346 101 586 021 900,00 146 ); 147 let geopoint5 parse geopoint = new parse geopoint( 148 15 414 859 532 811 000,00 149 6 000 625 459 569 370,00 150 ); 151	 152 // create our query 153 let parsequery parse query = new parse query('city'); 154	 155 // 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 156 parsequery withinpolygon('location', \[ 157 geopoint1, 158 geopoint2, 159 geopoint3, 160 geopoint4, 161 geopoint5, 162 ]); 163	 164 try { 165 let results \[parse object] = await parsequery find(); 166 // set query results to state variable 167 setqueryresults(results); 168 } catch (error) { 169 // error can be caused by lack of internet connection 170 alert alert('error!', error message); 171 } 172 }; 173	 174 const clearqueryresults = async function () promise\<boolean> { 175 setqueryresults(null); 176 return true; 177 }; 178	 179 return ( 180 <> 181 \<view style={styles header}> 182 \<image 183 style={styles header logo} 184 source={ { 185 uri 186 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png', 187 } } 188 /> 189 \<papertext style={styles header text}> 190 \<papertext style={styles header text bold}> 191 {'react native on back4app '} 192 \</papertext> 193 {' geopoint queries'} 194 \</papertext> 195 \</view> 196 \<scrollview style={styles wrapper}> 197 \<view> 198 \<title>{'result list'}\</title> 199 {/ query list /} 200 {queryresults !== null && 201 queryresults !== undefined && 202 queryresults map((result parse object) => ( 203 \<list item 204 key={result id} 205 title={result get('name')} 206 titlestyle={styles list text} 207 style={styles list item} 208 /> 209 ))} 210 {queryresults === null || 211 queryresults === undefined || 212 (queryresults !== null && 213 queryresults !== undefined && 214 queryresults length <= 0) ? ( 215 \<papertext>{'no results here!'}\</papertext> 216 ) null} 217 \</view> 218 \<view> 219 \<title>{'query buttons'}\</title> 220 \<paperbutton 221 onpress={() => doquerynear()} 222 mode="contained" 223 icon="search web" 224 color={'#208aec'} 225 style={styles list button}> 226 {'query near'} 227 \</paperbutton> 228 \<paperbutton 229 onpress={() => doquerywithinkilometers()} 230 mode="contained" 231 icon="search web" 232 color={'#208aec'} 233 style={styles list button}> 234 {'query within km'} 235 \</paperbutton> 236 \<paperbutton 237 onpress={() => doquerywithinpolygon()} 238 mode="contained" 239 icon="search web" 240 color={'#208aec'} 241 style={styles list button}> 242 {'query within polygon'} 243 \</paperbutton> 244 \<paperbutton 245 onpress={() => clearqueryresults()} 246 mode="contained" 247 icon="delete" 248 color={'#208aec'} 249 style={styles list button}> 250 {'clear results'} 251 \</paperbutton> 252 \</view> 253 \</scrollview> 254 \</> 255 ); 256 }; 257	 258 // these define the screen component styles 259 const styles = stylesheet create({ 260 header { 261 alignitems 'center', 262 paddingtop 30, 263 paddingbottom 50, 264 backgroundcolor '#208aec', 265 }, 266 header logo { 267 height 50, 268 width 220, 269 resizemode 'contain', 270 }, 271 header text { 272 margintop 15, 273 color '#f0f0f0', 274 fontsize 16, 275 }, 276 header text bold { 277 color '#fff', 278 fontweight 'bold', 279 }, 280 wrapper { 281 width '90%', 282 alignself 'center', 283 }, 284 list button { 285 margintop 6, 286 marginleft 15, 287 height 40, 288 }, 289 list item { 290 borderbottomwidth 1, 291 borderbottomcolor 'rgba(0, 0, 0, 0 12)', 292 }, 293 list text { 294 fontsize 15, 295 }, 296 }); コンポーネントがレンダリングされ、クエリ関数の1つをクエリした後の見た目は次のようになります 結論 このガイドの最後に、geopointデータクエリがparseでどのように機能するか、そしてreact nativeアプリからback4appでそれらをどのように実行するかを学びました。次のガイドでは、parseでユーザーを作成および管理する方法を確認します。