Get Coordinates on Tap in Flutter
This tutorial shows how to get and display the latitude and longitude coordinates when the user taps on the map — the Flutter equivalent of getting mouse coordinates on web.
Prerequisites
Before you begin, ensure you have:
- Completed the Flutter Setup Guide
- A MapMetrics API key and style URL from the MapMetrics Portal
Basic Tap Coordinates
Display coordinates in a bar at the bottom of the screen:
dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';
class TapCoordinatesScreen extends StatefulWidget {
@override
_TapCoordinatesScreenState createState() => _TapCoordinatesScreenState();
}
class _TapCoordinatesScreenState extends State<TapCoordinatesScreen> {
MapMetricsController? mapController;
LatLng? tappedPosition;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Tap for Coordinates')),
body: Column(
children: [
Expanded(
child: MapMetrics(
styleUrl:
'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
onMapCreated: (MapMetricsController controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: LatLng(48.8566, 2.3522),
zoom: 5.0,
),
onMapClick: (Point point, LatLng coordinates) {
setState(() {
tappedPosition = coordinates;
});
},
),
),
// Coordinates bar
Container(
padding: EdgeInsets.all(16),
color: Colors.grey[900],
width: double.infinity,
child: Text(
tappedPosition != null
? 'Lat: ${tappedPosition!.latitude.toStringAsFixed(6)} '
'Lng: ${tappedPosition!.longitude.toStringAsFixed(6)}'
: 'Tap the map to get coordinates',
style: TextStyle(
color: Colors.white,
fontFamily: 'monospace',
fontSize: 14,
),
textAlign: TextAlign.center,
),
),
],
),
);
}
}Tap Coordinates with Marker
Place a marker at the tapped location and show coordinates:
dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mapmetrics/mapmetrics.dart';
class TapMarkerCoordinatesScreen extends StatefulWidget {
@override
_TapMarkerCoordinatesScreenState createState() =>
_TapMarkerCoordinatesScreenState();
}
class _TapMarkerCoordinatesScreenState
extends State<TapMarkerCoordinatesScreen> {
MapMetricsController? mapController;
LatLng? tappedPosition;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Tap Marker Coordinates')),
body: Stack(
children: [
MapMetrics(
styleUrl:
'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
onMapCreated: (MapMetricsController controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: LatLng(48.8566, 2.3522),
zoom: 10.0,
),
onMapClick: (Point point, LatLng coordinates) {
setState(() {
tappedPosition = coordinates;
});
},
markers: tappedPosition != null
? {
Marker(
markerId: MarkerId('tapped'),
position: tappedPosition!,
infoWindow: InfoWindow(
title: 'Tapped Location',
snippet:
'${tappedPosition!.latitude.toStringAsFixed(6)}, '
'${tappedPosition!.longitude.toStringAsFixed(6)}',
),
),
}
: {},
),
// Floating coordinate card
if (tappedPosition != null)
Positioned(
top: 16,
left: 16,
right: 16,
child: Card(
elevation: 4,
child: Padding(
padding: EdgeInsets.all(12),
child: Row(
children: [
Icon(Icons.location_on, color: Colors.blue),
SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Latitude: ${tappedPosition!.latitude.toStringAsFixed(6)}',
style: TextStyle(fontFamily: 'monospace'),
),
Text(
'Longitude: ${tappedPosition!.longitude.toStringAsFixed(6)}',
style: TextStyle(fontFamily: 'monospace'),
),
],
),
),
IconButton(
icon: Icon(Icons.copy, size: 20),
tooltip: 'Copy coordinates',
onPressed: () {
final text =
'${tappedPosition!.latitude.toStringAsFixed(6)}, '
'${tappedPosition!.longitude.toStringAsFixed(6)}';
Clipboard.setData(ClipboardData(text: text));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Coordinates copied!')),
);
},
),
],
),
),
),
),
],
),
);
}
}Track Camera Center Coordinates
Show the coordinates of the map center as the user pans:
dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';
class CameraCenterScreen extends StatefulWidget {
@override
_CameraCenterScreenState createState() => _CameraCenterScreenState();
}
class _CameraCenterScreenState extends State<CameraCenterScreen> {
MapMetricsController? mapController;
double centerLat = 48.8566;
double centerLng = 2.3522;
double currentZoom = 10.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Camera Center Tracker')),
body: Stack(
children: [
MapMetrics(
styleUrl:
'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
onMapCreated: (MapMetricsController controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: LatLng(48.8566, 2.3522),
zoom: 10.0,
),
onCameraMove: (CameraPosition position) {
setState(() {
centerLat = position.target.latitude;
centerLng = position.target.longitude;
currentZoom = position.zoom;
});
},
),
// Crosshair at center
Center(
child: Icon(Icons.add, color: Colors.red, size: 24),
),
// Info overlay
Positioned(
bottom: 16,
left: 16,
child: Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Center:',
style: TextStyle(color: Colors.white70, fontSize: 11),
),
Text(
'Lat: ${centerLat.toStringAsFixed(6)}',
style: TextStyle(
color: Colors.white,
fontFamily: 'monospace',
fontSize: 13,
),
),
Text(
'Lng: ${centerLng.toStringAsFixed(6)}',
style: TextStyle(
color: Colors.white,
fontFamily: 'monospace',
fontSize: 13,
),
),
Text(
'Zoom: ${currentZoom.toStringAsFixed(2)}',
style: TextStyle(
color: Colors.greenAccent,
fontFamily: 'monospace',
fontSize: 13,
),
),
],
),
),
),
],
),
);
}
}Map Events Reference
| Event | Callback | Description |
|---|---|---|
| Tap | onMapClick | User taps the map |
| Long press | onMapLongClick | User long-presses the map |
| Camera move | onCameraMove | Camera position changes |
| Camera idle | onCameraIdle | Camera stops moving |
Next Steps
- Locate the User — Show user's GPS position
- Draggable Marker — Drag a marker to get coordinates
- Measure Distances — Measure between tapped points
Tip: Use onCameraIdle instead of onCameraMove if you only need the final position after panning — this avoids excessive rebuilds during fast panning.