Exemple #1
0
    def addLengthMeters(self, stream_network):
        """
        Adds length field in meters to network (The added field name will be 'LENGTH_M').

        .. note:: This may be needed for generating the kfac file depending on the units of your raster. See: :doc:`gis_tools`.

        Parameters:
            stream_network(str): Path to stream network file.

        Here is an example of how to use this:

        .. code:: python

            import os
            from RAPIDpy.gis.taudem import TauDEM

            td = TauDEM()

            output_directory = '/path/to/output/files'
            td.addLengthMeters(os.path.join(output_directory,"stream_reach_file.shp"))

        """
        network_shapefile = ogr.Open(stream_network, 1)
        network_layer = network_shapefile.GetLayer()
        network_layer_defn = network_layer.GetLayerDefn()

        #make sure projection EPSG:4326
        network_layer_proj = network_layer.GetSpatialRef()
        geographic_proj = osr.SpatialReference()
        geographic_proj.ImportFromEPSG(4326)
        proj_transform = None
        if network_layer_proj != geographic_proj:
            proj_transform = osr.CoordinateTransformation(
                network_layer_proj, geographic_proj)

        #check for field
        create_field = True
        for i in xrange(network_layer_defn.GetFieldCount()):
            field_name = network_layer_defn.GetFieldDefn(i).GetName()
            if field_name == 'LENGTH_M':
                create_field = False
                break

        if create_field:
            network_layer.CreateField(ogr.FieldDefn('LENGTH_M', ogr.OFTReal))

        geo_manager = Geod(ellps="WGS84")
        for network_feature in network_layer:
            feat_geom = network_feature.GetGeometryRef()
            #make sure coordinates are geographic
            if proj_transform:
                feat_geom.Transform(proj_transform)

            line = shapely_loads(feat_geom.ExportToWkb())
            lon_list, lat_list = line.xy
            az1, az2, dist = geo_manager.inv(lon_list[:-1], lat_list[:-1],
                                             lon_list[1:], lat_list[1:])
            network_feature.SetField('LENGTH_M', sum(dist))
            network_layer.SetFeature(network_feature)
Exemple #2
0
    def addLengthMeters(self, stream_network):
        """
        Adds length field in meters to network (The added field name will be 'LENGTH_M'). 
        
        .. note:: This may be needed for generating the kfac file depending on the units of your raster. See: :doc:`gis_tools`.       

        Parameters:
            stream_network(str): Path to stream network file.
        
        Here is an example of how to use this:
        
        .. code:: python
        
            import os
            from RAPIDpy.gis.taudem import TauDEM
            
            td = TauDEM()
                        
            output_directory = '/path/to/output/files'
            td.addLengthMeters(os.path.join(output_directory,"stream_reach_file.shp"))

        """
        network_shapefile = ogr.Open(stream_network, 1)
        network_layer = network_shapefile.GetLayer()
        network_layer_defn = network_layer.GetLayerDefn()
        
        #make sure projection EPSG:4326
        network_layer_proj = network_layer.GetSpatialRef()
        geographic_proj = osr.SpatialReference()
        geographic_proj.ImportFromEPSG(4326)
        proj_transform = None
        if network_layer_proj != geographic_proj:
            proj_transform = osr.CoordinateTransformation(network_layer_proj, geographic_proj)

        #check for field
        create_field=True
        for i in xrange(network_layer_defn.GetFieldCount()):
            field_name = network_layer_defn.GetFieldDefn(i).GetName()
            if field_name == 'LENGTH_M':
                create_field=False
                break
            
        if create_field:
            network_layer.CreateField(ogr.FieldDefn('LENGTH_M', ogr.OFTReal))

        geo_manager = Geod(ellps="WGS84")
        for network_feature in network_layer:
            feat_geom = network_feature.GetGeometryRef()
            #make sure coordinates are geographic
            if proj_transform:
                feat_geom.Transform(proj_transform)
                
            line = shapely_loads(feat_geom.ExportToWkb())
            lon_list, lat_list = line.xy
            az1, az2, dist = geo_manager.inv(lon_list[:-1], lat_list[:-1], lon_list[1:], lat_list[1:])
            network_feature.SetField('LENGTH_M', sum(dist))
            network_layer.SetFeature(network_feature)
Exemple #3
0
    def rasterToPolygon(self, raster_file, polygon_file):
        """
        Converts raster to polygon and then dissolves it
        """
        print("Process: Raster to Polygon ...")
        time_start = datetime.utcnow()
        temp_polygon_file = "{0}_temp.shp".format(os.path.splitext(os.path.basename(polygon_file))[0])
        cmd = ["gdal_polygonize.py", raster_file,
               "-f", "ESRI Shapefile", temp_polygon_file,  
               os.path.splitext(os.path.basename(temp_polygon_file))[0],
               "LINKNO"]

        process = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=False)
        out, err = process.communicate()
        if out:
            print("OUTPUT:")
            for line in out.split(b'\n'):
                print(line)
        if err:
            print("ERROR:")
            print(err)
            #raise Exception(err)
        print("Time to convert to polygon: {0}".format(datetime.utcnow()-time_start))
        
        print("Dissolving ...")
        time_start_dissolve = datetime.utcnow()
        ogr_polygin_shapefile = ogr.Open(temp_polygon_file)
        ogr_polygon_shapefile_lyr = ogr_polygin_shapefile.GetLayer()
        number_of_features = ogr_polygon_shapefile_lyr.GetFeatureCount()
        polygon_rivid_list = np.zeros(number_of_features, dtype=np.int32)
        for feature_idx, catchment_feature in enumerate(ogr_polygon_shapefile_lyr):
            polygon_rivid_list[feature_idx] = catchment_feature.GetField('LINKNO')
        
        
        shp_drv = ogr.GetDriverByName('ESRI Shapefile')
        # Remove output shapefile if it already exists
        if os.path.exists(polygon_file):
            shp_drv.DeleteDataSource(polygon_file)
            
        dissolve_shapefile = shp_drv.CreateDataSource(polygon_file)
        dissolve_layer = dissolve_shapefile.CreateLayer('', ogr_polygon_shapefile_lyr.GetSpatialRef(), 
                                                        ogr.wkbPolygon)
        dissolve_layer.CreateField(ogr.FieldDefn('LINKNO', ogr.OFTInteger))
        dissolve_layer_defn = dissolve_layer.GetLayerDefn()

        for unique_rivid in np.unique(polygon_rivid_list):
            #get indices where it is in the polygon
            feature_indices = np.where(polygon_rivid_list==unique_rivid)[0]
            new_feat = ogr.Feature(dissolve_layer_defn)
            new_feat.SetField('LINKNO', int(unique_rivid))

            if len(feature_indices) == 1:
                ##write feature to file
                feature = ogr_polygon_shapefile_lyr.GetFeature(feature_indices[0])
                new_feat.SetGeometry(feature.GetGeometryRef())
            else:
                ##dissolve
                dissolve_poly_list = []
                for feature_index in feature_indices:
                    feature = ogr_polygon_shapefile_lyr.GetFeature(feature_index)
                    feat_geom = feature.GetGeometryRef()
                    dissolve_poly_list.append(shapely_loads(feat_geom.ExportToWkb()))                
                dissolve_polygon = cascaded_union(dissolve_poly_list)
                new_feat.SetGeometry(ogr.CreateGeometryFromWkb(dissolve_polygon.wkb))
            dissolve_layer.CreateFeature(new_feat)
        #clean up
        shp_drv.DeleteDataSource(temp_polygon_file)
        print("Time to dissolve: {0}".format(datetime.utcnow()-time_start_dissolve))
        print("Total time to convert: {0}".format(datetime.utcnow()-time_start))
Exemple #4
0
def RTreeCreateWeightTable(lsm_grid_lat,
                           lsm_grid_lon,
                           in_catchment_shapefile,
                           river_id,
                           in_rapid_connect,
                           out_weight_table,
                           file_geodatabase=None,
                           area_id=None):
    """
    Create Weight Table for Land Surface Model Grids
    """
    time_start_all = datetime.utcnow()

    print("Generating LSM Grid Thiessen Array ...")
    if file_geodatabase:
        gdb_driver = ogr.GetDriverByName("OpenFileGDB")
        ogr_file_geodatabase = gdb_driver.Open(file_geodatabase, 0)
        ogr_catchment_shapefile_lyr = ogr_file_geodatabase.GetLayer(
            in_catchment_shapefile)
    else:
        ogr_catchment_shapefile = ogr.Open(in_catchment_shapefile)
        ogr_catchment_shapefile_lyr = ogr_catchment_shapefile.GetLayer()

    ogr_catchment_shapefile_lyr_proj = ogr_catchment_shapefile_lyr.GetSpatialRef(
    )
    original_catchment_proj = Proj(
        ogr_catchment_shapefile_lyr_proj.ExportToProj4())
    geographic_proj = Proj(init='EPSG:4326')  #geographic
    extent = ogr_catchment_shapefile_lyr.GetExtent()
    if original_catchment_proj != geographic_proj:
        x, y = transform(original_catchment_proj, geographic_proj,
                         [extent[0], extent[1]], [extent[2], extent[3]])
        extent = [min(x), max(x), min(y), max(y)]

    lsm_grid_feature_list = pointsToVoronoiGridArray(lsm_grid_lat,
                                                     lsm_grid_lon, extent)

    ##COMMENTED LINES FOR TESTING
    ##import os
    ##from .voronoi import pointsToVoronoiGridShapefile
    ##vor_shp_path = os.path.join(os.path.dirname(in_catchment_shapefile), "test_grid.shp")
    ##pointsToVoronoiGridShapefile(lsm_grid_lat, lsm_grid_lon, vor_shp_path, extent)

    time_end_lsm_grid_thiessen = datetime.utcnow()
    print(time_end_lsm_grid_thiessen - time_start_all)

    print("Generating LSM Grid Rtree ...")
    rtree_idx = rtree.index.Index()
    # Populate R-tree index with bounds of ECMWF grid cells
    for lsm_grid_pos, lsm_grid_feature in enumerate(lsm_grid_feature_list):
        rtree_idx.insert(lsm_grid_pos, lsm_grid_feature['polygon'].bounds)

    time_end_lsm_grid_rtree = datetime.utcnow()
    print(time_end_lsm_grid_rtree - time_end_lsm_grid_thiessen)

    print("Retrieving catchment river id list ...")
    number_of_catchment_features = ogr_catchment_shapefile_lyr.GetFeatureCount(
    )
    catchment_rivid_list = np.zeros(number_of_catchment_features,
                                    dtype=np.int32)
    for feature_idx, catchment_feature in enumerate(
            ogr_catchment_shapefile_lyr):
        catchment_rivid_list[feature_idx] = catchment_feature.GetField(
            river_id)

    print("Reading in RAPID connect file ...")
    rapid_connect_rivid_list = get_rivid_list_from_file(in_rapid_connect)

    print("Find LSM grid cells that intersect with each catchment")
    print("and write out weight table ...")

    dummy_lat_index, dummy_lon_index = _get_lat_lon_indices(
        lsm_grid_lat, lsm_grid_lon, lsm_grid_feature_list[0]['lat'],
        lsm_grid_feature_list[0]['lon'])
    dummy_row_end = [
        0, dummy_lon_index, dummy_lat_index, 1,
        lsm_grid_feature_list[0]['lon'], lsm_grid_feature_list[0]['lat']
    ]

    with open_csv(out_weight_table, 'w') as csvfile:
        connectwriter = csv.writer(csvfile)
        connectwriter.writerow([
            'rivid', 'area_sqm', 'lon_index', 'lat_index', 'npoints',
            'lsm_grid_lon', 'lsm_grid_lat'
        ])
        geographic_proj = Proj(init='EPSG:4326')  #geographic
        osr_geographic_proj = osr.SpatialReference()
        osr_geographic_proj.ImportFromEPSG(4326)
        proj_transform = None
        if original_catchment_proj != geographic_proj:
            proj_transform = osr.CoordinateTransformation(
                ogr_catchment_shapefile_lyr_proj, osr_geographic_proj)

        for rapid_connect_rivid in rapid_connect_rivid_list:
            intersect_grid_info_list = []

            try:
                catchment_pos = np.where(
                    catchment_rivid_list == rapid_connect_rivid)[0][0]
            except IndexError:
                #if it is not in the catchment, add dummy row in its place
                connectwriter.writerow([rapid_connect_rivid] + dummy_row_end)
                continue
                pass
            get_catchment_feature = ogr_catchment_shapefile_lyr.GetFeature(
                catchment_pos)
            feat_geom = get_catchment_feature.GetGeometryRef()
            #make sure coordinates are geographic
            if proj_transform:
                feat_geom.Transform(proj_transform)
            catchment_polygon = shapely_loads(feat_geom.ExportToWkb())
            for sub_lsm_grid_pos in rtree_idx.intersection(
                    catchment_polygon.bounds):
                if catchment_polygon.intersects(
                        lsm_grid_feature_list[sub_lsm_grid_pos]['polygon']):
                    intersect_poly = catchment_polygon.intersection(
                        lsm_grid_feature_list[sub_lsm_grid_pos]['polygon'])
                    if not area_id:
                        #attempt to calculate AREA
                        poly_area = get_poly_area_geo(intersect_poly)
                    else:
                        poly_area = float(
                            catchment_polygon.GetFeature(area_id)
                        ) * intersect_poly.area / catchment_polygon.area

                    index_lsm_grid_lat, index_lsm_grid_lon = _get_lat_lon_indices(
                        lsm_grid_lat, lsm_grid_lon,
                        lsm_grid_feature_list[sub_lsm_grid_pos]['lat'],
                        lsm_grid_feature_list[sub_lsm_grid_pos]['lon'])
                    intersect_grid_info_list.append({
                        'rivid':
                        rapid_connect_rivid,
                        'area':
                        poly_area,
                        'lsm_grid_lat':
                        lsm_grid_feature_list[sub_lsm_grid_pos]['lat'],
                        'lsm_grid_lon':
                        lsm_grid_feature_list[sub_lsm_grid_pos]['lon'],
                        'index_lsm_grid_lon':
                        index_lsm_grid_lon,
                        'index_lsm_grid_lat':
                        index_lsm_grid_lat
                    })
            npoints = len(intersect_grid_info_list)
            for intersect_grid_info in intersect_grid_info_list:
                connectwriter.writerow([
                    intersect_grid_info['rivid'], intersect_grid_info['area'],
                    intersect_grid_info['index_lsm_grid_lon'],
                    intersect_grid_info['index_lsm_grid_lat'], npoints,
                    intersect_grid_info['lsm_grid_lon'],
                    intersect_grid_info['lsm_grid_lat']
                ])

    time_end_all = datetime.utcnow()
    print(time_end_all - time_end_lsm_grid_rtree)
    print("TOTAL TIME: {0}".format(time_end_all - time_start_all))
Exemple #5
0
    def rasterToPolygon(self, raster_file, polygon_file):
        """
        Converts raster to polygon and then dissolves it
        """
        print("Process: Raster to Polygon ...")
        time_start = datetime.utcnow()
        temp_polygon_file = "{0}_temp.shp".format(
            os.path.splitext(os.path.basename(polygon_file))[0])
        cmd = [
            "gdal_polygonize.py", raster_file, "-f", "ESRI Shapefile",
            temp_polygon_file,
            os.path.splitext(os.path.basename(temp_polygon_file))[0], "LINKNO"
        ]

        process = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=False)
        out, err = process.communicate()
        if out:
            print("OUTPUT:")
            for line in out.split(b'\n'):
                print(line)
        if err:
            print("ERROR:")
            print(err)
            #raise Exception(err)
        print("Time to convert to polygon: {0}".format(datetime.utcnow() -
                                                       time_start))

        print("Dissolving ...")
        time_start_dissolve = datetime.utcnow()
        ogr_polygin_shapefile = ogr.Open(temp_polygon_file)
        ogr_polygon_shapefile_lyr = ogr_polygin_shapefile.GetLayer()
        number_of_features = ogr_polygon_shapefile_lyr.GetFeatureCount()
        polygon_rivid_list = np.zeros(number_of_features, dtype=np.int32)
        for feature_idx, catchment_feature in enumerate(
                ogr_polygon_shapefile_lyr):
            polygon_rivid_list[feature_idx] = catchment_feature.GetField(
                'LINKNO')

        shp_drv = ogr.GetDriverByName('ESRI Shapefile')
        # Remove output shapefile if it already exists
        if os.path.exists(polygon_file):
            shp_drv.DeleteDataSource(polygon_file)

        dissolve_shapefile = shp_drv.CreateDataSource(polygon_file)
        dissolve_layer = dissolve_shapefile.CreateLayer(
            '', ogr_polygon_shapefile_lyr.GetSpatialRef(), ogr.wkbPolygon)
        dissolve_layer.CreateField(ogr.FieldDefn('LINKNO', ogr.OFTInteger))
        dissolve_layer_defn = dissolve_layer.GetLayerDefn()

        for unique_rivid in np.unique(polygon_rivid_list):
            #get indices where it is in the polygon
            feature_indices = np.where(polygon_rivid_list == unique_rivid)[0]
            new_feat = ogr.Feature(dissolve_layer_defn)
            new_feat.SetField('LINKNO', int(unique_rivid))

            if len(feature_indices) == 1:
                ##write feature to file
                feature = ogr_polygon_shapefile_lyr.GetFeature(
                    feature_indices[0])
                new_feat.SetGeometry(feature.GetGeometryRef())
            else:
                ##dissolve
                dissolve_poly_list = []
                for feature_index in feature_indices:
                    feature = ogr_polygon_shapefile_lyr.GetFeature(
                        feature_index)
                    feat_geom = feature.GetGeometryRef()
                    dissolve_poly_list.append(
                        shapely_loads(feat_geom.ExportToWkb()))
                dissolve_polygon = cascaded_union(dissolve_poly_list)
                new_feat.SetGeometry(
                    ogr.CreateGeometryFromWkb(dissolve_polygon.wkb))
            dissolve_layer.CreateFeature(new_feat)
        #clean up
        shp_drv.DeleteDataSource(temp_polygon_file)
        print("Time to dissolve: {0}".format(datetime.utcnow() -
                                             time_start_dissolve))
        print("Total time to convert: {0}".format(datetime.utcnow() -
                                                  time_start))
Exemple #6
0
def rtree_create_weight_table(lsm_grid_lat,
                              lsm_grid_lon,
                              in_catchment_shapefile,
                              river_id,
                              in_rapid_connect,
                              out_weight_table,
                              file_geodatabase=None,
                              area_id=None,
                              lsm_grid_mask=None):
    """
    Create Weight Table for Land Surface Model Grids
    """
    time_start_all = datetime.utcnow()

    if lsm_grid_lat.ndim == 3 and lsm_grid_lon.ndim == 3:
        # assume first dimension is time
        lsm_grid_lat = lsm_grid_lat[0]
        lsm_grid_lon = lsm_grid_lon[0]

    log("Generating LSM Grid Thiessen Array ...")
    if file_geodatabase:
        gdb_driver = ogr.GetDriverByName("OpenFileGDB")
        ogr_file_geodatabase = gdb_driver.Open(file_geodatabase, 0)
        ogr_catchment_shapefile_lyr = \
            ogr_file_geodatabase.GetLayer(in_catchment_shapefile)
    else:
        ogr_catchment_shapefile = ogr.Open(in_catchment_shapefile)
        ogr_catchment_shapefile_lyr = ogr_catchment_shapefile.GetLayer()

    ogr_catchment_shapefile_lyr_proj = \
        ogr_catchment_shapefile_lyr.GetSpatialRef()
    original_catchment_proj = \
        Proj(ogr_catchment_shapefile_lyr_proj.ExportToProj4())
    geographic_proj = Proj(init='EPSG:4326')
    extent = ogr_catchment_shapefile_lyr.GetExtent()
    if original_catchment_proj != geographic_proj:
        x, y = transform(original_catchment_proj, geographic_proj,
                         [extent[0], extent[1]], [extent[2], extent[3]])
        extent = [min(x), max(x), min(y), max(y)]

    lsm_grid_feature_list = \
        pointsToVoronoiGridArray(lsm_grid_lat, lsm_grid_lon, extent)

    #    ##COMMENTED LINES FOR TESTING
    #    import os
    #    from .voronoi import pointsToVoronoiGridShapefile
    #    vor_shp_path = \
    #        os.path.join(os.path.dirname(in_catchment_shapefile), "test_grid.shp")
    #    pointsToVoronoiGridShapefile(lsm_grid_lat, lsm_grid_lon,
    #                                 vor_shp_path, extent)

    time_end_lsm_grid_thiessen = datetime.utcnow()
    log(time_end_lsm_grid_thiessen - time_start_all)

    log("Generating LSM Grid Rtree ...")
    rtree_idx = rtree.index.Index()
    # Populate R-tree index with bounds of ECMWF grid cells
    for lsm_grid_pos, lsm_grid_feature in enumerate(lsm_grid_feature_list):
        rtree_idx.insert(lsm_grid_pos, lsm_grid_feature['polygon'].bounds)

    time_end_lsm_grid_rtree = datetime.utcnow()
    log(time_end_lsm_grid_rtree - time_end_lsm_grid_thiessen)

    log("Retrieving catchment river id list ...")
    number_of_catchment_features = \
        ogr_catchment_shapefile_lyr.GetFeatureCount()
    catchment_rivid_list = \
        np.zeros(number_of_catchment_features, dtype=np.int32)
    for feature_idx, catchment_feature in \
            enumerate(ogr_catchment_shapefile_lyr):
        catchment_rivid_list[feature_idx] = \
            catchment_feature.GetField(river_id)

    log("Reading in RAPID connect file ...")
    rapid_connect_rivid_list = np.loadtxt(in_rapid_connect,
                                          delimiter=",",
                                          usecols=(0, ),
                                          ndmin=1,
                                          dtype=int)
    log("Find LSM grid cells that intersect with each catchment")
    log("and write out weight table ...")

    dummy_lat_index, dummy_lon_index = \
        _get_lat_lon_indices(lsm_grid_lat,
                             lsm_grid_lon,
                             lsm_grid_feature_list[0]['lat'],
                             lsm_grid_feature_list[0]['lon'])
    dummy_row_end = [
        0, dummy_lon_index, dummy_lat_index, 1,
        lsm_grid_feature_list[0]['lon'], lsm_grid_feature_list[0]['lat']
    ]

    with open_csv(out_weight_table, 'w') as csvfile:
        connectwriter = csv.writer(csvfile)
        connectwriter.writerow([
            'rivid', 'area_sqm', 'lon_index', 'lat_index', 'npoints',
            'lsm_grid_lon', 'lsm_grid_lat'
        ])
        geographic_proj = Proj(init='EPSG:4326')
        osr_geographic_proj = osr.SpatialReference()
        osr_geographic_proj.ImportFromEPSG(4326)
        proj_transform = None
        if original_catchment_proj != geographic_proj:
            proj_transform = \
                osr.CoordinateTransformation(ogr_catchment_shapefile_lyr_proj,
                                             osr_geographic_proj)

        for rapid_connect_rivid in rapid_connect_rivid_list:
            intersect_grid_info_list = []
            try:
                catchment_pos = \
                    np.where(catchment_rivid_list == rapid_connect_rivid)[0][0]
            except IndexError:
                # if it is not in the catchment, add dummy row in its place
                connectwriter.writerow([rapid_connect_rivid] + dummy_row_end)
                continue

            get_catchment_feature = \
                ogr_catchment_shapefile_lyr.GetFeature(catchment_pos)
            feat_geom = get_catchment_feature.GetGeometryRef()
            # make sure coordinates are geographic
            if proj_transform:
                feat_geom.Transform(proj_transform)
            catchment_polygon = shapely_loads(feat_geom.ExportToWkb())

            for sub_lsm_grid_pos in \
                    rtree_idx.intersection(catchment_polygon.bounds):
                lsm_grid_polygon = \
                    lsm_grid_feature_list[sub_lsm_grid_pos]['polygon']
                if catchment_polygon.intersects(lsm_grid_polygon):
                    try:
                        intersect_poly = \
                            catchment_polygon.intersection(lsm_grid_polygon)
                    except TopologicalError:
                        log('The catchment polygon with id {0} was '
                            'invalid. Attempting to self clean...'.format(
                                rapid_connect_rivid))
                        original_area = catchment_polygon.area
                        catchment_polygon = catchment_polygon.buffer(0)
                        area_ratio = original_area / catchment_polygon.area
                        log('AREA_RATIO: {0}'.format(area_ratio))
                        msg_level = "INFO"
                        if round(area_ratio, 5) != 1:
                            msg_level = "WARNING"
                        log('The cleaned catchment polygon area '
                            'differs from the original area by {0}%.'.format(
                                abs(area_ratio - 1)),
                            severity=msg_level)
                        intersect_poly = \
                            catchment_polygon.intersection(lsm_grid_polygon)
                    if not area_id:
                        # attempt to calculate AREA
                        poly_area = get_poly_area_geo(intersect_poly)
                    else:
                        poly_area = \
                            float(get_catchment_feature.GetField(area_id)) * \
                            intersect_poly.area/catchment_polygon.area

                    index_lsm_grid_lat, index_lsm_grid_lon = \
                        _get_lat_lon_indices(
                            lsm_grid_lat,
                            lsm_grid_lon,
                            lsm_grid_feature_list[sub_lsm_grid_pos]['lat'],
                            lsm_grid_feature_list[sub_lsm_grid_pos]['lon'])

                    if lsm_grid_mask is not None:
                        if lsm_grid_mask[int(index_lsm_grid_lat),
                                         int(index_lsm_grid_lon)] > 0:
                            poly_area /= lsm_grid_mask[int(index_lsm_grid_lat),
                                                       int(index_lsm_grid_lon)]

                    intersect_grid_info_list.append({
                        'rivid':
                        rapid_connect_rivid,
                        'area':
                        poly_area,
                        'lsm_grid_lat':
                        lsm_grid_feature_list[sub_lsm_grid_pos]['lat'],
                        'lsm_grid_lon':
                        lsm_grid_feature_list[sub_lsm_grid_pos]['lon'],
                        'index_lsm_grid_lon':
                        index_lsm_grid_lon,
                        'index_lsm_grid_lat':
                        index_lsm_grid_lat
                    })

            npoints = len(intersect_grid_info_list)
            # If no intersection found, add dummy row
            if npoints <= 0:
                connectwriter.writerow([rapid_connect_rivid] + dummy_row_end)
            for intersect_grid_info in intersect_grid_info_list:
                connectwriter.writerow([
                    intersect_grid_info['rivid'], intersect_grid_info['area'],
                    intersect_grid_info['index_lsm_grid_lon'],
                    intersect_grid_info['index_lsm_grid_lat'], npoints,
                    intersect_grid_info['lsm_grid_lon'],
                    intersect_grid_info['lsm_grid_lat']
                ])

    time_end_all = datetime.utcnow()
    log(time_end_all - time_end_lsm_grid_rtree)
    log("TOTAL TIME: {0}".format(time_end_all - time_start_all))
Exemple #7
0
    def rasterToPolygon(raster_file, polygon_file):
        """
        Converts watershed raster to polygon and then dissolves it.
        It dissolves features based on the LINKNO attribute.
        """
        log("Process: Raster to Polygon ...")
        time_start = datetime.utcnow()
        temp_polygon_file = \
            "{0}_temp.shp".format(
                os.path.splitext(os.path.basename(polygon_file))[0])

        GDALGrid(raster_file).to_polygon(out_shapefile=temp_polygon_file,
                                         fieldname="LINKNO",
                                         self_mask=True)

        log("Time to convert to polygon: {0}".format(datetime.utcnow() -
                                                     time_start))

        log("Dissolving ...")
        time_start_dissolve = datetime.utcnow()
        ogr_polygin_shapefile = ogr.Open(temp_polygon_file)
        ogr_polygon_shapefile_lyr = ogr_polygin_shapefile.GetLayer()
        number_of_features = ogr_polygon_shapefile_lyr.GetFeatureCount()
        polygon_rivid_list = np.zeros(number_of_features, dtype=np.int32)
        for feature_idx, catchment_feature in \
                enumerate(ogr_polygon_shapefile_lyr):
            polygon_rivid_list[feature_idx] = \
                catchment_feature.GetField('LINKNO')

        shp_drv = ogr.GetDriverByName('ESRI Shapefile')
        # Remove output shapefile if it already exists
        if os.path.exists(polygon_file):
            shp_drv.DeleteDataSource(polygon_file)

        dissolve_shapefile = shp_drv.CreateDataSource(polygon_file)
        dissolve_layer = \
            dissolve_shapefile.CreateLayer(
                '',
                ogr_polygon_shapefile_lyr.GetSpatialRef(),
                ogr.wkbPolygon)
        dissolve_layer.CreateField(ogr.FieldDefn('LINKNO', ogr.OFTInteger))
        dissolve_layer_defn = dissolve_layer.GetLayerDefn()

        for unique_rivid in np.unique(polygon_rivid_list):
            # get indices where it is in the polygon
            feature_indices = np.where(polygon_rivid_list == unique_rivid)[0]
            new_feat = ogr.Feature(dissolve_layer_defn)
            new_feat.SetField('LINKNO', int(unique_rivid))

            if len(feature_indices) == 1:
                # write feature to file
                feature = \
                    ogr_polygon_shapefile_lyr.GetFeature(feature_indices[0])
                new_feat.SetGeometry(feature.GetGeometryRef())
            else:
                # dissolve
                dissolve_poly_list = []
                for feature_index in feature_indices:
                    feature = \
                        ogr_polygon_shapefile_lyr.GetFeature(feature_index)
                    feat_geom = feature.GetGeometryRef()
                    dissolve_poly_list.append(
                        shapely_loads(feat_geom.ExportToWkb()))
                dissolve_polygon = cascaded_union(dissolve_poly_list)
                new_feat.SetGeometry(
                    ogr.CreateGeometryFromWkb(dissolve_polygon.wkb))
            dissolve_layer.CreateFeature(new_feat)
        # clean up
        shp_drv.DeleteDataSource(temp_polygon_file)
        log("Time to dissolve: {0}".format(datetime.utcnow() -
                                           time_start_dissolve))
        log("Total time to convert: {0}".format(datetime.utcnow() -
                                                time_start))
Exemple #8
0
def RTreeCreateWeightTable(lsm_grid_lat, lsm_grid_lon, 
                           in_catchment_shapefile, river_id,
                           in_rapid_connect, out_weight_table,
                           file_geodatabase=None, area_id=None):
                                      
    """
    Create Weight Table for Land Surface Model Grids
    """
    time_start_all = datetime.utcnow()    

    if lsm_grid_lat.ndim == 3 and lsm_grid_lon.ndim == 3:
        #assume first dimension is time
        lsm_grid_lat = lsm_grid_lat[0]
        lsm_grid_lon = lsm_grid_lon[0]
    
    print("Generating LSM Grid Thiessen Array ...")
    if file_geodatabase:
        gdb_driver = ogr.GetDriverByName("OpenFileGDB")
        ogr_file_geodatabase = gdb_driver.Open(file_geodatabase, 0)
        ogr_catchment_shapefile_lyr = ogr_file_geodatabase.GetLayer(in_catchment_shapefile)
    else:
        ogr_catchment_shapefile = ogr.Open(in_catchment_shapefile)
        ogr_catchment_shapefile_lyr = ogr_catchment_shapefile.GetLayer()
        
    ogr_catchment_shapefile_lyr_proj = ogr_catchment_shapefile_lyr.GetSpatialRef()
    original_catchment_proj = Proj(ogr_catchment_shapefile_lyr_proj.ExportToProj4())
    geographic_proj =  Proj(init='EPSG:4326') #geographic
    extent = ogr_catchment_shapefile_lyr.GetExtent()
    if original_catchment_proj != geographic_proj:
        x, y = transform(original_catchment_proj,
                         geographic_proj,
                         [extent[0], extent[1]], 
                         [extent[2], extent[3]])
        extent = [min(x), max(x), min(y), max(y)]
            
    lsm_grid_feature_list = pointsToVoronoiGridArray(lsm_grid_lat, lsm_grid_lon, extent)
    
    ##COMMENTED LINES FOR TESTING
#    import os
#    from .voronoi import pointsToVoronoiGridShapefile
#    vor_shp_path = os.path.join(os.path.dirname(in_catchment_shapefile), "test_grid.shp")
#    pointsToVoronoiGridShapefile(lsm_grid_lat, lsm_grid_lon, vor_shp_path, extent)
    
    time_end_lsm_grid_thiessen = datetime.utcnow()
    print(time_end_lsm_grid_thiessen - time_start_all)
    
    print("Generating LSM Grid Rtree ...")
    rtree_idx = rtree.index.Index()
    # Populate R-tree index with bounds of ECMWF grid cells
    for lsm_grid_pos, lsm_grid_feature in enumerate(lsm_grid_feature_list):
        rtree_idx.insert(lsm_grid_pos, lsm_grid_feature['polygon'].bounds)
     
    time_end_lsm_grid_rtree = datetime.utcnow()
    print(time_end_lsm_grid_rtree - time_end_lsm_grid_thiessen)
    
    print("Retrieving catchment river id list ...")
    number_of_catchment_features = ogr_catchment_shapefile_lyr.GetFeatureCount()
    catchment_rivid_list = np.zeros(number_of_catchment_features, dtype=np.int32)
    for feature_idx, catchment_feature in enumerate(ogr_catchment_shapefile_lyr):
        catchment_rivid_list[feature_idx] = catchment_feature.GetField(river_id)
        
    print("Reading in RAPID connect file ...")
    rapid_connect_rivid_list = np.loadtxt(in_rapid_connect, 
                                          delimiter=",", 
                                          usecols=(0,),
                                          dtype=int)
    print("Find LSM grid cells that intersect with each catchment")
    print("and write out weight table ...")
    
    dummy_lat_index, dummy_lon_index = _get_lat_lon_indices(lsm_grid_lat, lsm_grid_lon, 
                                                            lsm_grid_feature_list[0]['lat'], 
                                                            lsm_grid_feature_list[0]['lon'])
    dummy_row_end = [0,
                    dummy_lon_index,
                    dummy_lat_index,
                    1,
                    lsm_grid_feature_list[0]['lon'],
                    lsm_grid_feature_list[0]['lat']
                    ]
                    
    with open_csv(out_weight_table, 'w') as csvfile:
        connectwriter = csv.writer(csvfile)
        connectwriter.writerow(['rivid', 'area_sqm', 'lon_index', 'lat_index', 
                                'npoints', 'lsm_grid_lon', 'lsm_grid_lat'])
        geographic_proj =  Proj(init='EPSG:4326') #geographic
        osr_geographic_proj = osr.SpatialReference()
        osr_geographic_proj.ImportFromEPSG(4326)
        proj_transform = None
        if original_catchment_proj != geographic_proj:
            proj_transform = osr.CoordinateTransformation(ogr_catchment_shapefile_lyr_proj, osr_geographic_proj)
            
        for rapid_connect_rivid in rapid_connect_rivid_list:
            intersect_grid_info_list = []
            try:
                catchment_pos = np.where(catchment_rivid_list==rapid_connect_rivid)[0][0]
            except IndexError:
                #if it is not in the catchment, add dummy row in its place
                connectwriter.writerow([rapid_connect_rivid] + dummy_row_end)
                continue
                pass
            get_catchment_feature = ogr_catchment_shapefile_lyr.GetFeature(catchment_pos)
            feat_geom = get_catchment_feature.GetGeometryRef()
            #make sure coordinates are geographic
            if proj_transform:
                feat_geom.Transform(proj_transform)
            catchment_polygon = shapely_loads(feat_geom.ExportToWkb())

            for sub_lsm_grid_pos in rtree_idx.intersection(catchment_polygon.bounds):
                if catchment_polygon.intersects(lsm_grid_feature_list[sub_lsm_grid_pos]['polygon']):
                    intersect_poly = catchment_polygon.intersection(lsm_grid_feature_list[sub_lsm_grid_pos]['polygon'])
                    if not area_id:
                        #attempt to calculate AREA
                        poly_area = get_poly_area_geo(intersect_poly)
                    else:
                        poly_area = float(catchment_polygon.GetFeature(area_id))*intersect_poly.area/catchment_polygon.area

                    index_lsm_grid_lat, index_lsm_grid_lon = _get_lat_lon_indices(lsm_grid_lat, lsm_grid_lon, 
                                                                                  lsm_grid_feature_list[sub_lsm_grid_pos]['lat'], 
                                                                                  lsm_grid_feature_list[sub_lsm_grid_pos]['lon'])
                    intersect_grid_info_list.append({'rivid' : rapid_connect_rivid,
                                                     'area' : poly_area,
                                                     'lsm_grid_lat': lsm_grid_feature_list[sub_lsm_grid_pos]['lat'],
                                                     'lsm_grid_lon': lsm_grid_feature_list[sub_lsm_grid_pos]['lon'],
                                                     'index_lsm_grid_lon': index_lsm_grid_lon,
                                                     'index_lsm_grid_lat': index_lsm_grid_lat})

            npoints = len(intersect_grid_info_list)
            #If no intersection found, add dummy row
            if(npoints <=0):
                connectwriter.writerow([rapid_connect_rivid] + dummy_row_end)
                
            for intersect_grid_info in intersect_grid_info_list:
                connectwriter.writerow([intersect_grid_info['rivid'],
                                        intersect_grid_info['area'],
                                        intersect_grid_info['index_lsm_grid_lon'],
                                        intersect_grid_info['index_lsm_grid_lat'],
                                        npoints,
                                        intersect_grid_info['lsm_grid_lon'],
                                        intersect_grid_info['lsm_grid_lat']])
            
    time_end_all = datetime.utcnow()                                        
    print(time_end_all - time_end_lsm_grid_rtree)
    print("TOTAL TIME: {0}".format(time_end_all - time_start_all))