@@ -126,7 +126,7 @@ class _MapboxPagesState extends State<MapboxPages> with ShowAlertDialog {
setState ( ( ) {
userPosition = mapbox . Point (
coordinates:
mapbox . Position ( position . lat itude , position . long itude ) ) ;
mapbox . Position ( position . long itude , position . lat itude ) ) ;
isUserPositionInitialized = true ;
} ) ;
@@ -139,21 +139,72 @@ class _MapboxPagesState extends State<MapboxPages> with ShowAlertDialog {
Future < void > _fetchRoute (
mapbox . Point origin , mapbox . Point destination , String mode ) async {
final url = Uri . parse (
' https://api.mapbox.com/directions/v5/mapbox/ $ mode / ${ origin . coordinates . lng } , ${ origin . coordinates . lat } ; ${ destination . coordinates . lng } , ${ destination . coordinates . lat } ?geometries=geojson&access_token= ${ dotenv . env [ ' MAPBOX_ACCESS_TOKEN ' ] } ' ,
' https://api.mapbox.com/directions/v5/mapbox/ $ mode / '
' ${ origin . coordinates . lng } , ${ origin . coordinates . lat } ; '
' ${ destination . coordinates . lng } , ${ destination . coordinates . lat } '
' ?geometries=geojson&access_token= ${ dotenv . env [ ' MAPBOX_ACCESS_TOKEN ' ] } ' ,
) ;
final response = await http . get ( url ) ;
if ( response . statusCode = = 200 ) {
final data = jsonDecode ( response . body ) ;
final geometry = data [ ' routes ' ] [ 0 ] [ ' geometry ' ] [ ' coordinates ' ] ;
setState ( ( ) {
routeCoordinates = ( geometry as List )
. map < List < double > > ( ( coord ) = > [ coord [ 0 ] , coord [ 1 ] ] )
. toList ( ) ;
} ) ;
// Vérifie si 'routes' existe et contient au moins 1 élément
if ( data [ ' routes ' ] ! = null & & ( data [ ' routes ' ] as List ) . isNotEmpty ) {
final geometry = data [ ' routes ' ] [ 0 ] [ ' geometry ' ] [ ' coordinates ' ] ;
setState ( ( ) {
routeCoordinates = ( geometry as List )
. map < List < double > > ( ( coord ) = > [ coord [ 0 ] , coord [ 1 ] ] )
. toList ( ) ;
} ) ;
} else {
debugPrint ( " ⚠️ Aucune route trouvée entre ${ origin } et $ destination . " ) ;
// Optionnel : afficher un snackbar/toast à l’ utilisateur
}
} else {
debugPrint ( " ❌ Erreur API Mapbox: ${ response . statusCode } " ) ;
}
}
Future < void > _zoomToFitRoute ( List < List < double > > coordinates ) async {
if ( mapboxMap = = null | | coordinates . isEmpty ) return ;
double minLat = coordinates . first [ 1 ] ;
double maxLat = coordinates . first [ 1 ] ;
double minLng = coordinates . first [ 0 ] ;
double maxLng = coordinates . first [ 0 ] ;
for ( var coord in coordinates ) {
if ( coord [ 1 ] < minLat ) minLat = coord [ 1 ] ;
if ( coord [ 1 ] > maxLat ) maxLat = coord [ 1 ] ;
if ( coord [ 0 ] < minLng ) minLng = coord [ 0 ] ;
if ( coord [ 0 ] > maxLng ) maxLng = coord [ 0 ] ;
}
final bounds = mapbox . CoordinateBounds (
southwest: mapbox . Point ( coordinates: mapbox . Position ( minLng , minLat ) ) ,
northeast: mapbox . Point ( coordinates: mapbox . Position ( maxLng , maxLat ) ) ,
infiniteBounds: true ) ;
// Calculer une CameraOptions automatiquement à partir des bounds
final cameraOptions = await mapboxMap ! . cameraForCoordinateBounds (
bounds ,
mapbox . MbxEdgeInsets (
top: 50 , left: 50 , right: 50 , bottom: 50 ) , // marges
0.0 ,
0.0 ,
null ,
null ) ;
// Appliquer la caméra avec animation
await mapboxMap ! . flyTo (
cameraOptions ,
mapbox . MapAnimationOptions ( duration: 1000 ) ,
) ;
}
Future < void > _drawRouteAndMarkers ( ) async {
if ( mapboxMap = = null | | ! isUserPositionInitialized ) return ;
@@ -180,14 +231,12 @@ class _MapboxPagesState extends State<MapboxPages> with ShowAlertDialog {
iconSize: 0.4 ,
) ) ;
// Add event marker
// Ajoute directement la flèche rouge à la position de l’ événement
final eventIcon = await _loadMarkerImage ( ' images/marker-red.png ' ) ;
await pointAnnotationManager ! . create ( mapbox . PointAnnotationOptions (
geometry: mapbox . Point (
coordinates: mapbox . Position (
destination . coordinates . lng , destination . coordinates . lat ) ) ,
geometry: mapbox . Point ( coordinates: mapbox . Position ( longitude , latitude ) ) ,
image: eventIcon ,
iconSize: 0.4 ,
iconSize: 0.2 ,
) ) ;
// Fetch and draw route
@@ -201,6 +250,7 @@ class _MapboxPagesState extends State<MapboxPages> with ShowAlertDialog {
lineColor: Colors . blue . value ,
lineWidth: 4.0 ,
) ) ;
await _zoomToFitRoute ( routeCoordinates ) ;
}
}
@@ -216,15 +266,60 @@ class _MapboxPagesState extends State<MapboxPages> with ShowAlertDialog {
drawer: MyDrawer ( ) ,
body: isLoading
? const Center ( child: CircularProgressIndicator ( ) )
: mapbox . MapWidget (
onMapCreated: ( controller ) {
mapboxMap = controller ;
} ,
cameraOptions: mapbox . CameraOptions (
center: mapbox . Point (
coordinates: mapbox . Position ( longitude , latitude ) ) ,
zoom: 14.0 ,
) ,
: Column (
children: [
Row (
mainAxisAlignment: MainAxisAlignment . center ,
children: [
const Text ( " Mode : " ) ,
DropdownButton < String > (
value: selectedMode ,
items: const [
DropdownMenuItem (
value: ' driving ' , child: Text ( " 🚗 Voiture " ) ) ,
DropdownMenuItem (
value: ' walking ' , child: Text ( " 🚶 Marche " ) ) ,
DropdownMenuItem (
value: ' cycling ' , child: Text ( " 🚴 Vélo " ) ) ,
] ,
onChanged: ( value ) {
if ( value ! = null ) {
setState ( ( ) {
selectedMode = value ;
} ) ;
}
} ,
) ,
] ,
) ,
Expanded (
child: mapbox . MapWidget (
onMapCreated: ( controller ) async {
mapboxMap = controller ;
// Crée un manager si nécessaire
pointAnnotationManager ? ? = await mapboxMap ! . annotations
. createPointAnnotationManager ( ) ;
// Ajoute directement la flèche rouge à la position de l’ événement
final eventIcon =
await _loadMarkerImage ( ' images/marker-red.png ' ) ;
await pointAnnotationManager !
. create ( mapbox . PointAnnotationOptions (
geometry: mapbox . Point (
coordinates: mapbox . Position ( longitude , latitude ) ) ,
image: eventIcon ,
iconSize: 0.2 ,
) ) ;
} ,
cameraOptions: mapbox . CameraOptions (
center: mapbox . Point (
coordinates: mapbox . Position ( longitude , latitude ) ) ,
zoom: 14.0 ,
) ,
) ,
) ,
] ,
) ,
floatingActionButton: FloatingActionButton (
onPressed: _drawRouteAndMarkers ,