Ejemplo n.º 1
0
def basin_divide(sub_basins_tif, boundary_geoj, trace_tif, acc_tif, dir_tif):
    # 获得多边形边界信息
    polygons_array = sbu.get_polygon_points(boundary_geoj)
    # 找到主要边界所在多边形
    main_polygon, main_index = sbu.get_main_polygon(polygons_array)
    # 判断是否需要更新岛到边界
    if main_index['no_island'] == 1:
        polygon_pts = main_polygon
    else:
        # 更新岛到主要外边界
        polygon_pts = sbu.update_island2boundary(polygons_array[main_index['polygon_index']])

    trace_ds = gdal.Open(trace_tif)
    acc_ds = gdal.Open(acc_tif)
    dir_ds = gdal.Open(dir_tif)

    p_clockwise = sbu.is_clockwise(polygon_pts)
    # 边界为顺时针多边形
    if p_clockwise:
        # 获取多边形顶点在栅格数据中的索引
        p_offs = []
        for point in polygon_pts:
            p_offs.append(cu.coord_to_off(point, trace_ds))
        # 获取多边形其边对应的所有栅格索引的集合
        polygon_ras_indexes = sbu.raster_index_on_polygon(p_offs)

        # 更新边界外部多边形内像元到内边界栅格集内
        # 记录多个多边形连接处索引
        joint_offs = []
        if len(polygons_array) > 1:
            polygon_ras_indexes, joint_offs = sbu.update_outer2polygons(polygon_ras_indexes, trace_ds, polygons_array, main_index['polygon_index'])

        # 得到多边形边界内部邻接栅格像元的索引
        inner_ras_indexes = sbu.inner_boundary_raster_indexes(polygon_ras_indexes, joint_offs)
        # 得到流域集合边界上出口栅格顺时针编号
        outlets_order = outlets_index_order(inner_ras_indexes, trace_ds)
        # 以四个大流域为界将流域出口分组
        outlet_groups = divide_outlet_to_group(outlets_order, acc_ds)

        file_format = "GTiff"
        driver = gdal.GetDriverByName(file_format)
        sub_ds = driver.Create(sub_basins_tif, trace_ds.RasterXSize, trace_ds.RasterYSize, 1, gdal.GDT_Int16, options=['COMPRESS=DEFLATE'])
        sub_ds.SetGeoTransform(trace_ds.GetGeoTransform())
        sub_ds.SetProjection(trace_ds.GetProjection())
        sub_ds.GetRasterBand(1).SetNoDataValue(-1)

        for i in range(len(outlet_groups)):
            outlet_group = outlet_groups[i]
            for outlet in outlet_group:
                x_off = outlet[0]
                y_off = outlet[1]
                if cu.in_data(x_off, y_off, sub_ds.RasterXSize, sub_ds.RasterYSize):
                    outlet_basins(outlet, sub_ds, i + 1, dir_ds)
    else:
        print('No support anticlockwise!')

    trace_ds = None
    sub_ds = None
    acc_ds = None
    dir_ds = None
Ejemplo n.º 2
0
def down_point_coord(b_point, dir_index):
    current_dir_path = find_data_by_point(b_point, dir_index)
    cu_dir_ds = gdal.Open(current_dir_path)
    dir_off = cu.coord_to_off(b_point, cu_dir_ds)
    dir_value = cu.get_raster_int_value(cu_dir_ds, dir_off[0], dir_off[1])
    to_off = cu.get_to_point(dir_off[0], dir_off[1], dir_value)
    to_coord = cu.off_to_coord(to_off, cu_dir_ds)
    cu_dir_ds = None
    return to_coord
Ejemplo n.º 3
0
def get_trace_from_record(refer_tif, seaside_txt, final_txt, trace_tif):
    ref_ds = gdal.Open(refer_tif)

    print("Create Trace file...")
    file_format = "GTiff"
    driver = gdal.GetDriverByName(file_format)
    full_geotransform = ref_ds.GetGeoTransform()
    trace_ds = driver.Create(trace_tif, ref_ds.RasterXSize, ref_ds.RasterYSize,
                             1, gdal.GDT_Byte)
    trace_ds.SetGeoTransform(full_geotransform)
    trace_ds.SetProjection(ref_ds.GetProjection())
    trace_ds.GetRasterBand(1).SetNoDataValue(0)

    # 将内流区域终点更新到河流数据
    print("Add Final to Trace file...")
    with open(final_txt, 'r') as final_file:
        for line in final_file.readlines():
            final_info_str = line.strip('\n')
            final_info = final_info_str.split(',')
            # 将final像元的x,y索引
            f_x_coord = float(final_info[0])
            f_y_coord = float(final_info[1])
            off_xy = cu.coord_to_off([f_x_coord, f_y_coord], trace_ds)
            if cu.in_data(off_xy[0], off_xy[1], trace_ds.RasterXSize,
                          trace_ds.RasterYSize):
                cu.set_raster_int_value(trace_ds, off_xy[0], off_xy[1], 1)

    # 将内流区域终点更新到河流数据
    print("Add Seaside to Trace file...")
    with open(seaside_txt, 'r') as final_file:
        for line in final_file.readlines():
            final_info_str = line.strip('\n')
            final_info = final_info_str.split(',')
            # 将seaside像元的x,y索引
            f_x_coord = float(final_info[0])
            f_y_coord = float(final_info[1])
            off_xy = cu.coord_to_off([f_x_coord, f_y_coord], trace_ds)
            if cu.in_data(off_xy[0], off_xy[1], trace_ds.RasterXSize,
                          trace_ds.RasterYSize):
                cu.set_raster_int_value(trace_ds, off_xy[0], off_xy[1], 1)

    print('over.')
    ref_ds = None
    trace_ds = None
def basin_spill(boundary_geoj, dem_tif):
    # 获得多边形边界信息
    polygons_array = sbu.get_polygon_points(boundary_geoj)
    # 找到主要边界所在多边形
    main_polygon, main_index = sbu.get_main_polygon(polygons_array)
    # 判断是否需要更新岛到边界
    if main_index['no_island'] == 1:
        polygon_pts = main_polygon
    else:
        # 更新岛到主要外边界
        polygon_pts = sbu.update_island2boundary(polygons_array[main_index['polygon_index']])

    dem_ds = gdal.Open(dem_tif)

    p_clockwise = sbu.is_clockwise(polygon_pts)
    # 边界为顺时针多边形
    if p_clockwise:
        # 获取多边形顶点在栅格数据中的索引
        p_offs = []
        for point in polygon_pts:
            p_offs.append(cu.coord_to_off(point, dem_ds))
        # 获取多边形其边对应的所有栅格索引的集合
        polygon_ras_indexes = sbu.raster_index_on_polygon(p_offs)

        # 更新边界外部多边形内像元到内边界栅格集内
        # 记录多个多边形连接处索引
        joint_offs = []
        if len(polygons_array) > 1:
            polygon_ras_indexes, joint_offs = sbu.update_outer2polygons(polygon_ras_indexes, dem_ds, polygons_array, main_index['polygon_index'])

        # 得到多边形边界内部邻接栅格像元的索引
        inner_ras_indexes = sbu.inner_boundary_raster_indexes(polygon_ras_indexes, joint_offs)

        # # 输出到tif
        # temp_path = r'G:\Graduation\Program\Data\42\boundary.tif'
        # file_format = "GTiff"
        # driver = gdal.GetDriverByName(file_format)
        # temp_ds = driver.Create(temp_path, dem_ds.RasterXSize, dem_ds.RasterYSize, 1, gdal.GDT_Int16, options=['COMPRESS=DEFLATE'])
        # temp_ds.SetGeoTransform(dem_ds.GetGeoTransform())
        # temp_ds.SetProjection(dem_ds.GetProjection())
        # temp_ds.GetRasterBand(1).SetNoDataValue(-1)
        # for off_index in range(len(inner_ras_indexes)):
        #     off = inner_ras_indexes[off_index]
        #     cu.set_raster_int_value(temp_ds, off[0], off[1], off_index)
        # temp_ds = None

        # 得到流域内边界最低点及出流方向
        spill_point, spill_dir, reception_pt = spill_point_dir(inner_ras_indexes, dem_ds)
        # 得到接受点的坐标
        reception_pt_coord = cu.off_to_coord(reception_pt, dem_ds)
        return spill_point, spill_dir, reception_pt_coord
    else:
        print('No support anticlockwise!')
    dem_ds = None

    return [], 0, []
Ejemplo n.º 5
0
def update_outer2polygons(polygon_ras_indexes, refer_ds, polygons_array,
                          main_p_index):
    joint_offs = []
    for polygon_index in range(len(polygons_array)):
        # 遍历其他多边形
        if polygon_index != main_p_index:
            # 得到多边形
            polygon = polygons_array[polygon_index]
            # 若不存在岛
            if len(polygon) == 1:
                polygon = polygon[0]
                # 若为单个像元
                if len(polygon) == 5:
                    temp_list = polygon[:len(polygon) - 1]
                    for index in range(len(temp_list)):
                        polygon_pt = temp_list[index]
                        pt_off = cu.coord_to_off(polygon_pt, refer_ds)
                        # 若相邻
                        if pt_off in polygon_ras_indexes:
                            # 记录相邻点索引
                            joint_offs.append(pt_off)
                            # 获取插入到边界点集的位置
                            in_main_index = polygon_ras_indexes.index(pt_off)
                            # 初始化插入数组
                            join_off = []
                            for n_index in range(index, len(temp_list)):
                                pt = temp_list[n_index]
                                off = cu.coord_to_off(pt, refer_ds)
                                join_off.append(off)
                            for n_index in range(0, index):
                                pt = temp_list[n_index]
                                off = cu.coord_to_off(pt, refer_ds)
                                join_off.append(off)
                            join_off.reverse()
                            for off in join_off:
                                polygon_ras_indexes.insert(in_main_index, off)
                            break
                else:
                    print('暂不支持较大多边形')
            else:
                print('暂不支持含岛多边形')

    return polygon_ras_indexes, joint_offs
Ejemplo n.º 6
0
def update_acc_by_coord(point, acc_index, acc_value):
    current_acc_path = find_data_by_point(point, acc_index)
    cu_acc_ds = gdal.Open(current_acc_path, 1)
    cu_off = cu.coord_to_off(point, cu_acc_ds)
    cu.set_raster_float_value(cu_acc_ds, cu_off[0], cu_off[1], acc_value)
    cu_acc_ds = None
    # 另行记录更新的像元
    global update_index
    update_index += 1
    # check_off = cu.coord_to_off(point, dataset_ol)
    # cu.set_raster_float_value(dataset_ol, check_off[0], check_off[1], acc_value)
    print("\r", point, "->", acc_value, " Updated Num: ", update_index, end="")
Ejemplo n.º 7
0
def add_final_to_river(dir_tif,
                       final_points_txt,
                       river_tif,
                       acc_tif,
                       river_th=None):
    dir_ds = gdal.Open(dir_tif, 1)
    rt_ds = gdal.Open(river_tif, 1)
    acc_ds = gdal.Open(acc_tif)

    # 将内流区域终点更新到河流数据
    with open(final_points_txt, 'r') as final_file:
        for line in final_file.readlines():
            final_info_str = line.strip('\n')
            final_info = final_info_str.split(',')
            # 将final像元的x,y索引
            f_x_coord = float(final_info[0])
            f_y_coord = float(final_info[1])
            final_off = cu.coord_to_off([f_x_coord, f_y_coord], rt_ds)
            final_xoff = final_off[0]
            final_yoff = final_off[1]
            # 得到在河流中对应的索引
            r_off = cu.off_transform(final_xoff, final_yoff, dir_ds, rt_ds)
            # 若在数据内
            if cu.in_data(r_off[0], r_off[1], rt_ds.RasterXSize,
                          rt_ds.RasterYSize):
                # 寻找内流终点周边最小汇流累积像元(最后形成虚拟河系)
                ne_cells = cu.get_8_dir(final_xoff, final_yoff)
                min_acc_point = []
                min_acc = cu.get_raster_float_value(acc_ds, final_xoff,
                                                    final_yoff)
                for point in ne_cells:
                    acc_value = cu.get_raster_float_value(
                        acc_ds, point[0], point[1])
                    if acc_value < min_acc:
                        min_acc = acc_value
                        min_acc_point = point
                # 若最小累积量像元不成为河系
                if river_th is None or min_acc < river_th:
                    # 则赋值内流终点流向该方向
                    dir_value = 1
                    if river_th is not None:
                        dir_value = cu.dir_between_points(
                            [final_xoff, final_yoff], min_acc_point)
                    cu.set_raster_int_value(dir_ds, final_xoff, final_yoff,
                                            dir_value)
                    # 记录Final point到河流
                    cu.set_raster_int_value(rt_ds, r_off[0], r_off[1], 1)
Ejemplo n.º 8
0
def able_update_acc(b_point, x_size, y_size, acc_index, dir_index):
    global nc
    # 获取acc整体数据边界
    total_lt = list(acc_index.values())[0][0][:]
    total_rb = list(acc_index.values())[0][0][:]
    for value in acc_index.values():
        if total_lt[0] >= value[0][0]:
            total_lt[0] = value[0][0]
        if total_lt[1] <= value[0][1]:
            total_lt[1] = value[0][1]
        if total_rb[0] <= value[1][0]:
            total_rb[0] = value[1][0]
        if total_rb[1] >= value[1][1]:
            total_rb[1] = value[1][1]

    # 初始化上游像元汇流累积量(初始化为0)
    up_cells_acc = 0
    # 初始化标记存在上游像元(初始化为不存在)
    up_cell_flag = 0
    # 初始化标记存在上游像元acc暂为nodata(初始化为存在nodata上游点)
    up_nodata_flag = 0
    # 获取周边像元坐标(左上角)从邻近像元搜索
    n_cells = cu.get_8_dir_coord(b_point[0], b_point[1], x_size, y_size)
    for n_cell in n_cells:
        # 得到所处数据块
        acc_path = find_data_by_point(n_cell, acc_index)
        dir_path = find_data_by_point(n_cell, dir_index)
        if acc_path != "" and dir_path != "":
            # 判断是否为上游点
            dir_ds = gdal.Open(dir_path)
            # 根据坐标转为索引
            n_off = cu.coord_to_off(n_cell, dir_ds)
            # 获得此处流向值
            dir_value = cu.get_raster_int_value(dir_ds, n_off[0], n_off[1])
            # 获得下游像元索引
            d_off = cu.get_to_point(n_off[0], n_off[1], dir_value)
            # 若为有下游像元
            if d_off:
                # 获取该下游像元的坐标
                d_coord = cu.off_to_coord(d_off, dir_ds)
                # 若该下游像元坐标与当前坐标相同则此邻近像元为上游像元
                if d_coord == b_point:
                    up_cell_flag = 1
                    # 获取此上游像元处的汇流累积量值
                    acc_ds = gdal.Open(acc_path)
                    n_acc_off = cu.coord_to_off(n_cell, acc_ds)
                    n_acc = cu.get_raster_float_value(acc_ds, n_acc_off[0],
                                                      n_acc_off[1])
                    # 若此acc值为nodata则标记存在上游像元acc暂为nodata
                    if int(n_acc) <= 0:
                        up_nodata_flag = 1
                        break
                    # 否则记录当前值到总上游累积量
                    else:
                        up_cells_acc += n_acc
                    acc_ds = None
            dir_ds = None
    # 若存在上游像元
    if up_cell_flag:
        # 若上游像元均有有效acc值
        if up_nodata_flag == 0:
            # 更新上游acc总值和自身累积量值到当前像元
            current_acc = up_cells_acc + 1.0
            return current_acc
        # 存在上游像元暂为nodata
        else:
            return 0
    # 若不存在上游像元
    else:
        # 若考虑边界污染
        if nc:
            # 若在边界上
            if in_edge(b_point, total_lt, total_rb):
                return 0
            else:
                # 否则作为汇流起始点
                return 1.0
        # 若不考虑边界污染
        else:
            return 1.0
Ejemplo n.º 9
0
def basin_divide(sub_basins_tif, boundary_geoj, trace_tif, acc_tif, dir_tif):
    # 获得多边形边界信息
    polygons_array = sbu.get_polygon_points(boundary_geoj)
    # 找到主要边界所在多边形
    main_polygon, main_index = sbu.get_main_polygon(polygons_array)
    # 判断是否需要更新岛到边界
    if main_index['no_island'] == 1:
        polygon_pts = main_polygon
    else:
        # 更新岛到主要外边界
        polygon_pts = sbu.update_island2boundary(
            polygons_array[main_index['polygon_index']])

    trace_ds = gdal.Open(trace_tif)
    acc_ds = gdal.Open(acc_tif)
    dir_ds = gdal.Open(dir_tif)

    p_clockwise = sbu.is_clockwise(polygon_pts)
    # 边界为顺时针多边形
    if p_clockwise:
        # 获取多边形顶点在栅格数据中的索引
        p_offs = []
        for point in polygon_pts:
            p_offs.append(cu.coord_to_off(point, trace_ds))
        # 获取多边形其边对应的所有栅格索引的集合
        polygon_ras_indexes = sbu.raster_index_on_polygon(p_offs)

        # 更新边界外部多边形内像元到内边界栅格集内
        # 记录多个多边形连接处索引
        joint_offs = []
        if len(polygons_array) > 1:
            polygon_ras_indexes, joint_offs = sbu.update_outer2polygons(
                polygon_ras_indexes, trace_ds, polygons_array,
                main_index['polygon_index'])

        # 得到多边形边界内部邻接栅格像元的索引
        inner_ras_indexes = sbu.inner_boundary_raster_indexes(
            polygon_ras_indexes, joint_offs)

        # # 输出到tif
        # temp_path = r'G:\Graduation\Program\Data\51\nested\5\56\566\process\boundary.tif'
        # file_format = "GTiff"
        # driver = gdal.GetDriverByName(file_format)
        # temp_ds = driver.Create(temp_path, trace_ds.RasterXSize, trace_ds.RasterYSize, 1, gdal.GDT_Float32, options=['COMPRESS=DEFLATE'])
        # temp_ds.SetGeoTransform(trace_ds.GetGeoTransform())
        # temp_ds.SetProjection(trace_ds.GetProjection())
        # temp_ds.GetRasterBand(1).SetNoDataValue(-1)
        # for off_index in range(len(inner_ras_indexes)):
        #     off = inner_ras_indexes[off_index]
        #     cu.set_raster_float_value(temp_ds, off[0], off[1], off_index*0.001)
        # temp_ds = None

        # 得到流域集合边界上出口栅格顺时针编号
        outlets_order = outlets_index_order(inner_ras_indexes, trace_ds)

        # # 输出到tif
        # temp_path = r'G:\Graduation\Program\Data\51\nested\5\56\566\process\outlet_order.tif'
        # file_format = "GTiff"
        # driver = gdal.GetDriverByName(file_format)
        # temp_ds = driver.Create(temp_path, trace_ds.RasterXSize, trace_ds.RasterYSize, 1, gdal.GDT_Float32, options=['COMPRESS=DEFLATE'])
        # temp_ds.SetGeoTransform(trace_ds.GetGeoTransform())
        # temp_ds.SetProjection(trace_ds.GetProjection())
        # temp_ds.GetRasterBand(1).SetNoDataValue(-1)
        # for off_index in range(len(outlets_order)):
        #     off = outlets_order[off_index]
        #     cu.set_raster_float_value(temp_ds, off[0], off[1], off_index*0.001)
        # temp_ds = None

        # 得到排序好的出口索引在acc数据中的索引
        outlets_order_in_acc = []
        for outlet in outlets_order:
            coord = cu.off_to_coord(outlet, trace_ds)
            outlets_order_in_acc.append(cu.coord_to_off(coord, acc_ds))

        # 以四个大流域为界将流域出口分组
        outlet_groups = divide_outlet_to_group(outlets_order_in_acc, acc_ds)

        file_format = "GTiff"
        driver = gdal.GetDriverByName(file_format)
        sub_ds = driver.Create(sub_basins_tif,
                               acc_ds.RasterXSize,
                               acc_ds.RasterYSize,
                               1,
                               gdal.GDT_Int16,
                               options=['COMPRESS=DEFLATE'])
        sub_ds.SetGeoTransform(acc_ds.GetGeoTransform())
        sub_ds.SetProjection(acc_ds.GetProjection())
        sub_ds.GetRasterBand(1).SetNoDataValue(-1)

        for i in range(len(outlet_groups)):
            outlet_group = outlet_groups[i]
            for outlet in outlet_group:
                x_off = outlet[0]
                y_off = outlet[1]
                if cu.in_data(x_off, y_off, sub_ds.RasterXSize,
                              sub_ds.RasterYSize):
                    outlet_basins(outlet, sub_ds, i + 1, dir_ds)
    else:
        print('No support anticlockwise!')

    trace_ds = None
    sub_ds = None
    acc_ds = None
    dir_ds = None