v3.1.0flutter_polyline_points
좌표 또는 Google 인코딩된 폴리라인 문자열을 전달하여 폴리라인 점을 얻는 플러터 패키지
인코딩된 Google 폴리라인 문자열을 지도에 경로/폴리라인을 표시하는 데 적합한 지리 좌표 목록으로 디코드하는 플러터 플러그인
아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.
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 introduces a simplified and unified approach to Google's routing services:
PolylinePoints class for both APIsAdd this to your package's pubspec.yaml file:
dependencies:
flutter_polyline_points: ^3.0.1
Then run:
flutter pub get
Note: The Routes API may have different pricing than the Directions API. Check the Google Routes API documentation for details.
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();
}
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 ?? [];
}
// 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,
);
// 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');
}
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,
);
// 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(),
},
);
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)),
);
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
},
);
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.
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,
);
// Convert Routes API response to legacy format
RoutesApiResponse routesResponse = await polylinePoints.getRouteBetweenCoordinatesV2(
request: routesRequest,
);
PolylineResult legacyResult = polylinePoints.convertToLegacyResult(routesResponse);
// 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,
);
class PolylineResult {
List<PointLatLng> points;
String? errorMessage;
String? status;
}
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;
}
| 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 | ❌ | ✅ |
API Key Issues
Routes API Errors
Migration Issues
apiKey parameterconvertToLegacyResult() for compatibilitytry {
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');
}
Check out the /example folder for comprehensive examples:
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
This project is licensed under the MIT License - see the LICENSE file for details.
PolylinePoints classapiKey parameterRoutesApiRequest/RoutesApiResponseSee CHANGELOG.md for complete version history.