Uber for X, Uber clone app, Uber application,

Here in this article, you are going to know about Uber for x | Uber clone app | Uber Application introduction, What is leaflet? Overall App skeleton, Grabbing Dependencies and Setting up the HTML, Setting up the Routes and Server, Application Breakdown and code explanation, Uber for X Vs Our application, Application screenshots.

You can access full source-code from Here

For demo check out these links
(Edit: Links are not active for some migration. Please test locally.)

CustomerDriverServicemanFaker

1. Uber for x | Uber clone app | Uber Application introduction

This application is a prototype of real-time taxi aggregators and service providers like Ola or Uber. Along with cab service, we have also included daily needs Service facility such as food or grocery delivery.

Hence you can book both service and cab on the go. What it doesn’t include is the Book later option, therefore it’s an instant booking service. We use leaflet to build this mapping application.

The leaflet is an open-source JavaScript library for mobile-friendly interactive maps. It works smoothly across all desktop and mobile platforms. It can also be extended with a lot of plugins and has a beautiful, easy to use and well-documented API.

You can see what we are trying to achieve in following screenshots:

uber for x, uber clone app, uber application, uber,

Booked Cab with ETA shown to the customer

 

uber for x, uber clone app, uber application, uber,

Driver Application showing the path to reach customer

This application consists of four subsections as Customer, Driver, Serviceman, and Faker. Customer app is used by the customer to book both cab and service on the go.

For Customer: Uber for x | Uber clone app | Uber Application

It initially shows the user’s current location on his map and also the nearby drivers or service-providers(we’ll refer him as serviceman further).

Once the customer books either cab/service the nearest cab/serviceman is booked and all other drivers and serviceman are removed from his map, setting the map-view to the booked cab/serviceman with a pop-up showing ETA(Estimated Time Arrival).

A customer can also track the driver/serviceman location and see their movement in real-time on their map Uber for x | Uber clone app | Uber Application.

For Driver: Uber for X | Uber clone app | Uber Application

Driver application is used by the driver to navigate to the customer current location. It initially shows their current location to them in their map.

We have styled our marker to make it look better and also to differentiate customer, driver, and serviceman. Driver location is continuously watched and pushed to the customer and the location change is reflected in the customer app.

Once that driver is booked by any customer, the navigation path is shown to the driver on how to reach till customer location.

Faker: Uber for X | Uber clone app | Uber Application

Faker application is what its name implies. It is used to fake the driver location on the map. Otherwise, we have to move physically to a different location to see its effect on the customer map.

It is basically used to test the driver application. It simulates the position change of driver by clicking anywhere on the map.

Serviceman application is used by any service-providers such as food or grocery delivery. It’s same as drivers application but with different service provided. It is also shown to the customer but with a different icon. Its location is updated to the customer continuously.

2. What is leaflet?

The leaflet is an open-source JavaScript library for interactive web maps. It is a framework for showing and interacting with map data.

Weighing just about 33kb of JS it is lightweight, simple, and flexible, and is probably one of the most popular open-source map libraries at the moment.

It has all the features required for mapping application and gives a healthy competition to competitors such as Open-layers, Google Maps API and Bing maps API.

The added advantage is that it handles various basic tasks like converting data to map layers and mouse interactions. To know more–>Leaflet

3. Overall Uber Application skeleton

An organized directory structure is always a good practice for any application development as it will allow us and others to locate and use them. So, before we start working we will go ahead and create an app directory as follows:

#public

--for various resources needed as: js, css, config files and images

#views

--for front-end

--index.js //server

--package.json //dependencies and description

To be systematic and simplify things our application will consist of 2 sections:

a. Front-end showing what is displayed to the user

b. Server handling all get request

4. Grabbing Dependencies and Setting up the HTML

Once we are ready with our folder structure we will install the necessary dependencies required for this application. We assume that you have already installed Node.js, if not then install it.

Npm command line tool comes bundled with Node.js. It is a package manager for JS which manages dependencies of Node.js application and help a developer build amazing things by re-using, sharing packages of code available on Npm registry.

Other modules required includes Socket.io and Express. Socket.io for event-based communication between a user and the server. Express to handle GET and POST request for data. It is a Node.js application server framework. It is the de-facto standard server framework.

Now that we have installed all the dependencies and modules required. We will set up the HTML for each customer, driver, faker, and serviceman.

The basic structure of all the HTML file is almost same containing leaflet API link, div for the map and other js, CSS file for locating buttons. The only exception is their corresponding JS file and book buttons that of a customer.

Customer :

Now we have a basic layout set for our map. Few things to understand here are:

1. We have included a link to the Leaflet API (both leaflet.js and leaflet.css)

2. We have included a div for a map which will hold the map in the HTML page.

3. It contains buttons for booking and its corresponding JS file.

4. Required JS and CSS of locating button(easy-button and font-awesome).

<!DOCTYPE html>
<html>
<head>
<title>Uber-Customer</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- CSS -->
<!-- leaflet CSS file -->
<link rel="stylesheet" type="text/css" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<!--  CSS for Leaflet Routing -->
<link rel="stylesheet" type="text/css" href="/css/leaflet-routing-machine.css" />
<!--   CSS for Setview button -->
<link rel="stylesheet" type="text/css" href="/css/easy-button.css" />
<!--  Including the font-awesome CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
</head>
<style>
html,
body,
#map {
margin: 0;    /*Setting margin,height and width of Map-container which holds the map */
width: 100%;
height: 98%;
}
#button1,
#button2 {
width: 50%; 
height: 6%;
float: right;   /*Setting float as right to align button side by side*/
}
</style>
<body>
<div id="map"></div>
<!--JS -->
<!-- Loading the JS in body so that it doesn't block the loading of external CSS, images, and other assets while it’s downloading JavaScript. -->
<!--  Load Jquery and underscore for traversing driver's list -->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript" src="https://underscorejs.org/underscore-min.js"></script>
<!--  Loading leaflet JS file -->
<script type="text/javascript" src="https://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<!--   JS for locate button -->
<script type="text/javascript" src="/js/easy-button.js"></script>
<!--  Loading configuration file  -->
<script type="text/javascript" src="/config/config.js"></script>
<!--  JS for Leaflet Routing -->
<script type="text/javascript" src="/js/leaflet-routing-machine.js"></script>
<!--  JS for rotating the marker icon -->
<script type="text/javascript" src="/js/Marker.Rotate.js"></script>
<!-- JS for moving the marker icon -->
<script type="text/javascript" src="/js/MovingMarker.js"></script>
<!-- JS for socket connection -->
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<!-- Corresponding JS file of customer -->
<script type="text/javascript" src="/js/customer.js"></script>
<button id="button1" onclick="nearby(0)" style="width:inline" type="button" autofocus><b>Book Ride</b></button>
<button id="button2" onclick="nearby(1)" style="width:inline" type="button" autofocus><b>Book Service</b></button>
</body>
</html>

Driver:

<style>
html,
body,
#map {
margin: 0;  /*Setting margin,height and width of Map-container which holds the map */
width: 100%;
height: 100%;
}
</style>
<body>
<div id="map"></div>
<!--JS -->
<!--  Loading leaflet JS file -->
<script type="text/javascript" src="https://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<!--   JS for locate button -->
<script type="text/javascript" src="/js/easy-button.js"></script>
<!--  Loading configuration file  -->
<script type="text/javascript" src="/config/config.js"></script>
<!--  JS for Leaflet Routing -->
<script type="text/javascript" src="/js/leaflet-routing-machine.js"></script>
<!--  JS for rotating the marker icon -->
<script type="text/javascript" src="/js/Marker.Rotate.js"></script>
<!-- JS for moving the marker icon -->
<script type="text/javascript" src="/js/MovingMarker.js"></script>
<!-- JS for socket connection -->
<script src="/socket.io/socket.io.js"></script>
<!-- Corresponding JS file of driver -->
<script type="text/javascript" src="/js/drive.js"></script>
</body>

5. Setting up the Routes and Server

Now that we have our HTML structure for our map we will setup Node and express server for handling GET and POST data request.

The app starts a server and listens on port 8085 for connections. The app responds with corresponding HTML file for requests to the requested root URL (/) or route.

var express = require('express');
var app = express();	//instance of express
var server = require('http').Server(app)
var io = require('socket.io')(server);
var drivers = {};
var service = {};
app.use(express.static(__dirname + '/public'));
app.get('/customer', function(req, res) {
res.sendFile(__dirname + '/views/customer.html');
});
app.get('/faker', function(req, res) {
res.sendFile(__dirname + '/views/faker.html');
});
app.get('/driver', function(req, res) {
res.sendFile(__dirname + '/views/drive.html');
});
app.get('/serviceman', function(req, res) {
res.sendFile(__dirname + '/views/serviceman.html');
});

app.use sets the directory from where it will fetch the files which in our case is “public”

6. Application breakdown and Code-explanation

Our main server handler is index.js which handles GET requests and creates socket connections.

On the server-side, Socket works by adding event listeners to an instance of HTTP.Server. It’s possible to attach a Socket.io server to other HTTP frameworks, which in our case is Express.

To simplify things let’s break down our application into the following:

1.Server-side

2.Client

a. Customer

b. Driver

c. Serviceman

d. faker

Before going through all these applications. Let’s first understand the Config file which is been used in all client-side application.

Config:

It contains setting up of the basic configuration of the map.

1. initializing the map on the map div id and assigning it to map object, which in our case is the map.


var map=L.map('map')	//Initialise the map, assigns it to the ‘map’ div

2. checking for browser support for geolocation feature.

//checks if the browser supports geolocation feature
if ("geolocation" in navigator) {
console.log('Location found');
} else {
prompt('Allow location access')
}

3. Setting tile-layer and their attributes for the map.

//This code adds a layer to the map telling it what set of tiles to display and where to get them. 
//the first argument is the URL template so Leaflet knows how to fetch the tiles from the servers properly. Next is the attribution – this is what shows up in the bottom-right corner of the map. It is important that you add the right info here for proper attribution of the tile set.
L.tileLayer('https://mts1.google.com/vt/lyrs=m@186112443&hl=x-local&src=app&x={x}&y={y}&z={z}&s=Galile', {
attribution: 'Map data © <a href="https://maps.google.com">Google</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
maxZoom: 20,
minZoom: 5,
worldCopyJump: false
}).addTo(map);

4. Adding button for setting view of user’s current location and initializing custom icons.

//Button to change the current view of the map and switch to the drivers/customer/serviceman current position
L.easyButton('fa-location-arrow', function(btn, map) {
map.setView(mymarker.getLatLng(), 15)
}).addTo(map);
//Creating custom marker icon for Customer, Driver and Serviceman by creating Instance of LeafletIcon object
var carIcon = L.icon({
iconUrl: "/images/mycar.png",
iconSize: [30, 30]
});
var clientIcon = L.icon({
iconUrl: "/images/client.png",
iconSize: [15, 15]
});
var serviceIcon = L.icon({
iconUrl: "/images/service.png",
iconSize: [30, 30]
});

Server-side:

Socket.io allows us to emit and receive custom events. We have used several custom events.

Now we will go sequentially through each event and try to explain its purpose as follows:

  • io.on listens for connections initially when a socket is created between the server and client(customer/driver)

  • Init is one of our custom events which is fired when any of the drivers comes online. We then check if this event is fired by a driver, if yes then we add to the drivers’ object. Drivers object is used to maintain the list of all drivers and keeps updating the list whenever they come online or go offline. This list is broadcasted to a customer so that we can display only the driver’s online at the moment. If it is not the driver then we join it to customer room and fire “initdriverloc” which traverses the drivers list and adds all driver’s to the customer’s map.

    socket.on('init', function(data) {
    if (data.isDriver) {
    drivers[socket.id] = {
    id: socket.id,
    latLong: data.latLong
    };
    socket.isDriver = data.isDriver;
    console.log("Driver Added at " + socket.id);
    socket.broadcast.to('customers').emit('driverAdded', drivers[socket.id]);
    } else {
    socket.join('customers');
    socket.emit('initDriverLoc', drivers);
    }
    });

  • “Initservice” event is similar to previous init. This event handles the incoming of any service-providers and adds it to the customer’s map. Also, we maintain a separate object for service-providers and update it in a similar way as that of a driver.

    socket.on('initservice', function(data) {
    if (data.isservice) {
    service[socket.id] = {
    id: socket.id,
    latLong: data.latLong
    };
    socket.isservice = data.isservice;
    console.log("serviceman Added at " + socket.id);
    socket.broadcast.to('customers').emit('servicemanAdded', service[socket.id]);
    } else {
    socket.join('customers');
    socket.emit('initservicerLoc', service);
    }
    });

  • “Book” event is used to handle both Service and Cab booking. It first checks whether the type of booking: cab or service and perform operations respectively. We find the nearest cab/serviceman and find their unique id. Once we have found that, we emit the respective event I.e.drivepath or service-path with data containing their id and their type.

    socket.on('book', function(mymarker) {
    var near = 0,length, nr = 0;
    var at, id, key;
    var lat1 = mymarker.lat;
    var long1 = mymarker.lng;
    var lat2, long2;
    var details={};
    if (mymarker[1] == 0) {
    at = Object.keys(drivers);
    id = at[0];
    length = Object.keys(drivers).length;
    if (length == 0)
    id = 0;
    else if (length == 1) {
    id = at[0];
    } else {
    for (key in at) {
    console.log('id=' + at[key])
    lat2 = drivers[at[key]].latLong[0]
    long2 = drivers[at[key]].latLong[1]
    nr = distance(lat1, long1, lat2, long2);
    if (nr < near) {
    near = nr;
    id = key;
    }
    }
    }
    }
    else {
    at = Object.keys(service);
    id = at[0];
    length = Object.keys(service).length;
    if (length == 0)
    id = 0;
    else if (length == 1) {
    id = at[0];
    } else {
    for (key in at) {
    console.log('id=' + at[key])
    lat2 = service[at[key]].latLong[0]
    long2 = service[at[key]].latLong[1]
    nr = distance(lat1, long1, lat2, long2);
    if (nr < near) {
    near = nr;
    id = key;
    }
    }
    }
    }
    details[0]=id;	// id of booked car/service
    details[1]=mymarker[1];	//type 0 for cab or 1 for service
    socket.emit('bookid', details);
    if(details[1]==0)
    socket.to(id).emit('drivepath', mymarker[0]);
    else
    socket.to(id).emit('servicepath', mymarker[0]);
    });
  • “locChanged” is an event which is fired when the location of any driver changes. We update our drivers list to the new position of the driver and broadcast this list to update customer’s map.

     socket.on('locChanged', function(data) {
    drivers[socket.id] = {
    id: socket.id,
    latLong: data.latLong
    }
    socket.broadcast.emit('driverLocChanged', {
    id: socket.id,
    latLong: data.latLong
    })
    });
    
  • “servicelocChanged” is similar to previous “locChanged” and perform similar update operation of service list. The only difference is that it listens to the location change of any serviceman and updates customer’s map.

    	socket.on('servicelocChanged', function(data) {
    service[socket.id] = {
    id: socket.id,
    latLong: data.latLong
    }
    socket.broadcast.emit('serviceLocChanged', {
    id: socket.id,
    latLong: data.latLong
    })
    });

  • “disconnect” listens to the event if any driver/serviceman/customer goes offline, updates the corresponding list and broadcast’s it.

    socket.on('disconnect', function() {
    if (socket.isDriver) {
    console.log("Driver disconnected at " + socket.id);
    socket.broadcast.to('customers').emit('driverRemoved', drivers[socket.id]);
    delete drivers[socket.id];
    }
    if (socket.isservice) {
    console.log("service disconnected at " + socket.id);
    socket.broadcast.to('customers').emit('serviceRemoved', service[socket.id]);
    delete service[socket.id];
    } 
    else {
    console.log('Customer Disconnected at' + socket.id);
    }
    });

  • “distance” function finds out the nearest cab/serviceman. It receives lat-long of each cab/serviceman and calculates the distance from the customer and returns this distance.

    function distance(lat1, lon1, lat2, lon2) {
    var p = 0.017453292519943295;
    var c = Math.cos;
    var a = 0.5 - c((lat2 - lat1) * p) / 2 +
    c(lat1 * p) * c(lat2 * p) *
    (1 - c((lon2 - lon1) * p)) / 2;
    return 12742 * Math.asin(Math.sqrt(a));
    }

  • At last, we start our server and it listens on port 8085.

    server.listen(8085, function() {
    console.log('Server started at ' + (new Date().toLocaleString().substr(10, 12)));
    });

Customer:

Lets break down customer’s app into following subsections:

a. Location found event

b. Watching for location changes

c. Event-listener for location changes of both driver and serviceman.

d. Event-listener for the incoming of both driver and serviceman.

e. Event-listener for removal of both driver and serviceman.

f. Event-listener for booking of cab/service

g. Finding the direction angle for movement of both driver and serviceman.

The purpose of various functions and events are described as follows:

  • In map.locate, we set to watch as true to listen for any location change of customer.

    map.locate({
    maxZoom: 15,
    watch: true,		//starts continuous watching of location changes of customer
    enableHighAccuracy: true
    });

  • init function is called when customers are found. It represents customer’s location on the map with blue circle and fires init and initservice so that all the drivers and serviceman who are online can also be represented to a customer.

    //initialise driver first location 
    function init(position) {
    latLong = getLatLong(position);
    map.setView(latLong, 15);
    mymarker = L.Marker.movingMarker([
    latLong,
    latLong
    ], 0, {
    autostart: true,
    zoom: 15,
    icon: clientIcon
    }).addTo(map);
    socket.emit('init', {
    isDriver: isDriver,
    latLong: latLong
    });
    socket.emit('initservice', {
    isservice: isservice,
    latLong: latLong
    });
    inited = true;
    }
    

  • Success is initially called when a customer comes online for the first time and after that when its location changes. As the location changes its marker moves to the new detected location.

    //function executes for location found event
    function success(pos) {
    if (!inited)
    init(pos)
    else
    mymarker.moveTo(getLatLong(pos), 5000)
    }

  • InitDriverloc event is fired to any new driver comes online. Once any driver comes online it is pushed to the markers object and also shown on the customer’s map.

    //Event listener to initialise driver first location and push it to markers object
    socket.on('initDriverLoc', function(drivers) {
    //iterate through all drivers
    _.each(drivers, function(driver) {
    markers[driver.id] = L.Marker.movingMarker([
    driver.latLong,
    driver.latLong
    ], [0], {
    icon: carIcon,
    autostart: true,
    zoom: 15
    }).addTo(map);	//Add all drivers to the customer's map
    });
    });

  • Initserviceloc is similar to the previous event with the only difference that it listens for any new serviceman and adds them to map and markers.

    socket.on('initservicerLoc', function(drivers) {
    _.each(drivers, function(driver) {
    markers[driver.id] = L.Marker.movingMarker([
    driver.latLong,
    driver.latLong
    ], [0], {
    icon: serviceIcon,
    autostart: true,
    zoom: 15
    }).addTo(map);
    });
    });

  • Driveradded event listens for any new driver added. As it comes online it is pushed to markers object and added to the customer’s map represented with car icon.

    //Event listener fired when any new driver comes online, it is pushed into markers object and added to the customer's map
    socket.on('driverAdded', function(driver) {
    console.log("New driver joined.")
    markers[driver.id] = L.Marker.movingMarker([
    driver.latLong,
    driver.latLong
    ], [0], {
    icon: carIcon,
    autostart: true,
    zoom: 15
    }).addTo(map);
    });

  • Service-added is an event similar to previous event. It listens for any new serviceman added/joined. As any serviceman joins it is pushed to the marker object and added to the customer’s map.

    //Event listener fired when any new serviceman comes online, it is pushed into markers and added to the customer's map
    socket.on('servicemanAdded', function(driver) {
    console.log("New driver joined.")
    markers[driver.id] = L.Marker.movingMarker([
    driver.latLong,
    driver.latLong
    ], [0], {
    icon: serviceIcon,
    autostart: true,
    zoom: 15
    }).addTo(map);
    });

  • Driver-removed events listens for any driver which has gone offline. Once any driver is offline it’s marker icon is removed from the customer’s map.

    //event is fired when any driver goes offline
    socket.on('driverRemoved', function(driver) {
    console.log("driver left.")
    map.removeLayer(markers[driver.id])		//driver icon removed from customer's map
    });

  • Service-removed is similar to the previous event with the difference that it listens for any serviceman who has gone offline. Once he’s offline his corresponding icon is removed from customer’s map.

    //event is fired when any serviceman goes offline
    socket.on('serviceRemoved', function(serviceman) {
    console.log("driver left.")
    map.removeLayer(markers[serviceman.id])		////serviceman icon removed from customer's map
    });

  • Nearby function is called when customer books either cab/serviceman and an event is fired which sends a choice of booking and customer’s current latlong to server-side.

    function nearby(data) {
    send[0] = mymarker.getLatLng();
    send[1] = data;
    console.log('send[0]=' + send[0] + 'send[1]=' + send[1])
    socket.emit('book', send);
    }

  • Bookid is an event fired at server-side with the selected nearest cab/serviceman id and type of booking. It also shows the navigation path on how to reach customer location to driver/serviceman booked. It shows only booked serviceman/cab and removes all other from the map. Also, it shows ETA(estimated time arrival) to the customer.

    socket.on('bookid', function(id) {
    if (id[0] == 0) {
    confirm("Not available")
    } else {
    var time = L.Routing.control({
    waypoints: [
    L.latLng(mymarker.getLatLng()),
    L.latLng(markers[id[0]].getLatLng())
    ]
    });
    if (id[1] == 0)
    confirm('Your Ride has been booked');
    if (id[1] == 1)
    confirm('Your Service has been booked');
    for (key in markers) {
    if (markers[id[0]].getLatLng() != markers[key].getLatLng())
    map.removeLayer(markers[key]);
    }
    setTimeout(function() {
    markers[id[0]].bindPopup((Math.round(time._routes[0].summary.totalTime/60)) + ' Minutes away ').openPopup();
    }, 2000);
    }
    });

  • Setangle calculates the angle for setting the angle of the marker icon while moving along any navigation path.

    function setangle(slat, slong, dlat, dlong) {
    var y = Math.sin((dlong - slong)) * Math.cos((dlat));
    var x = (Math.cos((slat)) * Math.sin((dlat))) - (Math.sin((slat)) * Math.cos((dlat)) * Math.cos((dlong - slong)));
    angle1 = Math.atan2(y, x);
    angle1 = 180 * angle1 / Math.PI;
    return angle1;
    }

Driver:

Lets breakdown Driver app into following subsections:

a. Location found event

b. Watching for location changes

c. Event-listener for drive-path which describes the path to reach customer

d. Finding the direction angle for movement of both driver and serviceman

e. Event-listener for map-click which moves the driver to the clicked location.

 The main purpose of each function and event is described as follows:

  • locationfound event locates the driver’s current location once he allows the location access. It fires an event init sending its latlong to the customer.

    
    map.on('locationfound', success); //initialise driver first location
    function init(position) {
    latLong = getLatLong(position);
    map.setView(latLong, 15);
    mymarker = L.Marker.movingMarker([
    latLong,
    latLong
    ], 0, {
    autostart: true,
    zoom: 15,
    icon: carIcon
    }).addTo(map);
    socket.emit('init', {
    isDriver: isDriver,
    latLong: latLong
    });
    inited = true;
    }
  • Success function is called whenever the location of driver changes. It also fires LocChanged so that its new location is detected and updated by customer.

    //function listens for location change
    function success(position) {
    if (!inited)
    init(position)
    else {
    var loc = mymarker.getLatLng();
    var latLong = getLatLong(position)
    var angle = setangle(loc.lat, loc.lng, latLong[0], latLong[1])
    mymarker.setIconAngle(angle);
    mymarker.moveTo(latLong, 5000)
    socket.emit('locChanged', {
    latLong: latLong
    });
    }
    }

  • drivepath event listens for any driver booked by the customer. Once any driver is booked, server emits an event drive-path sending the navigation path details as latlong.

    //event listener for driver-path,shows navigation path to driver to reach customer's location
    socket.on('drivepath', function(id) {
    //drawing path from drivers location to customer location and showing it to the driver
    L.Routing.control({
    waypoints: [
    L.latLng(mymarker.getLatLng()),
    L.latLng(id.lat, id.lng)
    ],
    createMarker: function() {
    return null;
    }
    }).addTo(map);
    });
    

  • Setangle to calculate the angle for marker icon whenever it is moving along any navigation path.

    //set angle of the car marker for animation on the map
    function setangle(slat, slong, dlat, dlong) {
    var dLon = (dlong - slong);
    var y = Math.sin(dLon) * Math.cos(dlat);
    var x = Math.cos(slat) * Math.sin(dlat) - Math.sin(slat) * Math.cos(dlat) * Math.cos(dLon);
    angle1 = Math.atan2(y, x);
    angle1 = (180 * angle1) / 3.1454;
    angle1 = (angle1 + 360) % 360;
    return angle1;
    }

  • OnMapClick is an event fired whenever we click anywhere on the map. As a result, the driver moves to the clicked location. This function is used to test and simulate the driver app for location changes. This functionality can be tested either by using faker application or using a toggle-on button on the top left corner below locate button.

    //function for onclick event
    function onMapClick(e) {
    if (faker == true) {
    var loc = mymarker.getLatLng();
    var latLong = e.latlng;
    var angle = setangle(loc.lat, loc.lng, latLong.lat, latLong.lng)
    mymarker.setIconAngle(angle);
    mymarker.moveTo([e.latlng.lat, e.latlng.lng], 3000)
    socket.emit('locChanged', {
    latLong: [e.latlng.lat, e.latlng.lng]
    });
    }
    }

Serviceman:

This application is the same as the driver application with the only difference as the serviceman icon. Everything else is the same.

Faker:

This application is used to test the driver app for location changes and simulates that changes.

This application is same as driver’s application with the only difference as map-click event, which allows us to move the driver to the clicked location on the map and see it’s effect on Customer’s application.

We don’t need to look for location changes in this application since it is just used to test the driver’s application. Rather than making a separate faker application, we have integrated it within driver app.

The toggle-on button on left top corner in driver app changes the driver to the faker. Hence it starts behaving like faker app once you click on “toggle-on” button. The “toggle-off” button switches it back to driver application.

7. Uber for X vs Our Application

Were you searching for “Apps like Uber”? if yes, then you have got ONE. Our application is very much similar to Uber, says Uber for X prototype.

Our application provides On-demand service just like Uber for X. It only differs from Uber development in the sense that we have also included service booking option for the Customer.

Service option means here as utilities like food or grocery delivery like a delivery business. Also, we are showing one navigation template to the driver once his cab is booked.

Uber for X doesn’t offer this service booking facility right now in its app. So, we have included this one extra facility in our taxi app like Uber.

8. Uber Application Screenshots

 uber for x, uber clone app, uber application, uber,
Service Application
uber for x, uber clone app, uber application, uber,

Customer Application showing his location and nearby drivers, service-providers.

 

Also, read:

An overview of React portal

Portals in ReactJs

    • You can use Phonegap/Corodova for the same.

      Additional Tasks:
      1. Socket.io Notifications to change to Push Notification Messages
      2. Optionally use native location modules

  1. Map does not load, when I open “http://:8085/customer” on my Android phone Samsung Galaxy S5. It shows the two buttons “Book Service” and “Book Ride”. But does not load the map. I tried on my Nexus7 tablet. Same thing, map does not load.
    However, the same URL loads fine with the map on my iPhone5.
    What could be the problem?

    • @lokesh: It’s included in socket.io node-modules. You can’t find it since i have ignored node-modules in bitbucket.See .gitignore file

    • @Prateek: It’s was because of old version of leaflet-routing-machine. I have updated the code with v3.2.4 of leaflet-routing-machine. It’s working now. Thanks for letting me know.

  2. hi,
    I’m having hard time running this in PhoneGap. When I open this is phonegap it says the project doesn’t have config.xml file.
    I can’t locate any config.xml file in the source code. I’m sorry fr being naive but I don’t have technology background.Please help me out.

  3. that was super easy to get working.. i love things that work on the first try,
    quick question, could you tell me if it would be easy to change the map – from goolgle over to mapbox?

    I like mapbox maps better, google’s maps to me are cluttered. In your screenshot images, the google style map I like, but the map thats showing up on this install has alot of markers on it, bus stops, gas stations, etc…
    In all my other script I use mapbox.. take a look at my map on this page – its a perfect map for this type of project.

    mysticnow.com/m/test

  4. sorry my last question for tonight, have you figured out a way to load get the URL work in google Chrome?
    because since it’s requesting location chrome will block access to the site – unless the sites secure https – my server has ssl certificate thats valid, but I can’t load https:// with the 8080 port in the url.. I dont know how to work around that

  5. umm, google chrome blocks the site from loading, the website has to be using https when using location in chrome. take a look at my chrome screen shot
    SCREEN SHOT URL BELOW
    prntscr.com/ehkrfs

  6. hi do you still have a demo site setup of your script, my setup works 5% of the time and the rest nothing.
    like when i click book ride, says the ride was booked but on the driver side nothing happens.

    • No, demo is offline. You should use /faker route to simulate multiple drivers around your location and then book a ride and switch to driver window which has been booked.

  7. okay thanks my last quest for the night i promis 😉 okay so on the faker I fake move the car heading towards the customer, the directions don’t seem to update as I move, and on the customer its continues to show 2 minutes, should this information be changing as the driver is moving?

  8. so I loaded 2 fake drivers, but on the customer its showing 3 drivers, there is a driver right on top of the customer but it’s not neither of the faker, so when i click book it neither of the fakers get the booking it must be going to that ghost driver, how do you kill those types of drivers?

  9. hey I seen a link for when you had a demo site running, I noticed in your url you had https: and the port number, can I ask what your server setup was because my server I own is running centos 6.5 with WHM/Cpanel, but I run any of the node.js scripts from the root folder. but even if I copy the folder over in a cpanel account it still wont let me use https: and the port number. so just wondering what your setup was.

  10. A tour operator provides best support and solution to clients about tour & taxi services. its a vey nice and informative post, thank you for sharing.!!!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.