mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-02 06:46:22 +01:00
Show MapView if GPS data exists in exif
This commit is contained in:
parent
4a8784f508
commit
d7269a1cba
6 changed files with 119 additions and 0 deletions
|
@ -46,5 +46,9 @@
|
|||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_KEY"
|
||||
android:value="" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -89,6 +89,12 @@ class Exif {
|
|||
/// 0x920a FocalLength
|
||||
Rational get focalLength => data["FocalLength"];
|
||||
|
||||
/// 0x8825 GPS tags
|
||||
String get gpsLatitudeRef => data["GPSLatitudeRef"];
|
||||
List<Rational> get gpsLatitude => data["GPSLatitude"].cast<Rational>();
|
||||
String get gpsLongitudeRef => data["GPSLongitudeRef"];
|
||||
List<Rational> get gpsLongitude => data["GPSLongitude"].cast<Rational>();
|
||||
|
||||
static final dateTimeFormat = DateFormat("yyyy:MM:dd HH:mm:ss");
|
||||
|
||||
final Map<String, dynamic> data;
|
||||
|
|
3
lib/platform/features.dart
Normal file
3
lib/platform/features.dart
Normal file
|
@ -0,0 +1,3 @@
|
|||
import 'dart:io';
|
||||
|
||||
final isSupportMapView = Platform.isAndroid;
|
|
@ -1,9 +1,12 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:android_intent/android_intent.dart';
|
||||
import 'package:exifdart/exifdart.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
|
@ -13,6 +16,7 @@ import 'package:nc_photos/entity/exif.dart';
|
|||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/platform/features.dart' as features;
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
import 'package:nc_photos/use_case/remove.dart';
|
||||
|
@ -135,6 +139,36 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
|||
title: Text(_model),
|
||||
subtitle: cameraSubStr.isNotEmpty ? Text(cameraSubStr) : null,
|
||||
),
|
||||
if (features.isSupportMapView && _gps != null)
|
||||
SizedBox(
|
||||
height: 256,
|
||||
child: GoogleMap(
|
||||
compassEnabled: false,
|
||||
mapToolbarEnabled: false,
|
||||
rotateGesturesEnabled: false,
|
||||
scrollGesturesEnabled: false,
|
||||
zoomControlsEnabled: false,
|
||||
zoomGesturesEnabled: false,
|
||||
tiltGesturesEnabled: false,
|
||||
myLocationButtonEnabled: false,
|
||||
buildingsEnabled: false,
|
||||
// liteModeEnabled: true,
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: _gps,
|
||||
zoom: 16,
|
||||
),
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: MarkerId("at"),
|
||||
position: _gps,
|
||||
// for some reason, GoogleMap's onTap is not triggered if
|
||||
// tapped on top of the marker
|
||||
onTap: _onMapTap,
|
||||
),
|
||||
},
|
||||
onTap: (_) => _onMapTap(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -207,6 +241,16 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
|||
}
|
||||
}
|
||||
|
||||
void _onMapTap() {
|
||||
if (Platform.isAndroid) {
|
||||
final intent = AndroidIntent(
|
||||
action: "action_view",
|
||||
data: Uri.encodeFull("geo:${_gps.latitude},${_gps.longitude}?z=16"),
|
||||
);
|
||||
intent.launch();
|
||||
}
|
||||
}
|
||||
|
||||
void _updateMetadata(int imageWidth, int imageHeight, Exif exif) {
|
||||
if (imageWidth != null && imageHeight != null) {
|
||||
setState(() {
|
||||
|
@ -255,6 +299,30 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
|||
_isoSpeedRatings = exif.isoSpeedRatings;
|
||||
});
|
||||
}
|
||||
if (exif.gpsLatitudeRef != null &&
|
||||
exif.gpsLatitude != null &&
|
||||
exif.gpsLongitudeRef != null &&
|
||||
exif.gpsLongitude != null) {
|
||||
final lat = _gpsDmsToDouble(exif.gpsLatitude) *
|
||||
(exif.gpsLatitudeRef == "S" ? -1 : 1);
|
||||
final lng = _gpsDmsToDouble(exif.gpsLongitude) *
|
||||
(exif.gpsLongitudeRef == "W" ? -1 : 1);
|
||||
_log.fine("GPS: ($lat, $lng)");
|
||||
setState(() {
|
||||
_gps = LatLng(lat, lng);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static double _gpsDmsToDouble(List<Rational> dms) {
|
||||
double product = dms[0].toDouble();
|
||||
if (dms.length > 1) {
|
||||
product += dms[1].toDouble() / 60;
|
||||
}
|
||||
if (dms.length > 2) {
|
||||
product += dms[2].toDouble() / 3600;
|
||||
}
|
||||
return product;
|
||||
}
|
||||
|
||||
Future<void> _addToAlbum(BuildContext context, Album album) async {
|
||||
|
@ -287,6 +355,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
|||
String _exposureTime;
|
||||
double _focalLength;
|
||||
int _isoSpeedRatings;
|
||||
LatLng _gps;
|
||||
|
||||
static final _log =
|
||||
Logger("widget.viewer_detail_pane._ViewerDetailPaneState");
|
||||
|
|
35
pubspec.lock
35
pubspec.lock
|
@ -1,6 +1,13 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
android_intent:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: android_intent
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -153,6 +160,13 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flutter_staggered_grid_view:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -165,6 +179,20 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
google_maps_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_maps_flutter
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
google_maps_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
hashcodes:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -459,6 +487,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -26,6 +26,7 @@ dependencies:
|
|||
flutter_localizations:
|
||||
sdk: flutter
|
||||
|
||||
android_intent: ^2.0.0
|
||||
bloc: ^7.0.0
|
||||
cached_network_image: ^3.0.0
|
||||
connectivity: ^3.0.2
|
||||
|
@ -38,6 +39,7 @@ dependencies:
|
|||
ref: 1.0.0
|
||||
flutter_bloc: ^7.0.0
|
||||
flutter_staggered_grid_view: ^0.3.3
|
||||
google_maps_flutter: ^2.0.3
|
||||
http: ^0.13.1
|
||||
idb_shim: ^2.0.0
|
||||
idb_sqflite: ^1.0.0
|
||||
|
|
Loading…
Reference in a new issue