コード例 #1
0
def vectorize_prediction_map(prediction_map):
    image_1001 = prediction_map.read(1)
    image_1005 = prediction_map.read(2)
    results_1001 = ({
        'properties': {
            'raster_val': v
        },
        'geometry': s
    } for i, (s, v) in enumerate(
        shapes(image_1001, mask=None, transform=prediction_map.transform)))
    results_1005 = ({
        'properties': {
            'raster_val': v
        },
        'geometry': s
    } for i, (s, v) in enumerate(
        shapes(image_1005, mask=None, transform=prediction_map.transform)))

    geoms_1001 = list(results_1001)
    geoms_1005 = list(results_1005)

    gpd_polygonized_raster_1001 = gpd.GeoDataFrame.from_features(geoms_1001)
    gpd_polygonized_raster_1005 = gpd.GeoDataFrame.from_features(geoms_1005)
    gpd_polygonized_raster_1001['Species'] = 1001
    gpd_polygonized_raster_1005['Species'] = 1005
    df_prediction = pd.concat(
        [gpd_polygonized_raster_1001,
         gpd_polygonized_raster_1005]).drop(columns=['raster_val'])
    return df_prediction
コード例 #2
0
ファイル: gisexport.py プロジェクト: ns-1m/pyfor
def array_to_polygons(array, affine=None):
    """
    Returns a geopandas dataframe of polygons as deduced from an array.

    :param array: The 2D numpy array to polygonize.
    :param affine: The affine transformation.
    :return:
    """
    if affine == None:
        results = [{
            'properties': {
                'raster_val': v
            },
            'geometry': s
        } for i, (s, v) in enumerate(shapes(array))]
    else:
        results = [{
            'properties': {
                'raster_val': v
            },
            'geometry': s
        } for i, (s, v) in enumerate(shapes(array, transform=affine))]

    tops_df = geopandas.GeoDataFrame({
        'geometry':
        [shape(results[geom]['geometry']) for geom in range(len(results))],
        'raster_val': [
            results[geom]['properties']['raster_val']
            for geom in range(len(results))
        ]
    })

    return (tops_df)
コード例 #3
0
ファイル: test_features.py プロジェクト: swoonpan/rasterio
def test_shapes_blank_mask(basic_image):
    """Mask is blank so results should mask shapes without mask."""
    assert np.array_equal(
        list(
            shapes(basic_image,
                   mask=np.ones(basic_image.shape, dtype=rasterio.bool_))),
        list(shapes(basic_image)))
コード例 #4
0
def test_shapes_blank_mask(basic_image):
    """Mask is blank so results should mask shapes without mask."""
    assert np.array_equal(
        list(shapes(
            basic_image,
            mask=np.ones(basic_image.shape, dtype=rasterio.bool_))
        ),
        list(shapes(basic_image))
    )
コード例 #5
0
ファイル: test_features.py プロジェクト: swoonpan/rasterio
def test_shapes_band(pixelated_image, pixelated_image_file):
    """Shapes from a band should match shapes from an array."""
    truth = list(shapes(pixelated_image))

    with rasterio.open(pixelated_image_file) as src:
        band = rasterio.band(src, 1)
        assert truth == list(shapes(band))

        # Mask band should function, but will mask out some results
        assert truth[0] == list(shapes(band, mask=band))[0]
コード例 #6
0
def test_shapes_band(pixelated_image, pixelated_image_file):
    """Shapes from a band should match shapes from an array."""
    truth = list(shapes(pixelated_image))

    with rasterio.open(pixelated_image_file) as src:
        band = rasterio.band(src, 1)
        assert truth == list(shapes(band))

        # Mask band should function, but will mask out some results
        assert truth[0] == list(shapes(band, mask=band))[0]
コード例 #7
0
def test_shapes_blank_mask(basic_image):
    """ Mask is blank so results should mask shapes without mask """

    with rasterio.drivers():
        assert numpy.array_equal(
            list(shapes(
                basic_image,
                mask=numpy.ones(basic_image.shape, dtype=rasterio.bool_))
            ),
            list(shapes(basic_image))
        )
コード例 #8
0
ファイル: raster.py プロジェクト: JohannesSMHI/BAWS
    def get_shapes_from_raster(raster, mask_file, daymaps=False):
        shapes_with_properties = []
        # crs, transform, area_shape = area2transform_baws300_sweref99tm()
        crs, transform, area_shape = area2transform_baws1000_sweref99tm()

        classes = {int(cls): {'class': int(cls)} for cls in np.unique(raster)}
        classes[0] = None

        if mask_file:
            with fiona.open(mask_file, "r") as shapefile:
                mask_features = [feature["geometry"] for feature in shapefile]
            mask = rasterize(mask_features, area_shape, transform=transform)
        else:
            mask = None

        if daymaps:
            covered = False
            for i, (s, v) in enumerate(
                    shapes(raster, mask=mask, transform=transform)):
                if v != 4:
                    covered = True
                if v in [0, 1, 4]:
                    continue
                shapes_with_properties.append({
                    'properties': classes[int(v)],
                    'geometry': s
                })
            if not covered:
                return None

            # Clouds ontop!
            for i, (s, v) in enumerate(shapes(raster, transform=transform)):
                if v in [0, 2, 3]:
                    continue
                shapes_with_properties.append({
                    'properties': classes[int(v)],
                    'geometry': s
                })
        else:
            covered = False
            for i, (s, v) in enumerate(
                    shapes(raster, mask=mask, transform=transform)):
                if v == 0:
                    continue
                shapes_with_properties.append({
                    'properties': classes[int(v)],
                    'geometry': s
                })

        return shapes_with_properties
コード例 #9
0
def snap(dataurl, out_url, out_url2):
    wbt = whitebox.WhiteboxTools()
    wbt.set_verbose_mode(False)
    wbt.work_dir = out_url
    wbt.snap_pour_points("point.shp",
                         "Flow_acc.tif",
                         "snap_point.shp",
                         snap_dist=0.01)
    wbt.watershed("Flow_dir.tif", "snap_point.shp", "Watershed.tif")
    # wbt.longest_flowpath("DEM_fill.tif","Watershed.tif",'LongestFlowpath.shp')
    # wbt.raster_to_vector_lines("Watershed.tif","Watershed.shp")

    # Convert basin raster file to polygon
    mask = None
    with rasterio.open(os.path.join(out_url, "Watershed.tif")) as src:
        image = src.read(1)  # first band
        results = ({
            'properties': {
                'raster_val': v
            },
            'geometry': s
        } for i, (
            s,
            v) in enumerate(shapes(image, mask=mask, transform=src.transform)))

    geoms = list(results)
    boundary = shapes(geoms[0]['geometry'])
    gpd_polygonized_raster = gpd.GeoDataFrame.from_features(geoms)
    # Filter nodata value
    gpd_polygonized_raster = gpd_polygonized_raster[
        gpd_polygonized_raster['raster_val'] == 1]
    # Convert to geojson
    boundary = gpd_polygonized_raster.to_json()
    gpd_polygonized_raster.to_file(driver='ESRI Shapefile',
                                   filename=os.path.join(
                                       out_url, "basin_boundary.shp"))
    wbt.clip_raster_to_polygon("DEM_out.tif", "basin_boundary.shp",
                               "DEM_watershed.tif")
    wbt.hypsometric_analysis("DEM_watershed.tif", "hypso.html")
    wbt.slope_vs_elevation_plot("DEM_watershed.tif", "Slope_elevation.html")
    wbt.extract_raster_statistics("DEM_out.tif",
                                  "Watershed.tif",
                                  output=None,
                                  stat="total",
                                  out_table="stat.html")
    wbt.raster_histogram("DEM_watershed.tif", "hist.html")
    X, Y = hyspoparser.hypso(os.path.join(out_url, "hypso.html"))
    stat = hyspoparser.stat(os.path.join(out_url, "stat.html"))

    return boundary, X, Y, stat
コード例 #10
0
def test_shapes_dtype():
    """Test image data type handling"""

    rows = cols = 10
    with rasterio.drivers():
        supported_types = (('int16', -32768), ('int32', -2147483648),
                           ('uint8', 255), ('uint16', 65535), ('float32',
                                                               1.434532))

        for dtype, test_value in supported_types:
            image = numpy.zeros((rows, cols), dtype=dtype)
            image[2:5, 2:5] = test_value

            shapes = ftrz.shapes(image)
            shape, value = next(shapes)
            if dtype == 'float32':
                assert round(value, 6) == round(test_value, 6)
            else:
                assert value == test_value

        # Unsupported types should all raise exceptions
        unsupported_types = (('int8', -127), ('uint32', 4294967295),
                             ('int64', 20439845334323), ('float16', -9343.232),
                             ('float64', -98332.133422114))

        for dtype, test_value in unsupported_types:
            with pytest.raises(ValueError):
                image = numpy.zeros((rows, cols), dtype=dtype)
                image[2:5, 2:5] = test_value
                shapes = ftrz.shapes(image)
                next(shapes)

        # Test mask types
        image = numpy.zeros((rows, cols), dtype='uint8')
        image.fill(255)
        supported_mask_types = (('bool', 1), ('uint8', 255))
        for dtype, mask_value in supported_mask_types:
            mask = numpy.zeros((rows, cols), dtype=dtype)
            mask[2:5, 2:5] = mask_value
            shapes = ftrz.shapes(image, mask=mask)
            shape, value = next(shapes)
            assert value == 255

        unsupported_mask_types = (('int8', -127), ('int16', -32768))
        for dtype, mask_value in unsupported_mask_types:
            with pytest.raises(ValueError):
                mask = numpy.zeros((rows, cols), dtype=dtype)
                mask[2:5, 2:5] = mask_value
                shapes = ftrz.shapes(image, mask=mask)
                next(shapes)
コード例 #11
0
ファイル: test_features.py プロジェクト: alexatodd/rasterio
def test_shapes_connectivity_rook(diagonal_image):
    """
    Diagonals are not connected, so there will be 1 feature per pixel plus
    background.
    """
    with rasterio.Env():
        assert len(list(shapes(diagonal_image, connectivity=4))) == 12
コード例 #12
0
def test_shapes_internal_driver_manager():
    """Access to shapes of labeled features"""
    image = numpy.zeros((20, 20), dtype=rasterio.ubyte)
    image[5:15,5:15] = 127
    shapes = ftrz.shapes(image)
    shape, val = next(shapes)
    assert shape['type'] == 'Polygon'
コード例 #13
0
ファイル: test_features.py プロジェクト: swoonpan/rasterio
def test_shapes_invalid_mask_dtype(basic_image):
    """A mask that is the wrong dtype should fail."""
    for dtype in ('int8', 'int16', 'int32'):
        with pytest.raises(ValueError):
            next(
                shapes(basic_image,
                       mask=np.ones(basic_image.shape, dtype=dtype)))
コード例 #14
0
ファイル: test_features.py プロジェクト: alexatodd/rasterio
def test_shapes_connectivity_queen(diagonal_image):
    """
    Diagonals are connected, so there will be 1 feature for all pixels plus
    background.
    """
    with rasterio.Env():
        assert len(list(shapes(diagonal_image, connectivity=8))) == 2
コード例 #15
0
def polygonize(input_path):
    with rasterio.open(input_path, mode='r+') as src:
        print("Polygonizing GeoTIFF")
        # from https://stackoverflow.com/questions/17615963/standard-rgb-to-grayscale-conversion
        r = src.read(1)
        g = src.read(2)
        b = src.read(3)

        rgb = (r * 256 ** 2) + g * 256 + b
        rgb = rgb.astype('float32')

        # Make a mask
        # mask = grayscale != 1
        # iterate over shapes.
        results = (
            {'properties': {'raster_val': v}, 'geometry': s}
            for i, (s, v) in enumerate(features.shapes(rgb, transform=src.transform)))
        with fiona.open(
                'GOES17_Poly'
                '.json', 'w',
                driver='GeoJSON',
                crs=src.crs.wkt,
                schema={'properties': [('raster_val', 'int')],
                        'geometry': 'Polygon'}) as dst:
            dst.writerecords(results)
        print("Successfully polygonized GeoTIFF to JSON")
        return
コード例 #16
0
ファイル: test_features.py プロジェクト: EricAlex/rasterio
def test_shapes(basic_image):
    """ Test creation of shapes from pixel values """

    with Env():
        results = list(shapes(basic_image))

        assert len(results) == 2

        shape, value = results[0]
        assert shape == {
            'coordinates': [
                [(2, 2), (2, 5), (5, 5), (5, 2), (2, 2)]
            ],
            'type': 'Polygon'
        }
        assert value == 1

        shape, value = results[1]
        assert shape == {
            'coordinates': [
                [(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)],
                [(2, 2), (5, 2), (5, 5), (2, 5), (2, 2)]
            ],
            'type': 'Polygon'
        }
        assert value == 0
コード例 #17
0
def raster_shape(raster_path):

    if not os.path.exists(raster_path):
        print "File does not exist: %s" % raster_path

    with rasterio.open(raster_path) as src:

        # read the first band and create a binary mask
        arr = src.read(1)
        ndv = src.nodata
        binarray = (arr == ndv).astype('uint8')

        # extract shapes from raster
        shapes = features.shapes(binarray, transform=src.transform)

        # create geojson feature collection
        fc = {
            'type': 'FeatureCollection',
            'features': []}
        for geom, val in shapes:
            if val == 0:  # not nodata, i.e. valid data
                feature = {
                    'type': 'Feature',
                    'properties': {'name': raster_path},
                    'geometry': geom}
                fc['features'].append(feature)

        # Write to file
        with NamedTemporaryFile(suffix=".geojson", delete=False) as temp:
            temp.file.write(json.dumps(fc))

        return temp.name
コード例 #18
0
ファイル: __init__.py プロジェクト: loicdtx/antares3
    def polygonize(self, crs_out="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"):
        """Transform the raster result of a segmentation to a feature collection

        Args:
            crs_out (proj4): The coordinate reference system of the feature collection
                produced. Defaults to longlat, can be None if no reprojection is needed
        """
        if self.segments_array is None:
            raise ValueError("self.segments_array is None, you must run segment before this method")
        # Use rasterio.features.shapes to generate a geometries collection from the
        # segmented raster
        geom_collection = features.shapes(self.segments_array.astype(np.uint16),
                                          transform=self.affine)
        # Make it a valid featurecollection
        def to_feature(feature):
            """Tranforms the results of rasterio.feature.shape to a feature"""
            fc_out = {
                "type": "Feature",
                "geometry": {
                    "type": feature[0]['type'],
                    "coordinates": feature[0]['coordinates']
                },
                "properties": {
                    "id": feature[1]
                }
            }
            return fc_out
        fc_out = (to_feature(x) for x in geom_collection)
        if crs_out is not None:
            fc_out = (feature_transform(x, crs_out=crs_out, crs_in=self.crs) for x in fc_out)
        self.fc = fc_out
コード例 #19
0
def build_map(tiles_dir, preds_dir, map_dir, fn, truths):

    input_img_paths = sorted([
        os.path.join(preds_dir, fname) for fname in os.listdir(preds_dir)
        if fname.endswith(".png")
    ])

    print('\nConverting predictions to .GEOTIFF & extracting polygons as .SHP')

    for i in range(len(input_img_paths)):

        img = Image.open(input_img_paths[i])
        img_arr = np.array(img)

        ### convert prediction tile to geotiff using original geotiff metadata
        tif_number = get_name(input_img_paths[i])
        Gtif = tiles_dir + '/%s.tif' % tif_number
        raster = rasterio.open(Gtif)
        meta = raster.meta.copy()
        meta['nodata'] = 0
        # meta['count'] = 1

        saved_mask = preds_dir + '/%s.tif' % tif_number
        with rasterio.open(saved_mask, 'w+', **meta) as out:
            # out.write(img_arr.astype(rasterio.uint8), 1)
            # out.write(img_arr.astype(rasterio.uint8), 2)
            out.write(img_arr.astype(rasterio.uint8), 3)  ### visulaize in blue

        with rasterio.open(saved_mask) as data:

            crs = data.crs
            M = data.dataset_mask()
            mask = M != 0

            geo_list = []
            for g, val in features.shapes(M,
                                          transform=data.transform,
                                          mask=mask):

                # Transform shapes from the dataset's own coordinate system
                geom = rasterio.warp.transform_geom(crs, crs, g, precision=6)
                geo_list.append(geom)

        l = []
        for k in range(len(geo_list)):
            l.append(shape(geo_list[k]))

        if len(l) > 0:
            df = pd.DataFrame(l)
            polys = gpd.GeoDataFrame(geometry=df[0], crs=crs)

            polys.to_file(map_dir + '/%s.shp' % tif_number)

    print('\n.GEOTIFF & .SHP files saved in Predictions & Map directories.')

    print('\nBuilding Map...')
    if combine_shps(map_dir, fn, truths):
        return True
    else:
        return False
コード例 #20
0
def raster_to_geodataframe(raster_data: np.ndarray,
                           transform: affine.Affine) -> gpd.GeoDataFrame:
    '''
    Given an array of raster data and the transform, creates the correponsding
    vector reprseentation of the data
    '''

    geom_types = {'Polygon': Polygon}
    geom_type_multi = {'Polygon': MultiPolygon}

    if raster_data.dtype == np.float64:
        raster_data = raster_data.astype(np.float32)

    shape_gen = list(features.shapes(raster_data, transform=transform))
    gdf_data = {'geometry': [], 'data': []}
    for geom_dict, val in shape_gen:
        geom_type = geom_types[geom_dict['type']]
        multi_type = geom_type_multi[geom_dict['type']]

        coords = geom_dict['coordinates']
        if len(coords) <= 1:
            geom = geom_type(*coords)
        else:
            # This can be done better
            geom = multi_type(
                [geom_type(coords[i]) for i in range(len(coords))])

        gdf_data['geometry'].append(geom)
        gdf_data['data'].append(val)

    return gpd.GeoDataFrame(gdf_data)
コード例 #21
0
def polygonize(input_tif_dir, output_shp_dir, countries):

    rm_and_mkdir(output_shp_dir)
    for country in countries:
        shp_filename = country + '.shp'
        output_shp_path = os.path.join(output_shp_dir, shp_filename)
        tif_filename = country + '.tif'
        input_tif_path = os.path.join(input_tif_dir, tif_filename)

        with rasterio.open(input_tif_path) as src:
            band = src.read(1)

        mask = band != 255
        shapes = features.shapes(band, mask=mask, transform=src.transform)
        geomvals = list(shapes)

        geom_val_trios = []
        for idx, geom_val in enumerate(geomvals):
            shapely_geom = shape(geomvals[idx][0])
            shapely_val = geomvals[idx][1]
            geom_val_trio = [shapely_geom, shapely_val, country]
            geom_val_trios.append(geom_val_trio)
        gdf = gpd.GeoDataFrame(geom_val_trios, columns={'geometry', 'val', 'country'})
        gdf.crs = {'init': 'epsg:4326', 'no_defs': True}
        gdf.to_file(output_shp_path)
コード例 #22
0
def __mask_to_polys(mask):
    """[summary]

    Args:
        mask ([type]): [description]

    Returns:
        [type]: [description]
    """
    import numpy as np
    import pandas as pd
    from rasterio import features
    from shapely import ops, geometry

    shapes = features.shapes(mask.astype(np.int16), mask > 0)
    mp = ops.cascaded_union(
        geometry.MultiPolygon(
            [geometry.shape(shape) for shape, value in shapes]))

    if isinstance(mp, geometry.Polygon):
        polygon_gdf = pd.DataFrame({
            'geometry': [mp],
        })
    else:
        polygon_gdf = pd.DataFrame({
            'geometry': [p for p in mp],
        })
    return polygon_gdf
コード例 #23
0
ファイル: worker.py プロジェクト: ranchodeluxe/sheepdawg
def raster_shape(raster_path):
    with rasterio.open(raster_path) as src:

        # read the first band and create a binary mask
        arr = src.read(1)
        ndv = src.nodata
        binarray = (arr == ndv).astype('uint8')

        # extract shapes from raster
        shapes = features.shapes(binarray, transform=src.transform)

        # create geojson feature collection
        fc = {
            'type': 'FeatureCollection',
            'features': []}
        for geom, val in shapes:
            if val == 0:  # not nodata, i.e. valid data
                feature = {
                    'type': 'Feature',
                    'properties': {'name': raster_path},
                    'geometry': geom}
                fc['features'].append(feature)

        # Write to file
        with NamedTemporaryFile(suffix=".geojson", delete=False) as temp:
            temp.file.write(json.dumps(fc))

        return temp.name
コード例 #24
0
ファイル: footprint.py プロジェクト: wsf1990/raster-foundry
def extract_polygon(mask_tif_path):
    """Extracts polygon to a geojson dict

    Args:
        mask_tif_path (str): path to tif to extract geojson from

    Returns:
        str: path to geojson file
    """

    with rasterio.open(mask_tif_path, 'r') as src:
        raster = src.read(1)
        src_crs = Proj(init=src.crs.get('init'))
        src_affine = src.affine

    mask = np.ma.masked_equal(raster, 0)
    geoms = shapes(raster, mask=mask, transform=src_affine)
    footprint, value = geoms.next()

    assert value == 1.0, 'Geometry should be of value 1'

    target_crs = Proj(init='epsg:4326')
    feature = transform_polygon_coordinates(footprint, src_crs, target_crs)
    feature_collection = {
        'type':
        'FeatureCollection',
        'features': [{
            'type': 'Feature',
            'geometry': feature,
            'properties': {
                'value': value
            }
        }]
    }
    return feature_collection
コード例 #25
0
def raster_to_shape(in_dir, out_dir, img_name):

    file_name = in_dir + img_name

    mask = None
    with rasterio.open(file_name) as src:
        image = src.read(1)  # first band
        results = ({
            'properties': {
                'raster_val': v
            },
            'geometry': s
        } for i, (
            s,
            v) in enumerate(shapes(image, mask=mask, transform=src.transform)))

    geoms = list(results)

    gpd_polygonized_raster = gp.GeoDataFrame.from_features(geoms)
    gpd_polygonized_raster["single_val"] = 1
    gpd_polygonized_raster = gpd_polygonized_raster.dissolve(by="single_val")

    gpd_polygonized_raster.crs = src.crs
    shape_name = img_name.replace(".tif", ".shp")
    gpd_polygonized_raster.to_file(out_dir + shape_name)
コード例 #26
0
def main(raster_file, vector_file, driver, mask_value):

    with rasterio.drivers():

        with rasterio.open(raster_file) as src:
            image = src.read_band(1)

        if mask_value is not None:
            mask = image == mask_value
        else:
            mask = None

        results = ({
            'properties': {
                'raster_val': v
            },
            'geometry': s
        } for i, (
            s,
            v) in enumerate(shapes(image, mask=mask, transform=src.transform)))

        with fiona.open(vector_file,
                        'w',
                        driver=driver,
                        crs=src.crs,
                        schema={
                            'properties': [('raster_val', 'int')],
                            'geometry': 'Polygon'
                        }) as dst:
            dst.writerecords(results)

    return dst.name
コード例 #27
0
def clump(data):
    '''Contiguous groups of cells with the same value (‘clumps’)'
    
    Parameters
    ----------
    data: Numpy array with no-data cells as nan (np.NaN).
    
    returns
    ----------
    Numpy array with the data for which clumps are to be returned
    '''

    if not np.isnan(np.sum(data)):
        logging.warning(
            "convert no-data cells to np.NaN before using clump. If not, no-data cells will be clumped too"
        )

    #data = data * 0 + 1
    mask = data.copy()
    mask = mask * 0 + 1
    mask[np.isnan(mask)] = 0
    mask = mask.astype(np.bool)
    geoms = [
        (shape(s), idx)
        for idx, (s, v) in enumerate(shapes(data.astype(np.int32), mask=mask))
    ]

    clumps = rasterio.features.rasterize(geoms,
                                         out_shape=data.shape,
                                         fill=-999)

    return np.where(clumps == -999, np.NaN, clumps)
コード例 #28
0
ファイル: test_features.py プロジェクト: v0lat1le/rasterio
def test_shapes_connectivity_queen(diagonal_image):
    """
    Diagonals are connected, so there will be 1 feature for all pixels plus
    background.
    """
    with rasterio.Env():
        assert len(list(shapes(diagonal_image, connectivity=8))) == 2
コード例 #29
0
ファイル: test_features.py プロジェクト: v0lat1le/rasterio
def test_shapes_connectivity_rook(diagonal_image):
    """
    Diagonals are not connected, so there will be 1 feature per pixel plus
    background.
    """
    with rasterio.Env():
        assert len(list(shapes(diagonal_image, connectivity=4))) == 12
コード例 #30
0
ファイル: environment.py プロジェクト: jasmijnr/iSDM
    def polygonize(self, band_number=1):
        """
        Extract shapes from raster features. This is the inverse operation of rasterizing shapes.
        Uses the `Rasterio <https://mapbox.github.io/rasterio/_modules/rasterio/features.html>'_ library
        for this purpose. The data is loaded into a `geopandas <http://geopandas.org/user.html>`_ GeoDataFrame.
        GeoDataFrame data structures are pandas DataFrames with added functionality, containing a ``geometry``
        column for the `Shapely <http://toblerity.org/shapely/shapely.geometry.html>`_ geometries.
        The raster data should be loaded in the layer before calling this method.

        :param int band_number: The index of the raster band which is to be used as input for extracting \
        gemetrical shapes.

        :returns: geopandas.GeoDataFrame

        """
        raster_data = self.read(band_number)
        mask = raster_data != self.raster_reader.nodata
        T0 = self.raster_reader.affine
        shapes = features.shapes(raster_data, mask=mask, transform=T0)
        df = GeoDataFrame.from_records(shapes, columns=['geometry', 'value'])
        # convert the geometry dictionary from a dictionary format like {'coordinates': [[(-73.5, 83.5),
        #   (-73.5, 83.0),
        #   (-68.0, 83.0),
        #   (-68.0, 83.5),
        #   (-73.5, 83.5)]],
        # 'type': 'Polygon'}
        # to a proper shapely polygon format
        df.geometry = df.geometry.apply(lambda row: Polygon(row['coordinates'][0]))
        df.crs = self.raster_reader.crs
        return df
コード例 #31
0
def extract_polygon(mask_tif_path):
    """Extracts polygon to a geojson dict

    Args:
        mask_tif_path (str): path to tif to extract geojson from

    Returns:
        str: path to geojson file
    """

    with rasterio.open(mask_tif_path, 'r') as src:
        raster = src.read(1)
        src_crs = Proj(init=src.crs.get('init'))
        src_affine = src.affine

    mask = np.ma.masked_equal(raster, 0)
    geoms = shapes(raster, mask=mask, transform=src_affine, connectivity=8)

    footprint, value = geoms.next()

    assert value == 1.0, 'Geometry should be of value 1'

    target_crs = Proj(init='epsg:4326')
    feature = transform_polygon_coordinates(footprint, src_crs, target_crs)
    return {'type': 'MultiPolygon', 'coordinates': [feature['coordinates']]}
コード例 #32
0
def VectorizeTile(axis, row, col, params):
    """
    DOCME
    """

    rasterfile = params.watershed_raster.tilename(axis=axis, row=row, col=col)
    # config.tileset().tilename(
    #     'ax_watershed_raster',
    #     axis=axis,
    #     row=row,
    #     col=col)

    if os.path.exists(rasterfile):

        with rio.open(rasterfile) as ds:
            watershed = ds.read(1)
            transform = ds.transform

        polygons = features.shapes(watershed,
                                   connectivity=4,
                                   transform=transform)

        return [polygon for polygon, value in polygons
                if value == axis], row, col

    else:

        return [], row, col
コード例 #33
0
def __mask_to_polygons(mask):
    """[summary]

    Args:
        mask ([type]): [description]

    Returns:
        [type]: [description]
    """
    # XXX: maybe this should be merged with __mask_to_polys() defined above
    import numpy as np
    from rasterio import features, Affine
    from shapely import geometry

    all_polygons = []
    for shape, value in features.shapes(mask.astype(np.int16),
                                        mask=(mask > 0),
                                        transform=Affine(1.0, 0, 0, 0, 1.0,
                                                         0)):
        all_polygons.append(geometry.shape(shape))

    all_polygons = geometry.MultiPolygon(all_polygons)
    if not all_polygons.is_valid:
        all_polygons = all_polygons.buffer(0)
        # Sometimes buffer() converts a simple Multipolygon to just a Polygon,
        # need to keep it a Multi throughout
        if all_polygons.type == 'Polygon':
            all_polygons = geometry.MultiPolygon([all_polygons])
    return all_polygons
コード例 #34
0
def test_shapes_internal_driver_manager():
    """Access to shapes of labeled features"""
    image = numpy.zeros((20, 20), dtype=rasterio.ubyte)
    image[5:15, 5:15] = 127
    shapes = ftrz.shapes(image)
    shape, val = next(shapes)
    assert shape['type'] == 'Polygon'
コード例 #35
0
def get_data_polygon(rasterfile):

    import rasterio
    from rasterio.features import shapes
    from shapely.geometry import shape

    r = Raster(rasterfile)
    array = np.array(r.array.mask * 1, dtype=np.int16)

    #    with rasterio.drivers():
    with rasterio.open(rasterfile) as src:
        image = src.read(1)
        mask_array = image != src.nodata

        # https://github.com/mapbox/rasterio/issues/86
        if isinstance(src.transform, Affine):
            transform = src.transform
        else:
            transform = src.affine  # for compatibility with rasterio 0.36

        results = ({
            'properties': {
                'raster_val': v
            },
            'geometry': s
        } for i, (s, v) in enumerate(
            shapes(array, mask=mask_array, transform=transform)))

    geoms = list(results)
    polygons = [shape(geom['geometry']) for geom in geoms]

    return polygons
コード例 #36
0
ファイル: raster.py プロジェクト: cuulee/OpenSarToolkit
def polygonize_raster(infile, outfile, mask_value=1, driver='ESRI Shapefile'):

    with rasterio.open(infile) as src:

        image = src.read(1)

        if mask_value is not None:
            mask = image == mask_value
        else:
            mask = None

        results = (
            {'properties': {'raster_val': v}, 'geometry': s}
            for i, (s, v)
            in enumerate(
                shapes(image, mask=mask, transform=src.transform)))

        with fiona.open(
            outfile, 'w',
            driver=driver,
            crs=src.crs,
            schema={'properties': [('raster_val', 'int')],
                    'geometry': 'Polygon'}) as dst:

            dst.writerecords(results)
コード例 #37
0
def raster_bounds(path):
    '''
    Gets boundary of raster at path, ignoring no data values
    '''
    print('Getting raster bounds...')
    with rasterio.drivers():
        with rasterio.open(path) as src:
            # Raster band
            rb = src.read(1)
            nodata = src.nodatavals[0]
            # Array of 1's and 0's
            binary = np.where(rb <= nodata, 0, 1)
            # Array True, False
            mask = np.where(binary == 1, True, False)
            ## Create a dictionary of raster values and geometries, where
            ## the geometries are based on grouping the values in the binary array
            ## and ignoring the False values in the mask
            geoms = list(({
                'properties': {
                    'raster_val': value
                },
                'geometry': shp
            } for i, (shp, value) in enumerate(
                shapes(binary, mask=mask, transform=src.affine))))
            bb = shape(geoms[0]['geometry'])
    return bb
コード例 #38
0
ファイル: uniontiles.py プロジェクト: mapbox/supermercado
def union(inputtiles, parsenames):

    tiles = sutils.tile_parser(inputtiles, parsenames)

    xmin, xmax, ymin, ymax = sutils.get_range(tiles)

    zoom = sutils.get_zoom(tiles)

    # make an array of shape (xrange + 3, yrange + 3)
    burn = sutils.burnXYZs(tiles, xmin, xmax, ymin, ymax, 0)

    nw = mercantile.xy(*mercantile.ul(xmin, ymin, zoom))

    se = mercantile.xy(*mercantile.ul(xmax + 1, ymax + 1, zoom))

    aff = Affine(((se[0] - nw[0]) / float(xmax - xmin + 1)), 0.0, nw[0],
        0.0, -((nw[1] - se[1]) / float(ymax - ymin + 1)), nw[1])

    unprojecter = sutils.Unprojecter()

    unionedTiles = [
        {
            'geometry': unprojecter.unproject(feature),
            'properties': {},
            'type': 'Feature'
        } for feature, shapes in features.shapes(np.asarray(np.flipud(np.rot90(burn)).astype(np.uint8), order='C'), transform=aff) if shapes == 1
    ]

    return unionedTiles
コード例 #39
0
def main(raster_file, vector_file, driver, mask_value):
    
    with rasterio.drivers():
        
        with rasterio.open(raster_file) as src:
            image = src.read_band(1)
        
        if mask_value is not None:
            mask = image == mask_value
        else:
            mask = None
        
        results = (
            {'properties': {'raster_val': v}, 'geometry': s}
            for i, (s, v) 
            in enumerate(
                shapes(image, mask=mask, transform=src.affine)))

        with fiona.open(
                vector_file, 'w', 
                driver=driver,
                crs=src.crs,
                schema={'properties': [('raster_val', 'int')],
                        'geometry': 'Polygon'}) as dst:
            dst.writerecords(results)
    
    return dst.name
コード例 #40
0
def create_shapefile(in_files, out_shapefile, dest_crs):

    polygons = []
    for idx, f in enumerate(in_files):
        src = rasterio.open(f)
        crs = src.crs
        transform = src.transform

        bnd = src.read(1)
        polys = list(shapes(bnd, transform=transform))

        for geom, val in polys:
            if val == 0:
                continue
            polygons.append((Polygon(shape(geom)), val))

    shp_schema = {
        'geometry': 'Polygon',
        'properties': {'dmg': 'int'}
    }

    # Write out all the multipolygons to the same file
    with fiona.open(out_shapefile, 'w', 'ESRI Shapefile', shp_schema,
                    dest_crs) as shp:
        for polygon, px_val in polygons:
            shp.write({
                'geometry': mapping(polygon),
                'properties': {'dmg': int(px_val)}
            })
コード例 #41
0
def test_shapes_invalid_mask_dtype(basic_image):
    """A mask that is the wrong dtype should fail."""
    for dtype in ('int8', 'int16', 'int32'):
        with pytest.raises(ValueError):
            next(shapes(
                basic_image,
                mask=np.ones(basic_image.shape, dtype=dtype)
            ))
コード例 #42
0
def test_shapes_internal_driver_manager():
    """Make sure this works if driver is managed outside this test"""

    image = numpy.zeros((20, 20), dtype=rasterio.ubyte)
    image[5:15, 5:15] = 127
    shapes = ftrz.shapes(image)
    shape, val = next(shapes)
    assert shape['type'] == 'Polygon'
コード例 #43
0
def test_rasterize_geometries_symmetric():
    """Make sure that rasterize is symmetric with shapes."""
    transform = (1.0, 0.0, 0.0, 0.0, -1.0, 0.0)
    truth = np.zeros(DEFAULT_SHAPE, dtype=rasterio.ubyte)
    truth[2:5, 2:5] = 1
    s = shapes(truth, transform=transform)
    result = rasterize(s, out_shape=DEFAULT_SHAPE, transform=transform)
    assert np.array_equal(result, truth)
コード例 #44
0
def test_shapes_band_shortcut():
    """Access to shapes of labeled features"""
    with rasterio.drivers():
        with rasterio.open('rasterio/tests/data/shade.tif') as src:
            shapes = ftrz.shapes(rasterio.band(src, 1))
            shape, val = next(shapes)
            assert shape['type'] == 'Polygon'
            assert len(shape['coordinates']) == 1
            assert val == 255
コード例 #45
0
def test_shapes_connectivity():
    """Test connectivity options"""
    image = numpy.zeros((20, 20), dtype=rasterio.ubyte)
    image[5:11,5:11] = 1
    image[11,11] = 1

    shapes = ftrz.shapes(image, connectivity=8)
    shape, val = next(shapes)
    assert len(shape['coordinates'][0]) == 9
コード例 #46
0
def test_shapes_invalid_mask_shape(basic_image):
    """A mask that is the wrong shape should fail."""
    with pytest.raises(ValueError):
        next(shapes(
            basic_image,
            mask=np.ones(
                (basic_image.shape[0] + 10, basic_image.shape[1] + 10),
                dtype=rasterio.bool_
            )
        ))
コード例 #47
0
def test_shapes_band_shortcut():
    """Test rasterio bands as input to shapes"""

    with rasterio.drivers():
        with rasterio.open('tests/data/shade.tif') as src:
            shapes = ftrz.shapes(rasterio.band(src, 1))
            shape, val = next(shapes)
            assert shape['type'] == 'Polygon'
            assert len(shape['coordinates']) == 1
            assert val == 255
コード例 #48
0
def test_rasterize_geometries_symmetric():
    """Make sure that rasterize is symmetric with shapes"""
    rows = cols = 10
    transform = (1.0, 0.0, 0.0, 0.0, -1.0, 0.0)
    truth = numpy.zeros((rows, cols), dtype=rasterio.ubyte)
    truth[2:5, 2:5] = 1
    with rasterio.drivers():
        s = shapes(truth, transform=transform)
        result = rasterize(s, out_shape=(rows, cols), transform=transform)
        assert numpy.array_equal(result, truth)
コード例 #49
0
def test_rasterize_geometries_symmetric():
    """Make sure that rasterize is symmetric with shapes"""
    rows = cols = 10
    transform = [0, 1, 0, 0, 0, 1]
    truth = numpy.zeros((rows, cols), dtype=rasterio.ubyte)
    truth[2:5, 2:5] = 1
    with rasterio.drivers():
        s = shapes(truth, transform=transform)
        result = rasterize(s, out_shape=(rows, cols), transform=transform)
        assert (result == truth).min() == True
コード例 #50
0
def makeVectors(inArr, affine_trans):
    for feature, shapes in features.shapes(np.asarray(inArr,order='C'),transform=affine_trans):
        if shapes != 0:
            featurelist = [Polygon(f) for f in feature['coordinates']]
            print json.dumps({
                        'type': 'Feature',
                        'geometry': mapping(MultiPolygon(featurelist)),
                        'properties': {
                            'pred_delta': shapes
                        }
                })
コード例 #51
0
def test_shapes_connectivity():
    """Test connectivity options"""

    image = numpy.zeros((20, 20), dtype=rasterio.ubyte)
    image[5:11, 5:11] = 1
    image[11, 11] = 1

    shapes = ftrz.shapes(image, connectivity=4)
    shape, val = next(shapes)
    assert len(shape['coordinates'][0]) == 5

    shapes = ftrz.shapes(image, connectivity=8)
    shape, val = next(shapes)
    assert len(shape['coordinates'][0]) == 9
    # Note: geometry is not technically valid at this point, it has a self
    # intersection at 11,11

    # Test invalid connectivity
    with pytest.raises(ValueError):
        shapes = ftrz.shapes(image, connectivity=12)
        next(shapes)
コード例 #52
0
def test_shapes_dtype():
    """Test image data type handling"""

    rows = cols = 10
    with rasterio.drivers():
        supported_types = (
            ('int16', -32768),
            ('int32', -2147483648),
            ('uint8', 255),
            ('uint16', 65535),
            ('float32', 1.434532)
        )

        for dtype, test_value in supported_types:
            image = numpy.zeros((rows, cols), dtype=dtype)
            image[2:5, 2:5] = test_value

            shapes = ftrz.shapes(image)
            shape, value = next(shapes)
            if dtype == 'float32':
                assert round(value, 6) == round(test_value, 6)
            else:
                assert value == test_value

        # Unsupported types should all raise exceptions
        unsupported_types = (
            ('int8', -127),
            ('uint32', 4294967295),
            ('int64', 20439845334323),
            ('float16', -9343.232),
            ('float64', -98332.133422114)
        )

        for dtype, test_value in unsupported_types:
            with pytest.raises(ValueError):
                image = numpy.zeros((rows, cols), dtype=dtype)
                image[2:5, 2:5] = test_value
                shapes = ftrz.shapes(image)
                shape, value = next(shapes)
コード例 #53
0
def test_shapes_supported_dtypes(basic_image):
    """Supported data types should return valid results."""
    supported_types = (
        ('int16', -32768),
        ('int32', -2147483648),
        ('uint8', 255),
        ('uint16', 65535),
        ('float32', 1.434532)
    )

    for dtype, test_value in supported_types:
        shape, value = next(shapes(basic_image.astype(dtype) * test_value))
        assert np.allclose(value, test_value)
コード例 #54
0
def test_shapes_unsupported_dtypes(basic_image):
    """Unsupported data types should raise exceptions."""
    unsupported_types = (
        ('int8', -127),
        ('uint32', 4294967295),
        ('int64', 20439845334323),
        ('float16', -9343.232),
        ('float64', -98332.133422114)
    )

    for dtype, test_value in unsupported_types:
        with pytest.raises(ValueError):
            next(shapes(basic_image.astype(dtype) * test_value))
コード例 #55
0
def get_tile_geometry(path, origin_espg, tolerance=500):
    """ Calculate the data and tile geometry for sentinel-2 tiles """

    with rasterio.open(path) as src:

        # Get tile geometry
        b = src.bounds
        tile_shape = Polygon([(b[0], b[1]), (b[2], b[1]), (b[2], b[3]), (b[0], b[3]), (b[0], b[1])])
        tile_geojson = mapping(tile_shape)

        # read first band of the image
        image = src.read(1)

        # create a mask of zero values
        mask = image == 0.

        # generate shapes of the mask
        novalue_shape = shapes(image, mask=mask, transform=src.affine)

        # generate polygons using shapely
        novalue_shape = [Polygon(s['coordinates'][0]) for (s, v) in novalue_shape]

        if novalue_shape:

            # Make sure polygons are united
            # also simplify the resulting polygon
            union = cascaded_union(novalue_shape)

            # generates a geojson
            data_shape = tile_shape.difference(union)

            # If there are multipolygons, select the largest one
            if data_shape.geom_type == 'MultiPolygon':
                areas = {p.area: i for i, p in enumerate(data_shape)}
                largest = max(areas.keys())
                data_shape = data_shape[areas[largest]]

            # if the polygon has interior rings, remove them
            if list(data_shape.interiors):
                data_shape = Polygon(data_shape.exterior.coords)

            data_shape = data_shape.simplify(tolerance, preserve_topology=False)
            data_geojson = mapping(data_shape)

        else:
            data_geojson = tile_geojson

        # convert cooridnates to degrees
        return (to_latlon(tile_geojson, origin_espg), to_latlon(data_geojson, origin_espg))
コード例 #56
0
def test_shapes_mask(basic_image):
    """Only pixels not masked out should be converted to features."""
    mask = np.ones(basic_image.shape, dtype=rasterio.bool_)
    mask[4:5, 4:5] = False

    results = list(shapes(basic_image, mask=mask))

    assert len(results) == 2

    shape, value = results[0]
    assert shape == {
        'coordinates': [
            [(2, 2), (2, 5), (4, 5), (4, 4), (5, 4), (5, 2), (2, 2)]
        ],
        'type': 'Polygon'
    }
    assert value == 1
コード例 #57
0
def test_geometry_mask():
    rows = cols = 10
    transform = (1.0, 0.0, 0.0, 0.0, -1.0, 0.0)
    truth = numpy.zeros((rows, cols), dtype=rasterio.bool_)
    truth[2:5, 2:5] = True
    with rasterio.drivers():
        s = shapes((truth * 10).astype(rasterio.ubyte), transform=transform)
        # Strip out values returned from shapes, and only keep first shape
        geoms = [next(s)[0]]

        # Regular mask should be the inverse of truth raster
        mask = geometry_mask(geoms, out_shape=(rows, cols), transform=transform)
        assert numpy.array_equal(mask, numpy.invert(truth))

        # Inverted mask should be the same as the truth raster
        mask = geometry_mask(geoms, out_shape=(rows, cols), transform=transform,
                             invert=True)
        assert numpy.array_equal(mask, truth)
コード例 #58
0
def test_shapes():
    """Access to shapes of labeled features"""
    image = numpy.zeros((20, 20), dtype=rasterio.ubyte)
    image[5:15,5:15] = 127
    with rasterio.drivers():
        shapes = ftrz.shapes(image)
        shape, val = next(shapes)
        assert shape['type'] == 'Polygon'
        assert len(shape['coordinates']) == 2 # exterior and hole
        assert val == 0
        shape, val = next(shapes)
        assert shape['type'] == 'Polygon'
        assert len(shape['coordinates']) == 1 # no hole
        assert val == 127
        try:
            shape, val = next(shapes)
        except StopIteration:
            assert True
        else:
            assert False