Offline Vector Map

A Flutter package for displaying offline vector maps with support for offline routing, markers, custom map styles, and location-based navigation.

This package allows you to use OpenStreetMap data completely offline by converting .osm.pbf files into vector map tiles and generating routing files for fast route calculation without an internet connection.

Features

  • πŸ—ΊοΈ Offline vector maps
  • πŸš€ Fast map rendering using vector tiles
  • πŸ“ Location selection
  • πŸ“Œ Custom markers
  • 🎨 Custom map styles
  • 🧭 Offline route calculation
  • πŸš— Real-time route updates based on user location
  • πŸ“¦ Fully offline operation

1. Download and prepare maps

Step 1: Download OpenStreetMap data

Download the desired region from GeoFabrik:

https://download.geofabrik.de

The downloaded file will have the following format:

region.osm.pbf

Example:

peru.osm.pbf

Step 2: Convert OSM data to vector map tiles

Download Planetiler:

https://github.com/onthegomap/planetiler/releases/download/v0.10.2/planetiler.jar

Make sure Java is installed on your system.

Place the planetiler.jar file in the same folder as your .osm.pbf file.

Run:

java -Xmx8g -jar planetiler.jar --osm-path={mapWithoutConvertName}osm.pbf --output={mapConvertedName}.mbtiles

Replace:

  • {mapWithoutConvertName} with the original map filename without conversion.

Example:

peru
  • {mapConvertedName} with the name you want for the generated map.

Example:

peru_map

Result:

peru_map.mbtiles

This .mbtiles file contains the vector map data used by OfflineVectorMap.


2. Generate routing files

Offline routing requires additional files containing the road network graph.

Step 1: Download the routing converter

Download:

https://github.com/AleBesu/osm_converter_cli/releases/download/v1.0.0/osm_pbf_to_routing_converter.exe


Step 2: Prepare the files

Put the executable and your .osm.pbf file in the same folder.

Example:

routing_converter/
β”‚
β”œβ”€β”€ osm_pbf_to_routing_converter.exe
└── peru.osm.pbf

Step 3: Generate routing data

Open the executable.

The program will ask for a graphid.

The graphid is an identifier used for the generated routing graph.

After generation, you will obtain three files:

map.graph
map.meta
map.index

These files are required by the offline routing engine.


3. Add map files to your Flutter project

Copy the generated files into your Flutter assets folder.

Example:

assets/
└── maps/
    β”‚
    β”œβ”€β”€ peru_map.mbtiles
    β”œβ”€β”€ peru_car.index
    β”œβ”€β”€ peru_car.meta
    └── peru_car.graph

Register them in pubspec.yaml:

flutter:
  assets:
    - assets/maps/peru_map.mbtiles
    - assets/maps/peru_car.index
    - assets/maps/peru_car.meta
    - assets/maps/peru_car.graph

4. Using OfflineVectorMap

The main widget is:

OfflineVectorMap

It provides an offline vector map viewer with support for routing, markers, and custom styles.

Basic properties

selectedLocationWidget

Custom widget displayed when selecting a location.

Widget? selectedLocationWidget

isSelectingMode

Enables location selection mode.

When enabled, a long press on the map triggers onLongPressed.

bool isSelectingMode

onLongPressed

Callback that returns the coordinates selected by the user.

void Function(LatLng)?

Example:

onLongPressed: (point) {
  print(point.latitude);
  print(point.longitude);
}

initialCenter

Defines the initial camera position.

LatLng initialCenter

Example:

initialCenter: LatLng(
  -12.0464,
  -77.0428,
)

mapStyle

Defines the visual style of the map.

The style is provided through a JSON asset.

You can also use predefined styles from:

OfflineMapsStyles

locationDialogBuilder

Builder used when the user taps a point on the map.

required Widget Function({
  required BuildContext context,
  required void Function() setLocation
})

It allows creating a custom dialog or interface for selected locations.


controller

Controls map actions.

Type:

OfflineVectorMapController

OfflineVectorMapController

The controller allows interaction with the map after initialization.

Routing

Before calculating routes, configure routing:

setMapRounting()

Example:

await controller.setMapRounting(
  routing,
);

Calculate a route

Use:

setRouter()

Example:

await controller.setRouter(
  from: startPoint,
  to: destinationPoint,
);

Parameters:

fromUserLocation

Uses the current device location as the starting point.

bool fromUserLocation

from

Starting coordinate.

LatLng? from

to

Destination coordinate.

required LatLng to

updateInRealTime

Updates the route periodically using the current user location.

bool updateInRealTime

Remove route

Remove the current route:

controller.removeRouter();

Markers

The controller supports custom markers.

Add markers

controller.addMarker(marker);

Set multiple markers

controller.setMarkers(markers);

Remove all markers

controller.removeAllMarkers();

Delete a marker

controller.deleteMarker(marker);

Location selection

Select a location manually:

controller.selectLocation(point);

Remove selected location:

controller.removeSelectedLocation();

Follow user location

Enable or disable following the user's location:

controller.followUserLocation = true;

Read current state:

controller.followUserLocation;

License

This project is licensed under the MIT License.