vector_map 0.3.0 vector_map: ^0.3.0 copied to clipboard
Vector map for Flutter. Highly customizable. Compatible with GeoJSON. Map chart. Pure Flutter.
Vector Map #
- Compatible with GeoJSON
- Multi resolution with geometry simplification
- Highly customizable
- High performance
- Interactable
- Pure Flutter (no WebView/JavaScript)
Examples #
Simplified GeoJSONs will be used in the examples to demonstrate package usage. The following examples will assume that GeoJSONs have already been loaded into Strings. The full code is at https://github.com/caduandrade/vector_map_flutter_demo.
polygons.json (link)
Name | Seq | Rnd |
---|---|---|
"Einstein" | 1 | "73" |
"Newton" | 2 | "92" |
"Galileu" | 3 | "10" |
"Darwin" | 4 | |
"Pasteur" | 5 | "77" |
"Faraday" | 6 | "32" |
"Arquimedes" | 7 | "87" |
"Tesla" | 8 | "17" |
"Lavoisier" | 9 | |
"Kepler" | 10 | "32" |
"Turing" | 11 | "93" |
points.json (link)
Name | AN |
---|---|
"Titanium" | 22 |
"Niobium" | 41 |
"Carbon" | 6 |
"Neon" | 10 |
"Silicon" | 14 |
"Hydrogen" | 1 |
Reading GeoJSON from String #
No properties are loaded, only the geometries.
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON);
Creating the Widget #
MapLayer layer = MapLayer(dataSource: polygons);
VectorMap map = VectorMap(layers: [layer]);
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.
MapDataSource polygons = await MapDataSource.geoJSON(
geojson: polygonsGeoJSON,
keys: ['Seq', 'Rnd'],
parseToNumber: ['Rnd'],
labelKey: 'Rnd');
Theme #
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme(color: Colors.yellow, contourColor: Colors.red));
VectorMap map = VectorMap(layers: [layer]);
Label #
Mapping label property:
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON, labelKey: 'Name');
Visibility:
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme(labelVisibility: (feature) => true));
VectorMap map = VectorMap(layers: [layer]);
MapLayer layer = MapLayer(
dataSource: polygons,
theme:
MapTheme(labelVisibility: (feature) => feature.label == 'Darwin'));
VectorMap map = VectorMap(layers: [layer]);
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,
);
}));
VectorMap map = VectorMap(layers: [layer]);
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: polygonsGeoJSON, keys: ['Seq'], labelKey: 'Seq');
Setting the colors for the property values:
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme.value(
contourColor: Colors.white,
labelVisibility: (feature) => true,
key: 'Seq',
colors: {
2: Colors.green,
4: Colors.red,
6: Colors.orange,
8: Colors.blue
}));
VectorMap map = VectorMap(layers: [layer]);
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: polygonsGeoJSON, keys: ['Name', 'Seq']);
Setting the rules:
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme.rule(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;
}
]));
VectorMap map = VectorMap(layers: [layer]);
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: polygonsGeoJSON, keys: ['Seq'], labelKey: 'Seq');
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme.gradient(
contourColor: Colors.white,
labelVisibility: (feature) => true,
key: 'Seq',
colors: [Colors.blue, Colors.yellow, Colors.red]));
VectorMap map = VectorMap(layers: [layer]);
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: polygonsGeoJSON, keys: ['Seq'], labelKey: 'Seq');
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme.gradient(
contourColor: Colors.white,
labelVisibility: (feature) => true,
key: 'Seq',
min: 3,
max: 9,
colors: [Colors.blue, Colors.yellow, Colors.red]));
VectorMap map = VectorMap(layers: [layer]);
Contour #
Thickness
VectorMap map = VectorMap(
layers: [MapLayer(dataSource: polygons)], contourThickness: 3);
Hover theme #
Color
MapLayer layer = MapLayer(
dataSource: polygons, hoverTheme: MapTheme(color: Colors.green));
VectorMap map = VectorMap(layers: [layer]);
Contour color
MapLayer layer = MapLayer(
dataSource: polygons, hoverTheme: MapTheme(contourColor: Colors.red));
VectorMap map = VectorMap(layers: [layer]);
Label
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON, labelKey: 'Name');
MapLayer layer = MapLayer(
dataSource: polygons,
hoverTheme: MapTheme(labelVisibility: (feature) => true));
VectorMap map = VectorMap(layers: [layer]);
Listener
MapLayer layer = MapLayer(
dataSource: polygons, hoverTheme: MapTheme(color: Colors.grey[700]));
VectorMap map = VectorMap(
layers: [layer],
hoverListener: (MapFeature? feature) {
if (feature != null) {
int id = feature.id;
print('Hover - Feature id: $id');
}
});
Rule
Enabling hover by property value
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON, keys: ['Seq']);
// coloring only the 'Darwin' feature
MapLayer layer = MapLayer(
dataSource: polygons,
theme: MapTheme.value(key: 'Seq', colors: {4: Colors.green}),
hoverTheme: MapTheme(color: Colors.green[900]!));
// enabling hover only for the 'Darwin' feature
VectorMap map = VectorMap(
layers: [layer],
hoverRule: (feature) {
return feature.getValue('Seq') == 4;
});
Layers #
Loading multiple data sources:
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON);
MapDataSource points = await MapDataSource.geoJSON(geojson: pointsGeoJSON);
Creating a map with multiple layers:
MapTheme hoverTheme = MapTheme(color: Colors.green);
MapLayer polygonsLayer =
MapLayer(dataSource: polygons, hoverTheme: hoverTheme);
MapLayer pointsLayer = MapLayer(
dataSource: points,
theme: MapTheme(color: Colors.black),
hoverTheme: hoverTheme);
VectorMap map = VectorMap(layers: [polygonsLayer, pointsLayer]);
Overlay hover contour
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])
]);
MapTheme hoverTheme =
MapTheme(color: Colors.black, contourColor: Colors.black);
MapLayer layer1 = MapLayer(
dataSource: dataSource1,
theme: MapTheme(color: Colors.yellow, contourColor: Colors.black),
hoverTheme: hoverTheme);
MapLayer layer2 = MapLayer(
dataSource: dataSource2,
theme: MapTheme(color: Colors.green, contourColor: Colors.black),
hoverTheme: hoverTheme);
Overlay disabled:
VectorMap map = VectorMap(layers: [layer1, layer2]);
Overlay enabled:
VectorMap map =
VectorMap(layers: [layer1, layer2], overlayHoverContour: true);
Marker #
Allows different displays for point geometry.
Circle marker
Default marker.
Fixed radius
Sets a fixed size radius.
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON);
MapDataSource points =
await MapDataSource.geoJSON(geojson: pointsGeoJSON, keys: ['AN']);
MapLayer polygonsLayer = MapLayer(dataSource: polygons);
MapLayer pointsLayer = MapLayer(
dataSource: points,
theme: MapTheme(
color: Colors.black,
markerBuilder: CircleMakerBuilder.fixed(radius: 15)));
VectorMap map = VectorMap(layers: [polygonsLayer, pointsLayer]);
Radius by mapping values
Maps property values to radius values.
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON);
MapDataSource points = await MapDataSource.geoJSON(
geojson: pointsGeoJSON, keys: ['AN'], labelKey: 'AN');
MapLayer polygonsLayer = MapLayer(dataSource: polygons);
MapLayer pointsLayer = MapLayer(
dataSource: points,
theme: MapTheme(
color: Colors.black,
labelVisibility: (feature) => true,
markerBuilder: CircleMakerBuilder.map(
key: 'AN', radiuses: {41: 25, 22: 20, 14: 10, 10: 10})));
VectorMap map = VectorMap(layers: [polygonsLayer, pointsLayer]);
Radius by property values
Uses the property values as radius values.
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON);
MapDataSource points = await MapDataSource.geoJSON(
geojson: pointsGeoJSON, keys: ['AN'], labelKey: 'AN');
MapLayer polygonsLayer = MapLayer(dataSource: polygons);
MapLayer pointsLayer = MapLayer(
dataSource: points,
theme: MapTheme(
color: Colors.black,
labelVisibility: (feature) => true,
markerBuilder: CircleMakerBuilder.property(key: 'AN')));
VectorMap map = VectorMap(layers: [polygonsLayer, pointsLayer]);
Radius in proportion to property values
MapDataSource polygons =
await MapDataSource.geoJSON(geojson: polygonsGeoJSON);
MapDataSource points = await MapDataSource.geoJSON(
geojson: pointsGeoJSON, keys: ['AN'], labelKey: 'AN');
MapLayer polygonsLayer = MapLayer(dataSource: polygons);
MapLayer pointsLayer = MapLayer(
dataSource: points,
theme: MapTheme(
color: Colors.black,
labelVisibility: (feature) => true,
markerBuilder: CircleMakerBuilder.proportion(
key: 'AN', minRadius: 8, maxRadius: 30)));
VectorMap map = VectorMap(layers: [polygonsLayer, pointsLayer]);
Click listener #
MapLayer layer = MapLayer(
dataSource: polygons, hoverTheme: MapTheme(color: Colors.grey[800]!));
VectorMap map = VectorMap(
layers: [layer],
clickListener: (feature) {
print(feature.id);
});
Agenda for the next few days #
- More theming features
- Zoom / Pan
- Legend
- Release the final version (1.0.0). The API may have some small changes.