MotorSignal-App/lib/services/map/map_provider_interface.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,
});
}