Skip to main content

What are Points?

Points represent individual AVL (Automatic Vehicle Location) telemetry data points captured from vehicle tracking devices. Each point contains comprehensive information about a vehicle’s state at a specific moment in time, including:
  • Geospatial data: GPS coordinates, altitude, and PostGIS geometry
  • Movement metrics: Speed, angle, distance traveled
  • Time tracking: Driving time, parking time, engine hours
  • Device status: Battery, signal strength, network information
  • Contextual data: Geofences, quadrants, sectors, geocoding

Storage Architecture

Points are stored in partitioned PostgreSQL tables using RANGE partitioning by timestamp. This enables efficient time-series queries and automatic data lifecycle management. Key characteristics:
  • Composite primary key: (id, timestamp) - required for partitioned tables
  • PostGIS enabled: Spatial queries using the location geometry column
  • High-volume ingestion: Optimized for continuous telemetry data streams

Points Controller

The PointsController is defined in src/app/points/points.controller.ts but does not yet have endpoints implemented. The controller provides the structure for you to add your own REST endpoints.
You’ll need to implement your own endpoints in the controller. The PointsService and TypeORM repository are ready to use for data access.
Example implementation:
import { Controller, Get, Post, Body, Query } from '@nestjs/common';
import { PointsService } from './points.service';
import { Auth } from 'src/common/decorators';

@Controller('points')
export class PointsController {
  constructor(private readonly pointsService: PointsService) {}

  @Get()
  @Auth()
  async findAll(@Query('imei') imei: number) {
    // Add your query logic using pointsService
  }

  @Post()
  @Auth()
  async create(@Body() createPointDto: any) {
    // Add your creation logic
  }
}

Time-Series Query Patterns

Query by Time Range

Most queries filter by timestamp to leverage table partitioning:
const points = await pointsRepository.find({
  where: {
    timestamp: Between(startTime, endTime),
    trackerDeviceImei: deviceImei
  },
  order: { timestamp: 'ASC' }
});

Spatial Queries

Use PostGIS functions for geospatial filtering:
SELECT * FROM points
WHERE ST_DWithin(
  location::geography,
  ST_MakePoint(-99.1332, 19.4326)::geography,
  1000  -- meters
)
AND timestamp >= NOW() - INTERVAL '1 day';

Aggregation Queries

Calculate metrics over time windows:
// Total distance by vehicle per day
const dailyDistance = await pointsRepository
  .createQueryBuilder('point')
  .select('DATE(to_timestamp(timestamp / 1000))', 'date')
  .addSelect('tracker_device_imei', 'imei')
  .addSelect('MAX(tracker_device_total_distance)', 'total_distance')
  .where('timestamp >= :start', { start: startTimestamp })
  .groupBy('date, tracker_device_imei')
  .getRawMany();

Authentication

All Points API endpoints require authentication. Include a valid JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>

Rate Limits

To ensure system stability:
  • Read operations: 100 requests/minute
  • Write operations: 50 requests/minute
  • Bulk ingestion: Contact your administrator for higher limits

Next Steps

Data Model

Complete Point entity field reference

Service API

PointsService methods and usage

Build docs developers (and LLMs) love