Flutter Geo Map
- Compatible with GeoJSON
- Multi resolution with geometry simplification
- Highly customizable
- High performance
- Interactable
- Pure Flutter (no WebView/JavaScript)
GeoJson
GeoJSON is a JSON-based open standard format designed to represent geographical features, alongside non-spatial attributes (properties). Geographic shapes would usually be represented as features
in geojson. Each feature has a type
, geometry
, and properties
attribute. properties
is an object that can contain any kind of data that can be represented in JSON format. This can be time-series population data, GDP, or any other kind of data that relates to a given geography.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[10.6, 47.9],
[5.8, 47.9],
[5.8, 45.8],
[10.6, 45.8],
[10.6, 47.9]
]
]
},
"properties": {
"firstProperty": "Something",
"secondProperty": "Something else"
}
},
{ "type": "Feature", "geometry": {...}, "properties": {...} },
{ "type": "Feature", "geometry": {...}, "properties": {...} }
]
}
Reading GeoJSON from String
Reading the geometries only.
MapDataSource polygons = await MapDataSource.geoJson(geoJson: geoJson);
Reading GeoJSON properties
The keys
argument defines which properties must be loaded.
The parseToNumber
argument defines which properties will have numeric values in quotes parsed to numbers.
The labelKey
defines which property will be used to display its values as feature labels.
The filterKey
& filterValue
defines which property key will be used to filter json match value
MapDataSource polygons = await MapDataSource.geoJson(
geoJson: geoJson,
keys: ['Seq', 'Rnd'],
parseToNumber: ['Rnd'],
labelKey: 'Rnd',
filterKet: 'Seq',
filterValue '01');
Creating the Widget
SimpleMapController _controller = SimpleMapController();
MapDataSource polygons = await MapDataSource.geoJson(geoJson: geoJson);
MapLayer layer = MapLayer(dataSource: polygons);
_controller.addLayer(layer);
SimpleMap map = SimpleMap(controller: _controller);
Theme
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme(color: Colors.yellow, contourColor: Colors.red));
Label visibility
MapDataSource polygons =
await MapDataSource.geoJson(geoJson: geoJson, labelKey: 'Name');
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme(labelVisibility: (feature) => true));
Filter label name to visible
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme(labelVisibility: (feature) => feature.label == 'Darwin'));
Label style
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme(
labelVisibility: (feature) => true,
labelStyleBuilder: (feature, featureColor, labelColor) {
if (feature.label == 'Darwin') {
return TextStyle(
color: labelColor,
fontWeight: FontWeight.bold,
fontSize: 11,
);
}
return TextStyle(
color: labelColor,
fontSize: 11,
);
}));
Color by property value
Sets a color for each property value in GeoJSON. If a color is not set, the default color is used.
Mapping the property key:
MapDataSource polygons = await MapDataSource.geoJson(
geoJson: geoJson, keys: ['Seq'], labelKey: 'Seq');
Setting the colors for the property values:
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapValueTheme(
contourColor: Colors.white,
labelVisibility: (feature) => true,
key: 'Seq',
colors: {
2: Colors.green,
4: Colors.red,
6: Colors.orange,
8: Colors.blue
}));
Color by rule
The feature color is obtained from the first rule that returns a non-null color. If all rules return a null color, the default color is used.
Mapping the property key:
MapDataSource polygons =
await MapDataSource.geoJson(geoJson: geoJson, keys: ['Name', 'Seq']);
Setting the rules:
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapRuleTheme(contourColor: Colors.white, colorRules: [
(feature) {
String? value = feature.getValue('Name');
return value == 'Faraday' ? Colors.red : null;
},
(feature) {
double? value = feature.getDoubleValue('Seq');
return value != null && value < 3 ? Colors.green : null;
},
(feature) {
double? value = feature.getDoubleValue('Seq');
return value != null && value > 9 ? Colors.blue : null;
}
]));
Gradient
The gradient is created given the colors and limit values of the chosen property. The property must have numeric values.
Auto min/max values
Uses the min and max values read from data source.
MapDataSource polygons = await MapDataSource.geoJson(
geoJson: geoJson, keys: ['Seq'], labelKey: 'Seq');
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapGradientTheme(
contourColor: Colors.white,
labelVisibility: (feature) => true,
key: 'Seq',
colors: [Colors.blue, Colors.yellow, Colors.red]));
Setting min or max values manually
If the min
value is set, all lower values will be displayed using the first gradient color.
If the max
value is set, all higher values will be displayed using the last gradient color.
MapDataSource polygons = await MapDataSource.geoJson(
geoJson: geoJson, keys: ['Seq'], labelKey: 'Seq');
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapGradientTheme(
contourColor: Colors.white,
labelVisibility: (feature) => true,
key: 'Seq',
min: 3,
max: 9,
colors: [Colors.blue, Colors.yellow, Colors.red]));
Highlight theme
Used by addons and cursor hover to highlight layer features on the map.
Color
MapLayer layer = MapLayer(
dataSource: polygons,
highlightTheme: MapHighlightTheme(color: Colors.green));
Contour color
MapLayer layer = MapLayer(
dataSource: polygons,
highlightTheme: MapHighlightTheme(contourColor: Colors.red));
Label highlight
MapDataSource polygons =
await MapDataSource.geoJson(geoJson: geoJson, labelKey: 'Name');
MapLayer layer = MapLayer(
dataSource: polygons,
highlightTheme: MapHighlightTheme(labelVisibility: (feature) => true));
Contour thickness
SimpleMapController _controller = SimpleMapController(contourThickness: 3);
Cursor hover rule
Enabling hover by property value
MapDataSource polygons =
await MapDataSource.geoJson(geoJson: geoJson, keys: ['Seq']);
// coloring only the 'Darwin' feature
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapValueTheme(key: 'Seq', colors: {4: Colors.green}),
highlightTheme: MapHighlightTheme(color: Colors.green[900]!));
// enabling hover only for the 'Darwin' feature
SimpleMap map = SimpleMap(
controller: _controller,
hoverRule: (feature) {
return feature.getValue('Seq') == 4;
});
Cursor hover listener
SimpleMap map = SimpleMap(
controller: _controller,
hoverListener: (MapFeature? feature) {
if (feature != null) {
int id = feature.id;
}
});
Layers
MapHighlightTheme highlightTheme = MapHighlightTheme(color: Colors.green);
MapDataSource polygons =
await MapDataSource.geoJson(geoJson: polygonsGeoJson);
MapLayer polygonLayer =
MapLayer(dataSource: polygons, highlightTheme: highlightTheme);
_controller.addLayer(polygonLayer);
MapDataSource points = await MapDataSource.geoJson(geoJson: pointsGeoJson);
MapLayer pointsLayer = MapLayer(
dataSource: points,
theme: MapTheme(color: Colors.black),
highlightTheme: highlightTheme);
_controller.addLayer(pointsLayer);
Overlay hover contour
Allows you to draw the contour over all layers
MapDataSource dataSource1 = MapDataSource.geometries([
MapPolygon.coordinates([2, 3, 4, 5, 6, 3, 4, 1, 2, 3])
]);
MapDataSource dataSource2 = MapDataSource.geometries([
MapPolygon.coordinates([0, 2, 2, 4, 4, 2, 2, 0, 0, 2]),
MapPolygon.coordinates([4, 2, 6, 4, 8, 2, 6, 0, 4, 2])
]);
Overlay disabled:
MapHighlightTheme highlightTheme =
MapHighlightTheme(color: Colors.black, contourColor: Colors.black);
MapLayer layer1 = MapLayer(
dataSource: dataSource1,
theme: MapTheme(color: Colors.yellow, contourColor: Colors.black),
highlightTheme: highlightTheme);
MapLayer layer2 = MapLayer(
dataSource: dataSource2,
theme: MapTheme(color: Colors.green, contourColor: Colors.black),
highlightTheme: highlightTheme);
_controller = SimpleMapController(layers: [layer1, layer2]);
Overlay enabled:
MapLayer layer1 = MapLayer(
dataSource: dataSource1,
theme: MapTheme(color: Colors.yellow, contourColor: Colors.black),
highlightTheme: MapHighlightTheme(
color: Colors.black,
contourColor: Colors.black,
overlayContour: true));
MapLayer layer2 = MapLayer(
dataSource: dataSource2,
theme: MapTheme(color: Colors.green, contourColor: Colors.black),
highlightTheme:
MapHighlightTheme(color: Colors.black, contourColor: Colors.black));
_controller = SimpleMapController(layers: [layer1, layer2]);