11import 'package:flutter/material.dart' ;
22import 'package:flutter_osm_plugin/flutter_osm_plugin.dart' ;
3- import 'package:geolocator/geolocator.dart' ;
3+ import 'dart:math' ;
4+
5+ import 'package:mobile_app/pages/pages.dart' ;
46
57class RoutePage extends StatefulWidget {
6- const RoutePage ({super .key, required this .title});
8+ const RoutePage ({
9+ super .key,
10+ required this .title,
11+ required this .routePoints,
12+ required this .elapsedTime,
13+ });
714
815 final String title;
16+ final List <GeoPoint > routePoints;
17+ final String elapsedTime;
918
1019 @override
1120 State <RoutePage > createState () => _RoutePageState ();
1221}
1322
14- Future <Position > _determinePosition () async {
15- bool serviceEnabled;
16- LocationPermission locationPermission;
17- serviceEnabled = await Geolocator .isLocationServiceEnabled ();
18- if (! serviceEnabled) {
19- return Future .error ('Location services are disabled.' );
20- }
21- locationPermission = await Geolocator .checkPermission ();
22- if (locationPermission == LocationPermission .denied) {
23- locationPermission = await Geolocator .requestPermission ();
24- if (locationPermission == LocationPermission .denied) {
25- return Future .error ('Location permissions are denied' );
26- }
27- }
28- if (locationPermission == LocationPermission .deniedForever) {
29- return Future .error (
30- 'Location permissions are permanently denied, we cannot request permissions.' ,
31- );
32- }
33- return await Geolocator .getCurrentPosition ();
34- }
35-
3623class _RoutePageState extends State <RoutePage > {
3724 GeoPoint ? _initPosition;
38- List <GeoPoint > _routePoints = [] ;
25+ late List <GeoPoint > _routePoints;
3926 late MapController _mapController;
40- var distance = 0.0 ;
41- var numOfGeoPoints = 0 ;
42- var rocketPoints = 0 ;
27+ double distance = 0.0 ;
4328
4429 @override
4530 void initState () {
4631 super .initState ();
47- _setInitialPosition ();
32+ _routePoints = widget.routePoints;
33+ _initPosition = _routePoints.isNotEmpty
34+ ? _routePoints.first
35+ : GeoPoint (latitude: 48.61313 , longitude: 9.45881 );
4836 _mapController = MapController (
49- initPosition: GeoPoint (latitude : 48.61313 , longitude : 9.45881 ) ,
37+ initPosition: _initPosition ! ,
5038 );
39+ distance = _calculateTotalDistance (_routePoints);
5140 }
5241
53- /// Here: Instead of the hardcoded points use the points from the list _routePoints
54- Future <void > _setInitialPosition () async {
55- try {
56- setState (() {
57- _initPosition = GeoPoint (latitude: 48.61313 , longitude: 9.45881 );
58- _routePoints = [
59- _initPosition! ,
60- GeoPoint (latitude: 48.6156 , longitude: 9.45984 ),
61- GeoPoint (latitude: 48.61651 , longitude: 9.4549 ),
62- ];
63- });
64- } catch (e) {
65- // Handle the error accordingly
66- ///Instead of print maybe don't show map and just show earned points and so on
67- print (e);
42+ double _calculateTotalDistance (List <GeoPoint > points) {
43+ if (points.length < 2 ) return 0.0 ;
44+ double total = 0.0 ;
45+ for (int i = 0 ; i < points.length - 1 ; i++ ) {
46+ total += _calculateDistanceBetween (points[i], points[i + 1 ]);
6847 }
48+ return total;
49+ }
50+
51+ // Haversine formula for distance in km
52+ double _calculateDistanceBetween (GeoPoint a, GeoPoint b) {
53+ const double R = 6371 ; // Earth's radius in km
54+ double dLat = _deg2rad (b.latitude - a.latitude);
55+ double dLon = _deg2rad (b.longitude - a.longitude);
56+ double lat1 = _deg2rad (a.latitude);
57+ double lat2 = _deg2rad (b.latitude);
58+
59+ double hav = sin (dLat / 2 ) * sin (dLat / 2 ) +
60+ sin (dLon / 2 ) * sin (dLon / 2 ) * cos (lat1) * cos (lat2);
61+ double c = 2 * atan2 (sqrt (hav), sqrt (1 - hav));
62+ return R * c;
6963 }
7064
65+ double _deg2rad (double deg) => deg * (pi / 180 );
66+
7167 @override
7268 Widget build (BuildContext context) {
7369 return Scaffold (
@@ -76,88 +72,51 @@ class _RoutePageState extends State<RoutePage> {
7672 children: [
7773 SizedBox (
7874 height: 500 ,
79- child:
80- _initPosition == null
81- ? Center (child: CircularProgressIndicator ())
82- : OSMFlutter (
83- controller: _mapController,
84- osmOption: OSMOption (
85- zoomOption: ZoomOption (
86- minZoomLevel: 5 ,
87- maxZoomLevel: 18 ,
88- initZoom: 16 ,
89- ),
90- userLocationMarker: UserLocationMaker (
91- personMarker: MarkerIcon (
92- icon: Icon (
93- Icons .location_on,
94- color: Colors .red,
95- size: 48 ,
96- ),
75+ child: _initPosition == null || _routePoints.isEmpty
76+ ? Center (child: Text ("Keine Route verfügbar" ))
77+ : OSMFlutter (
78+ controller: _mapController,
79+ osmOption: OSMOption (
80+ zoomOption: ZoomOption (
81+ minZoomLevel: 5 ,
82+ maxZoomLevel: 18 ,
83+ initZoom: 16 ,
84+ ),
85+ userLocationMarker: UserLocationMaker (
86+ personMarker: MarkerIcon (
87+ icon: Icon (
88+ Icons .location_on,
89+ color: Colors .red,
90+ size: 48 ,
9791 ),
98- directionArrowMarker : MarkerIcon (
99- icon : Icon (
100- Icons .arrow_forward,
101- color : Colors .blue ,
102- size : 48 ,
103- ) ,
92+ ),
93+ directionArrowMarker : MarkerIcon (
94+ icon : Icon (
95+ Icons .arrow_forward ,
96+ color : Colors .blue ,
97+ size : 48 ,
10498 ),
10599 ),
106100 ),
107- mapIsLoading: Center (child: CircularProgressIndicator ()),
108- onMapIsReady: (isReady) async {
109- RoadInfo roadInfo;
110- ///Here draw the map and get the distance from point to point
111- for (var point in _routePoints){
112- /**
113- * Checks if all points have been already used
114- */
115- if (numOfGeoPoints == _routePoints.length){
116- break ;
117- }
118- numOfGeoPoints++ ;
119- /**
120- * Draws the road between the last and first point
121- */
122- if (_routePoints.indexOf (point) == _routePoints.length- 1 ){
123- roadInfo = await _mapController.drawRoad (
124- point,
125- _routePoints[0 ],
126- roadType: RoadType .foot,
127- roadOption: RoadOption (
128- roadColor: Colors .yellow,
129- roadWidth: 8 ,
130- ),
131- );
132- distance += roadInfo.distance ?? 0 ;
133- /**
134- * Draws road between each other point 0->1, 1->2, ...
135- */
136- }else {
137- roadInfo = await _mapController.drawRoad (
138- point,
139- _routePoints[_routePoints.indexOf (point) + 1 ],
140- roadType: RoadType .foot,
141- roadOption: RoadOption (
142- roadColor: Colors .yellow,
143- roadWidth: 8 ,
144- ),
145- );
146- /**
147- * Adds the distance of the road to the total distance
148- */
149- distance += roadInfo.distance ?? 0 ;
150- setState (() {
151- distance = double .parse (distance.toStringAsFixed (2 ));
152- });
153- }
154- }
155- // Logik für die Karte
156- },
157- onGeoPointClicked: (geoPoint) {
158- // Behandlung des Klicks auf einen Geopunkt
159- },
160101 ),
102+ mapIsLoading: Center (child: CircularProgressIndicator ()),
103+ onMapIsReady: (isReady) async {
104+ if (_routePoints.length > 1 ) {
105+ for (int i = 0 ; i < _routePoints.length - 1 ; i++ ) {
106+ await _mapController.drawRoad (
107+ _routePoints[i],
108+ _routePoints[i + 1 ],
109+ roadType: RoadType .foot,
110+ roadOption: RoadOption (
111+ roadColor: Colors .yellow,
112+ roadWidth: 8 ,
113+ ),
114+ );
115+ }
116+ }
117+ },
118+ onGeoPointClicked: (geoPoint) {},
119+ ),
161120 ),
162121 Container (
163122 padding: const EdgeInsets .all (16.0 ),
@@ -169,39 +128,33 @@ class _RoutePageState extends State<RoutePage> {
169128 mainAxisAlignment: MainAxisAlignment .spaceBetween,
170129 children: [
171130 Text (
172- "Distanz : ${distance .toStringAsFixed (2 )} km" ,
131+ "Distance : ${distance .toStringAsFixed (2 )} km" ,
173132 style: TextStyle (
174133 fontSize: 16 ,
175134 fontWeight: FontWeight .bold,
176135 ),
177136 ),
178137 Text (
179- "Dauer: 00:45:30 " ,
138+ "Time: ${ widget . elapsedTime } " ,
180139 style: TextStyle (
181140 fontSize: 16 ,
182141 fontWeight: FontWeight .bold,
183142 ),
184143 ),
185144 ],
186145 ),
187- SizedBox (height: 8 ),
188- Center (
189- child: Text (
190- "Punkte: ${distance .floor ()}" ,
191- style: TextStyle (fontSize: 16 , fontWeight: FontWeight .bold),
192- ),
193- ),
194- /**
195- * Here: Possible to add the challenges that are completed
196- */
197146 SizedBox (height: 16 ),
198147 Center (
199148 child: ElevatedButton (
200149 onPressed: () {
201- /**
202- * Here: Navigate back to the main app screen
203- */
204- },
150+ Navigator .pushAndRemoveUntil (
151+ context,
152+ MaterialPageRoute (
153+ builder: (context) => AppNavigator (title: 'Rocket App' , initialIndex: 2 ),
154+ ),
155+ (route) => false ,
156+ );
157+ },
205158 child: Text ("Back To App" ),
206159 ),
207160 ),
@@ -213,13 +166,3 @@ class _RoutePageState extends State<RoutePage> {
213166 );
214167 }
215168}
216-
217- void main () {
218- runApp (
219- MaterialApp (
220- title: 'Route Page' ,
221- theme: ThemeData (primarySwatch: Colors .blue),
222- home: RoutePage (title: 'Completed Run' ),
223- ),
224- );
225- }
0 commit comments