show correct landmark types when fetching from api
This commit is contained in:
parent
89511f39cb
commit
f71b9b19a6
@ -136,12 +136,20 @@ class _BasePageState extends State<BasePage> {
|
|||||||
// TODO: Implement this function
|
// TODO: Implement this function
|
||||||
Trip getFirstTrip(Future<List<Trip>> trips) {
|
Trip getFirstTrip(Future<List<Trip>> trips) {
|
||||||
Trip t1 = Trip(uuid: '1', landmarks: LinkedList<Landmark>());
|
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(
|
t1.landmarks.add(
|
||||||
Landmark(
|
Landmark(
|
||||||
uuid: '1',
|
uuid: '1',
|
||||||
name: "Eiffel Tower",
|
name: "Eiffel Tower",
|
||||||
location: [48.859, 2.295],
|
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"
|
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",
|
uuid: "2",
|
||||||
name: "Notre Dame Cathedral",
|
name: "Notre Dame Cathedral",
|
||||||
location: [48.8530, 2.3498],
|
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"
|
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",
|
uuid: "3",
|
||||||
name: "Louvre palace",
|
name: "Louvre palace",
|
||||||
location: [48.8606, 2.3376],
|
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"
|
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",
|
uuid: "4",
|
||||||
name: "Pont-des-arts",
|
name: "Pont-des-arts",
|
||||||
location: [48.8585, 2.3376],
|
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"
|
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",
|
uuid: "5",
|
||||||
name: "Panthéon",
|
name: "Panthéon",
|
||||||
location: [48.847, 2.347],
|
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"
|
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;
|
return t1;
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:anyway/structs/landmark.dart';
|
import 'package:anyway/structs/landmark.dart';
|
||||||
@ -21,7 +22,7 @@ class MapWidget extends StatefulWidget {
|
|||||||
|
|
||||||
class _MapWidgetState extends State<MapWidget> {
|
class _MapWidgetState extends State<MapWidget> {
|
||||||
late GoogleMapController mapController;
|
late GoogleMapController mapController;
|
||||||
// coordinates of Paris
|
|
||||||
CameraPosition _cameraPosition = CameraPosition(
|
CameraPosition _cameraPosition = CameraPosition(
|
||||||
target: LatLng(48.8566, 2.3522),
|
target: LatLng(48.8566, 2.3522),
|
||||||
zoom: 11.0,
|
zoom: 11.0,
|
||||||
@ -36,7 +37,7 @@ class _MapWidgetState extends State<MapWidget> {
|
|||||||
CameraUpdate update = CameraUpdate.newLatLng(LatLng(newLocation[0], newLocation[1]));
|
CameraUpdate update = CameraUpdate.newLatLng(LatLng(newLocation[0], newLocation[1]));
|
||||||
controller.moveCamera(update);
|
controller.moveCamera(update);
|
||||||
}
|
}
|
||||||
// addLandmarkMarker();
|
setMapMarkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCameraIdle() {
|
void _onCameraIdle() {
|
||||||
@ -44,45 +45,37 @@ class _MapWidgetState extends State<MapWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addLandmarkMarker() async {
|
void setMapMarkers() async {
|
||||||
LinkedList<Landmark>? landmarks = widget.trip?.landmarks;
|
List<Landmark> landmarks = widget.trip?.landmarks.toList() ?? [];
|
||||||
int i = mapMarkers.length;
|
Set<Marker> newMarkers = <Marker>{};
|
||||||
Landmark? current = landmarks!.elementAtOrNull(i);
|
for (int i = 0; i < landmarks.length; i++) {
|
||||||
if (current != null){
|
Landmark landmark = landmarks[i];
|
||||||
mapMarkers.add(
|
List<double> location = landmark.location;
|
||||||
Marker(
|
Marker marker = Marker(
|
||||||
markerId: MarkerId(current.name),
|
markerId: MarkerId(landmark.uuid),
|
||||||
position: LatLng(current.location[0], current.location[1]),
|
position: LatLng(location[0], location[1]),
|
||||||
icon: await CustomMarker(
|
icon: await CustomMarker(landmark: landmark, position: i).toBitmapDescriptor(
|
||||||
landmark: current,
|
logicalSize: const Size(150, 150),
|
||||||
position: i+1
|
imageSize: const Size(150, 150)
|
||||||
).toBitmapDescriptor(
|
),
|
||||||
logicalSize: const Size(150, 150),
|
|
||||||
imageSize: const Size(150, 150)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
setState(() {});
|
newMarkers.add(marker);
|
||||||
}
|
}
|
||||||
|
setState(() {
|
||||||
|
mapMarkers = newMarkers;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListenableBuilder(
|
widget.trip?.addListener(setMapMarkers);
|
||||||
listenable: widget.trip!,
|
return GoogleMap(
|
||||||
builder: (context, child) {
|
onMapCreated: _onMapCreated,
|
||||||
addLandmarkMarker();
|
initialCameraPosition: _cameraPosition,
|
||||||
return GoogleMap(
|
onCameraIdle: _onCameraIdle,
|
||||||
onMapCreated: _onMapCreated,
|
// onLongPress: ,
|
||||||
initialCameraPosition: _cameraPosition,
|
markers: mapMarkers,
|
||||||
onCameraIdle: _onCameraIdle,
|
cloudMapId: '41c21ac9b81dbfd8',
|
||||||
|
|
||||||
// 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
|
// 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
|
// As a small dot, the number of the landmark is displayed in the top right
|
||||||
Icon icon;
|
Icon icon;
|
||||||
if (landmark.type == museum) {
|
if (landmark.type == sightseeing) {
|
||||||
icon = Icon(Icons.museum, color: Colors.black, size: 50);
|
|
||||||
} else if (landmark.type == monument) {
|
|
||||||
icon = Icon(Icons.church, color: Colors.black, size: 50);
|
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);
|
icon = Icon(Icons.park, color: Colors.black, size: 50);
|
||||||
} else if (landmark.type == restaurant) {
|
} else if (landmark.type == shopping) {
|
||||||
icon = Icon(Icons.restaurant, color: Colors.black, size: 50);
|
|
||||||
} else if (landmark.type == shop) {
|
|
||||||
icon = Icon(Icons.shopping_cart, color: Colors.black, size: 50);
|
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 {
|
} else {
|
||||||
icon = Icon(Icons.location_on, color: Colors.black, size: 50);
|
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(
|
return RepaintBoundary(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
@ -136,18 +143,7 @@ class CustomMarker extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: icon,
|
child: icon,
|
||||||
),
|
),
|
||||||
Positioned(
|
positionIndicator ?? Container(),
|
||||||
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)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -29,66 +29,64 @@ class _NewTripPageState extends State<NewTripPage> {
|
|||||||
),
|
),
|
||||||
body: Form(
|
body: Form(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child:
|
child: Padding(
|
||||||
Padding(
|
padding: const EdgeInsets.all(15.0),
|
||||||
padding: const EdgeInsets.all(15.0),
|
child: Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
|
children: <Widget>[
|
||||||
children: <Widget>[
|
TextFormField(
|
||||||
TextFormField(
|
decoration: const InputDecoration(hintText: 'Lat'),
|
||||||
decoration: const InputDecoration(hintText: 'Lat'),
|
controller: latController,
|
||||||
controller: latController,
|
validator: (String? value) {
|
||||||
validator: (String? value) {
|
if (value == null || value.isEmpty || double.tryParse(value) == null){
|
||||||
if (value == null || value.isEmpty || double.tryParse(value) == null){
|
return 'Please enter a floating point number';
|
||||||
return 'Please enter a floating point number';
|
}
|
||||||
}
|
return null;
|
||||||
return null;
|
},
|
||||||
},
|
),
|
||||||
),
|
TextFormField(
|
||||||
TextFormField(
|
decoration: const InputDecoration(hintText: 'Lon'),
|
||||||
decoration: const InputDecoration(hintText: 'Lon'),
|
controller: lonController,
|
||||||
controller: lonController,
|
|
||||||
|
|
||||||
validator: (String? value) {
|
validator: (String? value) {
|
||||||
if (value == null || value.isEmpty || double.tryParse(value) == null){
|
if (value == null || value.isEmpty || double.tryParse(value) == null){
|
||||||
return 'Please enter a floating point number';
|
return 'Please enter a floating point number';
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Divider(height: 15, color: Colors.transparent),
|
Divider(height: 15, color: Colors.transparent),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
child: const Text('Create trip'),
|
||||||
if (_formKey.currentState!.validate()) {
|
onPressed: () {
|
||||||
List<double> startPoint = [
|
if (_formKey.currentState!.validate()) {
|
||||||
double.parse(latController.text),
|
List<double> startPoint = [
|
||||||
double.parse(lonController.text)
|
double.parse(latController.text),
|
||||||
];
|
double.parse(lonController.text)
|
||||||
Future<UserPreferences> preferences = loadUserPreferences();
|
];
|
||||||
Trip trip = Trip();
|
Future<UserPreferences> preferences = loadUserPreferences();
|
||||||
trip.landmarks.add(
|
Trip trip = Trip();
|
||||||
Landmark(
|
trip.landmarks.add(
|
||||||
location: startPoint,
|
Landmark(
|
||||||
name: "start",
|
location: startPoint,
|
||||||
type: LandmarkType(name: 'start'),
|
name: "Start",
|
||||||
uuid: "pending"
|
type: start,
|
||||||
)
|
uuid: "pending"
|
||||||
);
|
)
|
||||||
fetchTrip(trip, preferences);
|
);
|
||||||
Navigator.of(context).push(
|
fetchTrip(trip, preferences);
|
||||||
MaterialPageRoute(
|
Navigator.of(context).push(
|
||||||
builder: (context) => BasePage(mainScreen: "map", trip: trip)
|
MaterialPageRoute(
|
||||||
)
|
builder: (context) => BasePage(mainScreen: "map", trip: trip)
|
||||||
);
|
)
|
||||||
}
|
);
|
||||||
},
|
}
|
||||||
child: const Text('Create trip'),
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,13 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
const LandmarkType sightseeing = LandmarkType(name: 'sightseeing');
|
||||||
const LandmarkType museum = LandmarkType(name: 'Museum');
|
const LandmarkType nature = LandmarkType(name: 'nature');
|
||||||
const LandmarkType monument = LandmarkType(name: 'Monument');
|
const LandmarkType shopping = LandmarkType(name: 'shopping');
|
||||||
const LandmarkType park = LandmarkType(name: 'Park');
|
// const LandmarkType museum = LandmarkType(name: 'Museum');
|
||||||
const LandmarkType restaurant = LandmarkType(name: 'Restaurant');
|
// const LandmarkType restaurant = LandmarkType(name: 'Restaurant');
|
||||||
const LandmarkType shop = LandmarkType(name: 'Shop');
|
const LandmarkType start = LandmarkType(name: 'start');
|
||||||
|
const LandmarkType finish = LandmarkType(name: 'finish');
|
||||||
|
|
||||||
|
|
||||||
final class Landmark extends LinkedListEntry<Landmark>{
|
final class Landmark extends LinkedListEntry<Landmark>{
|
||||||
@ -55,7 +56,7 @@ final class Landmark extends LinkedListEntry<Landmark>{
|
|||||||
'location': List<dynamic> location,
|
'location': List<dynamic> location,
|
||||||
'type': String type,
|
'type': String type,
|
||||||
}) {
|
}) {
|
||||||
// refine the parsing on a few
|
// refine the parsing on a few fields
|
||||||
List<double> locationFixed = List<double>.from(location);
|
List<double> locationFixed = List<double>.from(location);
|
||||||
// parse the rest separately, they could be missing
|
// parse the rest separately, they could be missing
|
||||||
LandmarkType typeFixed = LandmarkType(name: type);
|
LandmarkType typeFixed = LandmarkType(name: type);
|
||||||
@ -106,6 +107,14 @@ class LandmarkType {
|
|||||||
// required this.description,
|
// required this.description,
|
||||||
// required this.icon,
|
// 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");
|
trip.updateUUID("error");
|
||||||
if (response.data["detail"] != null) {
|
if (response.data["detail"] != null) {
|
||||||
trip.updateError(response.data["detail"]);
|
trip.updateError(response.data["detail"]);
|
||||||
|
log(response.data["detail"]);
|
||||||
// throw Exception(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());
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user