Search for locations in arrays of geopoints Firestore - flutter

I'm able to find locations within firestore documents if those have the next structure:
But how to perform the same searching, if the JSON has a couple of geopoints? Like this:
I'm using geoflutterfire with cloud_firestore.
The code to save locations to the database:
final geo = Geoflutterfire();
final startPoint = geo.point(
latitude: 49.805378,
longitude: 23.982382,
);
final finishPoint = geo.point(
latitude: 49.79987621408566,
longitude: 24.035205183081246,
);
FirebaseFirestore.instance.collection('Drivers').doc('12345').set({
'location': [startPoint.data, finishPoint.data]
});
This code is for getting filtered locations:
final drivers = FirebaseFirestore.instance.collection('Drivers');
final geo = Geoflutterfire();
final center = geo.point(
latitude: 49.79987621408566,
longitude: 24.035205183081246,
);
final Stream<List<DocumentSnapshot>> stream =
geo.collection(collectionRef: drivers).within(
center: center,
radius: 4,
field: 'location',
strictMode: true,
);
stream.listen((List<DocumentSnapshot> documentList) {
// Always empty if there are arrays of locations.
print(documentList);
});

Related

Why do I have duplicates in Geoflutterfire `within`query?

I query my database for items within a distance from the user's position as follows:
/// Get a stream of nearby ads.
static Stream<List<DocumentSnapshot<Map<String, dynamic>>>> getNearbyStream(
{required Position center, required double radius}) {
final geo = Geoflutterfire();
final collectionReference =
FirebaseFirestore.instance.collection(collectionName);
final gfpCenter = GeoFirePoint(center.latitude, center.longitude);
return geo
.collection(collectionRef: collectionReference)
.within(
center: gfpCenter,
radius: radius,
field: 'position',
strictMode: true);
}
To my surprise, the results shows duplicates: each result is shown twice.
How it comes?

How to remove an element from a http call? Flutter/Dart

hello I am doing a http request and I want to remove the elements which have some specific value, for example if 'region' is 'USA' I don't want to receive it.
here is my call:
Future fetch() async {
if (isLoading) return;
isLoading = true;
const limit = 10;
final url = Uri.parse('https://everywhere-dev.iccs.gr:18083/evse/getEvsesPaged?page=$page&pageLimit=$limit&lat=' +
(this.widget.appController.currentLocation != null ? this.widget.appController.currentLocation!.latitude : this.widget.appController.originalMapPoint.latitude).toString() + '&lon=' +
(this.widget.appController.currentLocation != null ? this.widget.appController.currentLocation!.longitude : this.widget.appController.originalMapPoint.longitude).toString());
final response = await http.get(url);
if (response.statusCode == 200) {
final List newItems = json.decode(response.body)["results"];
setState(() {
page++;
isLoading = false;
if (newItems.length <limit) {
hasMore = false;
}
tempEvses.addAll(newItems.map<Evse>((items) {
final evseID = items['evseID'];
final friendlyName = items['friendlyName'];
final street = items['street'];
final streetNumber = items['streetNumber'];
final region = items['region'];
final lat = items['lat'] ?? 0.0;
final lng = items['lng'] ?? 0.0;
final connectorList = items['connectorList'];
final cpSerial = items['cpSerial'];
final img = items['img'];
return new Evse(evseID: evseID, friendlyName: friendlyName, street: street, streetNumber: streetNumber, region: region, lat: lat, lng: lng, connectorList: [connectorList], cpSerial: cpSerial, img: img);
}).toList());
for(int i=0 ; i<tempEvses.length; i++ ){
this.tempEvses[i].calculateDistance(widget.appController.currentLocation);
// this.tempEvses[i].calculateAvailability();
this.tempEvses[i].isEvseFavorite(widget.appController.favoritesList);
this.tempEvses[i].storePlugCounters();
}
showEvsePanels();
});
}
}
If you don't want to receive certain values you must work on the API and not on the app.
Maybe you couldn't work on the API so the only way is to work on the data that your app received.
You should try newItems.removeWhere((item) => item['region'] == 'USA')
Change you map to this:
tempEvses.addAll(
newItems.map<Evse>(
(items) {
final evseID = items['evseID'];
final friendlyName = items['friendlyName'];
final street = items['street'];
final streetNumber = items['streetNumber'];
final region = items['region'];
final lat = items['lat'] ?? 0.0;
final lng = items['lng'] ?? 0.0;
final connectorList = items['connectorList'];
final cpSerial = items['cpSerial'];
final img = items['img'];
if (region != 'USA') {
return new Evse(
evseID: evseID,
friendlyName: friendlyName,
street: street,
streetNumber: streetNumber,
region: region,
lat: lat,
lng: lng,
connectorList: [connectorList],
cpSerial: cpSerial,
img: img);
}
},
).toList(),
);

flutter map problem : final Completer<Null> _readyCompleter = Completer<Null>();

I am trying to build an app using flutter map plugin. But I got this error -
Before this error I added this line -
Stream<List<DocumentSnapshot>> getDataCollectionByLocation({
required GeoFirePoint center,
required double radius,
required String field,
}) {
Stream<List<DocumentSnapshot>> stream = _geo
.collection(collectionRef: ref)
.within(center: center, radius: radius, field: field);
return stream;
}

How to place markers dynamically from API to google map in flutter?

class LiveVehicleTrackingModel {
double lat;
double lng;
int speed;
double refDist;
String refLoc;
String accStatus;
String recDateTime;
String driver;
double temperature;
String imoblize;
LiveVehicleTrackingModel(
{this.lat,
this.lng,
this.speed,
this.refDist,
this.refLoc,
this.accStatus,
this.recDateTime,
this.driver,
this.temperature,
this.imoblize});
LiveVehicleTrackingModel.fromJson(Map<String, dynamic> json) {
lat = json['lat'];
lng = json['lng'];
speed = json['speed'];
refDist = json['refDist'];
refLoc = json['refLoc'];
accStatus = json['accStatus'];
recDateTime = json['recDateTime'];
driver = json['driver'];
temperature = json['temperature'];
imoblize = json['Imoblize'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['lat'] = lat;
data['lng'] = lng;
data['speed'] = speed;
data['refDist'] = refDist;
data['refLoc'] = refLoc;
data['accStatus'] = accStatus;
data['recDateTime'] = recDateTime;
data['driver'] = driver;
data['temperature'] = temperature;
data['Imoblize'] = imoblize;
return data;
}
}
// This is where i am getting location from the Api.
Future<List<LiveVehicleTrackingModel>> getLocations() async {
try {
var url = ApiConstants.liveTrackingApi;
final resp = await http.post(Uri.parse(url));
final responsebody = jsonDecode(resp.body);
return responsebody;
} catch (e) {
return [];
}
}
// This is the first question where i am loading locations with the help of model class.
// List locations = [];
LatLng latlng;
loadLocations() async {
List<LiveVehicleTrackingModel> locations;
locations = [];
locations = await getLocations(); //we store the response in a list
for (var i = 0; i < locations.length; i++) {
// LatLng latlng;
latlng = LatLng(
(locations[i].lat),
(locations[i].lng),
);
allMarkers.add(
Marker(
markerId: MarkerId(locations[i].accStatus.toString()),
position: latlng,
),
);
}
// setState(() {
//
// });
}
I have attached my model class and also the two functions through which i am fetching data from api. But the i am not able to place markers on map. Map just shows blank. Kindly help me out

how to format snapshots from firebase to list or set markers for map

How can I store firebase data so that I can use it for markers on a googlemap?
late CollectionReference vendorLocCollection =
FirebaseFirestore.instance.collection('vendorlocations');
late List vendors = [];
Future <void> populateVendors() async {
Map<dynamic, dynamic> marker = <MarkerId, Marker> {}; //from dynamic in snapshot to marker
final _vendorSnapshots = await vendorLocCollection.snapshots();
_vendorSnapshots.listen((result) {
result.docs.forEach((result) { //how do i extract the result so i can use
// it as marker? :
vendors.add(result.data());
print(vendors);
});
});
}
Parsing firebase snapshot results and putting markers on Google Maps are two different things.
Step 1: Serialise the data
Since we get the data in JSON format, we first change it to dart data types.
We can use something like this.
class VendorLocations {
String uid;
double latitude;
double longitude;
VendorLocations(this.uid, this.latitude, this.longitude);
}
...
vendors = (result.data() as List)
.map((e) {
return VendorLocations(e['uid'], e['latitude'], e['longitude']);
})
.toList();
Step 2: Put marker on Google Map
Create marker objects from the vendors list.
final markerId = vendors[0].uid; /// or something else
final Marker m = Marker(
markerId: markerId,
position: LatLng(
vendors[0].latitude,
vendors[0].longitude,
),
/// specify other parameters as needed
);
marker[markerId] = m;
// update UI
This creates a new marker. All the markers can be added by running the above code snippet in a loop.
Reference : google_maps_flutter