FastTicket Web App

A site that shows ticket offices, bus stops and tramway stops in the Florence area, using geolocation and routing programs to guide the user to the chosen destination.

Web Application for Public Transportation in Florence

The goal is to develop a web application that facilitates users in finding authorized ticket offices for public transportation in the Florence area, as well as bus and tram stops. The web app aims to provide a simple and intuitive interface for users.

Usage

Connection

The application should be usable under 3G/4G coverage, as it is intended for urban environments with decent coverage. The GPS location service is required.

Use Case

  • The website is loaded.
  • Consent to access the location is requested (required in modern operating systems).
  • The user grants consent, and an interactive map centered on the GPS location is displayed.
  • The app automatically shows the route to the nearest ticket office.
  • The map includes a button to select the layers to display.
  • Points of interest on the map are represented by markers, and the user can select a marker.
  • By clicking on a marker, the user can view information about the point of interest.
  • The user can start navigation towards the point of interest.
  • The user will be guided to the point of interest following the directions displayed on the map.

Functionality

The following functionalities need to be implemented:

Loading Leaflet Map

Initially, import leaflet.css and create a baseMap variable and a L.tileLayer connected to a URL.

Creating Markers

Create markers for:

  • Ticket offices
  • Tram stops
  • Bus stops
  • User icon

Load the markers on the map and combine them in a MarkerClusterGroup.

Data Sources

Data from three different databases are used for bus stops, ticket offices, and tram stops in the Florence area. The data was converted to GeoJSON format for use in Leaflet. The bus stop data was generated by combining specific .txt files, applying a CSV parse (implemented in Python).

Geolocation

Geolocation is essential for the web app as it relies on knowing the user’s location to recommend the nearest ticket office and provide directions to points of interest. The geolocation function checks if it’s allowed in the browser and updates the position every 2000 ms.

if (!navigator.geolocation){
    console.log("Browser does not support geolocation");
}else {
    setInterval(() => {
        navigator.geolocation.getCurrentPosition(getPosition)
    }, 2000);
}

The getPosition function is the one that actually controls the position and manages the movement of the user icon on the map.

function getPosition(position){
    	var lat = (position.coords.latitude) ;
    	var lng = (position.coords.longitude);
    	var accuracy = position.coords.accuracy;
    
    	if (check){
    		marker = L.marker([lat,lng], {icon: myicon}).bindPopup("I’m here!")
    		.openPopup().addTo(mymap);
    		check = false;
    
    	}
    	else{
    		marker.slideTo(	[lat, lng], {
    		duration: 1700
    });
    	}
    
};

User Repositioning Function

A button on the map allows the user to reposition the map centered on their location. The backToPosition() function uses the user’s real-time coordinates and the flyTo() function to reach that position on the map.

Routing Management

Clicking on any point of interest on the map triggers the “Take Me Here” button. Clicking the button calls the createRoute() function, which creates a route using real-time user data and the point of interest data.

//Routing

        var Route,latUser,lngUser;
        
        function createRoute(coordinates) {
        
        	if(navigator.geolocation){
            		navigator.geolocation.getCurrentPosition(function(position){
            			latUser = (position.coords.latitude) ;
            			lngUser = (position.coords.longitude);
            			WaitAndRoute();
            		})
        	}else console.log("geolocation does not work");

        lat = coordinates[1];	
        lng = coordinates[0];
        
        	function WaitAndRoute(){
        		if(Route){
        			    mymap.removeControl(Route);
        		}
        
        		Route = L.Routing.control({
        		    waypoints: [
        		        L.latLng(latUser, lngUser),
        		        L.latLng(lat, lng)
        		    ],
        		    routeWhileDragging: true,
        		    show: true
        		}).addTo(mymap);
        
        		mymap.closePopup();
        
        	}
    };

Routing to the Nearest Shop

Upon page load, the web app automatically calculates the route to the nearest ticket office based on the user’s real-time position.

function getNearest(){
        	if(navigator.geolocation){
            		navigator.geolocation.getCurrentPosition(function(position){
            			var latUser = (position.coords.latitude) ;
            			var lngUser = (position.coords.longitude);
            			var shop = L.geoJson(atafLayer);
            			shopIndex = leafletKnn(shop);
            			var nearestResult = shopIndex.nearest([lngUser,latUser], 1)[0];
            			lng = nearestResult.lon;
            			lat = nearestResult.lat;
            			createRoute([lng, lat])
        			
        		})
        	}
    }
    getNearest()

Removal of Displayed Route

A button on the map allows the user to remove the displayed route, effectively deleting the previously created route.

You can find my full project on this Github Repository.