如何使用Cloud Firestore在Flutter中存储地理位置数据

我从Cloud Firestore中的数据库查询地理位置数据时遇到问题。我浏览了Youtube上的文档后得出结论,当我将地理位置数据保存在子集合中时,它对我来说最有效。

这是我的数据库结构:

如何使用Cloud Firestore在Flutter中存储地理位置数据

如果您进入子集合中的文档之一:

如何使用Cloud Firestore在Flutter中存储地理位置数据

数据库本身有一个名为“ tourguides”的集合,每个文档都包含基本信息,例如游览名称和游览所在的区域(均为字符串)。然后,每个文档都有一个称为“位置”的子集合,其中每个文档都具有字符串“名称”和“ ID”,以及一个包含纬度和经度数据的地理位置。 ListView中显示了“ Tourguides”集合中的文档。每当我点击其中一个条目时,都会打开一个地图,其中显示了各个子集合中的所有标记。

这是我的ListView Builder:

@override
void initState() {
super.initState();
_pointsofinterest =    Firestore.instance.collection('tourguides').document('sydney_downtown_guide').col  lection('locations').orderBy('name').snapshots();
super.initState();
  }

  @override
 Widget build(BuildContext context) {
return Scaffold(
  body: StreamBuilder<Querysnapshot>(
    stream: _pointsofinterest,builder: (BuildContext context,Asyncsnapshot<Querysnapshot> snapshot) {
      if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
      switch (snapshot.connectionState) {
        case ConnectionState.waiting:
          return new Text('Loading...');
        default:
          return new ListView(
            children:
                snapshot.data.documents.map((Documentsnapshot document) {
              return InkWell(
                child: new ListTile(
                  title: new Text(document['name']),subtitle: new Text(document['region']),onTap: () {
                    return TourMap(
                      documents: snapshot.data.documents,initialPosition: const LatLng(-33.868210,151.208391),mapController: _mapController,);
                  },),);
            }).toList(),);
      }
    },);
 }

我将地图放入StatlessWidget(我不确定。也许必须是StatefulWidget?):

class TourMap extends StatelessWidget {
const TourMap({
Key key,@required this.documents,@required this.initialPosition,@required this.mapController,}) : super(key: key);

final List<Documentsnapshot> documents;
final LatLng initialPosition;
final Completer<GoogleMapController> mapController;

@override
Widget build(BuildContext context) {
 return GoogleMap(
  initialCameraPosition: CameraPosition(
    target: initialPosition,zoom: 12,markers: documents
      .map((document) => Marker(
            markerId: MarkerId(document['placeId']),icon: BitmapDescriptor.defaultMarker,position: LatLng(
              document['geolocation'].latitude,document['geolocation'].longitude,infoWindow: InfoWindow(
              title: document['location_name'],))
      .toSet(),onmapCreated: (mapController) {
    this.mapController.complete(mapController);
  },);
   }}

现在我不完全知道如何在我的OnTap函数中设置查询。 Firestore文档显示,如果我从数据库中删除这些集合,则必须始终引用特定的文档。

例如(集合/文档/集合)。但是在我的查询中,路径中间的“文档”始终是不同的,具体取决于用户单击哪个导游。

有什么想法吗?期待您的回复!

更新:我稍微配置了数据库结构!我现在使用两个独立的数据库。一个数据库保存有关可用导游的信息(当前只有两个字符串:Name和Region),另一个数据库存储实际的各个位置。 现在,我根据查询所属的向导的名称,使用where-query获取正确的位置。

查询本身现在可以在OnTap函数上运行:

 return new ListView(
            children:
                snapshot.data.documents.map((Documentsnapshot document) {
              return InkWell(
                child: new ListTile(
                  title: new Text(document['name']),onTap: () {
                    Firestore.instance.collection('locations').where(
                          "toactivity",isEqualTo: document['name'],)
                        .snapshots()
                        .listen((data) =>
                        data.documents.forEach((doc) => print(doc["location_name"])));
                  },);

数据库结构:

如何使用Cloud Firestore在Flutter中存储地理位置数据

如何使用Cloud Firestore在Flutter中存储地理位置数据

如果我点击ListView中的条目之一,则将正确的条目打印到控制台中。但是我需要弹出一个Google Map,以根据数据库中的“地理位置”值显示适当的标记。

linxierhebei 回答:如何使用Cloud Firestore在Flutter中存储地理位置数据

兄弟,我做到了。我可以通过两种方式检索它。 1.使用简单的“ initState”手动进行。 2.使用提供程序(但是使用第二种方法,我还没有成功显示标记)。希望可以帮助您,尽管很久以前。这是我通过使用'initState'来实现的:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
import 'package:visitmalang/provider/aktivitas_provider.dart';
import 'package:visitmalang/ui/home/beranda/aktivitas/profil_agen_wisata.dart';

import 'package:visitmalang/ui/widget/textcustom.dart';

class MapAktivitas extends StatefulWidget {
  @override
  _MapAktivitasState createState() => _MapAktivitasState();
}

class _MapAktivitasState extends State<MapAktivitas> {
  Map<MarkerId,Marker> markers = <MarkerId,Marker>{};

  GoogleMapController mapController;

  bool mapToggle = false;
  bool geraiToggle = false;

  var currentLocation;
  var clients = [];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Geolocator().getCurrentPosition().then((lokasiSekarang) {
      setState(() {
        currentLocation = lokasiSekarang;
        mapToggle = true;
        populateClients();
      });
    });
  }

  populateClients() {
    clients = [];
    Firestore.instance.collection('trail').getDocuments().then((docs) {
      if (docs.documents.isNotEmpty) {
        setState(() {
          geraiToggle = true;
        });

        for (int i = 0; i < docs.documents.length; i++) {
          clients.add(docs.documents[i].data);
          initMarker(docs.documents[i].data,docs.documents[i].documentID);
        }
      }
    });
  }

  void initMarker(request,requestId) {
    var markerIdVal = requestId;
    final MarkerId markerId = MarkerId(markerIdVal);
    final Marker marker = Marker(
        markerId: markerId,position: LatLng(
            request['koordinat'].latitude,request['koordinat'].longitude),infoWindow: InfoWindow(title: request['nama']));
    setState(() {
      markers[markerId] = marker;
    });
  }

  Widget clientCard(client) {
    return Padding(
      padding: const EdgeInsets.only(left: 8.0,top: 8.0),child: InkWell(
          onTap: () {
            zoomInMarker(client);
          },child: Stack(
            alignment: FractionalOffset(0.5,0.94),children: <Widget>[
              Material(
                elevation: 4.0,borderRadius: BorderRadius.circular(10.0),child: Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10.0),color: Colors.white,),height: 108,width: 200,child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[
//
                      ClipRRect(
                        borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(10.0),bottomLeft: Radius.circular(10.0)),child: Container(
                          width: 96,child: Image.asset(
                            'assets/trail.png',fit: BoxFit.cover,SizedBox(
                        width: 4,Stack(
                        alignment: FractionalOffset(0.5,0.9),children: <Widget>[
                          Container(
                            width: 100,child: Padding(
                              padding: const EdgeInsets.only(top: 8.0),child: Column(
                                children: <Widget>[
                                  Padding(
                                    padding: const EdgeInsets.symmetric(
                                        horizontal: 8.0),child: Container(
                                      alignment: Alignment.center,child: textCustom(client['nama'],Colors.black87,14,'Montserrat'),],ClipRRect(
                            borderRadius: BorderRadius.circular(10),child: InkWell(
                              onTap: () => Navigator.of(context).push(
                                  CupertinoPageRoute(
                                      builder: (BuildContext context) =>
                                          ProfilAgenWisata(
                                            nama: client['nama'],deskripsi: client['deskripsi'],website: client['website'],email: client['email'],noTelepon: client['noTelepon'],whatsApp: client['whatsApp'],alamat: client['alamat'],fasilitas: client['fasilitas'],))),child: Container(
                                alignment: Alignment.center,color: Color(0xFFDB5C48),height: 40,width: 88,child: textCustom(
                                    'Detail',Colors.white,)
                        ],)),);
  }

  zoomInMarker(client) {
    mapController.animateCamera(
      CameraUpdate.newCameraPosition(
        CameraPosition(
            target: LatLng(
                client['koordinat'].latitude,client['koordinat'].longitude),zoom: 16.0,bearing: 19.0,tilt: 15.0),);
  }

  @override
  Widget build(BuildContext context) {
//    AktivitasNotifier aktivitasNotifier = Provider.of<AktivitasNotifier>(context);
    return Scaffold(
        appBar: AppBar(
          title: textCustom('Ngetrail',18,centerTitle: true,elevation: 0.0,backgroundColor: Colors.transparent.withOpacity(0.0),leading: IconButton(
              icon: Icon(Icons.arrow_back_ios,color: Colors.black87),onPressed: (){Navigator.pop(context);},body: Stack(
          children: <Widget>[
            Column(
              children: <Widget>[
                Container(
                  width: double.infinity,height: MediaQuery.of(context).size.height - 80,child: mapToggle
                      ? GoogleMap(
                          myLocationEnabled: true,myLocationButtonEnabled: true,markers: Set<Marker>.of(markers.values),compassEnabled: false,zoomControlsEnabled: false,mapType: MapType.normal,initialCameraPosition: CameraPosition(
                              target: LatLng(currentLocation.latitude,currentLocation.longitude),zoom: 15),onMapCreated: (controller) {
                            setState(() {
                              mapController = controller;
                            });
                          },)
                      : Center(
                          child: textCustom(
                              'Loading...',20,'Hind')),Column(
              mainAxisAlignment: MainAxisAlignment.end,children: <Widget>[
                Container(
                  height: 140.0,width: MediaQuery.of(context).size.width,child: geraiToggle
                      ? ListView(
                          scrollDirection: Axis.horizontal,padding: EdgeInsets.all(8.0),children: clients.map((element) {
                            return clientCard(element);
                          }).toList(),)
                      : Container(),SizedBox(
                  height: 56.0,)
              ],)
          ],));
  }
}
,

这是使用提供程序的第二种方法。

首先,您必须确定模型(只关注“ koordinat”):

    class ModelAktivitas {
  String idAktivitas;
  var koordinat;
  String nama;
  String deskripsi;
  String alamat;
  String email;
  String noTelepon;
  String website;
  String gambarUtama;
  List galeri;
  List fasilitas;

  ModelAktivitas.fromMap(Map<String,dynamic> data) {
    idAktivitas = data['idAktivitas'];
    koordinat = data['koordinat'];
    nama = data['nama'];
    deskripsi = data['deskripsi'];
    noTelepon = data['nomorTelepon'];
    galeri = data['galeri'];
    fasilitas = data['fasilitas'];
    alamat = data['alamat'];
    email = data['alamat'];
    gambarUtama = data['gambarUtama'];
    website = data['website'];
  }
}

秒,为其提供提供商:

import 'dart:collection';
import 'package:flutter/cupertino.dart';
import 'package:visitmalang/models/aktivitas_model.dart';

class AktivitasNotifier with ChangeNotifier {
  List<ModelAktivitas> _listAktivitas = [];
  ModelAktivitas _detailAktivitas;

  UnmodifiableListView<ModelAktivitas> get listAktivitas =>
      UnmodifiableListView(_listAktivitas);

  ModelAktivitas get detailAktivitas => _detailAktivitas;

  set listAktivitas(List<ModelAktivitas> listAktivitas) {
    _listAktivitas = listAktivitas;
    notifyListeners();
  }

  set detailAktivitas(ModelAktivitas aktivitas) {
    _detailAktivitas = aktivitas;
    notifyListeners();
  }
}

然后,从您的Firestore服务中添加“获取”:

getListAktivitas(AktivitasNotifier aktivitasNotifier) async {
  QuerySnapshot snapshot =
  await Firestore.instance.collection('trail').getDocuments();

  List<ModelAktivitas> _listAktivitas = [];
  snapshot.documents.forEach((doc) {
    ModelAktivitas modelAktivitas = ModelAktivitas.fromMap(doc.data);
    _listAktivitas.add(modelAktivitas);
  });
  aktivitasNotifier.listAktivitas = _listAktivitas;

}

然后,最后一步将其流式传输到您的UI代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
import 'package:visitmalang/provider/aktivitas_provider.dart';
import 'package:visitmalang/ui/home/beranda/aktivitas/profil_agen_wisata.dart';
import 'package:visitmalang/ui/widget/textcustom.dart';
import 'package:visitmalang/service/user_service.dart';

class MapAktivitasTandingan extends StatefulWidget {
  @override
  _MapAktivitasTandinganState createState() => _MapAktivitasTandinganState();
}

class _MapAktivitasTandinganState extends State<MapAktivitasTandingan> {
  Map<MarkerId,Marker>{};
  GoogleMapController mapController;
  bool mapToggle = false;
  bool geraiToggle = false;
  var currentLocation;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Geolocator().getCurrentPosition().then((lokasiSekarang) {
      setState(() {
        currentLocation = lokasiSekarang;
        mapToggle = true;
      });
    });

    AktivitasNotifier aktivitasNotifier =
        Provider.of<AktivitasNotifier>(context,listen: false);
    getListAktivitas(aktivitasNotifier);
  }

  @override
  Widget build(BuildContext context) {
    AktivitasNotifier aktivitasNotifier =
        Provider.of<AktivitasNotifier>(context);
    return Scaffold(
        appBar: AppBar(
          title: textCustom('Ngetrail',leading: IconButton(
            icon: Icon(Icons.arrow_back_ios,onPressed: () {
              Navigator.pop(context);
            },markers: {

                          },children: <Widget>[
                Container(
                    height: 140.0,child: ListView.builder(
                      scrollDirection: Axis.horizontal,itemCount: aktivitasNotifier.listAktivitas.length,itemBuilder: (BuildContext context,int index) {
                        return Padding(
                          padding: const EdgeInsets.only(left: 8.0,child: InkWell(
                              onTap: () {
                                mapController.animateCamera(
                                  CameraUpdate.newCameraPosition(
                                    CameraPosition(
                                        target: LatLng(
                                            aktivitasNotifier
                                                .listAktivitas[index]
                                                .koordinat
                                                .latitude,aktivitasNotifier
                                                .listAktivitas[index]
                                                .koordinat
                                                .longitude),);
                              },child: Stack(
                                alignment: FractionalOffset(0.5,children: <Widget>[
                                  Material(
                                    elevation: 4.0,child: Container(
                                      decoration: BoxDecoration(
                                        borderRadius:
                                            BorderRadius.circular(10.0),child: Row(
                                        crossAxisAlignment:
                                            CrossAxisAlignment.center,children: <Widget>[
//
                                          ClipRRect(
                                            borderRadius: BorderRadius.only(
                                                topLeft: Radius.circular(10.0),bottomLeft:
                                                    Radius.circular(10.0)),child: Container(
                                              width: 96,child: Image.asset(
                                                'assets/trail.png',SizedBox(
                                            width: 4,Stack(
                                            alignment:
                                                FractionalOffset(0.5,children: <Widget>[
                                              Container(
                                                width: 100,child: Padding(
                                                  padding:
                                                      const EdgeInsets.only(
                                                          top: 8.0),child: Column(
                                                    children: <Widget>[
                                                      Padding(
                                                        padding:
                                                            const EdgeInsets
                                                                    .symmetric(
                                                                horizontal:
                                                                    8.0),child: Container(
                                                          alignment:
                                                              Alignment.center,child: textCustom(
                                                              aktivitasNotifier
                                                                  .listAktivitas[
                                                                      index]
                                                                  .nama,ClipRRect(
                                                borderRadius:
                                                    BorderRadius.circular(10),child: InkWell(
                                                  onTap: () => Navigator.of(
                                                          context)
                                                      .push(CupertinoPageRoute(
                                                          builder: (BuildContext
                                                                  context) =>
                                                              ProfilAgenWisata(
                                                                nama: aktivitasNotifier
                                                                    .listAktivitas[
                                                                        index]
                                                                    .nama,website: aktivitasNotifier
                                                                    .listAktivitas[
                                                                        index]
                                                                    .website,noTelepon: aktivitasNotifier
                                                                    .listAktivitas[
                                                                        index]
                                                                    .noTelepon,email: aktivitasNotifier
                                                                    .listAktivitas[
                                                                        index]
                                                                    .email,alamat: aktivitasNotifier
                                                                    .listAktivitas[
                                                                        index]
                                                                    .alamat,deskripsi: aktivitasNotifier
                                                                    .listAktivitas[
                                                                        index]
                                                                    .deskripsi,child: Container(
                                                    alignment: Alignment.center,child: textCustom(
                                                        'Detail',)
                                            ],);
                      },));
  }
}
本文链接:https://www.f2er.com/3161171.html

大家都在问