101 lines
3.0 KiB
Dart
101 lines
3.0 KiB
Dart
import 'dart:math' as math;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_map/flutter_map.dart';
|
|
import 'package:latlong2/latlong.dart' as ll;
|
|
import 'map_provider_interface.dart';
|
|
|
|
class OpenStreetMapProvider implements AppMapProvider {
|
|
final MapController _mapController = MapController();
|
|
|
|
@override
|
|
AppMapType get type => AppMapType.openStreetMap;
|
|
|
|
@override
|
|
String get name => 'OpenStreetMap';
|
|
|
|
@override
|
|
Widget buildMapView({
|
|
required BuildContext context,
|
|
required AppLatLng center,
|
|
required double zoom,
|
|
required List<AppMapMarker> markers,
|
|
required List<AppPolyline> polylines,
|
|
required bool isFollowMode,
|
|
required MapConfig config,
|
|
required ValueChanged<AppLatLng>? onPositionChanged,
|
|
required VoidCallback? onUserInteraction,
|
|
}) {
|
|
final centerLl = ll.LatLng(center.latitude, center.longitude);
|
|
|
|
if (isFollowMode) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
try {
|
|
_mapController.move(centerLl, zoom);
|
|
} catch (_) {}
|
|
});
|
|
}
|
|
|
|
return FlutterMap(
|
|
mapController: _mapController,
|
|
options: MapOptions(
|
|
initialCenter: centerLl,
|
|
initialZoom: zoom,
|
|
minZoom: config.minZoom,
|
|
maxZoom: config.maxZoom,
|
|
onPositionChanged: (position, hasGesture) {
|
|
if (hasGesture) {
|
|
onUserInteraction?.call();
|
|
}
|
|
if (position.center != null && onPositionChanged != null) {
|
|
onPositionChanged(AppLatLng(position.center!.latitude, position.center!.longitude));
|
|
}
|
|
},
|
|
),
|
|
children: [
|
|
TileLayer(
|
|
urlTemplate: config.tileUrlTemplate,
|
|
userAgentPackageName: 'com.example.motorcycle_dash',
|
|
),
|
|
PolylineLayer(
|
|
polylines: polylines.map((p) {
|
|
return Polyline(
|
|
points: p.points.map((pt) => ll.LatLng(pt.latitude, pt.longitude)).toList(),
|
|
strokeWidth: p.width,
|
|
color: p.color,
|
|
);
|
|
}).toList(),
|
|
),
|
|
MarkerLayer(
|
|
markers: markers.map((m) {
|
|
return Marker(
|
|
point: ll.LatLng(m.position.latitude, m.position.longitude),
|
|
width: 50,
|
|
height: 50,
|
|
child: GestureDetector(
|
|
onTap: m.onTap,
|
|
child: Transform.rotate(
|
|
angle: (m.heading * math.pi) / 180.0,
|
|
child: m.iconWidget ??
|
|
const Icon(
|
|
Icons.navigation,
|
|
color: Colors.cyanAccent,
|
|
size: 36,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
RichAttributionWidget(
|
|
attributions: [
|
|
TextSourceAttribution(
|
|
config.attributionText,
|
|
textStyle: const TextStyle(color: Colors.white70, fontSize: 10),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|