2021-11-17 15:41:11 +01:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_map/flutter_map.dart';
|
|
|
|
import 'package:latlong2/latlong.dart';
|
|
|
|
import 'package:nc_photos/mobile/platform.dart'
|
|
|
|
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
|
|
|
|
import 'package:nc_photos/pref.dart';
|
2022-07-08 11:38:24 +02:00
|
|
|
import 'package:nc_photos/url_launcher_util.dart';
|
2021-11-17 15:41:11 +01:00
|
|
|
import 'package:tuple/tuple.dart';
|
|
|
|
|
|
|
|
enum GpsMapProvider {
|
|
|
|
// the order must not be changed
|
|
|
|
google,
|
|
|
|
osm,
|
|
|
|
}
|
|
|
|
|
|
|
|
extension GpsMapProviderExtension on GpsMapProvider {
|
|
|
|
String toUserString() {
|
|
|
|
switch (this) {
|
|
|
|
case GpsMapProvider.google:
|
|
|
|
return "Google Maps";
|
|
|
|
|
|
|
|
case GpsMapProvider.osm:
|
|
|
|
return "OpenStreetMap";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class GpsMap extends StatelessWidget {
|
|
|
|
const GpsMap({
|
|
|
|
Key? key,
|
|
|
|
required this.center,
|
|
|
|
required this.zoom,
|
|
|
|
this.onTap,
|
|
|
|
}) : super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
build(BuildContext context) {
|
|
|
|
if (GpsMapProvider.values[Pref().getGpsMapProviderOr(0)] ==
|
|
|
|
GpsMapProvider.osm) {
|
|
|
|
return _OsmGpsMap(
|
|
|
|
center: center,
|
|
|
|
zoom: zoom,
|
|
|
|
onTap: onTap,
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return _GoogleGpsMap(
|
|
|
|
center: center,
|
|
|
|
zoom: zoom,
|
|
|
|
onTap: onTap,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A pair of latitude and longitude coordinates, stored as degrees
|
|
|
|
final Tuple2<double, double> center;
|
|
|
|
final double zoom;
|
|
|
|
final void Function()? onTap;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef _GoogleGpsMap = platform.GoogleGpsMap;
|
|
|
|
|
|
|
|
class _OsmGpsMap extends StatelessWidget {
|
|
|
|
const _OsmGpsMap({
|
|
|
|
Key? key,
|
|
|
|
required this.center,
|
|
|
|
required this.zoom,
|
|
|
|
this.onTap,
|
|
|
|
}) : super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
build(BuildContext context) {
|
|
|
|
const double pinSize = 48;
|
|
|
|
final centerLl = LatLng(center.item1, center.item2);
|
|
|
|
return GestureDetector(
|
|
|
|
onTap: () {
|
|
|
|
launch(
|
|
|
|
"https://www.openstreetmap.org/?mlat=${center.item1}&mlon=${center.item2}#map=${zoom.toInt()}/${center.item1}/${center.item2}");
|
|
|
|
},
|
|
|
|
behavior: HitTestBehavior.opaque,
|
|
|
|
// IgnorePointer is needed to prevent FlutterMap absorbing all pointer
|
|
|
|
// events
|
|
|
|
child: IgnorePointer(
|
|
|
|
child: FlutterMap(
|
|
|
|
options: MapOptions(
|
|
|
|
center: centerLl,
|
|
|
|
zoom: zoom,
|
|
|
|
allowPanning: false,
|
|
|
|
enableScrollWheel: false,
|
|
|
|
interactiveFlags: InteractiveFlag.none,
|
|
|
|
),
|
2022-07-08 11:52:40 +02:00
|
|
|
nonRotatedChildren: [
|
|
|
|
AttributionWidget.defaultWidget(
|
|
|
|
source: "OpenStreetMap contributors",
|
|
|
|
),
|
|
|
|
],
|
2021-11-17 15:41:11 +01:00
|
|
|
layers: [
|
|
|
|
TileLayerOptions(
|
|
|
|
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
|
|
),
|
|
|
|
MarkerLayerOptions(
|
|
|
|
markers: [
|
|
|
|
Marker(
|
|
|
|
width: pinSize,
|
|
|
|
height: pinSize,
|
|
|
|
point: centerLl,
|
|
|
|
anchorPos: AnchorPos.align(AnchorAlign.top),
|
|
|
|
builder: (context) => const Image(
|
2021-11-25 19:54:57 +01:00
|
|
|
image: AssetImage("assets/gps_map_pin.png"),
|
2021-11-17 15:41:11 +01:00
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
final Tuple2<double, double> center;
|
|
|
|
final double zoom;
|
|
|
|
final void Function()? onTap;
|
|
|
|
}
|