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.
example/lib/main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:routo_maps_flutter/routo_maps_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Routo Maps Example',
home: MapScreen(),
);
}
}
class MapScreen extends StatefulWidget {
const MapScreen({super.key});
@override
State<MapScreen> createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
RoutoMapController? _controller;
final List<StreamSubscription<dynamic>> _subs = [];
static const _seoul = LatLng(37.5665, 126.9780);
static const _gangnam = LatLng(37.4979, 127.0276);
@override
void dispose() {
for (final s in _subs) {
s.cancel();
}
_controller?.dispose();
super.dispose();
}
void _onMapCreated(RoutoMapController controller) {
setState(() => _controller = controller);
_subs.addAll([
controller.onMapReady.listen((_) {
debugPrint('[Example] 지도 준비 완료');
}),
controller.onCameraChanged.listen((e) {
debugPrint('[Example] 카메라: (${e.lat}, ${e.lng}) 줌: ${e.zoom}');
}),
controller.onMapTapped.listen((e) {
debugPrint('[Example] 탭: (${e.lat}, ${e.lng})');
}),
]);
}
Future<void> _moveTo(LatLng target, {int zoom = 15}) async {
await _controller?.animateCamera(
CameraUpdate.newLatLngZoom(target, zoom.toDouble()),
duration: const Duration(milliseconds: 600),
);
}
Future<void> _showDistance() async {
final dist = _seoul.distanceTo(_gangnam);
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('서울 시청 ↔ 강남역: ${dist.toStringAsFixed(0)} m')),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Routo Maps Example')),
body: Stack(
children: [
// ── 지도 위젯 ─────────────────────────────────────────────
RoutoMapView(
initialCameraPosition: const CameraPosition(
target: _seoul,
zoom: 13,
),
showTraffic: true,
onMapCreated: _onMapCreated,
),
// ── 컨트롤 버튼 ───────────────────────────────────────────
Positioned(
right: 16,
bottom: 40,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_Fab(
icon: Icons.location_city,
tooltip: '서울 시청',
onTap: () => _moveTo(_seoul, zoom: 14),
),
const SizedBox(height: 8),
_Fab(
icon: Icons.train,
tooltip: '강남역',
onTap: () => _moveTo(_gangnam, zoom: 16),
),
const SizedBox(height: 8),
_Fab(
icon: Icons.add,
tooltip: '줌 인',
onTap: () => _controller?.zoomIn(),
),
const SizedBox(height: 8),
_Fab(
icon: Icons.remove,
tooltip: '줌 아웃',
onTap: () => _controller?.zoomOut(),
),
const SizedBox(height: 8),
_Fab(
icon: Icons.straighten,
tooltip: '거리 측정',
onTap: _showDistance,
),
],
),
),
],
),
);
}
}
class _Fab extends StatelessWidget {
const _Fab({required this.icon, required this.tooltip, required this.onTap});
final IconData icon;
final String tooltip;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
return FloatingActionButton.small(
tooltip: tooltip,
heroTag: tooltip,
onPressed: onTap,
child: Icon(icon),
);
}
}