Geomap Package

A Flutter package for displaying geomaps with Google Maps and Flutter Map, supporting both mobile and web platforms with GetX state management.

Screenshots

Mobile View Web View

Features

  • πŸ—ΊοΈ Universal map widget that works on both mobile and web
  • πŸ”„ Support for both Google Maps and Flutter Map on all platforms
  • πŸ‘€ Role-based views: viewer (full features) and driver (simplified view)
  • πŸ“ Display markers, circles, polygons, and polylines
  • πŸ•’ Responsive Vertical Timeline with numbers and addresses (left-aligned)
  • πŸ“… Multi-day Tracking: Select and view history for specific days via a dropdown
  • πŸ“‘ Collapsible stop list for better map visibility
  • πŸ”— Close button callback for WebView integration
  • 🎨 Customizable font configuration
  • πŸ”§ Custom API base URLs for development and production

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  geomap_package: ^2.1.2

Then run:

flutter pub get

Quick Start

import 'package:geomap_package/geomap_package.dart';

// 1. Create configuration
final config = GeoMapConfig(
  apiKey: 'your_jwt_token_from_business_sharemap_live',
  mapType: GeoMapType.flutterMap, // or GeoMapType.googleMap
  environment: Environment.production,
  role: GeoMapRole.viewer,
);

// 2. Create controller
final controller = GeoMapController(config: config);

// 3. Use the widget
GeoMapPublic(
  controller: controller,
  geoMapCode: 'your_geomap_code',
  showCloseButton: true,
  onClosePressed: () {
    print('Close button pressed');
  },
)

Platform Configuration

No configuration needed! FlutterMap uses OpenStreetMap tiles which are free and don't require any API keys.

final config = GeoMapConfig(
  apiKey: 'your_jwt_token',
  mapType: GeoMapType.flutterMap, // βœ… No extra setup needed
);

Google Maps

If you choose GeoMapType.googleMap, you must configure Google Maps SDK for each platform:

Android

Add to android/app/src/main/AndroidManifest.xml:

<manifest ...>
  <application ...>
    <meta-data 
      android:name="com.google.android.geo.API_KEY"
      android:value="YOUR_GOOGLE_MAPS_API_KEY"/>
  </application>
</manifest>

iOS

Add to ios/Runner/AppDelegate.swift:

import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("YOUR_GOOGLE_MAPS_API_KEY")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Web

Add to web/index.html before the closing </head> tag:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY"></script>

πŸ“– For complete setup instructions, see google_maps_flutter documentation.


Web Testing

⚠️ Important: Use port 8080 for local web testing to work properly with ShareMap API.

# Run on Chrome with port 8080
flutter run -d chrome --web-port=8080

# For HTTPS testing (required for geolocation)
ngrok http 8080

FlutterMap vs GoogleMap

Feature FlutterMap GoogleMap
Cost βœ… Free (OpenStreetMap) πŸ’° Requires Google billing
Setup Required βœ… None βš™οΈ Must configure per platform
API Key Required βœ… No πŸ”‘ Yes
Web Support βœ… Full βœ… Full
Mobile Support βœ… Full βœ… Full
Tile Provider OpenStreetMap Google Maps

πŸ’‘ Recommendation: Use GeoMapType.flutterMap for quick setup. Use GeoMapType.googleMap only if you specifically need Google Maps features.


Configuration Reference

GeoMapConfig

Field Type Required Default Description
apiKey String βœ… - JWT token from business.sharemap.live. Required - stores geomap permissions, driver IDs, and date ranges (startTime/endTime in ms).
routeServiceKey String? ❌ null API key for route drawing. Used to render polylines on map.
mapType GeoMapType βœ… - GeoMapType.flutterMap (free) or GeoMapType.googleMap (requires setup)
environment Environment ❌ production Environment.production or Environment.development
role GeoMapRole ❌ viewer GeoMapRole.viewer (full UI) or GeoMapRole.driver (minimal UI)
fontConfig FontConfig ❌ default Custom font family and sizes
devApiUrl String? ❌ null Override development API base URL
prodApiUrl String? ❌ null Override production API base URL
showLogs bool ❌ false Enable/disable internal package logging (Recommended to disable in production)

GeoMapPublic Widget

Field Type Required Default Description
controller GeoMapController βœ… - Controller created with GeoMapConfig
geoMapCode String βœ… - GeoMap code from business.sharemap.live β†’ GeoMap β†’ Select GeoMap β†’ Copy code
onMapCreated VoidCallback? ❌ null Callback when map is initialized
myLocationEnabled bool ❌ true Show user's current location marker
zoomControlsEnabled bool ❌ false Show zoom +/- buttons
myLocationButtonEnabled bool ❌ true Show button to center on user location
compassEnabled bool ❌ false Show compass indicator
mapToolbarEnabled bool ❌ false Show map toolbar
showCloseButton bool ❌ false Show close button (for WebView/iframe)
onClosePressed VoidCallback? ❌ null Callback when close button pressed
onReloadPressed VoidCallback? ❌ null Callback when reload button pressed
onToggleSheetPressed Function(bool)? ❌ null Callback when info panel expanded/collapsed
onStopItemPressed Function(dynamic)? ❌ null Callback when user taps a stop
onCopyPressed Function(String)? ❌ null Callback when copy link button pressed
infoCardModel GeomapInfoCardModel? ❌ null Optional model to override fields in GeoMapInfoCard
driverInfoCardModel GeomapDriverInfoCardModel? ❌ null Optional model to override fields in GeoMapDriverInfoCard

FontConfig

Field Type Default Description
mobileFontFamily String 'RobotoRegular' Font family for mobile
webFontFamily String 'PoppinsRegular' Font family for web
titleFontSize double 18.0 Title text size
subtitleFontSize double 16.0 Subtitle text size
bodyFontSize double 14.0 Body text size
boldFontWeight FontWeight FontWeight.bold Bold text weight
regularFontWeight FontWeight FontWeight.normal Regular text weight

Custom Card Overrides

Pass these models to GeoMapPublic to override or add information to the UI cards.

GeomapInfoCardModel

Used to customize the general geomap details card.

Field Description
title Override card title (default: "BαΊ£n Δ‘α»“")
mapName Override geomap name text
mapCode Override geomap code text
dateDisplay Override formatted date string
description New: Display additional description text below the name
mapNameLabel Custom label for name field (default: "TΓͺn bαΊ£n Δ‘α»“")
mapCodeLabel Custom label for code field (default: "MΓ£ bαΊ£n Δ‘α»“")
dateDisplayLabel Custom label for date field (default: "NgΓ y")
descriptionLabel Custom label for description field

GeomapDriverInfoCardModel

Used to customize the driver/participant information card.

Field Description
title Override card title (default: "Người tham gia")
driverName Override the resolved driver name
plate Override the vehicle plate display
phone Override the driver phone number
avatarUrl Override the avatar image URL
description New: Display extra context or status below driver info

Technical Details

JWT Token Data Range

The package now supports accurate date ranges via JWT token fields:

  • startTime: Milliseconds since epoch for the start of tracking.
  • endTime: Milliseconds since epoch for the end of tracking.
  • date: (Legacy) Milliseconds since epoch. If startTime/endTime are missing, the package derives the 24h range from date.

UI Component State

  • Auto-Refresh: Mobile viewer mode automatically refreshes driver data every 5 minutes if automaticRunTime is not specified in the dataset.
  • Z-Index Display: Fixed layering where InfoWindows > Markers > Routes > Polygons.

Role-Based Views

Viewer Mode (default)

  • Full access to all UI components
  • Driver info card with location history
  • Auto-refresh timer for real-time updates
  • Check-in markers displayed

Driver Mode

  • Simplified view for drivers
  • Only shows route and stops
  • No driver history or auto-refresh
  • Filtered data to show only current driver
// Viewer mode (default)
final config = GeoMapConfig(
  apiKey: 'token',
  mapType: GeoMapType.flutterMap,
  role: GeoMapRole.viewer,
);

// Driver mode
final config = GeoMapConfig(
  apiKey: 'token',
  mapType: GeoMapType.flutterMap,
  role: GeoMapRole.driver,
);

Controller Methods

Data Loading

// Load all data for a geomap
await controller.getAllData('geomap_code');

// Refresh current data (force reload)
await controller.getAllData('geomap_code', force: true);

UI Control

// Toggle expandable sheet
controller.toggleSheet();

// Toggle collapsed timeline (left side)
controller.toggleTimeline();

// Select a specific day (for Multi-day tracking)
// day: DateTime object from controller.availableDays
await controller.selectDay(day, 'geomap_code');

// Expand/collapse sheet programmatically
controller.expandSheet();
controller.collapseSheet();

// Move camera to specific location
controller.moveCameraTo(lat: 10.762622, lng: 106.660172, zoomLevel: 15);

Accessing Data

// Map info
final mapDetail = controller.mapGeoDetail;
final stopList = controller.publicGeofencingList;
final publicUrl = controller.getPublicGeoMapUrl('geomap_code');

// Loading state
final isLoading = controller.isLoadingData;
final isReady = controller.isMapReady;

Permissions

Android

Add to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

iOS

Add to ios/Runner/Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs location access to show your position on the map</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs location access to track your position</string>

Marker Layering (Z-Index)

To ensure consistent overlapping of elements, the package follows a standardized Z-index layering (primarily for Google Maps):

Layer Z-Index Description
Polygons 0.0 Geofencing boundaries and circles
Center Markers 1.0 Central points of geofences
Tracing Routes 2.0 Vehicle/Driver path polylines
Tracing Dots 3.0 Historical location points
Avatars 5.0 Driver/User avatar markers
Info Windows 8.0 Popups and selection info

WebView Integration

When embedding this package in a WebView, use the close button callback to communicate with the host application:

GeoMapPublic(
  controller: controller,
  geoMapCode: 'CODE',
  showCloseButton: true,
  onClosePressed: () {
    // Option 1: JavaScript Channel (Mobile WebView)
    // js.context.callMethod('postMessage', ['GEOMAP_CLOSE']);
    
    // Option 2: URL Scheme
    // launchUrl(Uri.parse('sharemap://close'));
    
    // Option 3: Parent Frame Message (iframe)
    // html.window.parent?.postMessage('GEOMAP_CLOSE', '*');
  },
)

Custom API URLs

Override default API endpoints for different environments:

final config = GeoMapConfig(
  apiKey: 'token',
  mapType: GeoMapType.flutterMap,
  environment: Environment.development,
  devApiUrl: 'https://my-dev-api.com',
  prodApiUrl: 'https://my-prod-api.com',
);

License

MIT

Libraries

geomap_package