Angular  

Complete Source Code Structure for Real-Time GPS Tracking Dashboard (Angular + ASP.NET Core)

Below is a complete, ready-to-implement source code structure with essential files and sample code for a Real-Time GPS Tracking Dashboard using Angular (frontend) and ASP.NET Core (backend) with SignalR and SQL Server.
The structure is minimal but production-friendly — includes Docker, migrations, and run instructions. Use this as a starter and extend as needed.

Repository root

gps-tracking/
├─ backend/
│  ├─ src/
│  │  ├─ GpsTracking.sln
│  │  ├─ GpsTracking.Api/                 # ASP.NET Core Web API + SignalR
│  │  ├─ GpsTracking.Core/                # Domain models / DTOs
│  │  └─ GpsTracking.Infrastructure/      # EF Core DbContext, Migrations
│  ├─ docker-compose.yml
│  └─ README.md
├─ frontend/
│  ├─ gps-dashboard/                      # Angular project
│  │  ├─ src/
│  │  │  ├─ app/
│  │  │  │  ├─ components/
│  │  │  │  │  ├─ live-map/
│  │  │  │  │  │  ├─ live-map.component.ts
│  │  │  │  │  │  ├─ live-map.component.html
│  │  │  │  │  │  └─ live-map.component.scss
│  │  │  │  │  └─ device-list/
│  │  │  │  ├─ services/
│  │  │  │  │  ├─ tracking.service.ts
│  │  │  │  │  └─ signalr.service.ts
│  │  │  │  ├─ models/
│  │  │  │  │  └─ location.model.ts
│  │  │  │  ├─ app.module.ts
│  │  │  │  └─ app.component.* 
│  │  │  └─ index.html
│  │  ├─ angular.json
│  │  └─ package.json
│  └─ README.md
└─ README.md

Backend — ASP.NET Core (essential files & snippets)

Projects

  • GpsTracking.Api — ASP.NET Core Web API with SignalR hub and REST endpoints.

  • GpsTracking.Core — DTOs and domain models.

  • GpsTracking.InfrastructureApplicationDbContext, EF entities, migrations.

GpsTracking.Core (models / DTOs)

GpsTracking.Core/Models/Device.cs

namespace GpsTracking.Core.Models
{
    public class Device
    {
        public string DeviceId { get; set; } = null!;
        public string Name { get; set; } = "";
        public string? Type { get; set; }
        public bool IsActive { get; set; } = true;
    }
}

GpsTracking.Core/Models/LocationLog.cs

using System;

namespace GpsTracking.Core.Models
{
    public class LocationLog
    {
        public int LogId { get; set; }
        public string DeviceId { get; set; } = null!;
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public double? Speed { get; set; }
        public double? Direction { get; set; }
        public DateTime RecordedAt { get; set; } = DateTime.UtcNow;
    }
}

GpsTracking.Core/DTOs/LocationDto.cs

public class LocationDto
{
    public string DeviceId { get; set; } = null!;
    public double Latitude { get; set; }
    public double Longitude { get; set; }
    public double? Speed { get; set; }
    public double? Direction { get; set; }
    public DateTime RecordedAt { get; set; } = DateTime.UtcNow;
}

GpsTracking.Infrastructure — DbContext & EF configuration

GpsTracking.Infrastructure/ApplicationDbContext.cs

using Microsoft.EntityFrameworkCore;
using GpsTracking.Core.Models;

namespace GpsTracking.Infrastructure
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> opts) : base(opts) { }

        public DbSet<Device> Devices { get; set; }
        public DbSet<LocationLog> LocationLogs { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<Device>().HasKey(d => d.DeviceId);
            builder.Entity<LocationLog>().HasKey(l => l.LogId);

            builder.Entity<LocationLog>()
                   .HasIndex(l => new { l.DeviceId, l.RecordedAt });
        }
    }
}

Add EF Core packages to projects:

dotnet add GpsTracking.Infrastructure package Microsoft.EntityFrameworkCore.SqlServer
dotnet add GpsTracking.Infrastructure package Microsoft.EntityFrameworkCore.Design
dotnet add GpsTracking.Api package Microsoft.EntityFrameworkCore.SqlServer
dotnet tool install --global dotnet-ef

Create migration and update DB (run from solution root):

cd backend/src/GpsTracking.Api
dotnet ef migrations add InitialCreate --project ../GpsTracking.Infrastructure --startup-project ./ -o ../GpsTracking.Infrastructure/Migrations
dotnet ef database update --project ../GpsTracking.Infrastructure --startup-project . 

GpsTracking.Api — Program.cs (minimal)

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// DbContext
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// SignalR
builder.Services.AddSignalR();

// CORS (allow frontend)
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.AllowAnyHeader().AllowAnyMethod().AllowCredentials().WithOrigins("http://localhost:4200");
    });
});

var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.MapHub<TrackingHub>("/gpsHub");
app.Run();

SignalR Hub

GpsTracking.Api/Hubs/TrackingHub.cs

using Microsoft.AspNetCore.SignalR;
using GpsTracking.Core.DTOs;

public class TrackingHub : Hub
{
    public async Task BroadcastLocation(LocationDto dto)
    {
        await Clients.All.SendAsync("locationUpdated", dto);
    }
}

Controller: receive device updates and broadcast

GpsTracking.Api/Controllers/TrackingController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using GpsTracking.Core.DTOs;
using GpsTracking.Infrastructure;

[ApiController]
[Route("api/[controller]")]
public class TrackingController : ControllerBase
{
    private readonly ApplicationDbContext _db;
    private readonly IHubContext<TrackingHub> _hub;

    public TrackingController(ApplicationDbContext db, IHubContext<TrackingHub> hub)
    {
        _db = db;
        _hub = hub;
    }

    [HttpPost("update-location")]
    public async Task<IActionResult> UpdateLocation([FromBody] LocationDto dto)
    {
        // persist
        var log = new LocationLog
        {
            DeviceId = dto.DeviceId,
            Latitude = dto.Latitude,
            Longitude = dto.Longitude,
            Speed = dto.Speed,
            Direction = dto.Direction,
            RecordedAt = dto.RecordedAt
        };
        _db.LocationLogs.Add(log);
        await _db.SaveChangesAsync();

        // broadcast
        await _hub.Clients.All.SendAsync("locationUpdated", dto);

        return Ok();
    }

    [HttpGet("history/{deviceId}")]
    public IActionResult GetHistory(string deviceId, int limit = 100)
    {
        var rows = _db.LocationLogs
            .Where(l => l.DeviceId == deviceId)
            .OrderByDescending(l => l.RecordedAt)
            .Take(limit)
            .ToList();
        return Ok(rows);
    }
}

Dockerfile (API)

backend/src/GpsTracking.Api/Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["GpsTracking.Api/GpsTracking.Api.csproj","GpsTracking.Api/"]
COPY ["GpsTracking.Infrastructure/GpsTracking.Infrastructure.csproj","GpsTracking.Infrastructure/"]
COPY ["GpsTracking.Core/GpsTracking.Core.csproj","GpsTracking.Core/"]
RUN dotnet restore "GpsTracking.Api/GpsTracking.Api.csproj"
COPY . .
WORKDIR "/src/GpsTracking.Api"
RUN dotnet publish "GpsTracking.Api.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "GpsTracking.Api.dll"]

docker-compose.yml (backend)

backend/docker-compose.yml

version: '3.8'
services:
  mssql:
    image: mcr.microsoft.com/mssql/server:2019-latest
    environment:
      SA_PASSWORD: "Your_password123"
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"
    healthcheck:
      test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Your_password123 -Q 'select 1'"]
      interval: 10s
      timeout: 5s
      retries: 10

  api:
    build:
      context: ./src
      dockerfile: GpsTracking.Api/Dockerfile
    depends_on:
      - mssql
    environment:
      - ConnectionStrings__DefaultConnection=Server=mssql,1433;Database=GpsTrackingDb;User=sa;Password=Your_password123;
    ports:
      - "5000:80"

Frontend — Angular (essential files & snippets)

Create app

ng new gps-dashboard --routing=true --style=scss
cd gps-dashboard
npm install @microsoft/signalr

Models

src/app/models/location.model.ts

export interface LocationDto {
  deviceId: string;
  latitude: number;
  longitude: number;
  speed?: number;
  direction?: number;
  recordedAt?: string;
}

SignalR service

src/app/services/signalr.service.ts

import { Injectable } from '@angular/core';
import * as signalR from '@microsoft/signalr';
import { Subject } from 'rxjs';
import { LocationDto } from '../models/location.model';

@Injectable({ providedIn: 'root' })
export class SignalrService {
  private hubConnection!: signalR.HubConnection;
  public location$ = new Subject<LocationDto>();

  public startConnection(baseUrl: string) {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl(`${baseUrl}/gpsHub`)
      .withAutomaticReconnect()
      .build();

    this.hubConnection.start()
      .then(() => console.log('SignalR connected'))
      .catch(err => console.error('SignalR error', err));

    this.hubConnection.on('locationUpdated', (data: LocationDto) => {
      this.location$.next(data);
    });
  }

  public stop() {
    this.hubConnection?.stop();
  }
}

Tracking API service

src/app/services/tracking.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { LocationDto } from '../models/location.model';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class TrackingService {
  constructor(private http: HttpClient) {}

  sendLocation(dto: LocationDto) {
    return this.http.post('/api/tracking/update-location', dto);
  }

  getHistory(deviceId: string, limit = 100): Observable<LocationDto[]> {
    return this.http.get<LocationDto[]>(`/api/tracking/history/${deviceId}?limit=${limit}`);
  }
}

Map component (Google Maps + SignalR)

src/app/components/live-map/live-map.component.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { SignalrService } from '../../services/signalr.service';
import { environment } from '../../../environments/environment';

declare const google: any;

@Component({
  selector: 'app-live-map',
  templateUrl: './live-map.component.html',
  styleUrls: ['./live-map.component.scss']
})
export class LiveMapComponent implements OnInit, OnDestroy {
  map: any;
  markers: Record<string, any> = {};

  constructor(private signalr: SignalrService) {}

  ngOnInit() {
    this.initMap();
    this.signalr.startConnection(environment.apiBaseUrl);
    this.signalr.location$.subscribe(loc => this.updateMarker(loc));
  }

  ngOnDestroy() {
    this.signalr.stop();
  }

  initMap() {
    const el = document.getElementById('map')!;
    this.map = new google.maps.Map(el, {
      center: { lat: 19.0760, lng: 72.8777 },
      zoom: 12
    });
  }

  updateMarker(loc: any) {
    if (!this.markers[loc.deviceId]) {
      this.markers[loc.deviceId] = new google.maps.Marker({
        position: { lat: loc.latitude, lng: loc.longitude },
        map: this.map,
        title: loc.deviceId
      });
    } else {
      const pos = new google.maps.LatLng(loc.latitude, loc.longitude);
      this.markers[loc.deviceId].setPosition(pos);
    }
    // Optionally pan/animate map:
    // this.map.panTo(new google.maps.LatLng(loc.latitude, loc.longitude));
  }
}

src/app/components/live-map/live-map.component.html

<div id="map" class="map-container"></div>

src/app/components/live-map/live-map.component.scss

.map-container { width: 100%; height: 100vh; }

Add Google Maps script in index.html:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_KEY&libraries=geometry"></script>

Set environment.apiBaseUrl in src/environments/environment.ts:

export const environment = {
  production: false,
  apiBaseUrl: 'http://localhost:5000'
};

App module (imports)

app.module.ts must import HttpClientModule and declare components and services.

Build & Run instructions

Local (without Docker)

  1. Backend

    • Set connection string in appsettings.Development.json:

      "ConnectionStrings": {
        "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=GpsTrackingDb;Trusted_Connection=True;"
      }
      
    • Apply migrations and run:

      cd backend/src/GpsTracking.Api
      dotnet ef database update --project ../GpsTracking.Infrastructure --startup-project .
      dotnet run
      
  2. Frontend

    • Set Google Maps API key in index.html.

    • Start Angular dev server:

      cd frontend/gps-dashboard
      npm install
      ng serve
      
  3. Open http://localhost:4200 and the Angular app should connect to API at http://localhost:5000.

Using Docker (recommended for parity)

From backend/ folder

docker-compose up --build

This starts SQL Server and the API. Then run Angular locally or containerise it.

Notes & Next Steps (production hardening)

  • Use HTTPS and secure SignalR endpoint.

  • Configure CORS properly for production origin(s).

  • Use authentication (JWT) for devices and dashboard users.

  • Use SignalR scale-out (Redis backplane or Azure SignalR Service) for many concurrent connections.

  • Partition and index LocationLog for performance; consider time-based partitions.

  • Implement rate limiting and batch writes from devices to protect DB.

  • Add monitoring (Application Insights / Prometheus) and logging.

  • Add UI features: clustering, heatmaps, playback, geo-fences, alerts.