Easily Visualize OpenStreetMaps and Bing Maps in Flutter
Tags: flutter, dart, mobile, maps
Published: 2020-12-07 09:22:28

---
title: Easily Visualize OpenStreetMaps and Bing Maps in Flutter
published: true
date: 2020-11-26 11:00:50 UTC
tags: flutter, dart, mobile, maps
canonical_url: https://www.syncfusion.com/blogs/post/easily-visualize-openstreetmaps-and-bing-maps-in-flutter.aspx
cover_image: https://www.syncfusion.com/blogs/wp-content/uploads/2020/11/Easily-Visualize-OpenStreetMaps-and-Bing-Maps-in-Flutter-672x372.png
---

The [shape layer](https://dev.to/sureshmohan/introducing-the-new-maps-widget-in-flutter-544k-temp-slug-4970983) in the [Syncfusion Flutter Maps widget](https://www.syncfusion.com/flutter-widgets/flutter-maps) renders geographical areas from the GeoJSON data. Another popular style of map visualization, though, is to load map tiles or images from web map tile services ([WMTS](https://en.wikipedia.org/wiki/Web_Map_Tile_Service)) such as Bing Maps, OpenStreetMaps, Google Maps, and TomTom. We are excited to inform you that this [tile layer](https://help.syncfusion.com/flutter/maps/tile-layer#setting-url-template) rendering support has been included in our Syncfusion Flutter Maps widget in the [Essential Studio 2020 Volume 3](https://www.syncfusion.com/forums/158306/essential-studio-2020-volume-3-release-v18-3-0-35-is-available-for-download) release. This allows rendering tiles from these tile providers.

In this blog, we will look at the tile layer and how to add it in the [Flutter Maps](https://www.syncfusion.com/flutter-widgets/flutter-maps) widget to render tiles from providers like OpenStreetMap and Bing Maps. We will also briefly talk about adding markers and enabling the zooming and panning features in the tile layer.

## What is the tile layer?

The web map tile services, like OpenStreetMaps and Bing Maps, provide a single tile of **256 \* 256** pixels for every request for the region we ask for. Our newly introduced tile layer does this efficiently and arranges multiple tiles in appropriate positions to render the complete map.

You can then interact with this layer to have a closer look at a specific region by pinching and then panning across the map to check the places nearby.

![Tile Layer in Flutter Maps](https://www.syncfusion.com/blogs/wp-content/uploads/2020/11/Tile-Layer-in-Flutter-Maps.gif)<figcaption>Tile Layer in Flutter Maps</figcaption>

## Adding an OpenStreetMap

If you are looking for a cost-effective map tile provider, then the [OpenStreetMap](https://www.openstreetmap.org/#map=4/19.30/82.45) will best suit you. This is a widely used, free WMTS for mobile applications and websites, meeting the requirement of basic map rendering.

| **Disclaimer:**  OpenStreetMaps may be used free of cost. However, we recommend you check the licensing terms on their official website to make sure. |

The following code example explains the procedure to add the tile layer to the Maps widget with OpenStreetMap.

```dart
@override
Widget build(BuildContext context) {
  return SfMaps(
    layers: [
      MapTileLayer(
         urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
         initialZoomLevel: 2,
         initialFocalLatLng: MapLatLng(28.644800, 77.216721),
       ),
     ],
  );
}
```

![OpenStreetMap in Syncfusion Flutter Maps](https://www.syncfusion.com/blogs/wp-content/uploads/2020/11/OpenStreetMap-in-Syncfusion-Flutter-Maps-1-1.png)<figcaption>OpenStreetMap in Syncfusion Flutter Maps</figcaption>

### URL template

The [urlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/urlTemplate.html) property accepts the URL in WMTS format, i.e. {z} zoom level and {x} and {y} tile coordinates.

This URL might vary slightly depending on the providers. The formats can be:

[https://exampleprovider/{z}/{x}/{y}.png](https://exampleprovider/%7bz%7d/%7bx%7d/%7by%7d.png),

[https://exampleprovider/z={z}/x={x}/y={y}.png](https://exampleprovider/z=%7Bz%7D/x=%7Bx%7D/y=%7By%7D.png),

[https://exampleprovider/z={z}/x={x}/y={y}.png?key=subscription\_key](https://exampleprovider/z=%7Bz%7D/x=%7Bx%7D/y=%7By%7D.png?key=subscription_key), etc.

We will replace the {z}, {x}, and {y} internally based on the current focal point and the zoom level.

A subscription key may be needed for some of the providers, like Bing Maps. Please include it in the [urlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/urlTemplate.html) itself.

**Note:** The format may vary among map providers. You can check the exact URL format needed for the providers on their official websites.

### How tiles are rendered in the tile layer

At the lowest zoom level (level 0), the map is of 256 x 256 pixels and the whole world map will be rendered as a single tile. In each consecutive level, the map width and height grow by a factor of 2. So level 1 is 512 x 512 pixels with four tiles ((0, 0), (0, 1), (1, 0), (1, 1) where 0 and 1 are {x} and {y} in the [urlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/urlTemplate.html)), level 2 is 2048 x 2048 pixels with 8 tiles (from (0, 0) to (3, 3)), and so on.

However, the number of tiles needed in the current viewport alone will be requested and rendered initially. If you have enabled zooming and panning, other required tiles will be requested on demand and rendered during interaction.

### Enable zooming and panning

If you want to enable dynamic zooming and panning, please refer to the following code snippet. You can zoom in on the tile layer for a closer look at a specific region by:

- Pinching on touch devices.
- Scrolling the mouse wheel or trackpad.
- Using the toolbar on the web.

```dart
MapZoomPanBehavior _zoomPanBehavior;

  @override
  void initState() {
    _zoomPanBehavior = MapZoomPanBehavior();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SfMaps(
      layers: [
        MapTileLayer(
          urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
          initialZoomLevel: 2,
          initialFocalLatLng: MapLatLng(28.644800, 77.216721),
          zoomPanBehavior: _zoomPanBehavior,
        ),
      ],
    );
  }
```

![Zooming and Panning in the Tile Layer](https://www.syncfusion.com/blogs/wp-content/uploads/2020/11/Zooming-and-Panning-in-the-Tile-Layer-3.gif)<figcaption>Zooming and Panning in the Tile Layer</figcaption>

| **Note:** [MapZoomPanBehavior](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/zoomPanBehavior.html) objects are expected to be long-lived, not recreated with each build. |

While zooming and panning, new tiles will be requested and rendered. After the interaction, the current zoom level and the focal point can be obtained from the [MapZoomPanBehavior.zoomLevel](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapZoomPanBehavior/zoomLevel.html) and [MapZoomPanBehavior.focalLatLng](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapZoomPanBehavior/focalLatLng.html) properties, respectively. These properties can also be set dynamically.

## Adding Bing Maps

Adding Bing Maps to the MapTileLayer is the same as adding OpenStreetMaps except for the way we set the [urlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/urlTemplate.html) property.

For [Bing Maps](https://www.bing.com/maps), an additional step is required. The format of the required URL varies from the other tile services. So, we have added a top-level [getBingUrlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/getBingUrlTemplate.html) function that returns the URL in the required format. You can use the URL returned from this function to set it to the [urlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/urlTemplate.html) property.

A subscription key is needed for Bing Maps. It has to be added to the [urlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/urlTemplate.html) itself. Also, Bing Maps provides map types like Road, Aerial, and AerialWithLabelsOnDemand. These types, too, should be added in the [urlTemplate](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/urlTemplate.html) itself, as shown in the following code example. You can check the official websites of the tile providers to learn about the available types and the code for them.

Other than these differences, everything is exactly the same among all the different types of tile providers.

```dart
@override
Widget build(BuildContext context) {
  String bingKey =
      'SUBSCRIPTION_KEY';
  return Scaffold(
    body: Center(
       child: Container(
            child: FutureBuilder(
          future: getBingUrlTemplate(
              'https://dev.virtualearth.net/REST/V1/Imagery/Metadata/AerialWithLabelsOnDemand?output=json&uriScheme=https&include=ImageryProviders&key='+bingKey),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.connectionState == ConnectionState.done &&
                snapshot.hasData) {
              final String urlTemplate = snapshot.data;
              return SfMaps(
                layers: [
                  MapTileLayer(
                    initialZoomLevel: 2,
                    initialFocalLatLng: MapLatLng(28.644800, 77.216721),
                    urlTemplate: urlTemplate,
                  ),
                ],
              );
            } else {
              return const Center(child: CircularProgressIndicator());
            }
          },
       )),
     ),
  );
}
```

![Adding Bing Maps](https://www.syncfusion.com/blogs/wp-content/uploads/2020/11/Adding-Bing-Maps-1-1-1.png)<figcaption>Adding Bing Maps</figcaption>

## Other tile providers

In addition to OpenStreetMap and Bing Maps, it is possible to render other tile providers like [Google Maps](https://www.google.com/maps) or [TomTom](https://www.tomtom.com/en_us/drive/maps-services/maps/), which follow the WMTS format. For example, tiles from TomTom can be rendered like the following code.

**Note:** You have to append the subscription key at the end of the URL as we did for Bing Maps.

```dart
@override
Widget build(BuildContext context) {
  return SfMaps(
    layers: [
      MapTileLayer(
        urlTemplate: 'https://api.tomtom.com/map/1/tile/basic/main/{z}/{x}/{y}.png?key=SUBSCRIPTION_KEY',
        initialZoomLevel: 2,
        initialFocalLatLng: MapLatLng(28.644800, 77.216721),
      ),
    ],
  );
}
```

## Adding markers

As in the shape layer, you can add markers in the tile layer with exactly the same approach. They can be used to denote specific latitude and longitude in the tile layer as required by the user. You can use the built-in shapes (circles, diamonds, squares, and triangles) or any type of custom widget as a marker.

The [markerBuilder](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/markerBuilder.html) callback will be called the number of times of the value specified in the [initialMarkersCount](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapLayer/initialMarkersCount.html) property.

| **Note:** If you want to dynamically add the markers, please refer to [this](https://pub.dev/documentation/syncfusion_flutter_maps/latest/maps/MapTileLayer/controller.html) section. |

Refer to the following code example.

```dart
class _MyHomePageState extends State {
  List _data;

  @override
  void initState() {
    _data = const [
      Model('Brazil', -14.235004, -51.92528),
      Model('Germany', 51.16569, 10.451526),
      Model('Australia', -25.274398, 133.775136),
      Model('India', 20.593684, 78.96288),
      Model('Russia', 61.52401, 105.318756)
    ];

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          child: SfMaps(
            layers: [
              MapTileLayer(
                urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                initialZoomLevel: 2,
                initialFocalLatLng: MapLatLng(28.644800, 77.216721),
                initialMarkersCount: 5,
                markerBuilder: (BuildContext context, int index) {
                  return MapMarker(
                    latitude: _data[index].latitude,
                    longitude: _data[index].longitude,
                    iconColor: Colors.white,
                    iconStrokeColor: Colors.black,
                    iconStrokeWidth: 2,
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class Model {
  const Model(this.country, this.latitude, this.longitude);

  final String country;
  final double latitude;
  final double longitude;
}
```

![Adding Markers to the Tile Layer](https://www.syncfusion.com/blogs/wp-content/uploads/2020/11/Adding-Markers-to-the-Tile-Layer-1.png)<figcaption>Adding Markers to the Tile Layer</figcaption>

## Conclusion

In this blog post, we walked you through the new tile layer support included in the [Flutter Maps](https://www.syncfusion.com/flutter-widgets/flutter-maps) widget in our [2020 Volume 3 release](https://www.syncfusion.com/forums/158306/essential-studio-2020-volume-3-release-v18-3-0-35-is-available-for-download). You can download the latest setup [here](https://www.syncfusion.com/products/whatsnew). Try out this new feature and share your feedback in the comments section below.

Check out the complete [user guide](https://help.syncfusion.com/flutter/maps/) and see our samples in this [GitHub location](https://github.com/syncfusion/flutter-examples). Additionally, you can check out our demo apps in [Google Play Store](https://play.google.com/store/apps/details?id=com.syncfusion.flutter.examples&hl=en), [App Store](https://apps.apple.com/in/app/syncfusion-flutter-ui-widgets/id1475231341), and on our [website](https://flutter.syncfusion.com/#/).

If you need a new widget for the Flutter framework or new features in our existing widgets, you can contact us through our [support forums](https://www.syncfusion.com/forums), [Direct-Trac](https://www.syncfusion.com/support/directtrac/incidents), or [feedback portal](https://www.syncfusion.com/feedback/flutter). As always, we are happy to assist you!