Flutter
...
Data Queries
파스와 플러터로 지리 쿼리 수행하기: GeoPoint 활용
12 분
플러터 지리 위치를 사용하여 파스에서 지리 쿼리 수행하기 소개 이 가이드에서는 파스의 geopoint 데이터 유형과 플러터 지리 위치를 사용하여 파스에서 지리 쿼리를 수행하는 방법에 대해 배웁니다 지리 쿼리를 수행하고 파스 지리 포인트 파스 지리 포인트 을 사용하여 레코드를 검색하는 애플리케이션을 만들 것입니다 이 가이드의 주요 초점이 플러터와 파스에 있기 때문에 플러터 애플리케이션 코드는 설명하지 않겠습니다 전제 조건 이 튜토리얼을 완료하려면 다음이 필요합니다 back4app에서 생성된 앱입니다 참고 다음의 새 parse 앱 튜토리얼 을 따라 back4app에서 parse 앱을 만드는 방법을 배우세요 back4app에 연결된 flutter 앱입니다 참고 다음의 flutter 프로젝트에 parse sdk 설치하기 를 따라 back4app에 연결된 flutter 프로젝트를 만드세요 android 또는 ios를 실행하는 장치(또는 가상 장치)입니다 이 가이드 예제를 실행하려면 geolocator 플러그인을 올바르게 설정해야 합니다 장치 위치에 접근하기 위해 android 및 ios에 대한 권한을 추가하는 것을 잊지 마세요 { btn target=” blank” rel=”nofollow noreferer noopener”} 프로젝트에서 android 및 ios 프로젝트 설정에 대한 지침을 주의 깊게 읽으세요 목표 back4app 및 flutter 지리 위치를 사용하여 지오쿼리를 수행합니다 geopoint 데이터 유형 parse는 실제 세계의 위도 및 경도 좌표를 객체와 연관시킬 수 있도록 합니다 parsegeopoint parsegeopoint 을 parseobject parseobject 에 추가하면 객체와 기준점 간의 근접성을 고려하여 쿼리를 수행할 수 있습니다 이 기능을 통해 다른 사용자와 가장 가까운 사용자를 찾거나 사용자에게 가장 가까운 장소를 쉽게 찾을 수 있습니다 객체와 점을 연관시키려면 먼저 parsegeopoint parsegeopoint 을 생성해야 합니다 아래에서 위도가 40 0도이고 경도가 30 0도인 지오포인트를 찾을 수 있습니다 이 포인트는 다른 데이터 유형(문자열, 숫자, 날짜 등)과 마찬가지로 객체에 일반 필드로 저장됩니다 참고 현재 클래스에서 하나의 키만 parsegeopoint일 수 있습니다 1 querybuilder 클래스 모든 parse 쿼리 작업은 querybuilder querybuilder 객체 유형을 사용하며, 이는 앱 전반에 걸쳐 데이터베이스에서 특정 데이터를 검색하는 데 도움이 됩니다 새 querybuilder querybuilder 를 생성하려면 원하는 parseobject parseobject 하위 클래스를 매개변수로 전달해야 하며, 이는 쿼리 결과를 포함할 것입니다 알아야 할 중요한 점은 querybuilder querybuilder 는 retrieve 메서드를 호출한 후에만 해결된다는 것입니다 query query , 따라서 쿼리를 설정하고 실제로 호출되기 전에 여러 수정자를 연결할 수 있습니다 querybuilder querybuilder 클래스에 대한 자세한 내용은 여기에서 공식 문서 를 참조하세요 back4app에서 javascript 콘솔 사용하기 back4app 애플리케이션의 대시보드 내에서 javascript 코드를 직접 실행할 수 있는 매우 유용한 api 콘솔을 찾을 수 있습니다 이 가이드에서는 back4app에 데이터 객체를 저장하는 데 사용할 것입니다 앱의 주요 대시보드에서 core >api console >javascript core >api console >javascript 로 이동하세요 2 back4app에 데이터 저장하기 이 가이드에서 쿼리를 실행하려면 먼저 앱에 데이터를 채워야 합니다 city city 클래스를 생성할 것이며, 이는 이 가이드에서 우리의 쿼리의 대상이 될 것입니다 다음은 parse object parse object 클래스 생성 코드입니다 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!'); 이 코드를 실행한 후, 데이터베이스에 city city 클래스가 생성되어야 합니다 새 클래스는 다음과 같아야 합니다 이제 모든 querybuilder querybuilder 메서드의 예제를 살펴보고, 그들이 하는 일에 대한 간단한 설명을 추가하겠습니다 3 데이터 쿼리하기 이제 클래스가 채워졌으므로, geopoint 쿼리를 수행할 수 있습니다 시작하겠습니다 도시 도시 결과를 미국 달라스에서 가장 가까운 순으로 정렬하겠습니다 (위도 32 779167, 경도 96 808891), wherenear wherenear 메서드를 사용하여 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 } 이제 wherewithinkilometers wherewithinkilometers , 메서드를 사용하여 쿼리하겠습니다 이 메서드는 geopoint 필드가 최대 거리 내에 있는 모든 결과를 검색합니다 달라스를 다시 참조로 사용하고 거리 제한은 3000km가 될 것입니다 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 } 이제 wherewithinmiles wherewithinmiles 메서드를 사용하여 쿼리를 수행해 보겠습니다 이 메서드는 geopoint 필드가 최대 거리 내에 있는 모든 결과를 검색합니다 다시 한 번 댈러스를 참조로 사용하고 거리 제한은 3000마일이 될 것입니다 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 flutter에서 쿼리 이제 flutter 앱 내에서 예제 쿼리를 사용해 보겠습니다 결과를 보여주는 목록과 쿼리를 호출하는 3개의 버튼이 있는 간단한 인터페이스를 갖추고 있습니다 앱은 또한 geolocator 플러그인을 사용하여 장치의 현재 위치를 검색합니다(지침을 따르세요) 따라서 쿼리는 실제 데이터를 사용할 것입니다 flutter 프로젝트를 열고, main dart main dart 파일의 모든 코드를 정리하고 다음으로 교체하세요 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 } 애플리케이션 id와 클라이언트 키 자격 증명을 찾으려면 back4app 웹사이트 https //www back4app com/ 로 이동하세요 코드를 다음과 같이 업데이트하세요 main dart main dart back4app의 프로젝트의 applicationid와 clientkey 값으로 keyapplicationid = 앱 id keyclientkey = 클라이언트 키 프로젝트를 실행하면 앱이 이미지와 같이 로드됩니다 결론 이 가이드의 끝에서, 당신은 geopoint 데이터 쿼리가 parse에서 어떻게 작동하는지와 flutter 앱에서 back4app에서 이를 수행하는 방법을 배웠습니다