Basic Map with Flutter and MapMetrics
This tutorial will show you how to create a basic interactive map using Flutter and MapMetrics Atlas API.
Basic Map Implementation
Here's a complete example of a basic map with common interactions:
dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';
class BasicMapScreen extends StatefulWidget {
@override
_BasicMapScreenState createState() => _BasicMapScreenState();
}
class _BasicMapScreenState extends State<BasicMapScreen> {
MapMetricsController? mapController;
LatLng? lastTappedLocation;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Basic MapMetrics Map'),
actions: [
IconButton(
icon: Icon(Icons.my_location),
onPressed: _goToUserLocation,
),
],
),
body: MapMetrics(
styleUrl: 'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
onMapCreated: (MapMetricsController controller) {
setState(() {
mapController = controller;
});
},
onMapClick: (Point point, LatLng coordinates) {
setState(() {
lastTappedLocation = coordinates;
});
_showLocationInfo(coordinates);
},
onStyleLoaded: () {
print('Map style loaded successfully!');
},
initialCameraPosition: CameraPosition(
target: LatLng(40.7128, -74.0060), // New York City
zoom: 10.0,
),
myLocationEnabled: true,
myLocationTrackingMode: MyLocationTrackingMode.Tracking,
myLocationRenderMode: MyLocationRenderMode.COMPASS,
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
heroTag: "zoomIn",
onPressed: _zoomIn,
child: Icon(Icons.add),
),
SizedBox(height: 8),
FloatingActionButton(
heroTag: "zoomOut",
onPressed: _zoomOut,
child: Icon(Icons.remove),
),
],
),
);
}
void _zoomIn() {
mapController?.animateCamera(
CameraUpdate.zoomIn(),
);
}
void _zoomOut() {
mapController?.animateCamera(
CameraUpdate.zoomOut(),
);
}
void _goToUserLocation() {
mapController?.animateCamera(
CameraUpdate.zoomTo(15.0),
);
}
void _showLocationInfo(LatLng coordinates) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Location Information'),
content: Text(
'Latitude: ${coordinates.latitude.toStringAsFixed(6)}\n'
'Longitude: ${coordinates.longitude.toStringAsFixed(6)}',
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('OK'),
),
],
);
},
);
}
}
Map Configuration Options
Camera Position
Control the initial view of your map:
dart
initialCameraPosition: CameraPosition(
target: LatLng(40.7128, -74.0060), // Center point
zoom: 10.0, // Zoom level (0-22)
bearing: 0.0, // Rotation in degrees
tilt: 0.0, // Tilt in degrees
),
User Location
Enable user location tracking:
dart
myLocationEnabled: true,
myLocationTrackingMode: MyLocationTrackingMode.Tracking,
myLocationRenderMode: MyLocationRenderMode.COMPASS,
Map Interactions
Handle various map events:
dart
onMapCreated: (MapMetricsController controller) {
// Called when map is created
},
onMapClick: (Point point, LatLng coordinates) {
// Called when user taps the map
},
onMapLongClick: (Point point, LatLng coordinates) {
// Called when user long-presses the map
},
onStyleLoaded: () {
// Called when map style is loaded
},
onCameraIdle: () {
// Called when camera stops moving
},
Camera Controls
Programmatic Camera Movement
dart
// Zoom to specific level
mapController?.animateCamera(CameraUpdate.zoomTo(15.0));
// Zoom in/out
mapController?.animateCamera(CameraUpdate.zoomIn());
mapController?.animateCamera(CameraUpdate.zoomOut());
// Move to specific location
mapController?.animateCamera(
CameraUpdate.newLatLng(LatLng(37.7749, -122.4194)),
);
// Move with zoom
mapController?.animateCamera(
CameraUpdate.newLatLngZoom(LatLng(37.7749, -122.4194), 15.0),
);
// Fit bounds
mapController?.animateCamera(
CameraUpdate.newLatLngBounds(
LatLngBounds(
southwest: LatLng(37.7, -122.5),
northeast: LatLng(37.8, -122.4),
),
50.0, // padding
),
);
Camera Position Listeners
dart
onCameraMove: (CameraPosition position) {
print('Camera moving: ${position.zoom}');
},
onCameraIdle: () {
print('Camera stopped moving');
},
Map State Management
Get Current Camera Position
dart
void _getCurrentPosition() async {
CameraPosition? position = await mapController?.getCameraPosition();
if (position != null) {
print('Current zoom: ${position.zoom}');
print('Current center: ${position.target}');
}
}
Check Map State
dart
void _checkMapState() async {
bool? isMapReady = await mapController?.isMapReady();
if (isMapReady == true) {
print('Map is ready for interactions');
}
}
Error Handling
Add error handling for better user experience:
dart
MapMetrics(
styleUrl: 'your_style_url',
onMapCreated: (controller) {
mapController = controller;
},
onMapClick: (point, coordinates) {
// Handle clicks
},
onError: (String error) {
print('Map error: $error');
// Show error message to user
},
onStyleLoaded: () {
print('Style loaded successfully');
},
)
Performance Tips
- Reuse Controller: Store the
MapMetricsController
in a variable to avoid recreating it - Debounce Events: Use debouncing for frequent events like
onCameraMove
- Lazy Loading: Load map data only when needed
- Memory Management: Dispose of controllers when not needed
dart
@override
void dispose() {
mapController?.dispose();
super.dispose();
}
Custom Map Controls
Create custom floating action buttons for map controls:
dart
Widget _buildMapControls() {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton.small(
heroTag: "zoomIn",
onPressed: () => mapController?.animateCamera(CameraUpdate.zoomIn()),
child: Icon(Icons.add),
),
SizedBox(height: 8),
FloatingActionButton.small(
heroTag: "zoomOut",
onPressed: () => mapController?.animateCamera(CameraUpdate.zoomOut()),
child: Icon(Icons.remove),
),
SizedBox(height: 8),
FloatingActionButton.small(
heroTag: "location",
onPressed: _goToUserLocation,
child: Icon(Icons.my_location),
),
],
);
}
Next Steps
Now that you have a basic map working, try:
Pro Tip: Use the MapMetrics Portal to create custom map styles that match your app's design. You can customize colors, fonts, and which map features are displayed.