MapBox in Flutter
This tutorial is part of a series of articles
📝 This article: 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
📝 Historical map overlay with MapBox in Flutter — how to import a historical map to MapBox and then to Flutter
What you will learn from this post?
- Display a full-screen map
- Use MapBox as a map provider
- Detect current user location
- Place a pin (marker) on the long press
What preliminary knowledge is needed?
A basic understanding of Flutter.
Step 1: Setup
The first step is to build a code structure and to collect everything we need.
- pages package: Home page
main.dart class — a starting point of the application:
Dependencies in pubspec.yaml:
Step 2: Display a map
HomePage.dart
First, we define the Flutter Map options:
- initial coordinates
center: LatLng(51.5074, 0.1278)
- zoom level — initial map resolution
- min zoom level
Next, we define the layers. For displaying a map we need to use some of the providers out there. In the library documentation, you can find examples of integrating Open Street Map or Azure. Our goal is to apply MapBox.
MAPBOX
To get the urlTemplate
we have to complete the following steps:
- create a MapBox account
- open MapBox Studio and generate a map
Click “Create new Style” → select “Satellite Streets” → click “Customize…”.
💡 NOTE: I decided to go with Satellite Streets, but you can choose any other type.
You will see a menu where you can style your map in many different ways. I went with the default theme this time.
Now, to obtain a style URL, click “Share” in the top bar.
- copy and paste the link
Select the “Third party” → CARTO type → copy the URL and paste it in the place of the TODO from the code example above.
For the code to look more professional and most importantly for being able to secure your access token later, let’s extract it from the link place it in the additionalOptions
:
💡 NOTE: In the end, you only have to replace {user} and {style}, the rest of the URL template stays as you see it since we completely extract the access token from there.
Let’s run our app:
Step 3: Detect current location
Flutter Map library has a user_location plugin.
💡 NOTE: Make sure to apply all the platform necessary settings for Android or iOS.
Initialize MapController and set it in the Flutter Map using the mapController
property. Create an empty list of markers for now. Then, define UserLocationOptions. Set it as a plugin of the Flutter Map and also pass it inside the layers.
UserLocationOptions:
- pass context
- pass MapController
zoomToCurrentLocationOnLoad
means we don't want to detect the current location once the app is startedshowMoveToCurrentLocationFloatingActionButton
. It is common to see a FAB on the bottom of the screen for getting the user's location. Luckily, the lib creators already thought it through and we can enable such a feature.moveToCurrentLocationFloatingActionButton.
By default, the given FAB has limited styling options. We can modify its size and padding only, so if you would like to create a custom design you can achieve it, as in the example.
Step 4: Pin
When the user long presses some area we need to get its latitude and longitude and set a pin.
💡 NOTE: I used this pin icon in PNG 512px.
We already created an empty list of markers earlier. Markers are necessary to define pin properties and coordinates. Inside the MapOptions onLongPress function let’s create and pass our own private method _addPin:
addPin(LatLng latlng) {
setState(() {
markers.add(Marker(
width: 30.0,
height: 30.0,
point: latlng,
builder: (ctx) => Container(
child: Image.asset('assets/pin.png'),
),
));
});
}
Inside here we create a marker and pass latlng value as its point. Now, add MarkerLayerOptions add pass our markers there.
MarkerLayerOptions(
markers: markers,
),
TADA, We’re done 🎉
The full source code is available on my Github.
In two other parts of the series, we will learn how to integrate a historical map and create an overlay.
I’m curious to hear your feedback 🙂