141 lines
3.9 KiB
Dart
141 lines
3.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
enum AppMapType { openStreetMap, googleMaps, awsMaps }
|
|
|
|
class AppLatLng {
|
|
final double latitude;
|
|
final double longitude;
|
|
|
|
const AppLatLng(this.latitude, this.longitude);
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is AppLatLng &&
|
|
runtimeType == other.runtimeType &&
|
|
latitude == other.latitude &&
|
|
longitude == other.longitude;
|
|
|
|
@override
|
|
int get hashCode => latitude.hashCode ^ longitude.hashCode;
|
|
}
|
|
|
|
class AppMapMarker {
|
|
final String id;
|
|
final AppLatLng position;
|
|
final Widget? iconWidget;
|
|
final double heading; // degrees (0-360)
|
|
final String? label;
|
|
final VoidCallback? onTap;
|
|
|
|
const AppMapMarker({
|
|
required this.id,
|
|
required this.position,
|
|
this.iconWidget,
|
|
this.heading = 0.0,
|
|
this.label,
|
|
this.onTap,
|
|
});
|
|
}
|
|
|
|
class AppPolyline {
|
|
final String id;
|
|
final List<AppLatLng> points;
|
|
final Color color;
|
|
final double width;
|
|
|
|
const AppPolyline({
|
|
required this.id,
|
|
required this.points,
|
|
this.color = Colors.cyanAccent,
|
|
this.width = 4.0,
|
|
});
|
|
}
|
|
|
|
class MapConfig {
|
|
final String tileUrlTemplate;
|
|
final String attributionText;
|
|
final String userAgent;
|
|
final double minZoom;
|
|
final double maxZoom;
|
|
final List<String> subdomains;
|
|
final bool isDarkMode;
|
|
final bool offlineOnly;
|
|
|
|
const MapConfig({
|
|
this.tileUrlTemplate = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
this.attributionText = '© OpenStreetMap contributors',
|
|
this.userAgent = 'MotorcycleDashboard/1.0 (contact: support@earnable.store)',
|
|
this.minZoom = 3.0,
|
|
this.maxZoom = 19.0,
|
|
this.subdomains = const [],
|
|
this.isDarkMode = false,
|
|
this.offlineOnly = false,
|
|
});
|
|
|
|
const MapConfig.tacticalDark({
|
|
this.tileUrlTemplate = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
this.attributionText = '© OpenStreetMap contributors',
|
|
this.userAgent = 'MotorcycleDashboard/1.0 (contact: support@earnable.store)',
|
|
this.minZoom = 3.0,
|
|
this.maxZoom = 19.0,
|
|
this.subdomains = const [],
|
|
this.isDarkMode = true,
|
|
this.offlineOnly = false,
|
|
});
|
|
|
|
const MapConfig.satellite4K({
|
|
this.tileUrlTemplate =
|
|
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
|
|
this.attributionText = '© Esri, Maxar, Earthstar Geographics',
|
|
this.userAgent = 'MotorcycleDashboard/1.0 (contact: support@earnable.store)',
|
|
this.minZoom = 1.0,
|
|
this.maxZoom = 19.0,
|
|
this.subdomains = const [],
|
|
this.isDarkMode = false,
|
|
this.offlineOnly = false,
|
|
});
|
|
|
|
const MapConfig.elevation3D({
|
|
this.tileUrlTemplate = 'https://tile.opentopomap.org/{z}/{x}/{y}.png',
|
|
this.attributionText = '© OpenTopoMap, © OpenStreetMap contributors',
|
|
this.userAgent = 'MotorcycleDashboard/1.0 (contact: support@earnable.store)',
|
|
this.minZoom = 3.0,
|
|
this.maxZoom = 17.0,
|
|
this.subdomains = const ['a', 'b', 'c'],
|
|
this.isDarkMode = false,
|
|
this.offlineOnly = false,
|
|
});
|
|
|
|
const MapConfig.awsLocation({
|
|
required String apiKey,
|
|
String region = 'us-east-2',
|
|
this.offlineOnly = false,
|
|
}) : tileUrlTemplate =
|
|
'https://maps.geo.$region.amazonaws.com/v2/tiles/raster.satellite/{z}/{x}/{y}?key=$apiKey',
|
|
attributionText = '© AWS, Maxar, Earthstar Geographics',
|
|
userAgent = 'MotorcycleDashboard/1.0 (contact: support@earnable.store)',
|
|
minZoom = 1.0,
|
|
maxZoom = 19.0,
|
|
subdomains = const [],
|
|
isDarkMode = false;
|
|
}
|
|
|
|
abstract class AppMapProvider {
|
|
AppMapType get type;
|
|
String get name;
|
|
|
|
Widget buildMapView({
|
|
required BuildContext context,
|
|
required AppLatLng center,
|
|
required double zoom,
|
|
double bearing = 0.0,
|
|
required List<AppMapMarker> markers,
|
|
required List<AppPolyline> polylines,
|
|
required bool isFollowMode,
|
|
required MapConfig config,
|
|
required ValueChanged<AppLatLng>? onPositionChanged,
|
|
required VoidCallback? onUserInteraction,
|
|
});
|
|
}
|