def _sindex_drain_points(parm_dict): # for each drain point in the drain points shape file find the cell value in the combined stability index grid file # and use that value to populate the corresponding row in the drainpoints table driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) dataSource = driver.Open(parm_dict[ParameterNames.drain_points_file], 1) layer = dataSource.GetLayer() layerDefn = layer.GetLayerDefn() fld_index_graipdid = layerDefn.GetFieldIndex('GRAIPDID') si_grid = gdal.Open(parm_dict[ParameterNames.csi_grid_file]) si_band = si_grid.GetRasterBand(1) road_impact = False if parm_dict[ParameterNames.demang_file]: road_impact = True field_to_create = 'SIR' if road_impact else 'SI' try: #delete field if it exists in drainpoints shapefile fld_index_dp = layerDefn.GetFieldIndex(field_to_create) if fld_index_dp > 0: layer.DeleteField(fld_index_dp) # add a new field (column) to the attribute table of drainpoints shapefile layer.CreateField(ogr.FieldDefn(field_to_create, ogr.OFTReal)) fld_index_dp = layerDefn.GetFieldIndex(field_to_create) except: pass try: conn = pyodbc.connect(utils. MS_ACCESS_CONNECTION % parm_dict[ParameterNames.mdb]) cursor = conn.cursor() for feature in layer: geom = feature.GetGeometryRef() total_points = geom.GetPointCount() if total_points > 0: # lookup grid cell at drain point row, col = utils.get_coordinate_to_grid_row_col(geom.GetX(0), geom.GetY(0), si_grid) si_cell_data = si_band.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) graipdid = feature.GetFieldAsInteger(fld_index_graipdid) dp_row = cursor.execute("SELECT * FROM DrainPoints WHERE GRAIPDID=%d" % graipdid).fetchone() if dp_row: if si_cell_data[0][0] == si_band.GetNoDataValue(): if road_impact: dp_row.SIR = -9999 else: dp_row.SI = -9999 else: if road_impact: dp_row.SIR = float(si_cell_data[0][0]) else: dp_row.SI = float(si_cell_data[0][0]) if road_impact: update_sql = "UPDATE DrainPoints SET SIR=? WHERE GRAIPDID=?" data = (dp_row.SIR, dp_row.GRAIPDID) else: update_sql = "UPDATE DrainPoints SET SI=? WHERE GRAIPDID=?" data = (dp_row.SI, dp_row.GRAIPDID) cursor.execute(update_sql, data) # write si data to drainpoints shapefile feature.SetField(fld_index_dp, data[0]) # rewrite the feature to the layer - this will in fact save the data to the file layer.SetFeature(feature) geom = None conn.commit() except: raise finally: # cleanup if conn: conn.close() if dataSource: dataSource.Destroy()
def compute_mass_potential(graip_db, dp_shp, slpd, alpha, si=None, sic=None, dist=None): conn = pyodbc.connect(utils.MS_ACCESS_CONNECTION % graip_db) cursor = conn.cursor() slpd_gdal = gdal.Open(slpd) slpd_gdal_band = slpd_gdal.GetRasterBand(1) if si: si_gdal = gdal.Open(si) si_gdal_band = si_gdal.GetRasterBand(1) if sic: sic_gdal = gdal.Open(sic) sic_gdal_band = sic_gdal.GetRasterBand(1) if dist: dist_gdal = gdal.Open(dist) dist_gdal_band = dist_gdal.GetRasterBand(1) # open the drainpoints shapefile driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) dataSource = driver.Open(dp_shp, 1) layer = dataSource.GetLayer() try: # for each drain point in shape file for dp in layer: geom = dp.GetGeometryRef() # find grid row and col corresponding to drain point row, col = utils.get_coordinate_to_grid_row_col(geom.GetX(0), geom.GetY(0), slpd_gdal) geom = None # get the id of the drain point from shape file graipdid = dp.GetField('GRAIPDID') # get current grid cell data current_cell_slope_data = slpd_gdal_band.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) if si: current_cell_si_data = si_gdal_band.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) if sic: current_cell_sic_data = sic_gdal_band.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) if dist: current_cell_dist_data = dist_gdal_band.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) dp_row = cursor.execute("SELECT * FROM DrainPoints WHERE GRAIPDID=%d" % graipdid).fetchone() if dp_row: if current_cell_slope_data[0][0] != slpd_gdal_band.GetNoDataValue(): dp_row.Slope = float(current_cell_slope_data[0][0]) dp_row.ESI = dp_row.ELength * math.pow(dp_row.Slope, alpha) else: dp_row.Slope = utils.NO_DATA_VALUE dp_row.ESI = utils.NO_DATA_VALUE update_sql = "UPDATE DrainPoints SET Slope=?, ESI=? WHERE GRAIPDID=?" data = (dp_row.Slope, dp_row.ESI, dp_row.GRAIPDID) cursor.execute(update_sql, data) if si: if current_cell_si_data[0][0] != si_gdal_band.GetNoDataValue(): dp_row.SI = float(current_cell_si_data[0][0]) else: dp_row.SI = utils.NO_DATA_VALUE update_sql = "UPDATE DrainPoints SET SI=? WHERE GRAIPDID=?" data = (dp_row.SI, dp_row.GRAIPDID) cursor.execute(update_sql, data) if sic: if current_cell_sic_data[0][0] != sic_gdal_band.GetNoDataValue(): dp_row.SIR = float(current_cell_sic_data[0][0]) else: dp_row.SIR = utils.NO_DATA_VALUE update_sql = "UPDATE DrainPoints SET SIR=? WHERE GRAIPDID=?" data = (dp_row.SIR, dp_row.GRAIPDID) cursor.execute(update_sql, data) if dist: if current_cell_dist_data[0][0] != dist_gdal_band.GetNoDataValue(): dp_row.DistToStream = float(current_cell_dist_data[0][0]) else: dp_row.DistToStream = utils.NO_DATA_VALUE update_sql = "UPDATE DrainPoints SET DistToStream=? WHERE GRAIPDID=?" data = (dp_row.DistToStream, dp_row.GRAIPDID) cursor.execute(update_sql, data) conn.commit() except: raise finally: # cleanup if conn: conn.close() if dataSource: dataSource.Destroy()
def _create_weight_grids_from_points(weight_min_raster_file, weight_max_raster_file, params_dict): # Reference: c++ function: createweightgridfrompoints """ Creates the temporary weight grids (min and max) to be used with TauDEM areadinf function :param weight_min_raster_file: temporary weight grid file to which minimum weight data needs to be written :param weight_max_raster_file: temporary weight grid file to which maximum weight data needs to be written :param params_dict: a dictionary containing user parameter inputs for stability index computation :return: None """ driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) data_source = driver.Open(params_dict[ParameterNames.drain_points_file], 1) layer = data_source.GetLayer() layer_defn = layer.GetLayerDefn() try: layer_defn.GetFieldIndex('GRAIPDID') except: data_source.Destroy() raise utils.ValidationException("Invalid drain points shape file. Attribute 'GRAIPDID' is missing in " "this file.") try: conn = pyodbc.connect(utils.MS_ACCESS_CONNECTION % params_dict[ParameterNames.mdb]) cursor = conn.cursor() dp_rows = cursor.execute("SELECT * FROM DrainPoints ORDER BY GRAIPDID ASC").fetchall() dp_type_rows = cursor.execute("SELECT * FROM DrainTypeDefinitions").fetchall() accum_rmax = {} accum_rmin = {} for row in dp_rows: accum_area = 0 matching_dp_type_row = [dpt_row for dpt_row in dp_type_rows if dpt_row.DrainTypeID == row.DrainTypeID][0] if matching_dp_type_row.CCSI: accum_area = row.ELength * float(params_dict[ParameterNames.road_width]) accum_rmin[row.GRAIPDID] = accum_area * float(params_dict[ParameterNames.min_additional_runoff]) accum_rmax[row.GRAIPDID] = accum_area * float(params_dict[ParameterNames.max_additional_runoff]) # open the output temp weight grid files to write data to it weight_min_grid_file = gdal.Open(weight_min_raster_file, GA_Update) weight_max_grid_file = gdal.Open(weight_max_raster_file, GA_Update) # for each drain point in shape file for dp in layer: geom = dp.GetGeometryRef() # find weight grid row and col corresponding to drain point row, col = utils.get_coordinate_to_grid_row_col(geom.GetX(0), geom.GetY(0), weight_min_grid_file) geom = None # get the id of the drain point from shape file graipdid = dp.GetField('GRAIPDID') def _write_weight_to_grid(grid_file, weight_values): # create a 2D array to store weight data weight_array = np.zeros((1, 1), dtype=np.float32) grid_file_band = grid_file.GetRasterBand(1) # get current grid cell data current_cell_data = grid_file_band.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) if current_cell_data[0][0] != utils.NO_DATA_VALUE: weight_array[0][0] = weight_values[graipdid] # here we are writing to a specific cell of the grid grid_file_band.WriteArray(weight_array, xoff=col, yoff=row) _write_weight_to_grid(weight_min_grid_file, accum_rmin) _write_weight_to_grid(weight_max_grid_file, accum_rmax) grid_file_band = weight_min_grid_file.GetRasterBand(1) grid_file_band.FlushCache() grid_file_band = weight_max_grid_file.GetRasterBand(1) grid_file_band.FlushCache() except: raise finally: if data_source: data_source.Destroy() if conn: conn.close() weight_min_grid_file = None weight_max_grid_file = None
def compute_length_elevation_interpolation(rd_shapefile, input_dem): """ Calculates road segment length and elevation and writes to roadlines shapefile :param rd_shapefile: Path to roadlines shapefile :param input_dem: Path to dem file :return: None """ # DEBUG: print("Computing length/elevation interpolation...") driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) dataSource = driver.Open(rd_shapefile, 1) layer = dataSource.GetLayer() layerDefn = layer.GetLayerDefn() dem = gdal.Open(input_dem) dem_nx = dem.RasterXSize dem_ny = dem.RasterYSize gt = dem.GetGeoTransform() dem_band = dem.GetRasterBand(1) # Compute mid-point grid spacings # ref: http://gis.stackexchange.com/questions/7611/bilinear-interpolation-of-point-data-on-a-raster-in-python # gt[0] dem originX # gt[3] dem originY # gt[1] dem cell width (in pixel) # gt[5] dem cell height (in pixel) ax = array([gt[0] + ix * gt[1] + gt[1] / 2.0 for ix in range(dem_nx)]) ay = array([gt[3] + iy * gt[5] + gt[5] / 2.0 for iy in range(dem_ny)]) try: # delete field "Length" if it exists fld_index = layerDefn.GetFieldIndex('Length') if fld_index > 0: layer.DeleteField(fld_index) # delete "Range" if it exists fld_index = layerDefn.GetFieldIndex('Range') if fld_index > 0: layer.DeleteField(fld_index) except: pass # add a new field (column) 'Length' to the attribute table layer.CreateField(ogr.FieldDefn('Length', ogr.OFTReal)) fld_index_length = layerDefn.GetFieldIndex('Length') # add a new field (column) 'Range' to the attribute table layer.CreateField(ogr.FieldDefn('Range', ogr.OFTReal)) fld_index_range = layerDefn.GetFieldIndex('Range') for feature in layer: try: geom = feature.GetGeometryRef() if geom: total_points = geom.GetPointCount() # write length value to shapefile # feature.SetField(fld_index_length, geom.Length()) rd_length = geom.Length() if total_points > 0: # calculate range from the elevation of 2 end points of the road segment # using interpolation # first find the row, col of the dem corresponding to # the fist point of the road segment row, col = utils.get_coordinate_to_grid_row_col( geom.GetX(0), geom.GetY(0), dem) # get the dem cells corresponding to row, col needed to generate the interpolation function dem_array = dem_band.ReadAsArray(xoff=col, yoff=row, win_xsize=2, win_ysize=2) # define the interpolation function bilinterp = interpolate.interp2d(ax[col:col + 2], ay[row:row + 2], dem_array, kind='linear') # find the elevation of the 1st point using the interpolation function elevation_1 = bilinterp(geom.GetX(0), geom.GetY(0))[0] # find the row, col of the dem corresponding to # the 2nd point of the road segment row, col = utils.get_coordinate_to_grid_row_col( geom.GetX(total_points - 1), geom.GetY(total_points - 1), dem) # get the dem cells corresponding to row, col needed to generate the interpolation function dem_array = dem_band.ReadAsArray(xoff=col, yoff=row, win_xsize=2, win_ysize=2) # define the interpolation function bilinterp = interpolate.interp2d(ax[col:col + 2], ay[row:row + 2], dem_array, kind='linear') # find the elevation of the 1st point using the interpolation function elevation_2 = bilinterp(geom.GetX(total_points - 1), geom.GetY(total_points - 1))[0] rd_range = abs(elevation_2 - elevation_1) else: rd_range = 0 # sometimes shape/feature have no points - in that case we say range is zero else: rd_length = 0 rd_range = 0 # write length value to shapefile feature.SetField(fld_index_length, rd_length) # write range value to shapefile feature.SetField(fld_index_range, rd_range) # rewrite the feature to the layer - this will in fact save the data layer.SetFeature(feature) geom = None except Exception as ex: dataSource.Destroy() raise # close datasource dataSource.Destroy() # DEBUG: print("Finished computing length/elevation interpolation...")
def create_drainpoint_weighted_grid(input_dem, graip_db, dpsi_gridfile, dp_shapefile, is_stream_connected): """ Creates a new grid file with drain point sediment production data :param input_dem: Path to dem file :param graip_db: Path to graip database file :param dpsi_gridfile: Path the output grid file to which sediment data will be writen :param dp_shapefile: Path to drainpoint shapefile :param is_stream_connected: Flag(True/False) to indicate if sediment data grid file be created for all drainpoints or only stream connected points :return: None """ # DEBUG: print("Starting to write sediment data to output grid file.") dataSource = None conn = None try: conn = pyodbc.connect(utils.MS_ACCESS_CONNECTION % graip_db) cursor = conn.cursor() # TODO: May be use the no data value from the input dem # (ref: http://www.gdal.org/classGDALRasterBand.html#adcca51d230b5ac848c43f1896293fb50) # create a new weighted tif file based on the dem file dem = gdal.Open(input_dem) geotransform = dem.GetGeoTransform() originX = geotransform[0] originY = geotransform[3] pixelWidth = geotransform[1] pixelHeight = geotransform[5] rows = dem.RasterYSize cols = dem.RasterXSize # DEBUG: print("Creating sediment output grid file.") driver = gdal.GetDriverByName(utils.GDALFileDriver.TifFile()) number_of_bands = 1 outRaster = driver.Create(dpsi_gridfile, cols, rows, number_of_bands, gdal.GDT_Float32) outRaster.SetGeoTransform( (originX, pixelWidth, 0, originY, 0, pixelHeight)) # DEBUG: print("Initializing sediment output grid file with zeros.") # TODO: use the band Fill() method to initialize the raster (ref:http://www.gdal.org/classGDALRasterBand.html#a55bf20527df638dc48bf25e2ff26f353) # initialize the newly created tif file with zeros # grid_initial_data = np.zeros((rows, cols), dtype=np.float32) # grid_initial_data[:] = 0.0 # this causes memory error in case of big dem outband = outRaster.GetRasterBand(1) outband.SetNoDataValue(utils.NO_DATA_VALUE) # initialize the newly created tif file with zeros - this solves the memory error outband.Fill(0.0) #outband.WriteArray(grid_initial_data) # DEBUG: print("Finished initializing sediment grid file.") # set the projection of the tif file same as that of the dem outRasterSRS = osr.SpatialReference() outRasterSRS.ImportFromWkt(dem.GetProjectionRef()) outRaster.SetProjection(outRasterSRS.ExportToWkt()) # open the drainpoints shapefile driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) dataSource = driver.Open(dp_shapefile, 1) layer = dataSource.GetLayer() # for each drain point in shape file # DEBUG: print("Looping over drain points in shapefile") for dp in layer: geom = dp.GetGeometryRef() # find grid row and col corresponding to drain point row, col = utils.get_coordinate_to_grid_row_col( geom.GetX(0), geom.GetY(0), dem) geom = None # get the id of the drain point from shape file graipdid = dp.GetField('GRAIPDID') def _write_sed_accum_to_grid(): # create a 2D array to store sediment production data sed_array = np.zeros((1, 1), dtype=np.float32) # get current grid cell data current_cell_data = outband.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) if current_cell_data[0][0] != utils.NO_DATA_VALUE: sed_array[0][0] = current_cell_data[0][0] + dp_row.SedProd else: sed_array[0][0] = dp_row.SedProd # here we are writing to a specific cell of the grid outband.WriteArray(sed_array, xoff=col, yoff=row) # find the drain point matching row from the DrainPoints db table dp_row = cursor.execute( "SELECT SedProd, StreamConnectID FROM DrainPoints WHERE GRAIPDID=?", graipdid).fetchone() if is_stream_connected: if dp_row.StreamConnectID == 2: _write_sed_accum_to_grid() else: _write_sed_accum_to_grid() outband.FlushCache() # calculate raster statistics (min, max, mean, stdDev) outband.GetStatistics(0, 1) # DEBUG: print("Finished writing data to sediment grid file.") except: raise finally: if dataSource is not None: dataSource.Destroy() if conn: conn.close() dem = None outRaster = None
def compute_length_elevation_interpolation(rd_shapefile, input_dem): """ Calculates road segment length and elevation and writes to roadlines shapefile :param rd_shapefile: Path to roadlines shapefile :param input_dem: Path to dem file :return: None """ # DEBUG: print ("Computing length/elevation interpolation...") driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) dataSource = driver.Open(rd_shapefile, 1) layer = dataSource.GetLayer() layerDefn = layer.GetLayerDefn() dem = gdal.Open(input_dem) dem_nx = dem.RasterXSize dem_ny = dem.RasterYSize gt = dem.GetGeoTransform() dem_band = dem.GetRasterBand(1) # Compute mid-point grid spacings # ref: http://gis.stackexchange.com/questions/7611/bilinear-interpolation-of-point-data-on-a-raster-in-python # gt[0] dem originX # gt[3] dem originY # gt[1] dem cell width (in pixel) # gt[5] dem cell height (in pixel) ax = array([gt[0] + ix*gt[1] + gt[1]/2.0 for ix in range(dem_nx)]) ay = array([gt[3] + iy*gt[5] + gt[5]/2.0 for iy in range(dem_ny)]) try: # delete field "Length" if it exists fld_index = layerDefn.GetFieldIndex('Length') if fld_index > 0: layer.DeleteField(fld_index) # delete "Range" if it exists fld_index = layerDefn.GetFieldIndex('Range') if fld_index > 0: layer.DeleteField(fld_index) except: pass # add a new field (column) 'Length' to the attribute table layer.CreateField(ogr.FieldDefn('Length', ogr.OFTReal)) fld_index_length = layerDefn.GetFieldIndex('Length') # add a new field (column) 'Range' to the attribute table layer.CreateField(ogr.FieldDefn('Range', ogr.OFTReal)) fld_index_range = layerDefn.GetFieldIndex('Range') for feature in layer: try: geom = feature.GetGeometryRef() if geom: total_points = geom.GetPointCount() # write length value to shapefile # feature.SetField(fld_index_length, geom.Length()) rd_length = geom.Length() if total_points > 0: # calculate range from the elevation of 2 end points of the road segment # using interpolation # first find the row, col of the dem corresponding to # the fist point of the road segment row, col = utils.get_coordinate_to_grid_row_col(geom.GetX(0), geom.GetY(0), dem) # get the dem cells corresponding to row, col needed to generate the interpolation function dem_array = dem_band.ReadAsArray(xoff=col, yoff=row, win_xsize=2, win_ysize=2) # define the interpolation function bilinterp = interpolate.interp2d(ax[col:col+2], ay[row:row+2], dem_array, kind='linear') # find the elevation of the 1st point using the interpolation function elevation_1 = bilinterp(geom.GetX(0), geom.GetY(0))[0] # find the row, col of the dem corresponding to # the 2nd point of the road segment row, col = utils.get_coordinate_to_grid_row_col(geom.GetX(total_points-1), geom.GetY(total_points-1), dem) # get the dem cells corresponding to row, col needed to generate the interpolation function dem_array = dem_band.ReadAsArray(xoff=col, yoff=row, win_xsize=2, win_ysize=2) # define the interpolation function bilinterp = interpolate.interp2d(ax[col:col+2], ay[row:row+2], dem_array, kind='linear') # find the elevation of the 1st point using the interpolation function elevation_2 = bilinterp(geom.GetX(total_points-1), geom.GetY(total_points-1))[0] rd_range = abs(elevation_2 - elevation_1) else: rd_range = 0 # sometimes shape/feature have no points - in that case we say range is zero else: rd_length = 0 rd_range = 0 # write length value to shapefile feature.SetField(fld_index_length, rd_length) # write range value to shapefile feature.SetField(fld_index_range, rd_range) # rewrite the feature to the layer - this will in fact save the data layer.SetFeature(feature) geom = None except Exception as ex: dataSource.Destroy() raise # close datasource dataSource.Destroy() # DEBUG: print ("Finished computing length/elevation interpolation...")
def create_drainpoint_weighted_grid(input_dem, graip_db, dpsi_gridfile, dp_shapefile, is_stream_connected): """ Creates a new grid file with drain point sediment production data :param input_dem: Path to dem file :param graip_db: Path to graip database file :param dpsi_gridfile: Path the output grid file to which sediment data will be writen :param dp_shapefile: Path to drainpoint shapefile :param is_stream_connected: Flag(True/False) to indicate if sediment data grid file be created for all drainpoints or only stream connected points :return: None """ # DEBUG: print ("Starting to write sediment data to output grid file.") dataSource = None conn = None try: conn = pyodbc.connect(utils.MS_ACCESS_CONNECTION % graip_db) cursor = conn.cursor() # TODO: May be use the no data value from the input dem # (ref: http://www.gdal.org/classGDALRasterBand.html#adcca51d230b5ac848c43f1896293fb50) # create a new weighted tif file based on the dem file dem = gdal.Open(input_dem) geotransform = dem.GetGeoTransform() originX = geotransform[0] originY = geotransform[3] pixelWidth = geotransform[1] pixelHeight = geotransform[5] rows = dem.RasterYSize cols = dem.RasterXSize # DEBUG: print ("Creating sediment output grid file.") driver = gdal.GetDriverByName(utils.GDALFileDriver.TifFile()) number_of_bands = 1 outRaster = driver.Create(dpsi_gridfile, cols, rows, number_of_bands, gdal.GDT_Float32) outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight)) # DEBUG: print ("Initializing sediment output grid file with zeros.") # TODO: use the band Fill() method to initialize the raster (ref:http://www.gdal.org/classGDALRasterBand.html#a55bf20527df638dc48bf25e2ff26f353) # initialize the newly created tif file with zeros # grid_initial_data = np.zeros((rows, cols), dtype=np.float32) # grid_initial_data[:] = 0.0 # this causes memory error in case of big dem outband = outRaster.GetRasterBand(1) outband.SetNoDataValue(utils.NO_DATA_VALUE) # initialize the newly created tif file with zeros - this solves the memory error outband.Fill(0.0) #outband.WriteArray(grid_initial_data) # DEBUG: print ("Finished initializing sediment grid file.") # set the projection of the tif file same as that of the dem outRasterSRS = osr.SpatialReference() outRasterSRS.ImportFromWkt(dem.GetProjectionRef()) outRaster.SetProjection(outRasterSRS.ExportToWkt()) # open the drainpoints shapefile driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) dataSource = driver.Open(dp_shapefile, 1) layer = dataSource.GetLayer() # for each drain point in shape file # DEBUG: print ("Looping over drain points in shapefile") for dp in layer: geom = dp.GetGeometryRef() # find grid row and col corresponding to drain point row, col = utils.get_coordinate_to_grid_row_col(geom.GetX(0), geom.GetY(0), dem) geom = None # get the id of the drain point from shape file graipdid = dp.GetField('GRAIPDID') def _write_sed_accum_to_grid(): # create a 2D array to store sediment production data sed_array = np.zeros((1, 1), dtype=np.float32) # get current grid cell data current_cell_data = outband.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) if current_cell_data[0][0] != utils.NO_DATA_VALUE: sed_array[0][0] = current_cell_data[0][0] + dp_row.SedProd else: sed_array[0][0] = dp_row.SedProd # here we are writing to a specific cell of the grid outband.WriteArray(sed_array, xoff=col, yoff=row) # find the drain point matching row from the DrainPoints db table dp_row = cursor.execute("SELECT SedProd, StreamConnectID FROM DrainPoints WHERE GRAIPDID=?", graipdid).fetchone() if is_stream_connected: if dp_row.StreamConnectID == 2: _write_sed_accum_to_grid() else: _write_sed_accum_to_grid() outband.FlushCache() # calculate raster statistics (min, max, mean, stdDev) outband.GetStatistics(0, 1) # DEBUG: print ("Finished writing data to sediment grid file.") except: raise finally: if dataSource is not None: dataSource.Destroy() if conn: conn.close() dem = None outRaster = None
def _sindex_drain_points(mdb, dp, si): # for each drain point in the drain points shape file find the cell value in the combined stability index grid file # and use that value to populate the corresponding row in the drainpoints table driver = ogr.GetDriverByName(utils.GDALFileDriver.ShapeFile()) dataSource = driver.Open(dp, GA_Update) layer = dataSource.GetLayer() layerDefn = layer.GetLayerDefn() fld_index_graipdid = layerDefn.GetFieldIndex('GRAIPDID') si_grid = gdal.Open(si) si_band = si_grid.GetRasterBand(1) field_to_create = 'SI' try: #delete field if it exists in drainpoints shapefile fld_index_dp = layerDefn.GetFieldIndex(field_to_create) if fld_index_dp > 0: layer.DeleteField(fld_index_dp) # add a new field (column) to the attribute table of drainpoints shapefile layer.CreateField(ogr.FieldDefn(field_to_create, ogr.OFTReal)) fld_index_dp = layerDefn.GetFieldIndex(field_to_create) except: pass try: conn = pyodbc.connect(utils.MS_ACCESS_CONNECTION % mdb) cursor = conn.cursor() for feature in layer: geom = feature.GetGeometryRef() total_points = geom.GetPointCount() if total_points > 0: # calculate range from the elevation of 2 end points of the road segment row, col = utils.get_coordinate_to_grid_row_col( geom.GetX(0), geom.GetY(0), si_grid) si_cell_data = si_band.ReadAsArray(xoff=col, yoff=row, win_xsize=1, win_ysize=1) graipdid = feature.GetFieldAsInteger(fld_index_graipdid) dp_row = cursor.execute( "SELECT * FROM DrainPoints WHERE GRAIPDID=%d" % graipdid).fetchone() if dp_row: if si_cell_data[0][0] == si_band.GetNoDataValue(): dp_row.SI = -9999 else: dp_row.SI = float(si_cell_data[0][0]) update_sql = "UPDATE DrainPoints SET SI=? WHERE GRAIPDID=?" data = (dp_row.SI, dp_row.GRAIPDID) cursor.execute(update_sql, data) # write si data to drainpoints shapefile feature.SetField(fld_index_dp, data[0]) # rewrite the feature to the layer - this will in fact save the data to the file layer.SetFeature(feature) geom = None conn.commit() except: raise finally: # cleanup if conn: conn.close() if dataSource: dataSource.Destroy()