Ridesharing 1
Ridesharing 1
Ridesharing 1
BACHELOR OF TECHNOLOGY
in
COMPUTER SCIENCE AND ENGINEERING
of
APJ ABDUL KALAM TECHNOLOGICAL UNIVERSITY
by
J NAVNEETH KRISHNAN
MAC21CS028
JOHN K JOSEPH
MAC21CS030
JOEL SEBASTIAN
MAC21CS029
JULY 2024
ENHANCED RIDESHARING USING
DIRECTIONS API AND
GEOLOCATION
Mini Project Report
BACHELOR OF TECHNOLOGY
in
COMPUTER SCIENCE AND ENGINEERING
of
APJ ABDUL KALAM TECHNOLOGICAL UNIVERSITY
by
J NAVNEETH KRISHNAN
MAC21CS028
JOHN K JOSEPH
MAC21CS030
JOEL SEBASTIAN
MAC21CS029
JULY 2024
DECLARATION
We, undersigned hereby declare that the project report - Enhance Ridesharing
Using Directions API and Geolocation submitted for partial fulfillment of the
requirements for the award of degree of Bachelor of Technology of the APJ Abdul
Kalam Technological University, Kerala is a bonafide work done by us under
supervision of Project coordinator. This submission represents the ideas in our
own words and where ideas or words of others have been included, we have
adequately and accurately cited and referenced the original sources. we also
declare that we have adhered to ethics of academic honesty and integrity and
have not misrepresented or fabricated any data or idea or fact or source in my
submission. We understand that any violation of the above will be a cause for
disciplinary action by the institute or the University and can also evoke penal
action from the sources which have thus not been properly cited or from whom
proper permission has not been obtained. This report has not been previously
formed the basis for the award of any degree, diploma or similar title of any other
University.
3
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
MAR ATHANASIUS COLLEGE OF ENGINEERING
KOTHAMANGALAM
CERTIFICATE
First and foremost, we sincerely thank the ‘God Almighty’ for his grace for
the successful and timely completion of the project.
We express our sincere gratitude and thanks to Dr. Bos Mathew Jos, Princi-
pal and Prof. Joby George, Head of the Department for providing the necessary
facilities and their encouragement and support.
We owe special thanks to the project coordinator and project guide Prof. Asha
J George for her corrections, suggestions and sincere efforts to co-ordinate the
project under a tight schedule.
We express our sincere thanks to staff members in the Department of Com-
puter Science and Engineering who have taken sincere efforts in guiding and
correcting us in conducting this project.
Finally, we would like to acknowledge the heartfelt efforts, comments, criti-
cisms, co-operation and tremendous support given to us by our dear friends during
the preparation of the project and also during the presentation without which this
work would have been all the more difficult to accomplish.
i
ABSTRACT
ii
Table of Contents
ACKNOWLEDGEMENT i
ABSTRACT ii
List of Abbreviations v
1 Introduction 1
2 Background 4
2.1 Flutter Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Dart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Firebase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4 Directions API . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3 Requirement Specification 9
3.1 Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.1 User Authentication and Profile Management . . . . . . . 9
3.1.2 Ride Request and Management . . . . . . . . . . . . . . . 9
3.1.3 Driver Matching and Dispatching . . . . . . . . . . . . . . 10
3.1.4 Ride Status Updates and Notifications . . . . . . . . . . . 10
3.1.5 Payment Integration . . . . . . . . . . . . . . . . . . . . . 10
3.1.6 Ratings and Reviews . . . . . . . . . . . . . . . . . . . . . 10
3.1.7 Admin Dashboard and Reporting . . . . . . . . . . . . . . 11
3.1.8 Testing and Quality Assurance . . . . . . . . . . . . . . . 11
3.1.9 Deployment and Maintenance . . . . . . . . . . . . . . . . 11
3.2 System Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2.1 Feasibility Study . . . . . . . . . . . . . . . . . . . . . . . 12
iii
3.2.2 Requirements Analysis and Specification . . . . . . . . . . 13
3.3 Software Requirements . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4 Hardware Requirements . . . . . . . . . . . . . . . . . . . . . . . 14
3.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5 Results 18
6 Future Scope 30
7 Conclusion 32
8 Appendix 34
8.1 Dataset Description . . . . . . . . . . . . . . . . . . . . . . . . . . 34
8.1.1 Preprocessing . . . . . . . . . . . . . . . . . . . . . . . . . 34
8.2 Model Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . 34
8.3 Training Process . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
8.4 Evaluation Metrics . . . . . . . . . . . . . . . . . . . . . . . . . . 35
8.5 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
8.6 Model Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
8.6.1 loginp age.dart 35
8.6.2 homep age.dart 41
8.6.3 onr oute.dart 53
8.6.4 Booking Form Processing . . . . . . . . . . . . . . . . . . 55
8.6.5 selectr ide.dart 70
9 References 77
iv
List of Abbreviations
v
Chapter 1
Introduction
Introduction
Literature Review
1
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
Methodology
The project’s methodology will encompass various stages, starting with user
interface and design. Locations of the users will be found using geolocation API
. The optimal path will be found using Dijkstra’s algorithm. Users can interact
with each other using the user interface. The front-end will be designed using
the Flutter framework, and the back-end will be implemented using the
Firebase framework. System design , evaluation, and integration will be
conducted to ensure a seamless workflow.
System Architecture
Implementation
This section will delve into the implementation specifics of the project. It
will cover the data collection process, annotation procedures, and preprocessing
techniques applied to the collected data. The configuration and hyperparameter
tuning of the Bidirectional LSTM and LSTM models will be described, along
with the integration of the GloVe function for sarcasm detection. The front-end
design and functionality implemented using Flutter will also be explained, as
well as the back-end implementation using Python Flask.
References
4
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
2.2 Dart
Dart, developed by Google, is a statically-typed programming language de-
signed for building high-performance applications across platforms. With a fa-
miliar syntax for Java or C++ developers, Dart emphasizes productivity and
scalability. It enables cross-platform development, allowing code sharing between
web applications through Flutter Web, mobile applications with Flutter, and
server-side applications with frameworks like Aqueduct or Angel. This reduces
development time and effort.
Dart’s performance is enhanced by its just-in-time (JIT) compiler for fast
development cycles and ahead-of-time (AOT) compilation for highly performant
production applications. It offers a comprehensive standard library with built-
in support for asynchronous programming, HTTP requests, and more. Dart
also provides useful tools like a package manager, static analyzer, and debugger,
further enhancing the development process.
Developer productivity is prioritized with features like hot reload, instantly
reflecting code changes in the running application. Dart’s clean and concise
syntax contributes to a readable and maintainable codebase. Overall, Dart’s
combination of performance, productivity, and cross-platform capabilities makes
it an excellent choice for building various applications.
2.3 Firebase
Firebase is a powerful mobile and web application development platform that
provides a wide range of features and tools for building, deploying, and scaling
applications. Today, it is used by millions of developers worldwide to build high-
quality, user-friendly applications for a variety of platforms and devices. One of
the key features of Firebase is its real-time database, which allows developers to
store and synchronize data across multiple clients and devices in real-time. This
makes it an ideal choice for building collaborative applications, such as chat apps,
multiplayer games, and real-time collaboration tools. The database is built on
top of Google’s Cloud Firestore, which provides a scalable and reliable infrastruc-
ture for storing and accessing data. Another important aspect of Firebase is its
authentication system, which supports a wide range of authentication methods,
including email and password, phone number, Google, Facebook, Twitter, and
GitHub. This allows developers to easily add authentication to their applications,
and provides a seamless user experience for their users.
Firebase also offers a number of other features and tools, such as cloud
storage, hosting, and messaging. Cloud storage allows developers to store and
serve files, such as images and videos, from a centralized location. Hosting
provides a simple and secure way to deploy and host web applications, while
messaging allows developers to send push notifications to users on mobile
devices. In addition to these features, Firebase also provides a number of tools
for monitoring and analyzing application performance, such as Firebase
Crashlytics and Firebase Performance Monitoring. These tools allow developers
to quickly identify and fix issues in their applications, and to optimize their
performance for better user experience. One of the main advantages of Firebase
is its ease of use. It provides a simple and intuitive interface for developers, and
integrates seamlessly with popular development tools and frameworks, such as
Android Studio, Xcode, and Angular. This allows developers to quickly get up
and running with Firebase, and to start building and deploying applications in
no time. Another advantage of Firebase is its scalability. It is built on top of
Google’s powerful infrastructure, which provides a scalable and reliable platform
for hosting and running applications. This means that Firebase can easily
handle large amounts of traffic and data, and can scale up or down as needed to
meet the demands of the application. In conclusion, Firebase is a powerful and
versatile mobile and web application development platform that provides a wide
range of features and tools for building, deploying, and scaling applications. Its
real-time database, authentication system, cloud storage, hosting, and
messaging make it an ideal choice for building collaborative and interactive
applications, while its monitoring and analysis tools help developers optimize
their performance and user experience. With its ease of use, scalability, and
integration with popular development tools and frameworks, Firebase is a great
choice for developers looking to build high-quality, user-friendly applications.
distance, and the ability to request multiple potential routes between two
locations. In summary, the Directions API is a crucial tool for developers
looking to incorporate navigation and route planning features into their
applications. It offers a wide range of functionalities, including detailed
directions, route optimization, and customization options, making it an essential
component for location-based services and mapping applications.
2.5 Summary
In this chapter the discussion was all about the tech stacks that are used to
design and implement the application. Details of technologies like flutter, dart,
hive, android SDK, emulator have been elaborated.
3.1 Methodology
The overall architecture and design of the GPS enhanced ridesharing system
involve several components and steps. Here’s a description of the typical archi-
tecture and design for such a system:
Develop functionality for users to request rides by entering their pickup and
drop-off locations.
Implement real-time location tracking using Geolocator to determine the
user’s current location.
Allow users to view their ride requests and track the status (pending, accepted,
rejected) in real-time.
9
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
Create a system for matching ride requests with available drivers based on
proximity and other factors.
Notify drivers of incoming ride requests and allow them to accept or reject
requests within a specified time frame.
Provide drivers with navigation assistance to reach the pickup location effi-
ciently.
Enable users and drivers to rate each other and provide feedback after com-
pleting a ride.
Implement a rating system to maintain quality standards and foster trust
within the ridesharing community.
Create an admin dashboard to monitor ride activity, user feedback, and overall
system performance.
Generate reports on key metrics such as ride volume, driver ratings, and
revenue to analyze trends and make data-driven decisions.
Deploy the ridesharing app to app stores (e.g., Google Play Store, Apple App
Store) for public access.
Regularly update the app with new features, enhancements, and bug fixes
based on user feedback and market demands.
Provide ongoing maintenance and support to address user inquiries, technical
issues, and platform updates.
1. Problem Recognition
2. Feasibility Study
3. Requirement Analysis
5. Economic Feasibility: Focuses on the total cost incurred for system de-
velopment. The proposed system utilizes cost-effective software resources,
ensuring economic feasibility.
• The publisher can select travellers from the request list according to pref-
erences.
3.5 Summary
In this chapter the details of the requirements are specified. All the feasibility
factors are considered in this chapter. Technical, time, operational, economic,
implementation feasibility discussions are also included. The functional and non-
functional requirements of the project are also elaborated.
15
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
18
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
Figure 5.1
Figure 5.2
Figure 5.3
Figure 5.4
Figure 5.5
Figure 5.6
Figure 5.7
Figure 5.8
Figure 5.9
Figure 5.11
30
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
In conclusion the ridesharing app project has been a challenging and rewarding
experience, resulting in a robust and user-friendly application that addresses the
needs of passengers and drivers. The app’s development focused on overcoming
key challenges, including technology stack selection, user safety, mapping service
integration, user experience design, competition, and regulatory compliance. The
technology stack was carefully chosen, considering the development time, budget,
and desired app performance. The app was developed using a cross-platform de-
velopment approach, which allowed for code reusability across multiple platforms
and a seamless user experience. User safety was prioritized by implementing
features like emergency buttons, real-time tracking, driver identity verification,
extensive background checks, and driver training. These features build trust with
users and ensure a secure and reliable service. The mapping service integration
was critical for accurate location data, route optimization, and navigation fea-
tures. A reliable mapping service was selected, offering cost-effective payment
plans to manage expenses related to GPS tracking and data. User experience de-
sign was a significant focus, with a simple, attractive, and intuitive user interface
that emphasizes simplicity, ease of use, and clear communication. This approach
ensures a seamless user experience for both passengers and drivers. To address
competition and market penetration, strategies were developed to differentiate
the app, provide unique features, and offer competitive pricing. These strategies
aim to stand out in the market and attract a user base. Regulatory compliance
was ensured by adhering to local regulations and transportation laws, licensing,
insurance, and data privacy requirements. This approach ensures that the app
32
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
operates legally and maintains trust with users. In conclusion, the ridesharing
app project has been successful in addressing the key challenges of ridesharing
app development. The app offers a safe, efficient, and user-friendly experience
for both passengers and drivers. The project’s success is a testament to the
team’s dedication and expertise in creating a robust and innovative solution that
addresses the needs of the ridesharing industry.
8.1.1 Preprocessing
Before training the model, the dataset underwent several preprocessing steps,
including:
34
ENHANCED RIDESHARING USING DIRECTIONS API AND
GEOLOCATION
8.5 Deployment
The Charging Station Locator can be deployed as a web application, accessible
through web browsers on desktop and mobile devices. It can be integrated into
electric vehicle manufacturer websites, navigation systems, and mobile apps to
provide users with real-time information on charging station locations and avail-
ability. Additionally, the system can be scaled to support larger user bases and
expanded to include additional features such as route planning and reservation
functionalities.
import ’package:flutter/material.dart’;
import ’package:nimbus_v2/home.dart’;
import ’package:nimbus_v2/phone_number.dart’;
import ’package:nimbus_v2/signup_page.dart’;
import ’package:firebase_auth/firebase_auth.dart’; // Import FirebaseAuth for Fir
import ’package:cloud_firestore/cloud_firestore.dart’; // Import FirebaseFirestor
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text(’Enter your Credentials’, style: TextStyle(color: Colors.whit
backgroundColor: Colors.black,
),
body: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(’assets/background.jpeg’),
fit: BoxFit.cover,
),
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
border: UnderlineInputBorder(),
labelText: ’Email’,labelStyle: TextStyle(color: Colors.whit
),
validator: (value) {
if (value == null || value.isEmpty) {
return ’Please enter your email’;
}
return null;
},
onChanged: (value) => _email = value,
),
SizedBox(height: 20),
TextFormField(
style: TextStyle(color: Colors.white),
obscureText: true,
decoration: InputDecoration(
border: UnderlineInputBorder(),
labelText: ’Password’,labelStyle: TextStyle(color: Colors.w
),
validator: (value) {
try {
// Sign in with email and password
UserCredential userCredential = await FirebaseAuth.instance.signInWithEma
email: _email,
password: _password,
);
import ’dart:async’;
import ’dart:math’ as math;
import ’package:cloud_firestore/cloud_firestore.dart’;
import ’package:flutter/material.dart’;
import ’package:geocoding/geocoding.dart’;
import ’package:google_maps_flutter/google_maps_flutter.dart’;
import ’package:geolocator/geolocator.dart’;
import ’package:nimbus_v2/ride_publish_animation.dart’;
import ’package:nimbus_v2/ride_select.dart’;
import ’package:nimbus_v2/settings.dart’;
@override
_HomePageState createState() => _HomePageState();
}
@override
void initState() {
super.initState();
_checkPermissionAndFetchLocation();
}
_getCurrentLocation();
} else {
// Location permission denied, handle accordingly
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(’Nimbus’, style: TextStyle(color: Colors.black)),
backgroundColor: Colors.white,
actions: [
IconButton(
icon: Icon(Icons.lightbulb_outline,color: Colors.black),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.account_circle,color: Colors.black),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SettingsPage(userName: widget.userName)))
},
),
],
),
body:
SingleChildScrollView(
child: Container(
color: Colors.black,
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
’Welcome, ${widget.userName}!’,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold,color:
),
SizedBox(height: 10),
Text(
’Select Ride Option’,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold,color:
),
SizedBox(height: 10),
DropdownButtonFormField(
value: _selectedOption,
items: [’Ride Publish’, ’Ride Hire’]
.map((option) => DropdownMenuItem(
child: Text(option,style: TextStyle(color: Colors.white)),
value: option,
))
.toList(),
onChanged: (value) {
setState(() {
_selectedOption = value.toString();
_routes = [];
_selectedRoute = ’’;
});
},
dropdownColor: Colors.black,
),
SizedBox(height: 20),
TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: ’From’,
border: UnderlineInputBorder()
),
onChanged: (value) {
setState(() {
_fromLocation = value;
_buildMarkers();
_updateRoute();
});
},
controller:
TextEditingController(text: _fromLocation), // Update text field
),
SizedBox(height: 10),
TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: ’To’,
border: UnderlineInputBorder()
),
onChanged: (value) {
setState(() {
_toLocation = value;
_buildMarkers();
_updateRoute();
});
},
),
SizedBox(height: 20),
if (_selectedRoute.isNotEmpty)
// Display distance if route is available
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
’Distance: $_selectedRoute km’,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold,co
),
),
SizedBox(
height: 300, // Adjust height as needed
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: _currentPosition, // Set initial position to current
zoom: 10,
),
markers: _markers,
polylines: _polylines,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
),
SizedBox(height: 20),
ElevatedButton(
style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(Colo
onPressed: () {
if (_selectedOption == ’Ride Publish’) {
_publishRide();
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SelectDriverPage(
fromLocation: _fromLocation,
toLocation: _toLocation,
userName: widget.userName,
),
),
);
}
},
child: Text(_selectedOption == ’Ride Publish’ ? ’Publish Ride’ :
),
],
),
),
),
);
}
markers.add(
Marker(
markerId: MarkerId(i.toString()),
position: LatLng(location.latitude!, location.longitude!),
infoWindow: InfoWindow(title: i == 0 ? ’From Location’ : ’To Location
),
);
minLat = math.min(minLat, location.latitude!);
minLng = math.min(minLng, location.longitude!);
maxLat = math.max(maxLat, location.latitude!);
maxLng = math.max(maxLng, location.longitude!);
}
setState(() {
_markers = markers;
});
}
}
FirebaseFirestore.instance.collection(’ride_publish’).add({
’driverId’: widget.userName,
’fromLocation’: _fromLocation,
’toLocation’: _toLocation,
’status’: ’published’,
’distance’: double.parse(_selectedRoute), // Store the distance in the
});
}
}
}
void _updateRoute() {
if (_fromLocation.isNotEmpty && _toLocation.isNotEmpty) {
// Calculate and display distance using Vincenty’s formula
_calculateDistanceAndSetState(_fromLocation, _toLocation);
}
}
setState(() {
_selectedRoute = distance.toStringAsFixed(2); // Display distance with tw
});
} else {
// Handle case when geocoding fails
setState(() {
_selectedRoute = ’Geocoding failed’;
});
}
}
if (placemarks.isNotEmpty) {
Placemark placemark = placemarks.first;
setState(() {
_fromLocation = placemark.locality ?? ’Unknown Locality’;
});
} else {
setState(() {
_fromLocation = ’Unknown Locality’;
});
}
}
}
class DistanceCalculator {
static double calculateDistance(double startLat, double startLng, double endLat
const double earthRadius = 6371.0; // Earth’s radius in kilometers
return distance;
}
void main() {
runApp(MaterialApp(
home: HomePage(userName: ’John Doe’),
theme: ThemeData(
scaffoldBackgroundColor: Colors.black,
),
));
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<link rel="stylesheet" href="/static/user/user-login-
dashboard.css">
href="https://stackpath.bootstrapcdn.com/font-
awesome/4.7.0/css/font-awesome.min.css">
<title>user-login dashboard</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js">
" crossorigin="anonymous"></script>
</head>
<header>
<a href="{{ url_for(’home’) }}" class="logo"> <img
src="/static/pic/logo.png" alt="logo"> </a>
<nav>
<ul>
<li><a href="{{ url_for(’home’) }}">Home</a></li>
<li><a href="{{ url_for(’user_find_your_charger’)
}}">Find your charger</a></li>
<li><a href="{{ url_for(’about’) }}">About</a></li>
<li><a href="{{ url_for(’contact_us’) }}">Contact
us</a></li>
</ul>
</nav>
</header>
<body>
</button>
</div>
</div>
</div>
import ’package:flutter/material.dart’;
import ’package:google_maps_flutter/google_maps_flutter.dart’;
import ’package:cloud_firestore/cloud_firestore.dart’;
import ’package:url_launcher/url_launcher.dart’;
import ’package:geocoding/geocoding.dart’;
import ’home.dart’;
RideRequestWidget({
required this.requestId,
required this.name,
required this.pickupLocation,
required this.dropoffLocation,
required this.fare,
required this.userName,
required this.rideAccepted,
required this.onAccept,
required this.onCancel,
required this.isMarkerVisible, // Initialize with isMarkerVisible
required this.onToggleMarker, // Pass onToggleMarker function
});
@override
_RideRequestWidgetState createState() => _RideRequestWidgetState();
}
.collection(’users’)
.where(’name’, isEqualTo: widget.userName)
.get()
.then((querySnapshot) {
if (querySnapshot.docs.isNotEmpty) {
final userData = querySnapshot.docs.first.data();
final phoneNumber = userData[’phoneNumber’];
if (phoneNumber != null) {
print(’Phone number: $phoneNumber’);
// Launch caller app with the phone number
launch(’tel:$phoneNumber’);
} else {
print(’Phone number not found for user: ${widget.userName
}
} else {
print(’User document not found for username: ${widget.userN
}
}).catchError((error) {
print(’Error retrieving phone number: $error’);
});
},
child: Icon(Icons.phone),
),
],
),
SizedBox(height: 8.0),
ElevatedButton(
onPressed: widget.onToggleMarker, // Use onToggleMarker function to t
child: Text(widget.isMarkerVisible ? ’Hide Marker’ : ’Locate Marker’)
),
],
),
);
}
}
@override
_OnRoutePageState createState() => _OnRoutePageState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(’On Route’),
),
body: Column(
children: [
Expanded(
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: widget.fromLocation,
zoom: 14.0,
),
mapType: MapType.normal,
markers: _buildMarkers(),
onTap: (_) {
// Hide markers when the map is tapped
_hideAllMarkers();
},
),
),
Container(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
’Ride Requests’,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold,colo
),
SizedBox(height: 10),
StreamBuilder(
stream: FirebaseFirestore.instance.collection(’requests’).where
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text(’Error: ${snapshot.error}’);
} else {
final requests = snapshot.data!.docs;
return Column(
children: requests.map((request) {
final requestId = request.id;
final name = request[’driverName’];
final pickupLocation = request[’fromLocation’];
final dropoffLocation = request[’toLocation’];
final fare = ’’;
return RideRequestWidget(
requestId: requestId,
name: name,
pickupLocation: pickupLocation,
dropoffLocation: dropoffLocation,
fare: fare,
userName: widget.userName,
rideAccepted: request[’status’] == ’accepted’,
isMarkerVisible: _markerVisibility[requestId] ?? fals
onAccept: () {
FirebaseFirestore.instance.collection(’requests’).d
// Retrieve driver’s location and pass it to the
FirebaseFirestore.instance.collection(’drivers’).
final driverLat = docSnapshot[’latitude’];
final driverLng = docSnapshot[’longitude’];
final driverLocation = LatLng(driverLat, driver
widget.onRideAccepted(driverLocation); // Pass
}).catchError((error) {
print(’Error retrieving driver location: $error
});
}).catchError((error) {
print(’Error accepting ride request: $error’);
// Handle error accordingly
});
},
onCancel: () {
FirebaseFirestore.instance.collection(’requests’).d
},
onToggleMarker: () {
_toggleMarkerVisibility(requestId); // Call _toggle
},
);
}).toList(),
);
}
},
),
],
),
),
Container(
padding: EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _abandonRide,
child: Text(’Abandon Ride’),
),
),
SizedBox(height: 16), // Add some spacing
ElevatedButton(
onPressed: () {
// Navigate to the CompleteRidePage
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CompleteRidePage()),
);
},
Set<Marker> _buildMarkers() {
Set<Marker> markers = {};
});
return markers;
}
void _abandonRide() {
// Delete the ride entry from Firestore
FirebaseFirestore.instance
.collection(’rides’)
.where(’driverId’, isEqualTo: widget.userName)
.get()
.then((querySnapshot) {
querySnapshot.docs.forEach((doc) {
doc.reference.delete();
});
}).then((_) {
// Navigation logic after abandoning the ride
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => HomePage(userName: widget.userName),
)); // Navigate back to the previous page
}).catchError((error) {
print(’Error abandoning ride: $error’);
// Handle error accordingly
});
FirebaseFirestore.instance.collection(’rides’).where(’driverId’, isEqualTo: w
querySnapshot.docs.forEach((doc) {});
});
}
});
if (_markerVisibility[requestId]!) {
_showMarkersForRequest(requestId);
} else {
_hideMarkersForRequest(requestId);
}
}
setState(() {
_markers.remove(requestId);
});
}
void _hideAllMarkers() {
setState(() {
_markerVisibility.forEach((requestId, _) {
_markerVisibility[requestId] = false;
_markers.remove(requestId);
});
});
}
@override
Widget build(BuildContext context) {
return OnRoutePage(
fromLocation: fromLocation,
toLocation: toLocation,
userName: userName,
onRideAccepted: (driverLocation) {}, // Pass driverLocation to the OnRouteP
);
}
}
@override
void initState() {
super.initState();
void _startAnimation() {
// Set a delay to simulate animation duration
Future.delayed(Duration(seconds: 1), () {
// After the delay, mark the animation as complete
setState(() {
_isAnimationComplete = true;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(’Complete Ride’),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_isAnimationComplete
? _buildStaticTickMark()
: _buildAnimatedTickMark(),
SizedBox(height: 20),
_isAnimationComplete
? Text(
’Ride Completed’,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)
: SizedBox.shrink(),
],
),
),
);
}
Widget _buildStaticTickMark() {
return Icon(
Icons.check,
color: Colors.green,
size: 100, // Icon size
);
}
Widget _buildAnimatedTickMark() {
return AnimatedContainer(
duration: Duration(seconds: 1),
curve: Curves.easeInOut,
width: 100, // Initial width
height: 100, // Initial height
decoration: BoxDecoration(
color: Colors.green,
shape: BoxShape.circle,
),
child: Icon(
Icons.check,
color: Colors.white,
size: 60, // Icon size
),
onEnd: () {
void main() {
runApp(MaterialApp(
initialRoute: ’/’,
routes: {
’/’: (context) => RideSelectPage(fromLocation: LatLng(0, 0), toLocation: La
},
));
}
import ’package:flutter/material.dart’;
import ’package:cloud_firestore/cloud_firestore.dart’;
import ’package:geocoding/geocoding.dart’;
import ’package:nimbus_v2/waiting_for_confirmation.dart’;
@override
_SelectDriverPageState createState() => _SelectDriverPageState();
}
@override
void initState() {
super.initState();
_getUserLocation(); // Call the method to initialize _userLocationLatLong
}
@override
void dispose() {
super.dispose();
}
} else {
print(’Error: User location not found.’);
}
} catch (e) {
print(’Error getting user location: $e’);
}
}
Navigator.of(context).pop();
FirebaseFirestore.instance.collection(’requests’).add({
’driverId’: _selectedDriverId,
’driverName’: _selectedDriverName,
’hireId’: widget.userName,
’fromLocation’: widget.fromLocation,
’toLocation’: widget.toLocation,
’status’: ’pending’,
});
FirebaseFirestore.instance.collection(’ride_request’).add({
’driverId’: _selectedDriverId,
’driverName’: _selectedDriverName,
’hireId’: widget.userName,
’fromLocation’: widget.fromLocation,
’toLocation’: widget.toLocation,
’status’: ’pending’,
});
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => WaitingForConfirmationPage(
username: widget.userName,
userLocation: _userLocationLatLong,
driverLocation: ’$lat,$lng’,
),
),
);
} else {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(’Location Not Found’),
content: Text(’The selected driver location could not be found.’),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(’OK’),
),
],
),
);
}
} else {
showDialog(
context: context,
builder: (context) => AlertDialog(
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text(’Select Driver’),
backgroundColor: Colors.white,
),
body: Column(
children: [
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance.collection(’rides’).snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return ListTile(
title: Text(driverName,style: TextStyle(color:Colors.whit
subtitle: Text(’From: $fromLocation\nTo: $toLocation’,sty
tileColor: isSelected ? Colors.grey.withOpacity(0.5) : nu
onTap: () {
setState(() {
_selectedDriverId = driverId;
_selectedDriverName = driverName;
_selectedDriverLoc = fromLocation;
});
},
);
},
);
}
},
),
),
if (_selectedDriverId.isNotEmpty)
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(
onPressed: _hireRide,
child: Text(’Confirm Ride’,style: TextStyle(color:Colors.blac
),
ElevatedButton(
style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(
onPressed: () {
setState(() {
_selectedDriverId = ’’;
});
},
child: Text(’Clear Selection’,style: TextStyle(color:Colors.b
),
],
),
),
],
),
);
}
}
77