[Flutter] Geofflutterfire 범위 내 좌표의 신 포장에 대한 소개만 획득
무엇이 Geofflutterfire입니까?
여러분geoflutterfire이 신의 포장을 아십니까...
geoflutterfire를 사용하면 Firestore에서 범위 내의 좌표만 얻을 수 있다. 아래와 같다.(엔화 대체기준)
이번에는 관련 geoflutterfire 일본어 보도를 거의 찾지 못했기 때문에 여기에 기록한다.
마지막으로 샘플 코드도 넣어주세요!!
geofflutterfire 사용법
이 문서에 따르면 Geofflutterfire의 특징은 다음과 같다!
전제 조건
Firebase 연결 및 Firestore 사용 가능 상태
초기화
import 'package:geoflutterfire/geoflutterfire.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
// Init firestore and geoFlutterFire
final geo = Geoflutterfire();
final _firestore = FirebaseFirestore.instance;
지리적 정보 쓰기
사용
GeoFirePoint
GeoFirePoint geoFirePoint = geo.point(latitude: 12.960632, longitude: 77.641603);
GeoFirePoint는
지리 정보를 잘 처리하는 반.세 개의 Getter가 있습니다.
geoFirePoint.hash
: 9자 GeoHash의 문자열을 반환합니다.geohash에 관해서는 뒤에서 서술할 것이다.예:s1b8yu2njgeoFirePoint.geoPoint
: Firestore에서 사용된 GeoPoint를 반환합니다.GeoPoint (double latitude, double longitude)
는 위도 경도를 가지고 있다.geoFirePoint.data
: Firestore에 저장할 데이터를 반환합니다.예: {geopopint:Instance of'GeoPoint', geohash:s1b8yu2nj}GeoFirePoint
Firestore에 추가_firestore
.collection('shop')
.add({'name': 'random name', 'position': geoFirePoint.data});
실제로는 Firestore에 이렇게 저장되어 있어요.지리 정보 얻기
어느 지점에서 50km 이내의 문서를 검색하다.Stream에서 값을 받습니다.
// Create a geoFirePoint
GeoFirePoint center = geo.point(latitude: 12.960632, longitude: 77.641603);
// get the collection reference or query
var collectionReference = _firestore.collection('shop');
double radius = 50;
String field = 'position';
Stream<List<DocumentSnapshot>> stream =
geo.collection(collectionRef: collectionReference)
.within(center: center, radius: radius, field: field);
수신된 Stream을 모니터링합니다.stream.listen((List<DocumentSnapshot> documentList) {
// doSomething()
});
Geohash 소개
Yahoo!선생님의 문장은 매우 이해하기 쉽다
Geohash
!일부분을 인용할 수 있도록 허락해 주십시오
Geohash
.Geohash는 지도를 격자 모양으로 나누어 짧은 문자열로 구획을 표현할 수 있습니다.예를 들어 도쿄역 주변의 Geohash 6자리 숫자는'xn76ur'로 표시된다.
인접한 구획은 비슷한 문자열로 표시할 수 있기 때문에 Geohash 구획 옆에 있는 구획을 간단하게 계산할 수 있다.
간단히 설명
Geohash
Geofflutterfire는 9자리 문자열로 되돌아오기 때문에 정밀도가 높습니다.
※Yahoo!Tec의 블로그 참조
Geofflutterfire를 사용해 보십시오
마지막으로 여기 샘플 코드를 올려주세요!
차리다
Firebase 연결 및 Firestore 를 사용할 수 있습니다.
Firestore에서 GeoFluterPoint 추가
GoogleMap 사용 가능
사용 중인 라이브러리
pubspec.yaml
dependencies:
google_maps_flutter: ^2.1.2
geolocator: ^8.2.0
firebase_core: ^1.13.1
cloud_firestore: ^3.1.10
geoflutterfire: ^3.0.3
샘플 코드main.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:geoflutterfire/geoflutterfire.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:rxdart/rxdart.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MaterialApp(
title: 'Geo Flutter Fire example',
home: MyApp(),
debugShowCheckedModeBanner: true,
),
);
}
class MyApp extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
GoogleMapController? _mapController;
TextEditingController? _latitudeController, _longitudeController;
// firestore init
final radius = BehaviorSubject<double>.seeded(1.0);
final _firestore = FirebaseFirestore.instance;
final markers = <MarkerId, Marker>{};
late Stream<List<DocumentSnapshot>> stream;
late Geoflutterfire geo;
double _value = 20.0;
String _label = '';
double _ratio = 0;
double screenWidthKms = 600;
void initState() {
super.initState();
_latitudeController = TextEditingController();
_longitudeController = TextEditingController();
geo = Geoflutterfire();
GeoFirePoint center =
geo.point(latitude: 43.0779575, longitude: 142.337819);
stream = radius.switchMap(
(rad) {
final collectionReference = _firestore.collection('shop');
return geo.collection(collectionRef: collectionReference).within(
center: center, radius: rad, field: 'position', strictMode: true);
},
);
Future(() async {
//_mapControllerがinitializeされるのを待つ1秒
await Future.delayed(const Duration(seconds: 1));
final region = await _mapController?.getVisibleRegion();
final distanceInMeters = Geolocator.distanceBetween(
region!.northeast.latitude,
region.northeast.longitude,
region.southwest.latitude,
region.northeast.longitude);
screenWidthKms = distanceInMeters / 1000;
print('画面の横幅の距離 $screenWidthKms km');
});
}
void dispose() {
_latitudeController?.dispose();
_longitudeController?.dispose();
radius.close();
super.dispose();
}
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: Card(
elevation: 4,
margin: const EdgeInsets.symmetric(vertical: 8),
child: SizedBox(
height: 550,
child: Stack(
children: [
GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: const CameraPosition(
target: LatLng(43.0779575, 142.337819),
zoom: 6.5,
),
markers: Set<Marker>.of(markers.values),
),
Center(
child: Container(
width: MediaQuery.of(context).size.width * (_ratio),
height: MediaQuery.of(context).size.width * (_ratio),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.5),
shape: BoxShape.circle,
),
),
),
],
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Slider(
min: 1,
max: screenWidthKms / 2,
divisions: 10,
value: _value,
label: _label,
activeColor: Colors.blue,
inactiveColor: Colors.blue.withOpacity(0.2),
onChanged: (double value) {
setState(() {
_value = value;
_label = '${_value.toInt().toString()} kms';
_ratio = _value / (screenWidthKms / 2);
markers.clear();
});
radius.add(value);
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox(
width: 100,
child: TextField(
controller: _latitudeController,
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: 'lat',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
),
SizedBox(
width: 100,
child: TextField(
controller: _longitudeController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'lng',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
)),
),
),
MaterialButton(
color: Colors.blue,
onPressed: () {
final lat =
double.parse(_latitudeController?.text ?? '0.0');
final lng =
double.parse(_longitudeController?.text ?? '0.0');
_addPoint(lat, lng);
},
child: const Text(
'ADD',
style: TextStyle(color: Colors.white),
),
),
],
),
],
),
),
);
}
void _onMapCreated(GoogleMapController controller) async {
setState(() {
_mapController = controller;
//start listening after map is created
stream.listen((List<DocumentSnapshot> documentList) {
_updateMarkers(documentList);
});
});
}
void _addPoint(double lat, double lng) {
GeoFirePoint geoFirePoint = geo.point(latitude: lat, longitude: lng);
print(geoFirePoint.hash);
print(geoFirePoint.geoPoint);
print(geoFirePoint.data);
print(geoFirePoint);
_firestore
.collection('shop')
.add({'name': 'random name', 'position': geoFirePoint.data}).then((_) {
print('added ${geoFirePoint.hash} successfully');
});
}
void _addMarker(double lat, double lng) {
final id = MarkerId(lat.toString() + lng.toString());
final _marker = Marker(
markerId: id,
position: LatLng(lat, lng),
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueViolet),
infoWindow: InfoWindow(title: 'latLng', snippet: '$lat,$lng'),
);
setState(() {
markers[id] = _marker;
});
}
void _updateMarkers(List<DocumentSnapshot> documentList) {
documentList.forEach((DocumentSnapshot document) {
final data = document.data() as Map<String, dynamic>;
final GeoPoint point = data['position']['geopoint'];
_addMarker(point.latitude, point.longitude);
});
}
}
총결산
Geofflutterfire에 대해 조금만 이해해 주시겠어요!맵과 Firebase를 사용할 때는 꼭 사용하세요!
Reference
이 문제에 관하여([Flutter] Geofflutterfire 범위 내 좌표의 신 포장에 대한 소개만 획득), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/wakanao/articles/65972fe4e0894b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)