Getting started with Flutter Maps (SfMaps)
6 Jun 202316 minutes to read
This section explains the steps required to add the maps widget with shape layer and its elements such as data labels, tooltip, assignable colors based on region, and legends. It also explains about adding tile layer with OpenStreetMap. This section covers only basic features needed to know to get started with Syncfusion maps.
To get start quickly with our Flutter Maps widget, you can check on this video.
Add Flutter maps to an application
Create a simple project using the instructions given in the Getting Started with your first Flutter app documentation.
Add dependency
Add the Syncfusion Flutter maps dependency to your pubspec.yaml file.
dependencies:
syncfusion_flutter_maps: ^xx.x.xx
NOTE
Here xx.x.xx denotes the current version of
Syncfusion Flutter Maps
package.
Get packages
Run the following command to get the required packages.
$ flutter pub get
Import package
Import the following package in your Dart code.
import 'package:syncfusion_flutter_maps/maps.dart';
Initialize maps
After importing the package, initialize the maps widget as a child of any widget.
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SfMaps(),
),
);
}
Set GeoJSON data for shape layer from various source
The layers
in SfMaps
contains collection of either MapShapeLayer
or MapTileLayer
. The actual geographical rendering is done in the each MapShapeLayer
. The source
property of the MapShapeLayer
is of type MapShapeSource
. The source
can be set as the .json source from an asset bundle, from network or from Uint8List as bytes. Use the respective constructor depends on the type of the source.
The shapeDataField
property of the MapShapeSource
is used to refer the unique field name in the .json source to identify each shapes. In Mapping the data source
section of this document, this shapeDataField
will be used to map with respective value returned in primaryValueMapper
from the data source.
IMPORTANT
The Mercator projection is the default projection in the maps.
From asset bundle
Load .json data from an asset bundle.
NOTE
If you are using the
MapShapeSource.asset
constructor, you must add the .json file to the assets folder of your root directory and refer the json file path in thepubspec.yaml
file as shown in the below code snippet. You can get theaustralia.json
file here.
flutter:
uses-material-design: true
assets:
- australia.json
late MapShapeSource _dataSource;
@override
void initState() {
_dataSource = MapShapeSource.asset(
'assets/australia.json',
shapeDataField: 'STATE_NAME',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(15),
child: SfMaps(
layers: [
MapShapeLayer(source: _dataSource),
],
),
),
);
}
From network
Load .json data from the network.
late MapShapeSource _dataSource;
@override
void initState() {
_dataSource = MapShapeSource.network(
'http://www.json-generator.com/api/json/get/bVqXoJvfjC?indent=2',
shapeDataField: 'name',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(15),
child: SfMaps(
layers: [
MapShapeLayer(source: _dataSource),
],
),
),
);
}
From memory
Load .json data as bytes from Uint8List
.
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _fetchJsonData(),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
Uint8List bytesData = snapshot.data as Uint8List;
return SfMaps(
layers: [
MapShapeLayer(
source: MapShapeSource.memory(
bytesData,
shapeDataField: 'STATE_NAME',
),
),
],
);
} else {
return CircularProgressIndicator();
}
},
),
);
}
Future<Uint8List> _fetchJsonData() async {
return (await rootBundle.load('assets/australia.json')).buffer.asUint8List();
}
Mapping the data source for shape layer
By default, the value specified for the shapeDataField
in the GeoJSON source will be used in the elements like data labels, tooltip, and legend for their respective shapes. However, it is possible to keep a data source and customize these elements based on the requirement. As mentioned above, shapeDataField
will be used to map with respective value returned in primaryValueMapper
from the data source.
late List<Model> data;
@override
void initState() {
data = <Model>[
Model('New South Wales',
' New\nSouth Wales'),
Model('Queensland', 'Queensland'),
Model('Northern Territory', 'Northern\nTerritory'),
Model('Victoria', 'Victoria'),
Model('South Australia', 'South Australia'),
Model('Western Australia', 'Western Australia'),
Model('Tasmania', 'Tasmania'),
Model('Australian Capital Territory', 'ACT')
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: <MapShapeLayer>[
MapShapeLayer(
source: MapShapeSource.asset(
'assets/australia.json',
shapeDataField: 'STATE_NAME',
dataCount: data.length,
primaryValueMapper: (int index) => data[index].state,
),
),
],
),
);
}
class Model {
Model(this.state, this.stateCode);
String state;
String stateCode;
}
NOTE
- Refer the
MapShapeSource.primaryValueMapper
, for mapping the data of the data source collection with the respectiveMapShapeSource.shapeDataField
in .json source.- Refer the
MapShapeSource.bubbleSizeMapper
, for customizing the bubble size.- Refer the
MapShapeSource.bubbleColorValueMapper
, for customizing the bubble colors.- Refer the
MapShapeSource.dataLabelMapper
, for customizing the data label text.- Refer the
MapShapeSource.shapeColorValueMapper
, for customizing the shape colors.
Add shape layer maps elements
Add the basic maps elements such as data labels, legend, and tooltip as shown in the below code snippet.
-
Data labels - You can show data labels using the
MapShapeLayer.showDataLabels
property and also, it is possible to show data labels only for the particular shapes/or show custom text using theMapShapeSource.dataLabelMapper
property. -
Legend - You can enable legend using the
MapShapeLayer.legend
property. The icons color of the legend is applied based on the colors returned in theMapShapeSource.shapeColorValueMapper
property. It is possible to customize the legend icons color and texts using theMapShapeSource.shapeColorMappers
property. -
Tooltip - You can enable tooltip for the shapes using the
MapShapeLayer.shapeTooltipBuilder
property. It will be called with the corresponding index every time when you interacts with the shapes i.e., while tapping in touch devices and hover enter in the mouse enabled devices.
late List<Model> data;
late MapShapeSource dataSource;
@override
void initState() {
data = <Model>[
Model('New South Wales', Color.fromRGBO(255, 215, 0, 1.0),
' New\nSouth Wales'),
Model('Queensland', Color.fromRGBO(72, 209, 204, 1.0), 'Queensland'),
Model('Northern Territory', Colors.red.withOpacity(0.85),
'Northern\nTerritory'),
Model('Victoria', Color.fromRGBO(171, 56, 224, 0.75), 'Victoria'),
Model('South Australia', Color.fromRGBO(126, 247, 74, 0.75),
'South Australia'),
Model('Western Australia', Color.fromRGBO(79, 60, 201, 0.7),
'Western Australia'),
Model('Tasmania', Color.fromRGBO(99, 164, 230, 1), 'Tasmania'),
Model('Australian Capital Territory', Colors.teal, 'ACT')
];
dataSource = MapShapeSource.asset(
'assets/australia.json',
shapeDataField: 'STATE_NAME',
dataCount: data.length,
primaryValueMapper: (int index) => data[index].state,
dataLabelMapper: (int index) => data[index].stateCode,
shapeColorValueMapper: (int index) => data[index].color,
);
super.initState();
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
return Scaffold(
body: Center(
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.55,
child: SfMaps(
layers: <MapShapeLayer>[
MapShapeLayer(
source: dataSource,
showDataLabels: true,
legend: MapLegend(MapElement.shape),
shapeTooltipBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(7),
child: Text(data[index].stateCode,
style: themeData.textTheme.caption!
.copyWith(color: themeData.colorScheme.surface)),
);
},
tooltipSettings: MapTooltipSettings(
color: Colors.grey[700],
strokeColor: Colors.white,
strokeWidth: 2),
strokeColor: Colors.white,
strokeWidth: 0.5,
dataLabelSettings: MapDataLabelSettings(
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.caption!.fontSize)),
),
],
),
),
),
);
}
class Model {
Model(this.state, this.color, this.stateCode);
String state;
Color color;
String stateCode;
}
Add tile layer
The MapTileLayer
needs to be added in the layers
collection in SfMaps
. The URL of the providers must be set in the MapTileLayer.urlTemplate
property.
Kindly refer the tile layer section for more information.
@override
Widget build(BuildContext context) {
return SfMaps(
layers: [
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
),
],
);
}
NOTE
You can refer to our Flutter Maps feature tour page for its groundbreaking feature representations. You can also explore our Flutter Maps example that shows how to configure a Maps in Flutter.