map_flutter πŸ—ΊοΈ

pub.flutter-io.cn MIT License Platform Flutter Buy Me a Coffee

A complete, ready-to-use Flutter map package for ride-hailing, delivery, and location-based apps.
Supports both Google Maps and OpenStreetMap (OSM) out of the box.


✨ Features

Feature Description
πŸ—ΊοΈ Dual Provider Switch between Google Maps and OpenStreetMap (Nominatim + OpenRouteService)
πŸš— Trip Mode Full trip flow: pickup, dropoff, waypoints, real-time routing & polylines
πŸ“ Details Mode Display a list of map items with dynamic filtering and info windows
🚦 Live Status Driver tracking, request status updates (searching, assigned, in-progress)
🧩 Ready-made UI MapWidget + DraggableWidget with a customizable sliding bottom sheet
🏷️ Custom Markers Load markers from URLs with custom info windows and legends
πŸ“¦ Delivery Support Built-in delivery package info model for courier apps
πŸ‘₯ Book for others Book a ride for someone else, with contact info capture
βš™οΈ Configurable Set your own OSM User-Agent, button colors, texts, and behavior
πŸ’‰ State via Riverpod Clean, reactive state management with flutter_riverpod

πŸ“¦ Installation

Add this to your pubspec.yaml:

dependencies:
  map_flutter: ^0.0.1

Then run:

flutter pub get

πŸ› οΈ Platform Setup

Android

Add your Google Maps API key in 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>

Also add the INTERNET permission if not already present:

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

iOS

In 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)
  }
}

In ios/Runner/Info.plist, add location usage description keys:

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

πŸš€ Quick Start

Wrap your app in a ProviderScope (required by Riverpod):

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

Mode Trip (Ride-hailing / Delivery)

import 'package:map_flutter/map_flutter.dart';

Stack(
  children: [
    // 1. The map layer
    Positioned.fill(
      child: MapWidget(
        apiKey: 'YOUR_OPENROUTESERVICE_API_KEY',
        userAgent: 'MyApp/1.0 (contact@myapp.com)', // Required for OSM (Nominatim policy)
        mapApiProvider: MapApiProvider.openStreetMap,
        mapTypeProvider: MapTypeProvider.trip,
        mapRequestType: MapRequestType.transport,
        showInfoWindowButtonWidget: false,
        onFetchMapMarkers: () async {
          // Return dynamic markers (e.g. nearby drivers)
          return [];
        },
      ),
    ),

    // 2. The interactive bottom sheet
    DraggableWidget(
      pickHintText: 'Pickup location',
      dropHintText: 'Dropoff location',
      confirmAddressButtonText: 'Confirm',
      orderRideButtonText: 'Book Ride',
      buttonColor: Colors.black,
      textColor: Colors.white,
      onFetchVehicles: (pickup, waypoints, routeInfo, pkg, dropoff) async {
        // Call your API and return available vehicle types
        return [
          MapVehicleModel(name: 'Sedan', price: 2000, seats: 4),
          MapVehicleModel(name: 'Moto', price: 1000, seats: 1),
        ];
      },
      onGetVehicleSelectedToCreateRide: (vehicle, pickup, waypoints, routeInfo, someoneElse, pkg, dropoff) async {
        // Send booking request to your backend
        return true; // true = success
      },
    ),
  ],
)

Mode Details (Points of Interest / Store locator)

Stack(
  children: [
    Positioned.fill(
      child: MapWidget(
        apiKey: 'YOUR_KEY',
        userAgent: 'MyApp/1.0 (contact@myapp.com)',
        mapApiProvider: MapApiProvider.openStreetMap,
        mapTypeProvider: MapTypeProvider.details, // <-- Details mode
        mapRequestType: MapRequestType.transport,
        showInfoWindowButtonWidget: false,
      ),
    ),
    DraggableWidget(
      mapItems: [
        MapItemModel(
          name: 'Central Pharmacy',
          type: 'pharmacy',
          location: LatLng(6.1725, 1.2313),
          imageUrl: 'https://...',
          description: 'Open 24/7',
          rating: 4.5,
        ),
      ],
      onViewItem: (item) {
        // Navigate to item detail page
      },
      searchHintText: 'Search...',
      onViewItemText: 'View',
    ),
  ],
)

βš™οΈ Custom User-Agent for OSM

Nominatim's usage policy requires all apps to identify themselves with a unique User-Agent. Simply pass it when using MapApiProvider.openStreetMap:

MapWidget(
  userAgent: 'MyAwesomeApp/2.0 (contact@myapp.com)',
  mapApiProvider: MapApiProvider.openStreetMap,
  // ...
)

πŸ”Œ Access the Controller

Use ref.read(mapDataControllerProvider.notifier) anywhere in your widget tree to control the map programmatically:

final controller = ref.read(mapDataControllerProvider.notifier);

// Set a fixed pickup location
controller.setPickUpAddress(MapAddressListModel(
  id: '1',
  type: 'pick',
  address: '46 Avenue de la Paix, LomΓ©',
  latLng: LatLng(6.1319, 1.2228),
));

// Draw the route
controller.setPolylines('route', Colors.blue, 5);

// Get current state
final mapState = ref.watch(mapDataControllerProvider);
print(mapState.trip.mapRouteInfo?.distance); // Distance in meters

πŸ“‹ Key Models

Model Description
MapAddressListModel A location with address string and coordinates
MapVehicleModel A vehicle type with name, price, image, and seats
MapMarkerModel A custom map marker loaded from a URL
MapItemModel A point of interest for Details mode
MapRouteInfoModel Route summary with distance (m) and duration (s)
MapTripStatusModel Live trip status with driver, user, pickup/dropoff locations
MapDeliveryPackageModel Package details for delivery requests
MapTripForSomeoneElseModel Contact info when booking for another person

πŸ’Ό Support & Custom Services

If this package saved you hours of development, consider supporting its growth:

Need custom help? I offer:

  • πŸ”§ Integration consulting β€” custom integration into your existing project
  • πŸ“± Full app source code β€” purchase the source code of FixItNow, a complete service app built on this package
  • ⭐ Priority support β€” get bugs fixed faster for your use case

πŸ“§ Contact: mendoofficiel13@gmail.com


πŸ“„ License

This project is licensed under the MIT License β€” see the LICENSE file for details.


Made with ❀️ from Togo πŸ‡ΉπŸ‡¬

Libraries

map_flutter