flutter_polyline_points 3.0.1 copy "flutter_polyline_points: ^3.0.1" to clipboard
flutter_polyline_points: ^3.0.1 copied to clipboard

A flutter package to get polyline points by either passing the coordinates or google encoded polyline string

Flutter Polyline Points #

pub package License: MIT

A Flutter package for decoding polyline points from Google Maps Directions API and the new Google Routes API. This package provides a unified interface supporting both legacy Directions API and the enhanced Google Routes API.

๐Ÿš€ Version 3.0 - Simplified Routes API Integration #

Version 3.0 introduces a simplified and unified approach to Google's routing services:

  • Single PolylinePoints class for both APIs
  • Simplified Routes API integration with essential features
  • Enhanced request/response models with better type safety
  • Custom body parameters for advanced use cases
  • Comprehensive test coverage for reliability
  • Backward compatibility maintained for existing code

๐Ÿ“ฆ Installation #

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

dependencies:
  flutter_polyline_points: ^3.0.1

Then run:

flutter pub get

๐Ÿ”‘ API Key Setup #

  1. Go to the Google Cloud Console
  2. Enable the Directions API and/or Routes API
  3. Create an API key
  4. Configure API key restrictions as needed

Note: The Routes API may have different pricing than the Directions API. Check the Google Routes API documentation for details.

๐Ÿ“ฑ Basic Usage #

Legacy Directions API (Backward Compatibility) #

import 'package:flutter_polyline_points/flutter_polyline_points.dart';

// Initialize PolylinePoints
PolylinePoints polylinePoints = PolylinePoints(apiKey: "YOUR_API_KEY");

// Get route using legacy Directions API
PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
  request: PolylineRequest(
    origin: PointLatLng(37.7749, -122.4194), // San Francisco
    destination: PointLatLng(37.3382, -121.8863), // San Jose
    mode: TravelMode.driving,
  ),
);

if (result.points.isNotEmpty) {
  // Convert to LatLng for Google Maps
  List<LatLng> polylineCoordinates = result.points
      .map((point) => LatLng(point.latitude, point.longitude))
      .toList();
}

Routes API (Enhanced Features) #

import 'package:flutter_polyline_points/flutter_polyline_points.dart';

// Initialize PolylinePoints
PolylinePoints polylinePoints = PolylinePoints(apiKey: "YOUR_API_KEY");

// Create Routes API request
RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  travelMode: TravelMode.driving,
  routingPreference: RoutingPreference.trafficAware,
);

// Get route using Routes API
RoutesApiResponse response = await polylinePoints.getRouteBetweenCoordinatesV2(
  request: request,
);

if (response.routes.isNotEmpty) {
  Route route = response.routes.first;
  
  // Access route information
  print('Duration: ${route.durationMinutes} minutes');
  print('Distance: ${route.distanceKm} km');
  
  // Get polyline points
  List<PointLatLng> points = route.polylinePoints ?? [];
}

๐Ÿ๏ธ Two-Wheeler Routing #

// Get optimized route for motorcycles/scooters
RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  travelMode: TravelMode.twoWheeler,
  routeModifiers: RouteModifiers(
    avoidHighways: true,
    avoidTolls: false,
  ),
);

RoutesApiResponse response = await polylinePoints.getRouteBetweenCoordinatesV2(
  request: request,
);

๐Ÿ›ฃ๏ธ Alternative Routes #

// Get multiple route options
RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  computeAlternativeRoutes: true,
  intermediates: [
    PolylineWayPoint(location: "37.4419,-122.1430"), // Palo Alto coordinates
  ],
);

RoutesApiResponse response = await polylinePoints.getRouteBetweenCoordinatesV2(
  request: request,
);

// Access all alternative routes
for (int i = 0; i < response.routes.length; i++) {
  Route route = response.routes[i];
  print('Route ${i + 1}: ${route.durationMinutes} min, ${route.distanceKm} km');
}

โš™๏ธ Advanced Configuration #

Route Modifiers #

RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  travelMode: TravelMode.driving,
  routeModifiers: RouteModifiers(
    avoidTolls: true,
    avoidHighways: false,
    avoidFerries: true,
    avoidIndoor: false,
  ),
  routingPreference: RoutingPreference.trafficAware,
  units: Units.metric,
  polylineQuality: PolylineQuality.highQuality,
);

RoutesApiResponse response = await polylinePoints.getRouteBetweenCoordinatesV2(
  request: request,
);

Custom Body Parameters #

// Add custom parameters not covered by the standard API
RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  customBodyParameters: {
    'extraComputations': ['TRAFFIC_ON_POLYLINE'],
    'requestedReferenceTime': DateTime.now().toIso8601String(),
  },
);

Timing Preferences #

RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  travelMode: TravelMode.driving,
  routingPreference: RoutingPreference.trafficAware,
  departureTime: DateTime.now().add(Duration(hours: 1)),
  // OR
  // arrivalTime: DateTime.now().add(Duration(hours: 2)),
);

Custom Headers #

You can pass custom HTTP headers with your Routes API requests. This is particularly useful for Android-restricted API keys:

RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  travelMode: TravelMode.driving,
  headers: {
    'X-Android-Package': 'com.example.myapp',
    'X-Android-Cert': 'YOUR_SHA1_FINGERPRINT',
    // Add any other custom headers
  },
);

Using with google_api_headers Package

For easier Android header management, you can use the google_api_headers package:

dependencies:
  flutter_polyline_points: ^3.0.0
  google_api_headers: ^4.0.0
import 'package:google_api_headers/google_api_headers.dart';

// Get Android-specific headers
Map<String, String> headers = await const GoogleApiHeaders().getHeaders();

RoutesApiRequest request = RoutesApiRequest(
  origin: PointLatLng(37.7749, -122.4194),
  destination: PointLatLng(37.3382, -121.8863),
  travelMode: TravelMode.driving,
  headers: headers, // Use the generated headers
);

RoutesApiResponse response = await polylinePoints.getRouteBetweenCoordinatesV2(
  request: request,
);

Note: Custom headers are only supported with the Routes API (getRouteBetweenCoordinatesV2). The legacy Directions API uses GET requests and doesn't support custom headers.

๐Ÿ”„ Migration Guide #

From v2.x to v3.0 #

Version 3.0 simplifies the API while maintaining backward compatibility:

// OLD (v2.x)
PolylinePoints polylinePoints = PolylinePoints();
PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
  googleApiKey: "YOUR_API_KEY",
  request: request,
);

// NEW (v3.0)
PolylinePoints polylinePoints = PolylinePoints(apiKey: "YOUR_API_KEY");
PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
  request: request,
);

Converting Between APIs #

// Convert Routes API response to legacy format
RoutesApiResponse routesResponse = await polylinePoints.getRouteBetweenCoordinatesV2(
  request: routesRequest,
);

PolylineResult legacyResult = polylinePoints.convertToLegacyResult(routesResponse);

Factory Constructors #

// Optimized for legacy API
PolylinePoints legacyPoints = PolylinePoints.legacy("YOUR_API_KEY");

// Optimized for Routes API
PolylinePoints enhancedPoints = PolylinePoints.enhanced("YOUR_API_KEY");

// Custom configuration
PolylinePoints customPoints = PolylinePoints.custom(
  apiKey: "YOUR_API_KEY",
  timeout: Duration(seconds: 60),
  preferRoutesApi: true,
);

๐Ÿ“Š Response Data #

Legacy API Response #

class PolylineResult {
  List<PointLatLng> points;
  String? errorMessage;
  String? status;
}

Routes API Response #

class RoutesApiResponse {
  List<Route> routes;
  String? status;
  String? errorMessage;
}

class Route {
  int? duration;              // Duration in seconds
  int? staticDuration;        // Static duration in seconds
  int? distanceMeters;        // Distance in meters
  String? polylineEncoded;    // Encoded polyline string
  List<PointLatLng>? polylinePoints; // Decoded polyline points
  
  // Convenience getters
  double? get durationMinutes => duration != null ? duration! / 60.0 : null;
  double? get staticDurationMinutes => staticDuration != null ? staticDuration! / 60.0 : null;
  double? get distanceKm => distanceMeters != null ? distanceMeters! / 1000.0 : null;
}

๐ŸŽฏ Features Comparison #

Feature Legacy Directions API Routes API
Basic routing โœ… โœ…
Waypoints โœ… โœ…
Travel modes Driving, Walking, Bicycling, Transit + Two-Wheeler
Alternative routes โœ… โœ…
Route modifiers Basic Enhanced
Polyline quality Standard High-quality, Overview
Request format GET with query params POST with JSON
Custom parameters โŒ โœ…
Timing preferences โŒ โœ…
Field mask support โŒ โœ…

๐Ÿ”ง Troubleshooting #

Common Issues #

  1. API Key Issues

    • Ensure your API key has the correct APIs enabled
    • Check API key restrictions and quotas
    • Verify billing is enabled for your Google Cloud project
  2. Routes API Errors

  3. Migration Issues

    • Update constructor calls to include apiKey parameter
    • Use convertToLegacyResult() for compatibility
    • Check method signatures for parameter changes

Error Handling #

try {
  RoutesApiResponse response = await polylinePoints.getRouteBetweenCoordinatesV2(
    request: RoutesApiRequest(
      origin: PointLatLng(37.7749, -122.4194),
      destination: PointLatLng(37.3382, -121.8863),
    ),
  );
  
  if (response.routes.isNotEmpty) {
    // Success
    Route route = response.routes.first;
  } else {
    print('Error: ${response.errorMessage ?? "No routes found"}');
  }
} catch (e) {
  print('Exception: $e');
}

๐Ÿ“š Examples #

Check out the /example folder for comprehensive examples:

  • Legacy API Example: Basic routing with backward compatibility
  • Routes API Example: Enhanced features and custom parameters
  • Two-Wheeler Example: Motorcycle/scooter optimized routing
  • Advanced Configuration: Custom body parameters and timing preferences

๐Ÿค Contributing #

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

๐Ÿ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ“ˆ Changelog #

Version 3.0.0 #

  • ๐Ÿ”„ BREAKING: Simplified API with unified PolylinePoints class
  • ๐Ÿ”„ BREAKING: Constructor now requires apiKey parameter
  • โœจ Enhanced Routes API integration with RoutesApiRequest/RoutesApiResponse
  • ๐Ÿ› ๏ธ Added custom body parameters support
  • ๐Ÿ๏ธ Added two-wheeler routing mode
  • โฐ Added timing preferences (departure/arrival time)
  • ๐ŸŽฏ Added field mask support for response optimization
  • ๐Ÿงช Comprehensive test coverage added
  • ๐Ÿ“Š Improved response models with convenience getters
  • ๐Ÿ”ง Better error handling and type safety
  • ๐Ÿ› ๏ธ Maintained backward compatibility for legacy API

Previous Versions #

See CHANGELOG.md for complete version history.

637
likes
150
points
61.3k
downloads

Publisher

verified publishercraftme.dev

Weekly Downloads

A flutter package to get polyline points by either passing the coordinates or google encoded polyline string

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter, http

More

Packages that depend on flutter_polyline_points