def _scaled_tile(self, tile, stop_zoom, rescaled_tiles): """ Try to load tile by loading, scaling and clipping tiles from zoom levels above or below. stop_zoom determines if tiles from above should be scaled up, or if tiles from below should be scaled down. Returns an empty Tile if tile zoom level is stop_zoom. """ if tile.coord in rescaled_tiles: return rescaled_tiles[tile.coord] # Cache tile in rescaled_tiles. We initially set source to a fixed # BlankImageSource and overwrite it if we actually rescaled the tile. tile.source = RESCALE_TILE_MISSING rescaled_tiles[tile.coord] = tile tile_bbox = self.grid.tile_bbox(tile.coord) current_zoom = tile.coord[2] if stop_zoom == current_zoom: return tile if stop_zoom > current_zoom: src_level = current_zoom + 1 else: src_level = current_zoom - 1 src_bbox, src_tile_grid, affected_tile_coords = self.grid.get_affected_level_tiles(tile_bbox, src_level) affected_tiles = TileCollection(affected_tile_coords) for t in affected_tiles: # Add sources of cached tiles, to avoid loading same tile multiple times # loading recursive. if t.coord in rescaled_tiles: t.source = rescaled_tiles[t.coord].source tile_collection = self._load_tile_coords( affected_tiles, rescale_till_zoom=stop_zoom, rescaled_tiles=rescaled_tiles, ) if tile_collection.blank: return tile tile_sources = [] for t in tile_collection: # Replace RESCALE_TILE_MISSING with None, before transforming tiles. tile_sources.append(t.source if t.source is not RESCALE_TILE_MISSING else None) tiled_image = TiledImage(tile_sources, src_bbox=src_bbox, src_srs=self.grid.srs, tile_grid=src_tile_grid, tile_size=self.grid.tile_size) tile.source = tiled_image.transform(tile_bbox, self.grid.srs, self.grid.tile_size, self.image_opts) if self.cache_rescaled_tiles: self.cache.store_tile(tile) return tile
def _image(self, query): try: src_bbox, tile_grid, affected_tile_coords = \ self.grid.get_affected_tiles(query.bbox, query.size, req_srs=query.srs) except NoTiles: raise BlankImage() except GridError as ex: raise MapBBOXError(ex.args[0]) num_tiles = tile_grid[0] * tile_grid[1] if self.max_tile_limit and num_tiles >= self.max_tile_limit: raise MapBBOXError( "too many tiles, max_tile_limit: %s, num_tiles: %s" % (self.max_tile_limit, num_tiles)) if query.tiled_only: if num_tiles > 1: raise MapBBOXError("not a single tile") bbox = query.bbox if not bbox_equals(bbox, src_bbox, abs((bbox[2] - bbox[0]) / query.size[0] / 10), abs((bbox[3] - bbox[1]) / query.size[1] / 10)): raise MapBBOXError("query does not align to tile boundaries") with self.tile_manager.session(): tile_collection = self.tile_manager.load_tile_coords( affected_tile_coords, with_metadata=query.tiled_only) if tile_collection.empty: raise BlankImage() if query.tiled_only: tile = tile_collection[0].source tile.image_opts = self.tile_manager.image_opts tile.cacheable = tile_collection[0].cacheable return tile tile_sources = [tile.source for tile in tile_collection] tiled_image = TiledImage(tile_sources, src_bbox=src_bbox, src_srs=self.grid.srs, tile_grid=tile_grid, tile_size=self.grid.tile_size) try: return tiled_image.transform(query.bbox, query.srs, query.size, self.tile_manager.image_opts) except ProjError: raise MapBBOXError("could not transform query BBOX") except IOError as ex: from mapproxy.source import SourceError raise SourceError("unable to transform image: %s" % ex)
def _image(self, query): try: src_bbox, tile_grid, affected_tile_coords = \ self.grid.get_affected_tiles(query.bbox, query.size, req_srs=query.srs) except NoTiles: raise BlankImage() except GridError as ex: raise MapBBOXError(ex.args[0]) num_tiles = tile_grid[0] * tile_grid[1] if self.max_tile_limit and num_tiles >= self.max_tile_limit: raise MapBBOXError("too many tiles") if query.tiled_only: if num_tiles > 1: raise MapBBOXError("not a single tile") bbox = query.bbox if not bbox_equals(bbox, src_bbox, abs((bbox[2]-bbox[0])/query.size[0]/10), abs((bbox[3]-bbox[1])/query.size[1]/10)): raise MapBBOXError("query does not align to tile boundaries") with self.tile_manager.session(): tile_collection = self.tile_manager.load_tile_coords(affected_tile_coords, with_metadata=query.tiled_only) if tile_collection.empty: raise BlankImage() if query.tiled_only: tile = tile_collection[0].source tile.image_opts = self.tile_manager.image_opts tile.cacheable = tile_collection[0].cacheable return tile tile_sources = [tile.source for tile in tile_collection] tiled_image = TiledImage(tile_sources, src_bbox=src_bbox, src_srs=self.grid.srs, tile_grid=tile_grid, tile_size=self.grid.tile_size) try: return tiled_image.transform(query.bbox, query.srs, query.size, self.tile_manager.image_opts) except ProjError: raise MapBBOXError("could not transform query BBOX") except IOError as ex: from mapproxy.source import SourceError raise SourceError("unable to transform image: %s" % ex)