Search code examples
angularanimationvisualizationreal-time-data

How to Create Real-time Traffic Simulation in Web Browser Using Database Coordinates of Cars


I'm working on a project where I need to visualize real-time traffic in a web browser. I have a database containing coordinates of cars that are constantly updated. I want to create a simulation where these cars move on a map in real-time based on their coordinates from the database.Also the frontend technology used is Angular

Could someone guide me on how to achieve this? Are there any specific technologies or libraries I should use for this purpose? .Any example code or tutorials would be greatly appreciated. Thank you in advance for your help!

I tried using WebGl but looking for better solution?


Solution

  • I think You're on the right track! While WebGL is a powerful option, here's a refined approach to create a real-time traffic simulation in your Angular application using database coordinates and libraries:

    Back-end Considerations

    Real-time Data Delivery: You'll need a mechanism to push car coordinate updates from your database to the frontend in real-time. Here are common options: Like WebSockets,Server-Sent Events (SSE) & Polling.

    Data Format: Choose an efficient data format for transmitting car coordinates. JSON (JavaScript Object Notation) is a popular choice due to its simplicity and widespread browser support.

    Real-time Communication and Data Handling

    Use a library like @ngneat/until-destroy to manage subscriptions and prevent memory leaks when components are destroyed.

    Implement a service in your Angular application to handle the real-time communication with the backend using either WebSockets, SSE, or polling.

    Within the service, subscribe to the real-time data stream and update a local data store (e.g., BehaviorSubject) with the received car coordinates.

    Map Visualization and Car Movement

    Use Leaflet to create a map instance and add tile layers (e.g., OpenStreetMap).

    Subscribe to the local data store (BehaviorSubject) in your Angular component that displays the map.

    Based on the updated car coordinates, create or update Leaflet markers representing each car on the map.

    Animate the movement of the markers on the map using techniques like requestAnimationFrame for smooth and efficient updates. Here's an example you can see below:

    TypeScript

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
    import * as L from 'leaflet';
    
    interface Car {
      id: number;
      latitude: number;
      longitude: number;
    }
    
    @UntilDestroy()
    @Component({
      selector: 'app-traffic-simulation',
      templateUrl: './traffic-simulation.component.html',
      styleUrls: ['./traffic-simulation.component.css'],
    })
    export class TrafficSimulationComponent implements OnInit, OnDestroy {
      private map: L.Map;
      private carMarkers: { [key: number]: L.Marker } = {}; // Map car ID to marker
    
      constructor(private trafficService: TrafficService) {}
    
      ngOnInit() {
        this.map = L.map('map').setView([51.505, -0.09], 13);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
          attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        }).addTo(this.map);
    
        this.trafficService.carCoordinates$.pipe(untilDestroyed(this)).subscribe((cars: Car[]) => {
          // Update markers based on received car coordinates
          cars.forEach((car) => {
            const marker = this.carMarkers[car.id];
            if (marker) {
              marker.setLatLng([car.latitude, car.longitude]);
            } else {
              this.carMarkers[car.id] = L.marker([car.latitude, car.longitude]).addTo(this.map);
            }
          });
    
          // Remove markers for cars that are no longer present
          const markerToRemove = Object.keys(this.carMarkers).filter((id) => !cars.some((car) => car.id === Number(id)));
          markerToRemove.forEach((id) => {
            this.map.removeLayer(this.carMarkers[id]);
            delete this.carMarkers[id];
          });
        });
    

    If you want to more refer then please follow below links

    https://github.com/MarianeKaroline/SE-Frontend

    Nominatim is undefined when I use leaflet-routing-machine with angular 7