diff --git a/lib/cartopy/io/img_tiles.py b/lib/cartopy/io/img_tiles.py index b048dbd4f..7d201d0c4 100644 --- a/lib/cartopy/io/img_tiles.py +++ b/lib/cartopy/io/img_tiles.py @@ -680,3 +680,39 @@ def _merge_tiles(tiles): img[img_slice] = tile_img return img, [min(xs), max(xs), min(ys), max(ys)], 'lower' + + +class AzureMapsTiles(GoogleWTS): + + def __init__(self, subscription_key, tileset_id="microsoft.imagery", + api_version="2.0", desired_tile_form='RGB', cache=False): + """ + Set up a new instance to retrieve tiles from Azure Maps. + + Access to Azure Maps REST API requires a subscription key. + See https://docs.microsoft.com/en-us/azure/azure-maps/azure-maps-authentication#shared-key-authentication/ # noqa: E501 + for details. + + Parameters + ---------- + subscription_key + A valid Azure Maps subscription key. + tileset_id + A tileset ID for a map. See + https://docs.microsoft.com/en-us/rest/api/maps/renderv2/getmaptilepreview#tilesetid # noqa: E501 + for details. + api_version + API version to use. Defaults to 2.0 as recommended by Microsoft. + + """ + super().__init__(desired_tile_form=desired_tile_form, cache=cache) + self.subscription_key = subscription_key + self.tileset_id = tileset_id + self.api_version = api_version + + def _image_url(self, tile): + url = ('https://atlas.microsoft.com/map/tile?' + 'api-version={self.api_version}&tilesetId={self.tileset_id}' + '&x={x}&y={y}&zoom={z}&' + 'subscription-key={self.subscription_key}') + return url.format(self=self, x=tile[0], y=tile[1], z=tile[2]) diff --git a/lib/cartopy/tests/test_img_tiles.py b/lib/cartopy/tests/test_img_tiles.py index a4f5d032a..c5e292ab5 100644 --- a/lib/cartopy/tests/test_img_tiles.py +++ b/lib/cartopy/tests/test_img_tiles.py @@ -290,6 +290,44 @@ def test_ordnance_survey_get_image(): assert extent1 == extent2 +def test_azuremaps_tiles_api_url(): + subscription_key = 'foo' + tileset_id = 'bar' + tile = [0, 1, 2] + + exp_url = ('https://atlas.microsoft.com/map/tile?api-version=2.0' + '&tilesetId=bar&x=0&y=1&zoom=2&subscription-key=foo') + + az_maps_sample = cimgt.AzureMapsTiles(subscription_key, tileset_id) + url_str = az_maps_sample._image_url(tile) + assert url_str == exp_url + + +@pytest.mark.network +def test_azuremaps_get_image(): + # In order to test fetching map images from Azure Maps + # an API key needs to be provided + try: + api_key = os.environ['AZURE_MAPS_SUBSCRIPTION_KEY'] + except KeyError: + pytest.skip('AZURE_MAPS_SUBSCRIPTION_KEY environment variable ' + 'is unset.') + + am1 = cimgt.AzureMapsTiles(api_key, tileset_id="microsoft.imagery") + am2 = cimgt.AzureMapsTiles(api_key, tileset_id="microsoft.base.road") + + tile = (500, 300, 10) + + img1, extent1, _ = am1.get_image(tile) + img2, extent2, _ = am2.get_image(tile) + + # Different images for different layers + assert img1 != img2 + + # The extent is the same though + assert extent1 == extent2 + + @pytest.mark.network @pytest.mark.parametrize('cache_dir', ["tmpdir", True, False]) def test_cache(cache_dir, tmpdir):