flutter_3d_map
A high-performance, cross-platform Flutter plugin for embedding photorealistic 3D maps on Android (powered by Google Maps 3D Jetpack Compose SDK) and iOS (powered by Apple MapKit 3D Elevation & Flyover).
Screenshots
| Android (Google Maps 3D) | iOS (Apple MapKit 3D Elevation) |
|---|---|
![]() |
![]() |
Features
- 🏙️ Photorealistic 3D Map View: Full 3D terrain elevation, 3D photorealistic buildings, and camera control across altitude, tilt, heading, and range.
- 📍 Custom Remote Image Markers: Render markers with custom remote image URLs, circular clipping radius, custom sizes, title, snippet, and tap callbacks.
- 📹 Continuous Camera Movement Listener: Receive real-time
onCameraMovecallbacks delivering continuous(lat, lng, range, heading, tilt)during live drag, pan, pinch, zoom, and rotation gestures on both Android and iOS. - ✈️ Smooth
flyToCamera Animations: Animate the camera smoothly to any latitude, longitude, altitude, heading, tilt, and range with custom animation durations. - 🎨 Dynamic Map Modes: Easily switch between Hybrid, Satellite, and Roadmap modes at runtime.
- 🔄 2D / 3D Perspective Toggle: Instantly toggle between 2D top-down view (0° tilt) and 3D photorealistic perspective (60° tilt).
- 🔍 Geocoding & Landmark Search: Search for predefined global landmarks (e.g., Eiffel Tower, Taj Mahal, Burj Khalifa) or reverse-geocode location queries via
searchLocation.
Platform Setup
Android Setup
- Ensure your
android/app/build.gradlehasminSdkVersionset to 21 or higher. - Obtain a Google Maps API Key from the Google Cloud Console with Google Maps 3D / Maps SDK enabled.
- Add your API Key inside
android/app/src/main/AndroidManifest.xmlunder<application>:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_GOOGLE_MAPS_API_KEY_HERE" />
</application>
</manifest>
iOS Setup
- Ensure your
ios/Podfilesets platform deployment target to iOS 13.0 or higher:
platform :ios, '13.0'
- Apple MapKit is natively built into iOS — no extra API key is required for iOS!
Getting Started
Add flutter_3d_map to your pubspec.yaml:
dependencies:
flutter_3d_map: ^0.0.1
Run flutter pub get in your terminal.
Basic Usage Example
import 'package:flutter/material.dart';
import 'package:flutter_3d_map/flutter_3d_map.dart';
void main() {
runApp(const MaterialApp(
home: Map3DScreen(),
debugShowCheckedModeBanner: false,
));
}
class Map3DScreen extends StatefulWidget {
const Map3DScreen({super.key});
@override
State<Map3DScreen> createState() => _Map3DScreenState();
}
class _Map3DScreenState extends State<Map3DScreen> {
ThreeDMapController? _mapController;
final List<MapMarker> _markers = [
MapMarker(
id: 'profile_1',
latitude: 38.5540,
longitude: -107.6804,
altitude: 2450.0,
title: 'Alice Johnson',
snippet: 'Travel Blogger',
imageUrl: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=150',
imageSize: 60,
imageRadius: 30,
color: Colors.pinkAccent,
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('3D Map View'),
backgroundColor: Colors.indigo,
),
body: ThreeDMapViewWidget(
initialLat: 38.544012,
initialLng: -107.670428,
initialAlt: 2427.6,
heading: 310.0,
tilt: 63.0,
range: 8266.0,
mapMode: Map3DMode.hybrid,
markers: _markers,
onMapCreated: (controller) {
_mapController = controller;
},
onCameraMove: (lat, lng, range, heading, tilt) {
debugPrint('Camera position: ($lat, $lng) range: $range, tilt: $tilt, heading: $heading');
},
onMarkerTap: (marker) {
debugPrint('Tapped marker: ${marker.title}');
_mapController?.flyTo(
lat: marker.latitude,
lng: marker.longitude,
alt: marker.altitude + 200,
tilt: 60.0,
range: 1200.0,
durationMs: 2000,
);
},
onMapClick: (lat, lng, alt, placeId) {
debugPrint('Map clicked at: ($lat, $lng, $alt)');
},
),
);
}
}
API Reference
ThreeDMapViewWidget
The primary widget used to render the 3D map platform view.
| Parameter | Type | Default | Description |
|---|---|---|---|
initialLat |
double |
38.544012 |
Initial camera latitude coordinate. |
initialLng |
double |
-107.670428 |
Initial camera longitude coordinate. |
initialAlt |
double |
2427.6 |
Initial camera altitude in meters. |
heading |
double |
310.0 |
Initial camera heading angle (0.0° to 360.0°). |
tilt |
double |
63.0 |
Initial camera tilt pitch angle (0.0° for 2D, 60.0° for 3D). |
range |
double |
8266.0 |
Initial camera range distance in meters. |
mapMode |
Map3DMode |
Map3DMode.hybrid |
Active map mode (hybrid, satellite, roadmap). |
markers |
List<MapMarker> |
[] |
List of custom image markers to display. |
onMapCreated |
MapCreatedCallback? |
null |
Callback invoked when ThreeDMapController is ready. |
onMapReady |
VoidCallback? |
null |
Callback invoked when 3D tiles and map view finish loading. |
onCameraMove |
CameraMoveCallback? |
null |
Continuous callback during camera drag/zoom (lat, lng, range, heading, tilt). |
onMarkerTap |
MarkerTapCallback? |
null |
Callback invoked when a user taps a marker on the map. |
onMapClick |
MapClickCallback? |
null |
Callback invoked when a user clicks an empty location on the map. |
onError |
MapErrorCallback? |
null |
Callback invoked if an error occurs during initialization. |
ThreeDMapController
Controller returned by onMapCreated to programmatically control the 3D map.
| Method | Parameters | Description |
|---|---|---|
flyTo() |
lat, lng, alt, heading, tilt, range, durationMs |
Smoothly animates camera to target coordinates and angle. |
flyToPlace() |
PlaceLocation place, durationMs |
Animates camera to a predefined PlaceLocation. |
setTilt() |
tilt, durationMs |
Animates camera tilt/pitch angle. |
setNormalMapMode() |
isNormalMap, durationMs |
Switches between 2D roadmap mode and 3D photorealistic mode. |
setMapMode() |
Map3DMode mode |
Changes map mode (hybrid, satellite, roadmap). |
addMarker() |
Map<String, dynamic> markerData |
Dynamically adds a new marker to the 3D map. |
removeMarker() |
String id |
Removes a marker by its ID. |
clearMarkers() |
Future<void> |
Clears all markers from the map. |
searchLocation() |
String query |
Searches for landmark or location by name query. |
MapMarker
Data model defining custom image markers.
MapMarker(
id: 'user_1',
latitude: 38.5540,
longitude: -107.6804,
altitude: 2450.0,
title: 'Alice Johnson',
snippet: 'Travel Blogger',
imageUrl: 'https://example.com/avatar.png',
imageSize: 60.0, // Image width/height in dp
imageRadius: 30.0, // Corner clipping radius for circular avatars
color: Colors.indigo,
)
Supported Platforms
- Android: API 21+ (Google Maps 3D SDK)
- iOS: iOS 13.0+ (Apple MapKit 3D Elevation)
License
This project is licensed under the MIT License — see the LICENSE file for details.

