Как показать сообщение только в пределах одной мили в Flutter

#flutter #dart #location

Вопрос:

Я пытаюсь создать функциональность, которая может отображать близлежащие сообщения пользователя.

Из моего кода сначала я считываю данные из 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;
});
 

В строке времени информация для записей сохраняется таким образом, чтобы,

введите описание изображения здесь

Как только я получу информацию о публикации, я также определяю местоположение пользователя с помощью геолокатора.

   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
  }
 

Итак, я хочу, чтобы из первого кода, когда я делаю postsLocal, я хотел импортировать сообщение только в пределах 1 мили. Можете ли вы помочь мне с тем, как сделать снимки условного отображения?

Ответ №1:

Существует несколько способов сделать то же самое, в зависимости от требований:

  1. Получите текущую широту и долготу
  2. Создайте api, который возвращает список постов назначения вместе с их посттимуляцией и посттимуляцией в нем.
  3. найдите разницу между ними, используя приведенный ниже фрагмент кода.
     double distanceInMeters = Geolocator.distanceBetween(
        currentLatitudeTxt,
        currentLongitudeTxt,
        double.parse(posttimeLatitude),
        double.parse(posttimeLatitude),
      );      
     
  4. Преобразуйте расстояние в метрах в милю и используйте виджет listview.

Для справки рассмотрим фрагмент кода ниже:

   _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 amp;amp; 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