def _get_reprojected_features( input_file=None, dst_bounds=None, dst_crs=None, validity_check=False ): logger.debug("reading %s", input_file) try: with fiona.open(input_file, 'r') as src: src_crs = CRS(src.crs) # reproject tile bounding box to source file CRS for filter if src_crs == dst_crs: dst_bbox = box(*dst_bounds) else: dst_bbox = reproject_geometry( box(*dst_bounds), src_crs=dst_crs, dst_crs=src_crs, validity_check=True ) for feature in src.filter(bbox=dst_bbox.bounds): try: # check validity original_geom = _repair(to_shape(feature['geometry'])) # clip with bounds and omit if clipped geometry is empty clipped_geom = original_geom.intersection(dst_bbox) # reproject each feature to tile CRS g = reproject_geometry( clean_geometry_type( clipped_geom, original_geom.geom_type, raise_exception=False ), src_crs=src_crs, dst_crs=dst_crs, validity_check=validity_check ) if not g.is_empty: yield { 'properties': feature['properties'], 'geometry': mapping(g) } # this can be handled quietly except TopologicalError as e: # pragma: no cover logger.warning("feature omitted: %s", e) except Exception as e: if path_exists(input_file): logger.error("error while reading file %s: %s", input_file, e) raise e else: raise FileNotFoundError("%s not found" % input_file)
def get_best_zoom_level(input_file, tile_pyramid_type): """ Determine the best base zoom level for a raster. "Best" means the maximum zoom level where no oversampling has to be done. Parameters ---------- input_file : path to raster file tile_pyramid_type : ``TilePyramid`` projection (``geodetic`` or``mercator``) Returns ------- zoom : integer """ tile_pyramid = BufferedTilePyramid(tile_pyramid_type) with rasterio.open(input_file, "r") as src: xmin, ymin, xmax, ymax = reproject_geometry( segmentize_geometry( box(src.bounds.left, src.bounds.bottom, src.bounds.right, src.bounds.top), get_segmentize_value(input_file, tile_pyramid)), src_crs=src.crs, dst_crs=tile_pyramid.crs).bounds x_dif = xmax - xmin y_dif = ymax - ymin size = float(src.width + src.height) avg_resolution = ((x_dif / float(src.width)) * (float(src.width) / size) + (y_dif / float(src.height)) * (float(src.height) / size)) for zoom in range(0, 40): if tile_pyramid.pixel_x_size(zoom) <= avg_resolution: return zoom - 1
def width_height(bounds): try: l, b, r, t = reproject_geometry(box(*bounds), src_crs=tile.crs, dst_crs=dst_pyramid.crs).bounds except ValueError: raise TopologicalError( "bounds cannot be translated into target CRS") return r - l, t - b
def _read_as_tiledir(self, out_tile=None, tiles_paths=None, **kwargs): return [ dict(feature, geometry=mapping( reproject_geometry(shape(feature["geometry"]), src_crs=tile.crs, dst_crs=out_tile.crs).intersection( out_tile.bbox))) for tile, _ in tiles_paths for feature in self.read(tile) ] # pragma: no cover