Exemplo n.º 1
0
def add_id_range_data_to_grid(iso3, tile_lookup, side_length):
    """
    Query the Digital Elevation Model to get an estimated interdecile
    range for each grid square.

    """
    directory = os.path.join(DATA_INTERMEDIATE, iso3, 'grid')
    filename = 'grid_final.shp'
    path_output = os.path.join(directory, filename)

    if os.path.exists(path_output):
        return gpd.read_file(path_output, crs='epsg:4328')

    filename = 'grid_{}_{}_km.shp'.format(side_length, side_length)
    path = os.path.join(directory, filename)
    grid = gpd.read_file(path, crs='epsg:4328')

    output = []

    for idx, grid_tile in grid.iterrows():

        path_input = find_tile(
            grid_tile['geometry'].bounds,
            tile_lookup
        )

        stats = next(gen_zonal_stats(
            grid_tile['geometry'],
            path_input,
            add_stats={
                'interdecile_range': interdecile_range
            },
            nodata=0
        ))

        id_range_m = stats['interdecile_range']

        output.append({
            'type': 'Feature',
            'geometry': grid_tile['geometry'],
            'properties': {
                'id_range_m': id_range_m,
                'area_km2': grid_tile['area_km2'],
                # 'pop_density_km2': grid_tile['pop_densit'],
                # 'population': grid_tile['population'],
            }
        })

    output = gpd.GeoDataFrame.from_features(output, crs='epsg:4326')

    output = output.replace([np.inf, -np.inf], np.nan)

    output = output[output.geometry.notnull()]

    output.to_file(path_output, crs="epsg:4326")

    return output
Exemplo n.º 2
0
def zonalstats(features, raster, all_touched, band, categorical, indent, info,
               nodata, prefix, stats, sequence, use_rs):
    '''zonalstats generates summary statistics of geospatial raster datasets
    based on vector features.

    The input arguments to zonalstats should be valid GeoJSON Features. (see cligj)

    The output GeoJSON will be mostly unchanged but have additional properties per feature
    describing the summary statistics (min, max, mean, etc.) of the underlying raster dataset.

    The raster is specified by the required -r/--raster argument.

    Example, calculate rainfall stats for each state and output to file:

    \b
       rio zonalstats states.geojson -r rainfall.tif > mean_rainfall_by_state.geojson
    '''

    if info:
        logging.basicConfig(level=logging.INFO)

    if stats is not None:
        stats = stats.split(" ")
        if 'all' in [x.lower() for x in stats]:
            stats = "ALL"

    zonal_results = gen_zonal_stats(features,
                                    raster,
                                    all_touched=all_touched,
                                    band_num=band,
                                    categorical=categorical,
                                    nodata=nodata,
                                    stats=stats,
                                    prefix=prefix,
                                    geojson_out=True)

    if sequence:
        for feature in zonal_results:
            if use_rs:
                click.echo(b'\x1e', nl=False)
            click.echo(json.dumps(feature))
    else:
        click.echo(
            json.dumps({
                'type': 'FeatureCollection',
                'features': list(zonal_results)
            }))
Exemplo n.º 3
0
def zonalstats(features, raster, all_touched, band, categorical,
               indent, info, nodata, prefix, stats, sequence, use_rs):
    '''zonalstats generates summary statistics of geospatial raster datasets
    based on vector features.

    The input arguments to zonalstats should be valid GeoJSON Features. (see cligj)

    The output GeoJSON will be mostly unchanged but have additional properties per feature
    describing the summary statistics (min, max, mean, etc.) of the underlying raster dataset.

    The raster is specified by the required -r/--raster argument.

    Example, calculate rainfall stats for each state and output to file:

    \b
       rio zonalstats states.geojson -r rainfall.tif > mean_rainfall_by_state.geojson
    '''

    if info:
        logging.basicConfig(level=logging.INFO)

    if stats is not None:
        stats = stats.split(" ")
        if 'all' in [x.lower() for x in stats]:
            stats = "ALL"

    zonal_results = gen_zonal_stats(
        features,
        raster,
        all_touched=all_touched,
        band=band,
        categorical=categorical,
        nodata=nodata,
        stats=stats,
        prefix=prefix,
        geojson_out=True)

    if sequence:
        for feature in zonal_results:
            if use_rs:
                click.echo(b'\x1e', nl=False)
            click.echo(json.dumps(feature))
    else:
        click.echo(json.dumps(
            {'type': 'FeatureCollection',
             'features': list(zonal_results)}))
Exemplo n.º 4
0
def terrain_area(dem, lon, lat, cell_range):
    """
    This module takes a single set of point coordinates for a site
    along with an estimate of the cell range. The irregular terrain
    parameter is returned.

    Parameters
    ----------
    dem : str
        Path to the available Digital Elevation Model as single raster file or vrt.
    lon : float
        Longitude of cell point
    lat : float
        Latitude of cell point
    cell_range : int
        Radius of cell area in meters.

    Returns
    -------
    Inter-decile range : int
        The terrain irregularity parameter.

    """
    # Buffer around cell point
    cell_area = geodesic_point_buffer(lon, lat, cell_range)

    # Calculate raster stats
    stats = next(gen_zonal_stats(
        [cell_area],
        dem,
        add_stats={
            'interdecile_range': interdecile_range
        },
        nodata=-9999
    ))

    id_range = stats['interdecile_range']

    return id_range
Exemplo n.º 5
0
def check_foliage_presence(routing_structure, modis_lookup):
    """
    Check for potential foliage.

    """
    geom = shape(routing_structure['geometry'])
    routing_structure = gpd.GeoDataFrame({'geometry': [geom]},
                                         index=[0],
                                         crs='epsg:3857')

    routing_structure['geometry'] = routing_structure['geometry'].to_crs(
        'epsg:4326')

    representative_point = routing_structure['geometry'].representative_point(
    )[0]

    tile_paths = find_correct_tile(representative_point, modis_lookup)

    results = []

    for tile_path in tile_paths:
        stats = next(
            gen_zonal_stats(routing_structure['geometry'],
                            tile_path,
                            nodata=-9999))

        if not stats['mean'] == None:
            results.append(stats['mean'])

    mean = sum(results) / len(results)

    if mean < 20:
        return 'nofoliage'
    elif mean >= 20:
        return 'foliage'
    else:
        print('Did not recognize zonal stats result')
Exemplo n.º 6
0
def get_data(iso3, tile_lookup):
    """

    """
    output = []

    path = os.path.join(DATA_INTERMEDIATE, iso3, 'gid_3_regional_data.csv')

    if os.path.exists(path):
        return

    path_settlements = os.path.join(DATA_INTERMEDIATE, iso3, 'settlements.tif')

    filename = 'regions_3_{}.shp'.format(iso3)
    path = os.path.join(DATA_INTERMEDIATE, iso3, 'regions', filename)
    regions = gpd.read_file(path, crs='epsg:4326')  #[:1]

    for idx, region in regions.iterrows():

        area_km2 = get_area(region)

        path_input = find_correct_raster_tile(region['geometry'].bounds,
                                              tile_lookup)

        stats = next(
            gen_zonal_stats(region['geometry'],
                            path_input,
                            add_stats={'interdecile_range': interdecile_range},
                            nodata=0))

        id_range_m = stats['interdecile_range']

        with rasterio.open(path_settlements) as src:

            affine = src.transform
            array = src.read(1)
            array[array <= 0] = 0

            population = [
                d['sum'] for d in zonal_stats(region['geometry'],
                                              array,
                                              stats=['sum'],
                                              nodata=0,
                                              affine=affine)
            ][0]

        if not population == None:
            if population > 0:
                pop_density_km2 = population / area_km2
            else:
                pop_density_km2 = 0
        else:
            population = 0
            pop_density_km2 = 0

        output.append({
            'GID_0': region['GID_0'],
            'GID_2': region['GID_2'],
            'GID_3': region['GID_3'],
            'population': population,
            'area_km2': area_km2,
            'pop_density_km2': pop_density_km2,
            'id_range_m': id_range_m,
        })

    output = pd.DataFrame(output)
    output.to_csv(path, index=False)

    return
Exemplo n.º 7
0
def create_pop_and_terrain_regional_lookup(country):
    """
    Extract regional luminosity and population data.

    Parameters
    ----------
    country : dict
        Contains all country-specific information for modeling.

    """
    iso3 = country['iso3']

    path_settlements = os.path.join(DATA_INTERMEDIATE, iso3, 'settlements.tif')

    filename = 'modeling_regions.shp'
    path = os.path.join(DATA_INTERMEDIATE, iso3, 'modeling_regions', filename)
    modeling_regions = gpd.read_file(path, crs='epsg:4326')  #[:5]

    filename = 'main_nodes.shp'
    path = os.path.join(DATA_INTERMEDIATE, iso3, 'network_routing_structure',
                        filename)
    main_nodes = gpd.read_file(path, crs='epsg:4326')  #[:5]

    tile_lookup = load_raster_tile_lookup(country)

    output = []

    for index, modeling_region in modeling_regions.iterrows():

        # if not modeling_region['regions'] == 'PER.15.1_1':
        #     continue

        area_km2 = get_area(modeling_region)

        path_input = find_correct_raster_tile(
            modeling_region['geometry'].bounds, tile_lookup)

        stats = next(
            gen_zonal_stats(modeling_region['geometry'],
                            path_input,
                            add_stats={'interdecile_range': interdecile_range},
                            nodata=0))

        id_range_m = stats['interdecile_range']

        with rasterio.open(path_settlements) as src:

            affine = src.transform
            array = src.read(1)
            array[array <= 0] = 0

            population = [
                d['sum'] for d in zonal_stats(modeling_region['geometry'],
                                              array,
                                              stats=['sum'],
                                              nodata=0,
                                              affine=affine)
            ][0]

        if not population == None:
            if population > 0:
                pop_density_km2 = population / area_km2
            else:
                pop_density_km2 = 0
        else:
            population = 0
            pop_density_km2 = 0

        if modeling_region['geometry'].type == 'Polygon':
            region_geom = gpd.GeoDataFrame(
                {'geometry': modeling_region['geometry']},
                index=[0],
                crs='epsg:4326')
        else:
            region_geom = gpd.GeoDataFrame(
                {'geometry': modeling_region['geometry']}, crs='epsg:4326')

        main_node = gpd.overlay(main_nodes, region_geom, how='intersection')
        if len(main_node) == 0:
            continue
        modeling_region_id = main_node['GID_{}'.format(
            country['regional_level'])].values[0]

        output.append({
            'modeling_region': modeling_region_id,
            'regions': modeling_region['regions'],
            'names': modeling_region['names'],
            'id_range_m': id_range_m,
            'population': population,
            'area_km2': area_km2,
            'pop_density_km2': pop_density_km2,
        })

    output = pd.DataFrame(output)

    filename = 'population_and_terrain_lookup.csv'
    path = os.path.join(DATA_INTERMEDIATE, iso3, filename)
    output.to_csv(path, index=False)

    return print('Completed population and terrain lookup')
Exemplo n.º 8
0
def create_pop_and_terrain_regional_lookup(country):
    """
    Extract regional luminosity and population data.
    Parameters
    ----------
    country : dict
        Contains all country-specific information for modeling.
    """
    iso3 = country['iso3']

    filename = 'ppp_2020_1km_Aggregated.tif'
    path_settlements = os.path.join(DATA_RAW, 'settlement_layer', filename)

    filename = 'modeling_regions.shp'
    path = os.path.join(DATA_INTERMEDIATE, iso3, 'modeling_regions', filename)
    modeling_regions = gpd.read_file(path, crs='epsg:4326')#[:5]

    tile_lookup = load_raster_tile_lookup(country)

    output = []

    for index, modeling_region in modeling_regions.iterrows():

        # if not modeling_region['regions'] == 'PER.15.1_1':
        #     continue

        area_km = get_area(modeling_region)

        path_input = find_correct_raster_tile(modeling_region['geometry'].bounds,
            tile_lookup)

        stats = next(gen_zonal_stats(
            modeling_region['geometry'],
            path_input,
            add_stats={
                'interdecile_range': interdecile_range
            },
            nodata=0
        ))

        id_range_m = stats['interdecile_range']

        with rasterio.open(path_settlements) as src:

            affine = src.transform
            array = src.read(1)
            array[array <= 0] = 0

            population = [d['sum'] for d in zonal_stats(
                modeling_region['geometry'],
                array,
                stats=['sum'],
                nodata=0,
                affine=affine
                )][0]

        if population > 0:
            pop_density_km2 = population / area_km
        else:
            pop_density_km2 = 0

        output.append({
            'regions': modeling_region['regions'],
            'id_range_m': id_range_m,
            'population': population,
            'area_m': area_km,
            'pop_density_km2': pop_density_km2,
        })

    output = pd.DataFrame(output)

    filename = 'population_and_terrain_lookup.csv'
    path = os.path.join(DATA_INTERMEDIATE, iso3, filename)
    output.to_csv(path, index=False)

    return print('Completed population and terrain lookup')