Historical map overlay with MapBox in Flutter

Daria Dobszai
5 min readFeb 10, 2021

This tutorial is part of a series of articles

📝 Mapbox in Flutter — integrate MapBox map in Flutter and perform basic operations with it

📝 Georeferencing with MapBox and QGIS — teaches how to take an old map image and convert it to a format used in real maps

📝 This article: Historical map overlay with MapBox in Flutter — how to import a historical map to MapBox and then to Flutter

Unsplash source

What you will learn from this article?

  • Import a historical map into the MapBox Studio map style to create an overlay
  • Integrate the map from the previous step in Flutter

What preliminary knowledge do you need?

This tutorial is a short guide, meant for someone who is already a bit familiar with MapBox or red MapBox in Flutter tutorial.

Step 1. Importing a historical map into the MapBox Studio

💡 NOTE: I provide the ready file to work with, but if you would like to import your historical map, check Georeferencing with MapBox and QGIS article first.

Step 1.1. Importing a file

Use your own .tif format file or download one from my Github repo.

Now go to your MapBox Studio and click “New style”:

Select one and hit “Customize”:

The following map view will appear:

For adding a .tif file click on “+” -> “Source” -> “Upload data” -> “Select file”, then press “Confirm”:

To add it to the map, press on “+” -> “Source” -> choose from “Your Source” and find your file:

When it’s selected, close the side menu:

Output

Step 1.2. Saving map and creating URL

In order to save the style select “Publish” in the top menu and hit “Publish”:

Once it’s done, we can get a link to use in the Flutter app.

Click “Sare”, select “Third party” -> CARTO type, and copy the URL:

Step 2. Display map with overlay in Flutter

For completing this step, refer to the first tutorial — Mapbox in Flutter. I continue to work on the same project, available here. I created a new historical-map-overlay branch to work on.

There are 3 modifications to make:

  • change center LatLng to Budapest Széchenyi Chain Bridge: LatLng(47.4990, 19.0437), so when the app loads the map will be centered to this location, so we can see the overlay instantly.
  • set zoom level to 12/14, to view the map overlay from a further distance.
  • urlTemplate is where you should paste the copied URL. One difference here, comparing to the previous project is that I’m not using @2x a scale factor. The reason for that is because the app becomes less responsive and the overlay loads slowly. Therefore, I suggest applying 256 px size without a scale factor, at least for testing and learning purposes (refer to MapBox documentation).
Mapbox Static Tiles
full source code

Output

🎁 BONUS Task

It would be convenient to have a button for switching between the default map and the map with the overlay. For that, we will need two different styles. One is already created. Do the same steps as above, except skip importing any overlay this time, then you can get a URL for this style, the same way as before. After that, create button(s) (e.g. Radio Button, Raised Buttons, Switch, etc.) to change between two map styles.

Desired result

I encourage you to try completing this task on your own, before viewing the solution:)

Solution

I took inspiration from the google maps app and decided to create a menu that will be opened from the Floating action button.

Step 1. Create a FAB for opening a popup menu

I implemented my solution based on this post on StackOverflow. Since the Popup menu button by default only accepts an icon, I had to create a custom Container that would resemble a floating button:

To add a button inside the Scaffold and to display it on top of the FlutterMap we should wrap the map inside the Stack widget, which allows to position elements on top of each other:

Step 2. Switch between maps

Create a bool isPresentTimeand, when the first menu item is clicked, it will be set to true otherwise to false. Don’t forget to frame it inside the setState otherwise the map won’t be refreshed.

For switching between style URLs conveniently, let’s split the URL into two-parts. One contains the user, another one includes the rest, this way the style is in the middle and we can easily flip between the two.

On the place of a style, we perform a check whether it’s a present map or not. If yes, apply your basic map, otherwise, display the overlay.

TADA, We’re done 🎉

The full source code is available on my Github, where you can switch between master, historical_map_overlay, and bonus_task branches.

Thank you for reading!

I’m curious to hear your feedback 🙂

--

--

Daria Dobszai

I am a mobile developer with a passion for UX/UI design and teaching. My main field of work is Android and Flutter development.