如何在 Flutter 中仅在一英里内显示 post

How to only show post within one mile in Flutter

我正在尝试开发一项功能,可以显示附近的 post 用户。

根据我的代码,首先我从 firebase (timelineLocalRef) 读取数据,这样

getTimelineLocal() async {
QuerySnapshot snapshotLocal = await timelineLocalRef
    .doc('test')
    .collection('userPosts')
    .orderBy('timestamp', descending: true)
    .get();

List<PostL> postsLocal =
    snapshotLocal.docs.map((doc) => PostL.fromDocument(doc)).toList();
setState(() {
  this.postsLocal = postsLocal;
});

在 timelineRef 中,post 的信息被保存为

获得 post 信息后,我还将使用地理定位器获取用户位置。

  getUserLocation() async {
    Position position = await Geolocator()
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    posXuser = position.latitude;
    posYuser = position.longitude;
  }

有了用户位置 (posXuser, posYuser) 和 posting 位置 (posX,posY),我应该能够使用下面的函数计算两者之间的距离。

  double calculateDistance(lat1, lon1, lat2, lon2) {
    var p = 0.017453292519943295;
    var c = cos;
    var a = 0.5 -
        c((lat2 - lat1) * p) / 2 +
        c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p)) / 2;
    return 0.621371 * 12742 * asin(sqrt(a));
    //return mile distance
  }

所以我想要的是第一个代码,当我制作 postsLocal 时,我只想导入 1 英里外的 post。你能帮我做一个条件映射快照吗?

您需要在查询服务器端进行操作。 Firebase 对此类查询的支持有限:

Cloud Firestore only allows a single range clause per compound query, which means we can't perform geo queries by simply storing latitude and longitude as separate fields and querying a bounding box.

https://firebase.google.com/docs/firestore/solutions/geoqueries

根据要求,有多种方法可以做到这一点:

  1. 获取当前纬度和经度

  2. 创建一个 api returns 目标 Postlist 以及其中的 PostTimelatitude 和 PostTimelatitude。

  3. 使用下面的代码片段找出它们之间的区别。

    double distanceInMeters = Geolocator.distanceBetween(
        currentLatitudeTxt,
        currentLongitudeTxt,
        double.parse(posttimeLatitude),
        double.parse(posttimeLatitude),
      );      
    
  4. 将以米为单位的距离转换为英里并使用列表视图小部件。

供您参考,请考虑以下代码片段:

  _handleAllRestaurantListResponse(value) {
var arrData = value
    .map<RestaurantModel>((json) => RestaurantModel.fromJson(json))
    .toList();
arrayRestaurantList = arrData;
print("ALL RESTAURANT LENGTH : ${arrayRestaurantList.length}");

if (arrayRestaurantList.isNotEmpty) {
  for (var item in arrayRestaurantList) {
    var responseLatitude = item.latitude;
    var responseLongitude = item.longitude;
    print(responseLatitude);
    print(responseLongitude);
    if (responseLatitude != null && responseLongitude != null) {
      double distanceInMeters = Geolocator.distanceBetween(
        currentLatitudeTxt,
        currentLongitudeTxt,
        double.parse(responseLatitude),
        double.parse(responseLongitude),
      );
      double distanceInKm = distanceInMeters / 1000;
      int roundedDistanceInKM = distanceInKm.toInt();
      if (nearByRestaurantRadius > roundedDistanceInKM) {
        filterRestaurantList.add(item);
      }
    }
  }
} else {
  print("object");
}

}