show correct landmark types when fetching from api
This commit is contained in:
		| @@ -136,12 +136,20 @@ class _BasePageState extends State<BasePage> { | ||||
| // TODO: Implement this function | ||||
| Trip getFirstTrip(Future<List<Trip>> trips) { | ||||
|   Trip t1 = Trip(uuid: '1', landmarks: LinkedList<Landmark>()); | ||||
|   t1.landmarks.add( | ||||
|     Landmark( | ||||
|       uuid: '0', | ||||
|       name: "Start", | ||||
|       location: [48.85, 2.32], | ||||
|       type: start, | ||||
|     ), | ||||
|   ); | ||||
|   t1.landmarks.add( | ||||
|     Landmark( | ||||
|       uuid: '1', | ||||
|       name: "Eiffel Tower", | ||||
|       location: [48.859, 2.295], | ||||
|       type: monument, | ||||
|       type: sightseeing, | ||||
|       imageURL: "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Tour_Eiffel_Wikimedia_Commons.jpg/1037px-Tour_Eiffel_Wikimedia_Commons.jpg" | ||||
|     ), | ||||
|   ); | ||||
| @@ -150,7 +158,7 @@ Trip getFirstTrip(Future<List<Trip>> trips) { | ||||
|       uuid: "2", | ||||
|       name: "Notre Dame Cathedral", | ||||
|       location: [48.8530, 2.3498], | ||||
|       type: monument, | ||||
|       type: sightseeing, | ||||
|       imageURL: "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Notre-Dame_de_Paris%2C_4_October_2017.jpg/440px-Notre-Dame_de_Paris%2C_4_October_2017.jpg" | ||||
|     ), | ||||
|   ); | ||||
| @@ -159,7 +167,7 @@ Trip getFirstTrip(Future<List<Trip>> trips) { | ||||
|       uuid: "3", | ||||
|       name: "Louvre palace", | ||||
|       location: [48.8606, 2.3376], | ||||
|       type: museum, | ||||
|       type: sightseeing, | ||||
|       imageURL: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Louvre_Museum_Wikimedia_Commons.jpg/540px-Louvre_Museum_Wikimedia_Commons.jpg" | ||||
|     ), | ||||
|   ); | ||||
| @@ -168,7 +176,7 @@ Trip getFirstTrip(Future<List<Trip>> trips) { | ||||
|       uuid: "4", | ||||
|       name: "Pont-des-arts", | ||||
|       location: [48.8585, 2.3376], | ||||
|       type: monument, | ||||
|       type: sightseeing, | ||||
|       imageURL: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/Pont_des_Arts%2C_6e_Arrondissement%2C_Paris_%28HDR%29_20140320_1.jpg/560px-Pont_des_Arts%2C_6e_Arrondissement%2C_Paris_%28HDR%29_20140320_1.jpg" | ||||
|     ), | ||||
|   ); | ||||
| @@ -177,9 +185,18 @@ Trip getFirstTrip(Future<List<Trip>> trips) { | ||||
|       uuid: "5", | ||||
|       name: "Panthéon", | ||||
|       location: [48.847, 2.347], | ||||
|       type: monument, | ||||
|       type: sightseeing, | ||||
|       imageURL: "https://upload.wikimedia.org/wikipedia/commons/thumb/8/80/Pantheon_of_Paris_007.JPG/1280px-Pantheon_of_Paris_007.JPG" | ||||
|     ), | ||||
|   ); | ||||
|   t1.landmarks.add( | ||||
|     Landmark( | ||||
|       uuid: "6", | ||||
|       name: "Galeries Lafayette", | ||||
|       location: [48.87, 2.32], | ||||
|       type: shopping, | ||||
|       imageURL: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/de/GaleriesLafayetteNuit.jpg/220px-GaleriesLafayetteNuit.jpg" | ||||
|     ), | ||||
|   ); | ||||
|   return t1; | ||||
| } | ||||
| @@ -1,4 +1,5 @@ | ||||
| import 'dart:collection'; | ||||
| import 'dart:developer'; | ||||
|  | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:anyway/structs/landmark.dart'; | ||||
| @@ -21,7 +22,7 @@ class MapWidget extends StatefulWidget { | ||||
|  | ||||
| class _MapWidgetState extends State<MapWidget> { | ||||
|   late GoogleMapController mapController; | ||||
|   // coordinates of Paris | ||||
|  | ||||
|   CameraPosition _cameraPosition = CameraPosition( | ||||
|     target: LatLng(48.8566, 2.3522), | ||||
|     zoom: 11.0, | ||||
| @@ -36,7 +37,7 @@ class _MapWidgetState extends State<MapWidget> { | ||||
|       CameraUpdate update = CameraUpdate.newLatLng(LatLng(newLocation[0], newLocation[1])); | ||||
|       controller.moveCamera(update); | ||||
|     } | ||||
|     // addLandmarkMarker(); | ||||
|     setMapMarkers(); | ||||
|   } | ||||
|  | ||||
|   void _onCameraIdle() { | ||||
| @@ -44,45 +45,37 @@ class _MapWidgetState extends State<MapWidget> { | ||||
|   } | ||||
|  | ||||
|  | ||||
|   void addLandmarkMarker() async { | ||||
|     LinkedList<Landmark>? landmarks = widget.trip?.landmarks; | ||||
|     int i = mapMarkers.length; | ||||
|     Landmark? current = landmarks!.elementAtOrNull(i); | ||||
|     if (current != null){ | ||||
|       mapMarkers.add( | ||||
|         Marker( | ||||
|           markerId: MarkerId(current.name), | ||||
|           position: LatLng(current.location[0], current.location[1]), | ||||
|           icon: await CustomMarker( | ||||
|             landmark: current, | ||||
|             position: i+1 | ||||
|           ).toBitmapDescriptor( | ||||
|             logicalSize: const Size(150, 150), | ||||
|             imageSize: const Size(150, 150) | ||||
|           ) | ||||
|         ) | ||||
|   void setMapMarkers() async { | ||||
|     List<Landmark> landmarks = widget.trip?.landmarks.toList() ?? []; | ||||
|     Set<Marker> newMarkers = <Marker>{}; | ||||
|     for (int i = 0; i < landmarks.length; i++) { | ||||
|       Landmark landmark = landmarks[i]; | ||||
|       List<double> location = landmark.location; | ||||
|       Marker marker = Marker( | ||||
|         markerId: MarkerId(landmark.uuid), | ||||
|         position: LatLng(location[0], location[1]), | ||||
|         icon: await CustomMarker(landmark: landmark, position: i).toBitmapDescriptor( | ||||
|           logicalSize: const Size(150, 150), | ||||
|           imageSize: const Size(150, 150) | ||||
|         ), | ||||
|       ); | ||||
|       setState(() {}); | ||||
|       newMarkers.add(marker); | ||||
|     } | ||||
|     setState(() { | ||||
|       mapMarkers = newMarkers; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return ListenableBuilder( | ||||
|       listenable: widget.trip!, | ||||
|       builder: (context, child) { | ||||
|         addLandmarkMarker(); | ||||
|         return GoogleMap( | ||||
|           onMapCreated: _onMapCreated, | ||||
|           initialCameraPosition: _cameraPosition, | ||||
|           onCameraIdle: _onCameraIdle, | ||||
|            | ||||
|           // onLongPress: , | ||||
|           markers: mapMarkers, | ||||
|           cloudMapId: '41c21ac9b81dbfd8', | ||||
|         ); | ||||
|       } | ||||
|     widget.trip?.addListener(setMapMarkers); | ||||
|     return GoogleMap( | ||||
|       onMapCreated: _onMapCreated, | ||||
|       initialCameraPosition: _cameraPosition, | ||||
|       onCameraIdle: _onCameraIdle, | ||||
|       // onLongPress: , | ||||
|       markers: mapMarkers, | ||||
|       cloudMapId: '41c21ac9b81dbfd8', | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @@ -103,20 +96,34 @@ class CustomMarker extends StatelessWidget { | ||||
|     // This returns an outlined circle, with an icon corresponding to the landmark type | ||||
|     // As a small dot, the number of the landmark is displayed in the top right | ||||
|     Icon icon; | ||||
|     if (landmark.type == museum) { | ||||
|       icon = Icon(Icons.museum, color: Colors.black, size: 50); | ||||
|     } else if (landmark.type == monument) { | ||||
|     if (landmark.type == sightseeing) { | ||||
|       icon = Icon(Icons.church, color: Colors.black, size: 50); | ||||
|     } else if (landmark.type == park) { | ||||
|     } else if (landmark.type == nature) { | ||||
|       icon = Icon(Icons.park, color: Colors.black, size: 50); | ||||
|     } else if (landmark.type == restaurant) { | ||||
|       icon = Icon(Icons.restaurant, color: Colors.black, size: 50); | ||||
|     } else if (landmark.type == shop) { | ||||
|     } else if (landmark.type == shopping) { | ||||
|       icon = Icon(Icons.shopping_cart, color: Colors.black, size: 50); | ||||
|     } else if (landmark.type == start || landmark.type == finish) { | ||||
|       icon = Icon(Icons.flag, color: Colors.black, size: 50); | ||||
|     } else { | ||||
|       icon = Icon(Icons.location_on, color: Colors.black, size: 50); | ||||
|     } | ||||
|  | ||||
|     Widget? positionIndicator; | ||||
|     if (landmark.type != start && landmark.type != finish) { | ||||
|       positionIndicator = Positioned( | ||||
|         top: 0, | ||||
|         right: 0, | ||||
|         child: Container( | ||||
|           padding: EdgeInsets.all(5), | ||||
|           decoration: BoxDecoration( | ||||
|             color: Theme.of(context).primaryColor, | ||||
|             shape: BoxShape.circle, | ||||
|           ), | ||||
|           child: Text('$position', style: TextStyle(color: Colors.white, fontSize: 20)), | ||||
|         ), | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     return RepaintBoundary( | ||||
|       child: Stack( | ||||
|         children: [ | ||||
| @@ -136,18 +143,7 @@ class CustomMarker extends StatelessWidget { | ||||
|             ), | ||||
|             child: icon, | ||||
|           ), | ||||
|           Positioned( | ||||
|             top: 0, | ||||
|             right: 0, | ||||
|             child: Container( | ||||
|               padding: EdgeInsets.all(5), | ||||
|               decoration: BoxDecoration( | ||||
|                 color: Theme.of(context).primaryColor, | ||||
|                 shape: BoxShape.circle, | ||||
|               ), | ||||
|               child: Text('$position', style: TextStyle(color: Colors.white, fontSize: 20)), | ||||
|             ), | ||||
|           ), | ||||
|           positionIndicator ?? Container(), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   | ||||
| @@ -29,66 +29,64 @@ class _NewTripPageState extends State<NewTripPage> { | ||||
|       ), | ||||
|       body: Form( | ||||
|         key: _formKey, | ||||
|         child:  | ||||
|           Padding( | ||||
|             padding: const EdgeInsets.all(15.0), | ||||
|             child: Column( | ||||
|               crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                | ||||
|               children: <Widget>[ | ||||
|                 TextFormField( | ||||
|                   decoration: const InputDecoration(hintText: 'Lat'), | ||||
|                   controller: latController, | ||||
|                   validator: (String? value) { | ||||
|                     if (value == null || value.isEmpty || double.tryParse(value) == null){ | ||||
|                       return 'Please enter a floating point number'; | ||||
|                     } | ||||
|                     return null; | ||||
|                   }, | ||||
|                 ), | ||||
|                 TextFormField( | ||||
|                   decoration: const InputDecoration(hintText: 'Lon'), | ||||
|                   controller: lonController, | ||||
|         child: Padding( | ||||
|           padding: const EdgeInsets.all(15.0), | ||||
|           child: Column( | ||||
|             crossAxisAlignment: CrossAxisAlignment.start, | ||||
|              | ||||
|             children: <Widget>[ | ||||
|               TextFormField( | ||||
|                 decoration: const InputDecoration(hintText: 'Lat'), | ||||
|                 controller: latController, | ||||
|                 validator: (String? value) { | ||||
|                   if (value == null || value.isEmpty || double.tryParse(value) == null){ | ||||
|                     return 'Please enter a floating point number'; | ||||
|                   } | ||||
|                   return null; | ||||
|                 }, | ||||
|               ), | ||||
|               TextFormField( | ||||
|                 decoration: const InputDecoration(hintText: 'Lon'), | ||||
|                 controller: lonController, | ||||
|  | ||||
|                   validator: (String? value) { | ||||
|                     if (value == null || value.isEmpty || double.tryParse(value) == null){ | ||||
|                       return 'Please enter a floating point number'; | ||||
|                     } | ||||
|                     return null; | ||||
|                   }, | ||||
|                 ), | ||||
|                 Divider(height: 15, color: Colors.transparent), | ||||
|                 ElevatedButton( | ||||
|                   onPressed: () { | ||||
|                     if (_formKey.currentState!.validate()) { | ||||
|                       List<double> startPoint = [ | ||||
|                         double.parse(latController.text), | ||||
|                         double.parse(lonController.text) | ||||
|                       ]; | ||||
|                       Future<UserPreferences> preferences = loadUserPreferences(); | ||||
|                       Trip trip = Trip(); | ||||
|                       trip.landmarks.add( | ||||
|                         Landmark( | ||||
|                           location: startPoint, | ||||
|                           name: "start", | ||||
|                           type: LandmarkType(name: 'start'), | ||||
|                           uuid: "pending" | ||||
|                         ) | ||||
|                       ); | ||||
|                       fetchTrip(trip, preferences); | ||||
|                         Navigator.of(context).push( | ||||
|                           MaterialPageRoute( | ||||
|                             builder: (context) => BasePage(mainScreen: "map", trip: trip) | ||||
|                           ) | ||||
|                         ); | ||||
|                     } | ||||
|                   }, | ||||
|                   child: const Text('Create trip'), | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ) | ||||
|          | ||||
|                 validator: (String? value) { | ||||
|                   if (value == null || value.isEmpty || double.tryParse(value) == null){ | ||||
|                     return 'Please enter a floating point number'; | ||||
|                   } | ||||
|                   return null; | ||||
|                 }, | ||||
|               ), | ||||
|               Divider(height: 15, color: Colors.transparent), | ||||
|               ElevatedButton( | ||||
|                 child: const Text('Create trip'), | ||||
|                 onPressed: () { | ||||
|                   if (_formKey.currentState!.validate()) { | ||||
|                     List<double> startPoint = [ | ||||
|                       double.parse(latController.text), | ||||
|                       double.parse(lonController.text) | ||||
|                     ]; | ||||
|                     Future<UserPreferences> preferences = loadUserPreferences(); | ||||
|                     Trip trip = Trip(); | ||||
|                     trip.landmarks.add( | ||||
|                       Landmark( | ||||
|                         location: startPoint, | ||||
|                         name: "Start", | ||||
|                         type: start, | ||||
|                         uuid: "pending" | ||||
|                       ) | ||||
|                     ); | ||||
|                     fetchTrip(trip, preferences); | ||||
|                     Navigator.of(context).push( | ||||
|                       MaterialPageRoute( | ||||
|                         builder: (context) => BasePage(mainScreen: "map", trip: trip) | ||||
|                       ) | ||||
|                     ); | ||||
|                   } | ||||
|                 }, | ||||
|               ), | ||||
|             ], | ||||
|           ), | ||||
|         ) | ||||
|       ) | ||||
|     ); | ||||
|   } | ||||
|   | ||||
| @@ -3,12 +3,13 @@ import 'dart:convert'; | ||||
|  | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
|  | ||||
|  | ||||
| const LandmarkType museum = LandmarkType(name: 'Museum'); | ||||
| const LandmarkType monument = LandmarkType(name: 'Monument'); | ||||
| const LandmarkType park = LandmarkType(name: 'Park'); | ||||
| const LandmarkType restaurant = LandmarkType(name: 'Restaurant'); | ||||
| const LandmarkType shop = LandmarkType(name: 'Shop'); | ||||
| const LandmarkType sightseeing = LandmarkType(name: 'sightseeing'); | ||||
| const LandmarkType nature = LandmarkType(name: 'nature'); | ||||
| const LandmarkType shopping = LandmarkType(name: 'shopping'); | ||||
| // const LandmarkType museum = LandmarkType(name: 'Museum'); | ||||
| // const LandmarkType restaurant = LandmarkType(name: 'Restaurant'); | ||||
| const LandmarkType start = LandmarkType(name: 'start'); | ||||
| const LandmarkType finish = LandmarkType(name: 'finish'); | ||||
|  | ||||
|  | ||||
| final class Landmark extends LinkedListEntry<Landmark>{ | ||||
| @@ -55,7 +56,7 @@ final class Landmark extends LinkedListEntry<Landmark>{ | ||||
|         'location': List<dynamic> location, | ||||
|         'type': String type, | ||||
|       }) { | ||||
|       // refine the parsing on a few | ||||
|       // refine the parsing on a few fields | ||||
|       List<double> locationFixed = List<double>.from(location); | ||||
|       // parse the rest separately, they could be missing | ||||
|       LandmarkType typeFixed = LandmarkType(name: type); | ||||
| @@ -106,6 +107,14 @@ class LandmarkType { | ||||
|     // required this.description, | ||||
|     // required this.icon, | ||||
|   }); | ||||
|   @override | ||||
|   bool operator ==(Object other) { | ||||
|     if (other is LandmarkType) { | ||||
|       return name == other.name; | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -49,24 +49,26 @@ fetchTrip( | ||||
|     trip.updateUUID("error"); | ||||
|     if (response.data["detail"] != null) { | ||||
|       trip.updateError(response.data["detail"]); | ||||
|       log(response.data["detail"]); | ||||
|       // throw Exception(response.data["detail"]); | ||||
|     } | ||||
|   } | ||||
|   } else { | ||||
|     Map<String, dynamic> json = response.data; | ||||
|  | ||||
|     // only fill in the trip "meta" data for now | ||||
|     trip.loadFromJson(json); | ||||
|  | ||||
|     // now fill the trip with landmarks | ||||
|     // we are going to recreate ALL the landmarks from the information given by the api | ||||
|     trip.landmarks.remove(trip.landmarks.first); | ||||
|     String? nextUUID = json["first_landmark_uuid"]; | ||||
|     while (nextUUID != null) { | ||||
|       var (landmark, newUUID) = await fetchLandmark(nextUUID); | ||||
|       trip.addLandmark(landmark); | ||||
|       nextUUID = newUUID; | ||||
|     } | ||||
|  | ||||
|   log(response.data.toString()); | ||||
|   Map<String, dynamic> json = response.data; | ||||
|  | ||||
|   // only fill in the trip "meta" data for now | ||||
|   trip.loadFromJson(json); | ||||
|  | ||||
|   // now fill the trip with landmarks | ||||
|   // we are going to recreate ALL the landmarks from the information given by the api | ||||
|   trip.landmarks.remove(trip.landmarks.first); | ||||
|   String? nextUUID = json["first_landmark_uuid"]; | ||||
|   while (nextUUID != null) { | ||||
|     var (landmark, newUUID) = await fetchLandmark(nextUUID); | ||||
|     trip.addLandmark(landmark); | ||||
|     nextUUID = newUUID; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user