I'm building a Flutter App where the user can post a photo and it's location. The use can both get a picture from the camera or from the library.
If the user take a picture from camera I can use the GPS location of the device to set the picture's location. I'm trying to get the GSP location of the pictures based on its metadata, but, I didn't found a way to do it yet.
Is possible to do it? How the best way?
Edit: I put "GPS" in the question to make it clear. I'm trying to discover the physical position where the picture was taken. I also added "Flutter" to the question to make it clear that I'm facing the problem of solving this problem in a Flutter App.
I discovered that my previous problem was related to the Camera permissions of the devices. Usually a camera from android access the user location and save the GPS coordinates as Exif tag, but the ios devices usually don't save this by default unless the user allows location permissions to the camera app.
I changed my app to check if the image has GPS coordinates and the user decides if he wants to share his actual location or the image location.
I'm also having to do some math to process the coordinates:
In order to you use the code you have to add the package exif and geoflutterfire to your app.
void _checkGPSData() async {
Map<String, IfdTag> imgTags = await readExifFromBytes( File(image.path).readAsBytesSync() );
if (imgTags.containsKey('GPS GPSLongitude')) {
setState(() {
_imgHasLocation = true;
_imgLocation = exifGPSToGeoFirePoint(imgTags);
});
}
}
GeoFirePoint exifGPSToGeoFirePoint(Map<String, IfdTag> tags) {
final latitudeValue = tags['GPS GPSLatitude'].values.map<double>( (item) => (item.numerator.toDouble() / item.denominator.toDouble()) ).toList();
final latitudeSignal = tags['GPS GPSLatitudeRef'].printable;
final longitudeValue = tags['GPS GPSLongitude'].values.map<double>( (item) => (item.numerator.toDouble() / item.denominator.toDouble()) ).toList();
final longitudeSignal = tags['GPS GPSLongitudeRef'].printable;
double latitude = latitudeValue[0]
+ (latitudeValue[1] / 60)
+ (latitudeValue[2] / 3600);
double longitude = longitudeValue[0]
+ (longitudeValue[1] / 60)
+ (longitudeValue[2] / 3600);
if (latitudeSignal == 'S') latitude = -latitude;
if (longitudeSignal == 'W') longitude = -longitude;
return GeoFirePoint(latitude, longitude);
}
The geolocation metadata is stored as Exif tags provided the image is a JPEG or a RAW image file. In Android this is done through the ExifInterface
class.
The tags are TAG_GPS_LATITUDE
and TAG_GPS_LONGITUDE
:
https://developer.android.com/reference/android/media/ExifInterface.html
Please note the coordinates need to be expressed in the rational format: degrees, minutes and seconds, as dd/1,mm/1,ss/1
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With