분류, 패키지 및 저장소 검색

flutter_polyline_points 표지
패키지 상세v3.1.0

flutter_polyline_points

좌표 또는 Google 인코딩된 폴리라인 문자열을 전달하여 폴리라인 점을 얻는 플러터 패키지

AndroidiOSmacOSWindowsLinux
30일 다운로드
7.5만
좋아요
662
Pub 점수
150

패키지 설치

flutter pub add flutter_polyline_points

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

지리 좌표 또는 Google 인코딩 폴리라인 문자열을 위도와 경도 점 목록으로 변환하는 플러터 패키지입니다. 라우팅 서비스에서 흔히 사용되는 복잡한 폴리라인 데이터를 디코드함으로써 지도에서 폴리라인을 다루는 과정을 단순화합니다. 플러터 애플리케이션 내 지도에 경로, 경로 또는 여행 트랙을 표시하는 데 이상적입니다. 이 패키지는 Android, iOS, macOS, Windows, Linux 등 여러 플랫폼을 지원하여 크로스플랫폼 일관성을 보장합니다.

사용 사례

  • 인코딩된 폴리라인에서 지도 경로 표시
  • 좌표 목록을 다각형으로 변환
  • 내비게이션 또는 추적 기능과의 통합
  • 지도에 사용자 정의 경로 렌더링
  • API에서 라우트 데이터 처리

주요 기능

  • Google 인코딩 폴리라인 디코딩을 지원합니다
  • 원시 좌표 배열 처리
  • 크로스 플랫폼 호환성
  • 경량이며 통합이 쉬움
  • 정확한 포인트 변환을 제공합니다

적합한 대상

  • 경로 계획이 있는 지도 기반 앱
  • 위치 추적 애플리케이션
  • 내비게이션 도구
  • 경로 시각화 기능
  • Google Maps API를 사용하는 개발자

고려 사항

  • 유효한 입력 데이터(좌표 또는 인코딩된 문자열)가 필요합니다
  • 지도 렌더링 자체를 처리하지 않음
  • 표시를 위해 외부 지도 위젯에 의존합니다
  • 잘못된 입력에 대한 내장된 오류 처리 없음
  • 다각형 점 추출만 가능

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

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.

🔗 Links

📈 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.

카테고리

의존성

의존성 목록 1 개

소스 저장소

이 패키지를 사용하는 프로젝트