protectedWithinWithDistance method
Stream<List<DistanceDocSnapshot<Map<String, dynamic> > > >
protectedWithinWithDistance({
- required GeoFirePoint center,
- required double radius,
- required String field,
- required int limit,
- required GeoPoint? geopointFrom(),
- required bool? strictMode,
inherited
query firestore documents based on geographic radius
from geoFirePoint center
field
specifies the name of the key in the document
Implementation
@protected
Stream<List<DistanceDocSnapshot<T>>> protectedWithinWithDistance({
required GeoFirePoint center,
required double radius,
required String field,
required int limit, // Added By Uraam
required GeoPoint? Function(T t) geopointFrom,
required bool? strictMode,
}) {
final nonNullStrictMode = strictMode ?? false;
final precision = MathUtils.setPrecision(radius);
final centerHash = center.hash.substring(0, precision);
final area = GeoFirePoint.neighborsOf(hash: centerHash)..add(centerHash);
final queries = area.map((hash) {
final tempQuery = _queryPoint(hash, field);
return _createStream(tempQuery).map((querySnapshot) {
return querySnapshot.docs;
});
});
final mergedObservable = mergeObservable(queries);
final filtered = mergedObservable.map((list) {
final mappedList = list.map((documentSnapshot) {
final snapData =
documentSnapshot.exists ? documentSnapshot.data() : null;
assert(snapData != null, 'Data in one of the docs is empty');
if (snapData == null) return null;
// We will handle it to fail gracefully
final geoPoint = geopointFrom(snapData);
assert(geoPoint != null, 'Couldnt find geopoint from stored data');
if (geoPoint == null) return null;
// We will handle it to fail gracefully
final kmDistance = center.kmDistance(
lat: geoPoint.latitude,
lng: geoPoint.longitude,
);
return DistanceDocSnapshot(
documentSnapshot: documentSnapshot,
kmDistance: kmDistance,
);
});
final nullableFilteredList = nonNullStrictMode
? mappedList
.where((doc) =>
doc != null &&
doc.kmDistance <=
radius * 1.02 // buffer for edge distances;
)
.toList()
: mappedList.toList();
final filteredList = nullableFilteredList.whereNotNull().toList();
filteredList.sort(
(a, b) => (a.kmDistance * 1000).toInt() - (b.kmDistance * 1000).toInt(),
);
return filteredList;
});
return filtered.asBroadcastStream();
}