def test_bounds_invalid_obj(geometry): with pytest.raises( ValueError, match= "geometry must be a GeoJSON-like geometry, GeometryCollection, or FeatureCollection" ): bounds(geometry)
def test_bounds_existing_bbox(basic_featurecollection): """Test with existing bbox in geojson. Similar to that produced by rasterio. Values specifically modified here for testing, bboxes are not valid as written. """ fc = basic_featurecollection fc['bbox'] = [0, 10, 10, 20] fc['features'][0]['bbox'] = [0, 100, 10, 200] assert bounds(fc['features'][0]) == (0, 100, 10, 200) assert bounds(fc) == (0, 10, 10, 20)
def test_bounds_geometry_collection(): gc = { 'type': 'GeometryCollection', 'geometries': [ {'type': 'Point', 'coordinates': [1, 1]}, {'type': 'LineString', 'coordinates': [[-10, -20], [10, 20]]}, {'type': 'Polygon', 'coordinates': [[[5, 5], [25, 50], [25, 5]]]} ] } assert bounds(gc) == (-10, -20, 25, 50) assert bounds(MockGeoInterface(gc)) == (-10, -20, 25, 50)
def test_feature_collection(): fc = { 'features': [{ 'geometry': { 'coordinates': [ [[-107, 40], [-106, 40], [-106, 41], [-107, 41], [-107, 40]] ], 'type': 'Polygon' }, 'type': 'Feature' }], 'type': 'FeatureCollection' } assert bounds(fc['features'][0]) == (-107, 40, -106, 41) assert bounds(fc) == (-107, 40, -106, 41)
def zonal_stats(feature, raster, band=1, f_crs=None): """ A stripped down version of rasterstats.zonal_stats. This circumvents issues with shapely to prevent errors with GEOS setup. Feature is assumed to be geographic (WGS84) unless a separate CRS is specified. :param feature A dictionary that adheres to the __geo_interface__ for a Feature. :param raster The path to a rasterio-readable dataset. :param band The band to perform the zonal statistics on. :param f_crs The feature's coordinate reference system. Default is geographic (WGS84). """ if f_crs is None: f_crs = {'init': 'EPSG:4326'} with rasterio.open(raster, 'r') as src: # Get the overall raster affine src_affine = src.transform # What's the nodata value? nodata = src.nodata # Project geometry to src CRS geom = transform_geom(f_crs, src.crs, feature['geometry']) # Get bounds geom_bounds = features.bounds(geom) # Get the source data from the bounds fsrc, shape, affine = read_window(src, src_affine, geom_bounds, band=band) # Get the rasterized geometry with similar affine and shape rv_array = rasterize_geom(geom, affine=affine, shape=shape) # Get a nodata mask isnodata = (fsrc == nodata) # Add a nan mask if numpy.issubdtype(fsrc.dtype, float) and numpy.isnan(fsrc.min()): isnodata = (isnodata | numpy.isnan(fsrc)) # Create the masked array masked = numpy.ma.MaskedArray(fsrc, mask=(isnodata | ~rv_array)) # Calculate pixel counts if masked.compressed().size == 0: feature_stats = {} else: keys, counts = numpy.unique(masked.compressed(), return_counts=True) feature_stats = dict( dict( zip([numpy.asscalar(k) for k in keys], [numpy.asscalar(c) for c in counts]))) return feature_stats, masked
def test_bounds_existing_bbox(): """ Test with existing bbox in geojson, similar to that produced by rasterio. Values specifically modified here for testing, bboxes are not valid as written. """ fc = { 'bbox': [-107, 40, -105, 41], 'features': [{ 'bbox': [-107, 40, -104, 42], 'geometry': { 'coordinates': [ [[-107, 40], [-106, 40], [-106, 41], [-107, 41], [-107, 40]] ], 'type': 'Polygon' }, 'type': 'Feature' }], 'type': 'FeatureCollection' } assert bounds(fc['features'][0]) == (-107, 40, -104, 42) assert bounds(fc) == (-107, 40, -105, 41)
def test_feature_collection(basic_featurecollection): fc = basic_featurecollection assert bounds(fc) == bounds(fc['features'][0]) == (2, 2, 4.25, 4.25)
def test_bounds_invalid_obj(): with pytest.raises(KeyError): bounds({'type': 'bogus', 'not_coordinates': []})
def test_bounds_z(): g = {'type': 'Point', 'coordinates': [10, 10, 10]} assert bounds(g) == (10, 10, 10, 10) assert bounds(MockGeoInterface(g)) == (10, 10, 10, 10)
def test_bounds_polygon(): g = {'type': 'Polygon', 'coordinates': [[[0, 0], [10, 10], [10, 0]]]} assert bounds(g) == (0, 0, 10, 10) assert bounds(MockGeoInterface(g)) == (0, 0, 10, 10)
def test_bounds_polygon(): g = {'type': 'Polygon', 'coordinates': [[[0, 0], [10, 10], [10, 0]]]} assert bounds(g) == (0, 0, 10, 10)
def test_bounds_ring(): g = {'type': 'LinearRing', 'coordinates': [[0, 0], [10, 10], [10, 0]]} assert bounds(g) == (0, 0, 10, 10) assert bounds(MockGeoInterface(g)) == (0, 0, 10, 10)
def test_bounds_line(): g = {'type': 'LineString', 'coordinates': [[0, 0], [10, 10]]} assert bounds(g) == (0, 0, 10, 10)
def test_bounds_z(): g = {'type': 'Point', 'coordinates': [10, 10, 10]} assert bounds(g) == (10, 10, 10, 10)