Skip to content

Add a GeoJSON Polygon in Flutter

This tutorial shows how to add a GeoJSON Polygon to your MapMetrics Flutter map — perfect for highlighting regions, zones, or areas.

Prerequisites

Before you begin, ensure you have:

Basic GeoJSON Polygon

Add a filled polygon from GeoJSON data:

dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';

class GeoJsonPolygonScreen extends StatefulWidget {
  @override
  _GeoJsonPolygonScreenState createState() => _GeoJsonPolygonScreenState();
}

class _GeoJsonPolygonScreenState extends State<GeoJsonPolygonScreen> {
  MapMetricsController? mapController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('GeoJSON Polygon')),
      body: MapMetrics(
        styleUrl:
            'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
        onMapCreated: (MapMetricsController controller) {
          mapController = controller;
        },
        initialCameraPosition: CameraPosition(
          target: LatLng(48.8, 2.35),
          zoom: 11.0,
        ),
        onStyleLoaded: () {
          _addGeoJsonPolygon();
        },
      ),
    );
  }

  void _addGeoJsonPolygon() {
    final geoJson = {
      'type': 'Feature',
      'properties': {'name': 'Central Paris'},
      'geometry': {
        'type': 'Polygon',
        'coordinates': [
          [
            [2.3200, 48.8400],
            [2.3800, 48.8400],
            [2.3800, 48.8700],
            [2.3200, 48.8700],
            [2.3200, 48.8400], // close the ring
          ]
        ],
      },
    };

    // Add the GeoJSON source
    mapController?.addGeoJsonSource('region-source', geoJson);

    // Add a fill layer
    mapController?.addFillLayer(
      'region-fill',
      'region-source',
      fillColor: '#3b82f6',
      fillOpacity: 0.3,
    );

    // Add an outline layer
    mapController?.addLineLayer(
      'region-outline',
      'region-source',
      lineColor: '#1d4ed8',
      lineWidth: 2.0,
    );
  }
}

Multiple Polygons with FeatureCollection

Display several regions with different colors:

dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';

class MultiPolygonScreen extends StatefulWidget {
  @override
  _MultiPolygonScreenState createState() => _MultiPolygonScreenState();
}

class _MultiPolygonScreenState extends State<MultiPolygonScreen> {
  MapMetricsController? mapController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Multiple Polygons')),
      body: MapMetrics(
        styleUrl:
            'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
        onMapCreated: (MapMetricsController controller) {
          mapController = controller;
        },
        initialCameraPosition: CameraPosition(
          target: LatLng(48.0, 8.0),
          zoom: 4.0,
        ),
        onStyleLoaded: () {
          _addMultiplePolygons();
        },
      ),
    );
  }

  void _addMultiplePolygons() {
    final featureCollection = {
      'type': 'FeatureCollection',
      'features': [
        {
          'type': 'Feature',
          'properties': {'name': 'France', 'color': 'blue'},
          'geometry': {
            'type': 'Polygon',
            'coordinates': [
              [
                [-1.75, 43.3],
                [3.0, 43.3],
                [7.7, 43.8],
                [8.2, 48.9],
                [2.5, 51.1],
                [-4.8, 48.5],
                [-1.75, 43.3],
              ]
            ],
          },
        },
        {
          'type': 'Feature',
          'properties': {'name': 'Germany', 'color': 'red'},
          'geometry': {
            'type': 'Polygon',
            'coordinates': [
              [
                [5.9, 47.3],
                [15.0, 47.3],
                [15.0, 55.0],
                [5.9, 55.0],
                [5.9, 47.3],
              ]
            ],
          },
        },
      ],
    };

    mapController?.addGeoJsonSource('countries', featureCollection);

    // Fill layer with semi-transparent color
    mapController?.addFillLayer(
      'countries-fill',
      'countries',
      fillColor: '#3b82f6',
      fillOpacity: 0.2,
    );

    // Outline layer
    mapController?.addLineLayer(
      'countries-outline',
      'countries',
      lineColor: '#1e40af',
      lineWidth: 2.0,
    );
  }
}

Polygon with Hole

Create a polygon with a cutout hole inside:

dart
void _addPolygonWithHole() {
  final geoJson = {
    'type': 'Feature',
    'properties': {},
    'geometry': {
      'type': 'Polygon',
      'coordinates': [
        // Outer ring
        [
          [2.2800, 48.8200],
          [2.4200, 48.8200],
          [2.4200, 48.8900],
          [2.2800, 48.8900],
          [2.2800, 48.8200],
        ],
        // Inner ring (hole)
        [
          [2.3300, 48.8450],
          [2.3700, 48.8450],
          [2.3700, 48.8650],
          [2.3300, 48.8650],
          [2.3300, 48.8450],
        ],
      ],
    },
  };

  mapController?.addGeoJsonSource('polygon-hole', geoJson);

  mapController?.addFillLayer(
    'polygon-hole-fill',
    'polygon-hole',
    fillColor: '#22c55e',
    fillOpacity: 0.4,
  );

  mapController?.addLineLayer(
    'polygon-hole-outline',
    'polygon-hole',
    lineColor: '#15803d',
    lineWidth: 2.0,
  );
}

GeoJSON Polygon Properties

PropertyTypeDescription
fillColorStringFill color as hex string
fillOpacitydoubleFill opacity from 0.0 to 1.0
lineColorStringOutline color as hex string
lineWidthdoubleOutline width in pixels

Next Steps


Tip: Always close polygon rings — the first and last coordinate must be identical. Use FeatureCollection to group multiple polygons into one source for better performance.