Angelos Orfanakos

BingTileLayer component for React Leaflet

React Leaflet is a React library that exposes Leaflet classes as React components, making it very easy to add interactive maps to React web apps.

This is the second in a series of posts on how I use the library. My intention is to share back some of the things I’ve learned and implemented in the hope of them being useful to others.

In this post, I present the BingTileLayer component which exposes Bing Maps tile layers by wrapping leaflet-bing-layer as a React component.

First, the component:

import { createLayerComponent } from '@react-leaflet/core';
import bingTileLayer from 'leaflet-bing-layer';
import PropTypes from 'prop-types';

const IMAGERY_SETS = [  'Aerial',
  'AerialWithLabels',
  'AerialWithLabelsOnDemand',
  'CanvasDark',
  'CanvasLight',
  'CanvasGray',
  'Road',
  'RoadOnDemand',
  'OrdnanceSurvey',
];

const CULTURES = [  'af', 'am', 'ar-sa', 'as', 'az-Latn', 'be', 'bg', 'bn-BD',
  'bn-IN', 'bs', 'ca', 'ca-ES-valencia', 'cs', 'cy', 'da', 'de',
  'de-de', 'el', 'en-GB', 'en-US', 'es', 'es-ES', 'es-US', 'es-MX',
  'et', 'eu', 'fa', 'fi', 'fil-Latn', 'fr', 'fr-FR', 'fr-CA', 'ga',
  'gd-Latn', 'gl', 'gu', 'ha-Latn', 'he', 'hi', 'hr', 'hu', 'hy',
  'id', 'ig-Latn', 'is', 'it', 'it-it', 'ja', 'ka', 'kk', 'km',
  'kn', 'ko', 'kok', 'ku-Arab', 'ky-Cyrl', 'lb', 'lt', 'lv',
  'mi-Latn', 'mk', 'ml', 'mn-Cyrl', 'mr', 'ms', 'mt', 'nb', 'ne',
  'nl', 'nl-BE', 'nn', 'nso', 'or', 'pa', 'pa-Arab', 'pl',
  'prs-Arab', 'pt-BR', 'pt-PT', 'qut-Latn', 'quz', 'ro', 'ru',
  'rw', 'sd-Arab', 'si', 'sk', 'sl', 'sq', 'sr-Cyrl-BA',
  'sr-Cyrl-RS', 'sr-Latn-RS', 'sv', 'sw', 'ta', 'te', 'tg-Cyrl',
  'th', 'ti', 'tk-Latn', 'tn', 'tr', 'tt-Cyrl', 'ug-Arab', 'uk',
  'ur', 'uz-Latn', 'vi', 'wo', 'xh', 'yo-Latn', 'zh-Hans',
  'zh-Hant', 'zu',
];

const createBingTileLayer = (props, context) => {
  const instance = new bingTileLayer(props);

  // Fix attribution not showing initially.
  // TODO: Remove once
  // https://github.com/digidem/leaflet-bing-layer/pull/30
  // is merged.
  instance._onAdd = instance.onAdd;  instance.onAdd = function (map) {    this._onAdd(map);    this._updateAttribution();  };
  return { instance, context };
};

const BingTileLayer =
  createLayerComponent(createBingTileLayer, () => null);

BingTileLayer.propTypes = {
  bingMapsKey: PropTypes.string.isRequired,
  imagerySet: PropTypes.oneOf(IMAGERY_SETS),
  culture: PropTypes.oneOf(CULTURES),
  style: PropTypes.string,
};

BingTileLayer.defaultProps = {
  imagerySet: IMAGERY_SETS[0],  culture: CULTURES[19],  style: null,
};

export default BingTileLayer;

Things to note:

  • Line 5, 62: Possible values for imagerySet prop (default: 'Aerial')
  • Line 17, 63: Possible values for culture prop (default: 'en-US')
  • Line 42-46: A temporary hack to fix a bug in leaflet-bing-layer that prevents the attribution text from showing. I’ve created a pull request for this but the project seems dead.

And here’s how you’d use it in a map:

import React from 'react';

import BingTileLayer from './BingTileLayer';

const GREECE_BOUNDS = [
  [31.08, 14.26],
  [44.91, 34.69],
];

const BING_MAPS_KEY = 'mykey';
function MyMap() {
  return (
    <MapContainer
      bounds={GREECE_BOUNDS}
      style={{ width: '100%', height: '100vh' }}
    >
      <BingTileLayer         bingMapsKey={BING_MAPS_KEY}         imagerySet="AerialWithLabels"         culture="el"       />     </MapContainer>
  );
}

export default MyMap;

Things to note:

  • Line 10: Replace mykey with your Bing Maps key that you can obtain for free
  • Line 18-22: Example of using the component