routo_maps_flutter 0.1.4
routo_maps_flutter: ^0.1.4 copied to clipboard
Official Flutter plugin for Routo Maps SDK. Embed high-performance native maps on Android and iOS with camera control, events, traffic, markers, and route lines.
routo Maps Flutter SDK #
routo Maps Flutter SDK는 routo의 공식 Flutter 플러그인으로, Android/iOS 네이티브 RoutoMapSDK를 Flutter 위젯으로 통합합니다.
웹 및 데스크톱은 지원하지 않습니다.
Supported API #
| Feature | Android | iOS |
|---|---|---|
| Map Widget | ✅ | ✅ |
| Camera position | ✅ | ✅ |
| Camera animations | ✅ | ✅ |
| Events | ✅ | ✅ |
| Map gestures | ✅ | ✅ |
| Map styles (Light / Dark / Custom) | ✅ | ✅ |
| User Location | ✅ | ✅ |
| Traffic layer | ✅ | ✅ |
| Scale bar | ✅ | ✅ |
| POI picking & filter | ✅ | ✅ |
| Incident layer | ✅ | ✅ |
| Parking layer | ✅ | ✅ |
| Markers | ✅ | ✅ |
| Marker clusters | ✅ | ✅ |
| Route lines | ✅ | ✅ |
| Dot / Pattern lines | ✅ | ✅ |
| Polygons | ✅ | ✅ |
| 2.5D layer | ✅ | ✅ |
| HillShade layer | ✅ | ✅ |
| HD Map layer | ✅ | ✅ |
| Snapshot | ✅ | ✅ |
| RoutoMapScope (InheritedWidget) | ✅ | ✅ |
| Style DSL | ❌ | ❌ |
| Expression DSL | ❌ | ❌ |
| View Annotations | ❌ | ❌ |
Requirements #
- iOS 15.1 or higher
- Android SDK 21 or higher
- Flutter 3.10.0 / Dart 3.0.0 or higher
Getting Started #
1. SDK 접근 권한 신청 #
SDK 사용을 위한 App Key 및 패키지 접근 토큰은 routo 개발팀에 요청하세요.
App Key는 Android / iOS 공통으로 사용하는 단일 인증 키입니다. Android는
AndroidManifest.xml, iOS는Info.plist에 각각 설정합니다.
2. pubspec.yaml #
dependencies:
routo_maps_flutter: ^0.1.4
flutter pub get
3. Android 설정 #
android/settings.gradle — JFrog Maven 저장소 추가 (네이티브 SDK 다운로드에 필수):
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
maven { url 'https://storage.flutter-io.cn/download.flutter.io' }
maven { url 'https://jitpack.io' }
maven {
url = uri("https://routo.jfrog.io/artifactory/routo-sdk")
credentials {
username = "" // 계정정보는 routo 개발팀에 문의 바랍니다.
password = "" // 계정정보는 routo 개발팀에 문의 바랍니다.
}
}
}
}
AndroidManifest.xml — 권한 및 App Key:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application>
<!-- App Key (iOS의 RoutoAccessToken과 동일한 키) -->
<meta-data
android:name="com.routo.mapsdk.appkey"
android:value="YOUR_ROUTO_APP_KEY" />
</application>
MainActivity.kt — FlutterFragmentActivity 상속 필수:
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.android.RenderMode
class MainActivity : FlutterFragmentActivity() {
override fun getRenderMode(): RenderMode = RenderMode.texture
}
4. iOS 설정 #
RoutoMapSDK SPM 패키지 추가 — Xcode에서 직접 추가합니다:
- Xcode에서
ios/Runner.xcworkspace열기 - File > Add Package Dependencies 선택
- 패키지 URL 입력:
https://github.com/hyundai-autoever-routo/routo-maps-ios.git - 계정 정보 입력 (routo 개발팀에 문의)
- Dependency Rule을
Exact Version으로 선택 후 배포 버전 입력 - Add Package 클릭하여 완료
Info.plist — App Key 및 위치 권한:
<!-- App Key (Android의 com.routo.mapsdk.appkey와 동일한 키) -->
<key>RoutoAccessToken</key>
<string>YOUR_ROUTO_APP_KEY</string>
<!-- 위치 권한 -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>지도 서비스 이용을 위해 위치 권한이 필요합니다.</string>
cd ios && pod install && cd ..
Add a map #
import 'package:routo_maps_flutter/routo_maps_flutter.dart';
class MapScreen extends StatefulWidget {
const MapScreen({super.key});
@override
State<MapScreen> createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
RoutoMapController? _controller;
@override
Widget build(BuildContext context) {
return Scaffold(
body: RoutoMapView(
initialCameraPosition: CameraPosition(
target: LatLng(37.5665, 126.9780),
zoom: 14,
),
onMapCreated: (controller) => _controller = controller,
onMapReady: () => print('지도 준비 완료'),
),
);
}
}
RoutoMapController #
RoutoMapController는 onMapCreated 콜백으로 전달됩니다.
하위 위젯에서 공유하려면 RoutoMapScope를 사용하세요:
RoutoMapScope(
controller: _controller!,
child: MyMapControls(),
)
// 하위 위젯에서
RoutoMapScope.of(context).setMapTraffic(true);
Camera and animations #
// 즉시 이동
await _controller?.moveCamera(37.4979, 127.0276, zoom: 15);
// 애니메이션 이동 (CameraUpdate 빌더)
await _controller?.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(target: LatLng(37.4979, 127.0276), zoom: 16, bearing: 90, tilt: 45),
),
duration: const Duration(milliseconds: 800),
);
// 줌 in / out
await _controller?.zoomIn();
await _controller?.zoomOut(duration: const Duration(milliseconds: 300));
// 현재 카메라 상태 조회
final camera = await _controller?.getCamera();
print('중심: ${camera?.target} 줌: ${camera?.zoom}');
// 범위에 맞추기
await _controller?.fitBounds(
LatLngBounds(southwest: LatLng(37.45, 126.90), northeast: LatLng(37.60, 127.10)),
padding: const EdgeInsets.all(60),
);
Events #
void _onMapCreated(RoutoMapController controller) {
controller.onCameraChanged.listen((e) {
print('중심: (${e.lat}, ${e.lng}) 줌: ${e.zoom}');
});
controller.onPoiPicked.listen((e) { // setPoiPickingEnabled(true) 필요
print('POI: ${e.name} (${e.lat}, ${e.lng})');
});
controller.onMapTapped.listen((e) => print('탭: (${e.lat}, ${e.lng})'));
controller.onMapLongTapped.listen((e) => print('롱탭: (${e.lat}, ${e.lng})'));
controller.onMarkerTapped.listen((e) => print('마커: ${e.id}'));
}
Map styles #
// 프리셋 스타일 변경
await _controller?.setStyle(RoutoMapStyle.basic); // Routo Light
await _controller?.setStyle(RoutoMapStyle.dark); // Routo Dark
await _controller?.setStyle(RoutoMapStyle.hybrid); // Routo Hybrid
await _controller?.setStyle(RoutoMapStyle.trafficDay); // Traffic Day
await _controller?.setStyle(RoutoMapStyle.trafficNight);// Traffic Night
await _controller?.setStyle(RoutoMapStyle.streets); // Mapbox Streets
// 커스텀 URL 지정
await _controller?.setMapStyle('https://example.com/custom-style.json');
// 초기 스타일 — 프리셋 (RoutoMapStyle enum 직접 사용)
RoutoMapView(mapStyle: RoutoMapStyle.dark, ...)
// 초기 스타일 — 커스텀 URL
RoutoMapView(mapStyleUri: 'https://example.com/custom-style.json', ...)
Map layers #
await _controller?.setMapTraffic(true); // 교통 레이어
await _controller?.setScaleBar(true); // 스케일바
await _controller?.setIncidentLayer(true); // 유고정보
await _controller?.setMap2_5DLayer(true); // 2.5D 건물
await _controller?.setHillShadeLayer(true); // HillShade 지형
Markers #
await _controller?.addMarker('marker_1', 37.5665, 126.9780);
await _controller?.addMarkerWithLabel('marker_2', 37.4979, 127.0276, label: '강남역');
await _controller?.removeMarker('marker_1');
User location #
await _controller?.setUserLocationEnabled(true);
await _controller?.startLocationTracking(mode: FollowUserMode.following);
_controller?.onLocationMapMoved.listen((_) {
setState(() => _isTracking = false);
});
Snapshot #
final imageBytes = await _controller?.snapshotMap(); // Uint8List (PNG)
LatLng utilities #
const seoul = LatLng(37.5665, 126.9780);
const gangnam = LatLng(37.4979, 127.0276);
final meters = seoul.distanceTo(gangnam); // ≈ 9,400 m
Platform docs #
© 2026 routo Inc. All rights reserved.