Skip to main content

Overview

Trackmart uses Mapbox for displaying interactive maps, calculating routes between drivers and buyers, and providing real-time location tracking. This guide covers the complete Mapbox setup process.
You’ll need a Mapbox account and API tokens. Sign up at mapbox.com to get started.

Why Mapbox?

Mapbox provides powerful mapping capabilities for Trackmart:

Real-time Tracking

Track driver locations in real-time on interactive maps

Route Calculation

Calculate optimal driving routes with distance and ETA

Custom Styling

Customize map appearance with various styles

Offline Support

Cache map tiles for offline functionality

Dependencies

Trackmart uses the following packages for map functionality:
pubspec.yaml
dependencies:
  flutter_map: 0.7.0+2
  geolocator: 5.1.1+1
  flutter_polyline_points: 0.1.0
  http: ^0.12.0  # For Mapbox API calls

Step 1: Create Mapbox Account

1

Sign up for Mapbox

Go to mapbox.com and create a free account.
2

Navigate to Access Tokens

After signing in, go to your Account Dashboard and click on Tokens.
3

Create tokens

You’ll need two types of tokens:
  • Public token (starts with pk.): For client-side map display
  • Secret token (starts with sk.): For server-side API calls
Never commit your secret token to version control. Use environment variables or secure storage for production.

Step 2: Configure API Keys

Trackmart uses Mapbox in two places:

Public Token (Map Display)

Used for rendering map tiles in the Flutter app:
lib/map.dart
TileLayerOptions(
  urlTemplate: "https://api.tiles.mapbox.com/v4/"
      "{id}/{z}/{x}/{y}@2x.png?access_token={accessToken}",
  additionalOptions: {
    'accessToken': 'pk.YOUR_PUBLIC_TOKEN_HERE',
    'id': 'mapbox.streets',
  },
)

Secret Token (Directions API)

Used for calculating routes and ETAs:
lib/map.dart
var url = 'https://api.mapbox.com/directions/v5/mapbox/driving/'
    '${startLong},${startLat};${endLong},${endLat}'
    '?access_token=sk.YOUR_SECRET_TOKEN_HERE';
For development, you can hardcode tokens directly in the code (as shown above). Remember to replace them before committing.

Step 3: Update Map Configuration

Replace the placeholder tokens in your map implementation:
// Directions API - Line 70-71
var url = 'https://api.mapbox.com/directions/v5/mapbox/driving/'
    '${dlong},${dlat};${widget.ulong},${widget.ulat}'
    '?access_token=YOUR_SECRET_TOKEN_HERE';

// Map Tiles - Line 134-141
TileLayerOptions(
  urlTemplate: "https://api.tiles.mapbox.com/v4/"
      "{id}/{z}/{x}/{y}@2x.png?access_token={accessToken}",
  additionalOptions: {
    'accessToken': 'YOUR_PUBLIC_TOKEN_HERE',
    'id': 'mapbox.streets',
  },
)

Step 4: Understanding Map Styles

Mapbox offers various map styles. Trackmart uses mapbox.streets by default:

mapbox.streets

Standard street map with labels and points of interest

mapbox.light

Light-themed map, great for data visualization overlays

mapbox.dark

Dark-themed map for night mode

mapbox.satellite

Satellite imagery for detailed terrain view
To change the map style, update the id parameter:
additionalOptions: {
  'accessToken': 'pk.your_token_here',
  'id': 'mapbox.dark',  // Change this
}

Step 5: Route Calculation

Trackmart uses the Mapbox Directions API to calculate routes between drivers and buyers:

How It Works

1

Get coordinates

Fetch driver location from Firebase Realtime Database and buyer location from device GPS.
2

Call Directions API

Make an HTTP request to Mapbox Directions API with coordinates.
3

Decode polyline

Parse the response and decode the route geometry into map coordinates.
4

Display route

Render the polyline on the map with distance and ETA information.

Implementation

lib/map.dart
_updateLocation(Position position) {
  setState(() {
    dlat = position.latitude;
    dlong = position.longitude;
  });
  
  // Build Directions API URL
  var url = 'https://api.mapbox.com/directions/v5/mapbox/driving/'
      '${dlong},${dlat};${widget.ulong},${widget.ulat}'
      '?access_token=YOUR_SECRET_TOKEN_HERE';
  
  http.get(url).then((response) {
    route = json.decode(response.body)['routes'][0];
    
    // Decode polyline geometry
    var k = PolylinePoints().decodePolyline(route['geometry']);
    
    setState(() {
      points = List.generate(k.length, (i) {
        return LatLng(k[i].latitude, k[i].longitude);
      });
      
      // Extract distance and duration
      distance = '${(route['distance'] / 1000).toStringAsFixed(2)}km';
      duration = '${(route['duration'] / 60).toStringAsFixed(0)}min';
    });
  });
}
The Directions API returns distance in meters and duration in seconds. Trackmart converts these to kilometers and minutes for display.

Step 6: Real-time Driver Tracking

Trackmart listens to Firebase Realtime Database updates to track driver locations:
lib/map.dart
@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();
}

How It Works

  1. Driver app updates location → Firebase Realtime Database
  2. Database triggers listener → Buyer app receives update
  3. App calls Mapbox API → Gets new route
  4. Map updates → Shows current driver position and route
This creates a seamless real-time tracking experience for buyers watching their delivery.

Step 7: Map Features

Trackmart’s map implementation includes several key features:

Markers

Display driver and buyer locations:
lib/map.dart
MarkerLayerOptions(
  markers: [
    // Buyer marker
    Marker(
      width: 60.0,
      height: 60.0,
      point: LatLng(widget.ulat, widget.ulong),
      builder: (ctx) => Column(
        children: [
          Text('You', style: TextStyle(backgroundColor: Colors.white)),
          Icon(Icons.person_pin_circle, size: 30),
        ],
      ),
    ),
    // Driver marker
    Marker(
      width: 60.0,
      height: 60.0,
      point: LatLng(dlat, dlong),
      builder: (ctx) => Column(
        children: [
          Text(widget.driver, style: TextStyle(backgroundColor: Colors.white)),
          Icon(Icons.local_shipping, size: 30),
        ],
      ),
    ),
  ],
)

Polyline (Route)

Display the driving route:
lib/map.dart
PolylineLayerOptions(
  polylines: [
    Polyline(
      points: points,
      strokeWidth: 5.0,
      color: Theme.of(context).accentColor,
    )
  ],
)

ETA Calculation

Show estimated arrival time:
lib/map.dart
void _eta() {
  if (route != null) {
    showDialog(
      context: context,
      builder: (context) {
        return SimpleDialog(
          title: Text('ETA'),
          children: [
            Text(
              DateFormat('h:mm a').format(
                DateTime.now().add(
                  Duration(seconds: route['duration'].toInt())
                )
              ),
              style: TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.bold,
              ),
            ),
          ],
        );
      },
    );
  }
}

Step 8: Location Permissions

Ensure location permissions are configured:
Add to android/app/src/main/AndroidManifest.xml:
<manifest>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.INTERNET" />
</manifest>

Step 9: Test the Integration

1

Run the app

flutter run
2

Grant location permissions

Allow the app to access device location when prompted.
3

View map

Navigate to the map screen and verify:
  • Map tiles load correctly
  • Your location marker appears
  • Driver markers are visible (if available)
4

Test routing

Select a driver to see:
  • Route polyline between locations
  • Distance and duration display
  • ETA calculation

API Usage and Limits

Mapbox free tier includes:
  • Map loads: 50,000 free per month
  • Directions API: 100,000 free requests per month
Monitor your usage in the Mapbox Dashboard to avoid unexpected charges. Consider implementing request caching for production apps.

Troubleshooting

  • Verify your public token is correct and has the proper scopes
  • Check internet connectivity
  • Ensure the token hasn’t expired
  • Look for CORS errors in debug console
  • Verify your secret token is correct
  • Check that coordinates are in the correct format (longitude, latitude)
  • Ensure coordinates are valid geographic locations
  • Check Mapbox API status page for outages
  • Verify location permissions are granted
  • Check Firebase Realtime Database for driver location updates
  • Ensure GPS is enabled on the device
  • Test with a physical device (emulators have limited GPS)
  • Verify flutter_polyline_points package is installed
  • Check that route geometry is being decoded correctly
  • Ensure points array is not empty
  • Verify map bounds include the route coordinates

Advanced Features

Multiple Drivers Map

Trackmart includes a feature to show all available drivers:
lib/map.dart (MapPage2)
// Fetch all active drivers
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) {
        // Calculate route to each driver
        var url = 'https://api.mapbox.com/directions/v5/mapbox/driving/'
            '${values['long']},${values['lat']};${widget.ulong},${widget.ulat}'
            '?access_token=YOUR_SECRET_TOKEN_HERE';
        
        // Display marker and distance for each driver
      });
    }
  });

Custom Map Controls

Trackmart provides custom controls for better UX:
lib/map.dart
// Center on user location
IconButton(
  icon: Icon(Icons.my_location),
  onPressed: () {
    _mapController.move(
      LatLng(widget.ulat, widget.ulong),
      _mapController.zoom,
    );
  },
)

// Center on driver location
IconButton(
  icon: Icon(Icons.local_shipping),
  onPressed: () {
    _mapController.move(
      LatLng(dlat, dlong),
      _mapController.zoom,
    );
  },
)

Next Steps

Firebase Setup

Configure real-time location updates with Firebase

Push Notifications

Notify users of driver location updates

Build docs developers (and LLMs) love