// * Interactive map widget for camera trap location selection // * Features: // * - OpenStreetMap integration // * - Location marker placement // * - GPS coordinates display and saving // * - Localized interface import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:geolocator/geolocator.dart'; import 'package:latlong2/latlong.dart'; // import 'package:geocoding/geocoding.dart'; import 'package:fforte/l10n/app_localizations.dart'; /// Widget for displaying and interacting with the map /// Allows users to select and save camera trap locations class Karte extends StatefulWidget { /// Controller for nearby location name final TextEditingController beiOrtC; /// Controller for location details final TextEditingController ortInfoC; /// Controller for longitude coordinate final TextEditingController decLngC; /// Controller for latitude coordinate final TextEditingController decLatC; /// Current GPS position final Position currentPosition; const Karte( {super.key, required this.currentPosition, required this.beiOrtC, required this.ortInfoC, required this.decLngC, required this.decLatC}); @override KarteState createState() => KarteState(); } /// State class for the map widget class KarteState extends State { /// Current marker on the map Marker? currentMarker; /// Selected position coordinates LatLng? selectedPosition; /// Whether the save button should be visible bool saveVisible = false; @override void initState() { super.initState(); // Initialize marker at current position currentMarker = Marker( point: LatLng( widget.currentPosition.latitude, widget.currentPosition.longitude), child: const Icon( Icons.location_on, color: Colors.red, )); saveVisible = true; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(AppLocalizations.of(context)!.map), actions: [ // Save location button Visibility( visible: saveVisible, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: ElevatedButton.icon( onPressed: () async { if (currentMarker != null) { setState(() { widget.decLatC.text = currentMarker!.point.latitude.toString(); widget.decLngC.text = currentMarker!.point.longitude.toString(); }); } if (context.mounted) Navigator.pop(context, currentMarker?.point); }, icon: const Icon(Icons.save), label: Text(AppLocalizations.of(context)!.saveMap), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), ), ), ), ), ], ), // Map display with OpenStreetMap tiles body: FlutterMap( mapController: MapController(), options: MapOptions( interactionOptions: const InteractionOptions( flags: InteractiveFlag.pinchZoom | InteractiveFlag.drag | InteractiveFlag.pinchMove), initialCenter: LatLng(widget.currentPosition.latitude, widget.currentPosition.longitude), initialZoom: 16.0, onTap: _handleTap, ), children: [ // OpenStreetMap tile layer TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', userAgentPackageName: 'de.lupus.apps', ), // Marker layer MarkerLayer(markers: [currentMarker!]), ]), ); } /// Handle tap events on the map /// Creates a new marker at the tapped location /// @param position The tap position on the screen /// @param latlng The geographical coordinates of the tap _handleTap(TapPosition position, LatLng latlng) { setState(() { currentMarker = Marker( width: 80.0, height: 80.0, point: latlng, child: const Icon( Icons.location_on, color: Colors.red, ), ); // selectedPosition = latlng; saveVisible = true; }); // ScaffoldMessenger.of(context).showSnackBar(SnackBar( // content: Text( // "${AppLocalizations.of(context)!.markerSet}\n${selectedPosition!.latitude}\n${selectedPosition!.longitude}"))); } }