mapsforge_flutter
A comprehensive Flutter widget library for interactive map visualization with advanced marker and overlay support. This package provides the main UI components for the Mapsforge Flutter ecosystem, enabling rich mapping experiences with customizable overlays, markers, and gesture handling.
Screenshots
Why mapsforge_flutter?
Fully Offline: No internet? No problem! Load and render maps without network access.
Support for online maps: If you ADDITIONALLY need online maps you can do so easily with the same codebase and api.
High Customizability: Supports custom rendering themes, allowing you to tailor the map’s look and feel.
Lightweight & Efficient: Designed for mobile, mapsforge uses optimized mapfiles that provide rich geographical data in a compact format.
Advanced Features: Indoor navigation, hillshading, map rotation and more!
Overview
With this library, you can load and render mapfiles directly from a user’s device. No internet connection required! Perfect for offline navigation, custom mapping applications, and seamless user experiences!
The mapsforge_view
package is the primary UI layer for Mapsforge Flutter applications.
It provides a complete set of widgets, overlays, and markers that work seamlessly with the underlying rendering engine to create interactive, feature-rich map applications.
mapsforge_flutter brings pure offline mapping capabilities to Flutter by porting the well-established mapsforge library from Java/Android.
Key Features:
- Complete map widget with gesture support
- Rich marker system for POIs, areas, and custom elements
- Overlay system for UI controls and information display
- Context menu support with customizable actions
- Indoor mapping support with level controls
- Performance-optimized rendering with caching
- Hillshading
- Drag-and-drop support
- Online and Offline Maps
- Map rotation
- Convert PBF files to mapsforge files
- Convert PBF files to osm files
Core Components
Map Widget
MapsforgeView
: Complete map widget with all standard featuresTileView
: Core tile rendering widgetLabelView
: Label rendering with rotation supportMapModel
: Central state management for map data
Gesture System
GenericGestureDetector
: Generic gesture handlingMoveGestureDetector
: Pan and drag gesturesScaleGestureDetector
: Pinch-to-zoom gesturesRotationGestureDetector
: Two-finger rotationTapGestureDetector
: Single and long tap handlingDoubleTapGestureDetector
: Double-tap zoom
Overlay System
ZoomOverlay
: Zoom in/out buttonsDistanceOverlay
: Scale ruler displayIndoorlevelOverlay
: Indoor level controlsContextMenuOverlay
: Contextual menu system
Marker System
PoiMarker
: Point of interest markers with iconsCircleMarker
: Circular markers with customizable stylingAreaMarker
: Polygon area markersRectMarker
: Rectangular markersPolylineMarker
: Line and path markersCaptionMarker
: Text label markers
Installation
Add these packages to your pubspec.yaml
:
dependencies:
mapsforge_flutter: ^4.0.0
mapsforge_flutter_core: ^4.0.0
mapsforge_flutter_mapfile: ^4.0.0
mapsforge_flutter_renderer: ^4.0.0
mapsforge_flutter_rendertheme: ^4.0.0
Note: See doc/development for working with a local copy of mapsforge_flutter.
List all required assets in your pubspec.yaml
(see pubspec file from simple_example
project)
flutter:
assets:
- packages/mapsforge_flutter/assets/patterns/coniferous.svg
- packages/mapsforge_flutter/assets/patterns/coniferous_and_deciduous.svg
- packages/mapsforge_flutter/assets/patterns/deciduous.svg
# and more
add your rendertheme to your pubspec.yaml
flutter:
assets:
- assets/defaultrender.xml
and to your assets folder.
Quick Start
Basic Map Setup
Find the device to pixel ratio end set the global property accordingly. This will shrink the tiles, requires to produce more tiles but makes the map crispier.
double ratio = MediaQuery.devicePixelRatioOf(context);
MapsforgeSettingsMgr().setDeviceScaleFactor(ratio);
Read the map from the assets folder. Since monaco is small, we can keep it in memory.
ByteData mapContent = await rootBundle.load("assets/monaco.map");
Datastore datastore = await Mapfile.createFromContent(content: mapContent.buffer.asUint8List());
Alternatively read the map from the file system.
datastore = await Mapfile.createFromFile(filename: filename);
Now create the MapModel. In our example we restrict the max zoomlevel. The MapModel must be disposed after use.
_mapModel = await MapModelHelper.createOfflineMapModel(datastore: datastore, zoomlevelRange: const ZoomlevelRange(0, 21));
For demo purposes set a position and zoomlevel. Note that this information would come from e.g. a gps provider in the real world.
MapPosition mapPosition = MapPosition(43.7399, 7.4262, 18);
_mapModel!.setPosition(mapPosition);
Note: There are many methods in MapModel
to move/zoom/rotate the map.
Use the MapModel to view the map
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: FutureBuilder(
// retrieve the MapModel we just created
future: _createModelFuture,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.error != null) {
// an error occured, show it on screen
return ErrorhelperWidget(error: snapshot.error!, stackTrace: snapshot.stackTrace);
}
if (snapshot.data != null) {
// cool we have already the MapModel so we can start the view
MapModel mapModel = snapshot.data;
return MapsforgeView(mapModel: mapModel);
}
// mapModel is still not availabe or no position defined
return const CircularProgressIndicator();
},
),
),
);
}
voilà you have a running map!
Markers
// Create a POI marker with custom icon
final poiMarker = PoiMarker<String>(
latLong: LatLong(52.5200, 13.4050),
src: "assets/icons/restaurant.png",
);
// Add to marker datastore
final markerDatastore = DefaultMarkerDatastore();
markerDatastore.addMarker(poiMarker);
// Add to your map stack
Stack(
children: [
MapsforgeView(mapModel: mapModel),
MarkerDatastoreOverlay(markerDatastore: markerDatastore),
],
)
See also doc/marker
Overlays
Zoom overlays provide interactive zoom in/out buttons.
// Standard zoom overlay with positioned buttons
ZoomOverlay(
mapModel: mapModel,
top: 50, // Position from top
right: 20, // Position from right
)
// Alternative: zoom-in only overlay
ZoomInOverlay(
mapModel: mapModel,
bottom: 100,
right: 20,
)
See also doc/overlay
Context Menus
Context menu overlays handle interactions with customizable menus.
// Custom context menu
final contextMenu = SimpleContextMenu(
items: [
ContextMenuItem(
title: "Add Marker",
icon: Icons.place,
onTap: (position) {
// Add marker at tapped position
final marker = PoiMarker(
latLong: position,
src: "assets/icons/pin.png",
);
markerDatastore.addMarker(marker);
},
),
ContextMenuItem(
title: "Get Info",
icon: Icons.info,
onTap: (position) {
// Show location information
showLocationInfo(position);
},
),
],
);
// Add to overlay stack
ContextMenuOverlay(
mapModel: mapModel,
contextMenu: contextMenu,
)
Gesture Customization
// Create custom map widget with selective gestures
class CustomMapView extends StatelessWidget {
final MapModel mapModel;
final bool enableRotation;
final bool enableZoom;
const CustomMapView({
required this.mapModel,
this.enableRotation = true,
this.enableZoom = true,
});
@override
Widget build(BuildContext context) {
return Stack(
children: [
MoveGestureDetector(mapModel: mapModel),
if (enableRotation) RotationGestureDetector(mapModel: mapModel),
if (enableZoom) ScaleGestureDetector(mapModel: mapModel),
TapGestureDetector(mapModel: mapModel),
TileView(mapModel: mapModel),
// Add your custom overlays
],
);
}
}
Dependencies
mapsforge_flutter
: Flutter UI frameworkmapsforge_flutter_core
: Core utilities and data modelsmapsforge_flutter_renderer
: Rendering engine integration (online and offline)mapsforge_flutter_rendertheme
: Theme and styling supportmapsforge_flutter_mapfile
: Map file reading and processing
Contributing
- Follow the existing code style and patterns
- Add tests for new functionality
- Update documentation for API changes
- Ensure performance optimizations are maintained
- Test with various map data sources and scenarios
- Buy me a coffee: If you'd like to support the project financially, consider buying me a coffee. Your support helps cover the costs of development and keeps the project growing.
Examples
Check the apps/simple_example
directory for a basic map setup.
Check the apps/online_renderer_example
directory for a basic setup for pure online rendering.
Check the apps/complete_example
directory for comprehensive usage examples including:
- Basic map setup with markers
- Custom marker implementations
- Advanced gesture handling
- Indoor mapping integration
License
This package is part of the Mapsforge Flutter ecosystem. See the main project license for details.
Credits
A huge shout-out to the original mapsforge developer for building such an incredible project!
Also, thanks to Chemnitz University of Technology for implementing indoor map support.
A big thank you to all of you who uses that library and supports me with ideas, bugfixes, PullRequests and even a coffee!
Related Packages
mapsforge_flutter_core
: Core utilities and data structuresmapsforge_flutter_renderer
: High-performance tile rendering for offline mapfiles as well as online renderersmapsforge_flutter_rendertheme
: Theme processing and styling for offline mapfilesmapsforge_flutter_mapfile
: Map file reading and processingmapsforge_flutter
: Complete Flutter UI mapping solution with markers, overlays, and gesture handling
Documentation
Decision why/how we use melos: doc/melos
Setting up a new project which contains mapsforge_flutter: doc/development
Upgrading to a newer version: doc/changes
Known issue: doc/known_issues
Working with markers: doc/marker
Performance considerations during development: doc/performance
Enhanced usage of the library: doc/enhanced_usage