Skip to main content

Overview

Trackmart’s tracking system provides real-time location monitoring for active deliveries. Using Mapbox for map visualization and Firebase Realtime Database for location updates, buyers can see exactly where their driver is and when to expect delivery.

Tracking Architecture

The tracking system uses a combination of technologies:

Mapbox

Interactive map rendering with custom styling

Firebase Realtime DB

Live location updates from drivers

Geolocator

Device GPS for buyer location

Map Implementation

Basic Map Setup

The map is implemented using Flutter Map with Mapbox tiles:
FlutterMap(
  options: new MapOptions(
    center: _center ?? new LatLng(widget.dlat, widget.dlong),
    zoom: 15.0,
  ),
  mapController: _mapController,
  layers: [
    new TileLayerOptions(
      urlTemplate: "https://api.tiles.mapbox.com/v4/"
          "{id}/{z}/{x}/{y}@2x.png?access_token={accessToken}",
      additionalOptions: {
        'accessToken': 'YOUR_MAPBOX_TOKEN',
        'id': 'mapbox.streets',
      },
    ),
    // Additional layers...
  ],
)
Replace 'YOUR_MAPBOX_TOKEN' with your actual Mapbox access token. Keep tokens secure and use environment variables in production.

Real-Time Location Updates

Driver locations are streamed from Firebase:
@override
void initState() {
  FirebaseDatabase.instance
      .reference()
      .child('Drivers')
      .child(widget.driverId)
      .onValue
      .listen((e) {
        if(mounted) {
          Map<String, dynamic> map = e.snapshot.value.cast<String, dynamic>();
          _updateLocation(Position(
              longitude: map['long'].toDouble(),
              latitude: map['lat'].toDouble()));
        }
  });
  super.initState();
}
Location updates are received in real-time as drivers move. The onValue listener ensures the map always shows the current position.

Location Update Handler

_updateLocation(Position position) {
  setState(() {
    dlat = position.latitude;
    dlong = position.longitude;
  });
  var url =
      'https://api.mapbox.com/directions/v5/mapbox/driving/${dlong},${dlat};${widget.ulong},${widget.ulat}?access_token=YOUR_TOKEN';
  http.get(url).then((response) {
    route = json.decode(response.body)['routes'][0];
    var k = PolylinePoints().decodePolyline(route['geometry']);
    setState(() {
      points = List.generate(k.length, (i) {
        return LatLng(k[i].latitude, k[i].longitude);
      });
      distance = '${(route['distance'] / 1000).toStringAsFixed(2)}km';
      duration = '${(route['duration'] / 60).toStringAsFixed(0)}min';
    });
  });
}

Route Visualization

The app draws a polyline showing the route from driver to buyer:
1

Fetch Route

Query Mapbox Directions API with driver and buyer coordinates
2

Decode Polyline

Convert encoded polyline geometry to LatLng points
3

Render on Map

Display the route as a colored polyline overlay
PolylineLayerOptions(polylines: [
  new Polyline(
    points: points,
    strokeWidth: 5.0,
    color: Theme.of(context).accentColor,
  )
])

Map Markers

Two markers indicate buyer and driver locations:
new Marker(
  width: 60.0,
  height: 60.0,
  point: new LatLng(widget.ulat, widget.ulong),
  builder: (ctx) => new Container(
    child: GestureDetector(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('You',
                style: TextStyle(backgroundColor: Colors.white)),
            Icon(
              Icons.person_pin_circle,
              color: Theme.of(context).accentColor,
              size: 30,
            ),
          ],
        ),
        onTap: () {
          print('hi');
        }),
  ),
)

Distance and ETA

The tracking view displays real-time distance and estimated time of arrival:
FlatButton.icon(
  color: Colors.white,
  onPressed: _eta,
  icon: Icon(
    Icons.access_time,
    color: Theme.of(context).accentColor,
  ),
  label: Text('${distance ?? ''} (${duration ?? ''}'),
)

ETA Calculation

void _eta() {
  if(route!=null)
  showDialog(
    context: context,
    builder: (context) {
      return SimpleDialog(
        title: Text('ETA'),
        contentPadding: EdgeInsets.all(12),
        children: <Widget>[
          Text(
            '${DateFormat('h:mm a').format(DateTime.now().add(Duration(seconds: route['duration'].toInt())))}',
            style: TextStyle(
                color: Theme.of(context).accentColor,
                fontWeight: FontWeight.bold,
                fontSize: 24),
          ),
        ],
      );
    },
  );
}
The ETA dialog shows the expected arrival time in 12-hour format (e.g., “2:45 PM”) by adding the route duration to the current time.

Finding Nearest Drivers

Buyers can view all available drivers on a map:
FirebaseDatabase.instance
    .reference()
    .child('Drivers')
    .orderByChild('status')
    .equalTo(true)
    .onValue
    .listen((e) {
  Map<String, dynamic> map = e.snapshot.value?.cast<String, dynamic>();
  if (map != null) {
    map.forEach((key, values) {
      var url =
          'https://api.mapbox.com/directions/v5/mapbox/driving/${values['long']},${values['lat']};${widget.ulong},${widget.ulat}?access_token=YOUR_TOKEN';
      http.get(url).then((response) {
        var route = json.decode(response.body)['routes'][0];
        if(mounted)setState(() {
          distances.add('${(route['distance'] / 1000).toStringAsFixed(2)}km');
          durations.add((route['duration'] / 60).toInt());
          // Add driver to map...
        });
      });
    });
  }
});

Driver Cards

Each driver marker shows name, distance, and ETA when tapped

Quick Selection

Tap a driver marker to view details and confirm selection

Map Controls

The tracking interface includes navigation controls:
  • My Location (bottom-left): Centers map on buyer’s location
  • Driver Location (bottom-right): Centers map on driver’s location
  • Help (app bar): Shows ETA dialog
IconButton(
    iconSize: 40,
    icon: Icon(Icons.my_location,
        color: Theme.of(context).accentColor),
    onPressed: () {
      _mapController.move(
          LatLng(widget.ulat, widget.ulong), _mapController.zoom);
    }),

Buyer Location Tracking

The app also tracks the buyer’s location:
_updateLocation(Position position) {
  if (mounted)
    setState(() {
      currentLat = position.latitude;
      currentLong = position.longitude;
    });
  databaseReference
      .child('buyers')
      .child(currentUserId)
      .update({
        'lat': position.latitude,
        'long': position.longitude,
      })
      .then((v) {})
      .catchError((e) {
        print(e.toString());
      });
}
Buyer location updates are pushed to Firebase so drivers can see the delivery destination in real-time.

Performance Considerations

1

Location Filtering

Uses distanceFilter: 10 to only update when position changes by 10+ meters
2

Mounted Checks

Always checks if (mounted) before calling setState() to prevent memory leaks
3

Stream Disposal

Properly cancels position subscriptions in dispose() method

Next Steps

Delivery Management

Learn about delivery workflows and status updates

In-App Messaging

Chat with drivers during delivery

Build docs developers (and LLMs) love