如何在 Flutter 中仅显示一英里内的帖子

Posted

技术标签:

【中文标题】如何在 Flutter 中仅显示一英里内的帖子【英文标题】:How to only show post within one mile in Flutter 【发布时间】:2021-06-18 22:35:59 【问题描述】:

我正在尝试制作一个可以显示用户附近帖子的功能。

从我的代码中,首先我从 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中,帖子的信息被保存,

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

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

有了用户位置(posXuser,posYuser)和发布位置(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
  

所以我想要的是从第一个代码开始,当我在本地发布帖子时,我只想导入 1 英里外的帖子。你能帮我制作一个条件映射快照吗?

【问题讨论】:

【参考方案1】:

根据要求有多种方法:

    获取当前的纬度和经度

    创建一个返回目标 Postlist 及其 PostTimelatitude 和 PostTimelatitude 的 api。

    使用下面的代码 sn-p 找出它们之间的区别。

    double distanceInMeters = Geolocator.distanceBetween(
        currentLatitudeTxt,
        currentLongitudeTxt,
        double.parse(posttimeLatitude),
        double.parse(posttimeLatitude),
      );      
    

    将距离以米为单位转换为英里并使用列表视图小部件。

请考虑以下代码 sn-p 供您参考:

  _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");

【讨论】:

【参考方案2】:

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

Cloud Firestore 仅允许每个复合查询使用单个范围子句,这意味着我们无法通过简单地将纬度和经度存储为单独的字段并查询边界框来执行地理查询。

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

【讨论】:

以上是关于如何在 Flutter 中仅显示一英里内的帖子的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中仅突出显示 Text 中的数字和特殊字符?

Flutter:如何在 DatePicker 中仅启用特定日期的日期

如何返回邮政编码列表的## 英里半径内的所有实例

计算半径内的 100 英里

如何在特定半径内的地图上显示点

排除父帖子并在存档中仅显示子帖子