def _wmts_images(self, wmts, layer, matrix_set_name, extent, max_pixel_span): """ Add images from the specified WMTS layer and matrix set to cover the specified extent at an appropriate resolution. The zoom level (aka. tile matrix) is chosen to give the lowest possible resolution which still provides the requested quality. If insufficient resolution is available, the highest available resolution is used. Parameters ---------- wmts The owslib.wmts.WebMapTileService providing the tiles. layer The owslib.wmts.ContentMetadata (aka. layer) to draw. matrix_set_name The name of the matrix set to use. extent Tuple of (left, right, bottom, top) in Axes coordinates. max_pixel_span Preferred maximum pixel width or height in Axes coordinates. """ # Find which tile matrix has the appropriate resolution. tile_matrix_set = wmts.tilematrixsets[matrix_set_name] tile_matrices = tile_matrix_set.tilematrix.values() meters_per_unit = METERS_PER_UNIT[tile_matrix_set.crs] tile_matrix = self._choose_matrix(tile_matrices, meters_per_unit, max_pixel_span) # Determine which tiles are required to cover the requested extent. tile_span_x, tile_span_y = self._tile_span(tile_matrix, meters_per_unit) tile_matrix_set_links = getattr(layer, 'tilematrixsetlinks', None) if tile_matrix_set_links is None: tile_matrix_limits = None else: tile_matrix_set_link = tile_matrix_set_links[matrix_set_name] tile_matrix_limits = tile_matrix_set_link.tilematrixlimits.get( tile_matrix.identifier) min_col, max_col, min_row, max_row = self._select_tiles( tile_matrix, tile_matrix_limits, tile_span_x, tile_span_y, extent) # Find the relevant section of the image cache. tile_matrix_id = tile_matrix.identifier cache_by_wmts = WMTSRasterSource._shared_image_cache cache_by_layer_matrix = cache_by_wmts.setdefault(wmts, {}) image_cache = cache_by_layer_matrix.setdefault((layer.id, tile_matrix_id), {}) # To avoid nasty seams between the individual tiles, we # accumulate the tile images into a single image. big_img = None n_rows = 1 + max_row - min_row n_cols = 1 + max_col - min_col # Ignore out-of-range errors if the current version of OWSLib # doesn't provide the regional information. ignore_out_of_range = tile_matrix_set_links is None for row in range(min_row, max_row + 1): for col in range(min_col, max_col + 1): # Get the tile's Image from the cache if possible. img_key = (row, col) img = image_cache.get(img_key) if img is None: try: tile = wmts.gettile( layer=layer.id, tilematrixset=matrix_set_name, tilematrix=str(tile_matrix_id), row=str(row), column=str(col), **self.gettile_extra_kwargs) except owslib.util.ServiceException as exception: if ('TileOutOfRange' in exception.message and ignore_out_of_range): continue raise exception img = Image.open(io.BytesIO(tile.read())) image_cache[img_key] = img if big_img is None: size = (img.size[0] * n_cols, img.size[1] * n_rows) big_img = Image.new('RGBA', size, (255, 255, 255, 255)) top = (row - min_row) * tile_matrix.tileheight left = (col - min_col) * tile_matrix.tilewidth big_img.paste(img, (left, top)) if big_img is None: img_extent = None else: matrix_min_x, matrix_max_y = tile_matrix.topleftcorner min_img_x = matrix_min_x + tile_span_x * min_col max_img_y = matrix_max_y - tile_span_y * min_row img_extent = (min_img_x, min_img_x + n_cols * tile_span_x, max_img_y - n_rows * tile_span_y, max_img_y) return big_img, img_extent
def _wmts_images(self, wmts, layer, matrix_set_name, extent, max_pixel_span): """ Add images from the specified WMTS layer and matrix set to cover the specified extent at an appropriate resolution. The zoom level (aka. tile matrix) is chosen to give the lowest possible resolution which still provides the requested quality. If insufficient resolution is available, the highest available resolution is used. Args: * wmts - The owslib.wmts.WebMapTileService providing the tiles. * layer - The owslib.wmts.ContentMetadata (aka. layer) to draw. * matrix_set_name - The name of the matrix set to use. * extent - Tuple of (left, right, bottom, top) in Axes coordinates. * max_pixel_span - Preferred maximum pixel width or height in Axes coordinates. """ # Find which tile matrix has the appropriate resolution. tile_matrix_set = wmts.tilematrixsets[matrix_set_name] tile_matrices = tile_matrix_set.tilematrix.values() meters_per_unit = METERS_PER_UNIT[tile_matrix_set.crs] tile_matrix = self._choose_matrix(tile_matrices, meters_per_unit, max_pixel_span) # Determine which tiles are required to cover the requested extent. tile_span_x, tile_span_y = self._tile_span(tile_matrix, meters_per_unit) tile_matrix_set_links = getattr(layer, 'tilematrixsetlinks', None) if tile_matrix_set_links is None: tile_matrix_limits = None else: tile_matrix_set_link = tile_matrix_set_links[matrix_set_name] tile_matrix_limits = tile_matrix_set_link.tilematrixlimits.get( tile_matrix.identifier) min_col, max_col, min_row, max_row = self._select_tiles( tile_matrix, tile_matrix_limits, tile_span_x, tile_span_y, extent) # Find the relevant section of the image cache. tile_matrix_id = tile_matrix.identifier cache_by_wmts = WMTSRasterSource._shared_image_cache cache_by_layer_matrix = cache_by_wmts.setdefault(wmts, {}) image_cache = cache_by_layer_matrix.setdefault((layer.id, tile_matrix_id), {}) # To avoid nasty seams between the individual tiles, we # accumulate the tile images into a single image. big_img = None n_rows = 1 + max_row - min_row n_cols = 1 + max_col - min_col # Ignore out-of-range errors if the current version of OWSLib # doesn't provide the regional information. ignore_out_of_range = tile_matrix_set_links is None for row in range(min_row, max_row + 1): for col in range(min_col, max_col + 1): # Get the tile's Image from the cache if possible. img_key = (row, col) img = image_cache.get(img_key) if img is None: try: tile = wmts.gettile( layer=layer.id, tilematrixset=matrix_set_name, tilematrix=tile_matrix_id, row=row, column=col) except owslib.util.ServiceException as exception: if ('TileOutOfRange' in exception.message and ignore_out_of_range): continue raise exception img = Image.open(io.BytesIO(tile.read())) image_cache[img_key] = img if big_img is None: size = (img.size[0] * n_cols, img.size[1] * n_rows) big_img = Image.new('RGBA', size, (255, 255, 255, 255)) top = (row - min_row) * tile_matrix.tileheight left = (col - min_col) * tile_matrix.tilewidth big_img.paste(img, (left, top)) if big_img is None: img_extent = None else: matrix_min_x, matrix_max_y = tile_matrix.topleftcorner min_img_x = matrix_min_x + tile_span_x * min_col max_img_y = matrix_max_y - tile_span_y * min_row img_extent = (min_img_x, min_img_x + n_cols * tile_span_x, max_img_y - n_rows * tile_span_y, max_img_y) return big_img, img_extent
iks, igrek = convertDegrees(58.3953, 15.5596) # iks, igrek = (90+ (-54.611667), 180 + 18.808056) # iks, igrek = (40.7127,180 + -74.0059) le_z = 0 divider = ((0.5625 * 512) / pow(2, le_z)) le_x = int(floor(iks / divider)) le_y = int(floor(igrek / divider)) print(le_x, le_y) # tile = wmts.gettile(layer='MODIS_Terra_CorrectedReflectance_TrueColor', tilematrixset='EPSG4326_250m', tilematrix=le_z, row=le_x, column=le_y, format="image/jpeg", time="2016-04-22") tile = wmts.gettile(layer='MLS_HNO3_46hPa_Day', tilematrixset='EPSG4326_2km', tilematrix=le_z, row=le_x, column=le_y, format="image/png") out = open('nasa_modis_terra_truecolour.png', 'wb') bytes_written = out.write(tile.read()) out.close() wmts = WebMapTileService( 'http://data.geus.dk/arcgis/rest/services/OneGeologyGlobal/S071_G2500_OneGeology/MapServer/WMTS/1.0.0/WMTSCapabilities.xml' )
# iks, igrek = (8421281.093346566, 3375105.7843203144) def convertDegrees(lat, lon): return (90 - lat, 180 + lon) iks, igrek = convertDegrees(58.3953, 15.5596) # iks, igrek = (90+ (-54.611667), 180 + 18.808056) # iks, igrek = (40.7127,180 + -74.0059) le_z = 0 divider = ((0.5625 * 512)/ pow(2,le_z)); le_x = int(floor(iks/divider)) le_y = int(floor(igrek/divider)) print(le_x, le_y) # tile = wmts.gettile(layer='MODIS_Terra_CorrectedReflectance_TrueColor', tilematrixset='EPSG4326_250m', tilematrix=le_z, row=le_x, column=le_y, format="image/jpeg", time="2016-04-22") tile = wmts.gettile(layer='MLS_HNO3_46hPa_Day', tilematrixset='EPSG4326_2km', tilematrix=le_z, row=le_x, column=le_y, format="image/png") out = open('nasa_modis_terra_truecolour.png', 'wb') bytes_written = out.write(tile.read()) out.close() wmts = WebMapTileService('http://data.geus.dk/arcgis/rest/services/OneGeologyGlobal/S071_G2500_OneGeology/MapServer/WMTS/1.0.0/WMTSCapabilities.xml')