def get_surface_route(surface_route_start):
    global acc_ds, dir_ds, route_ds, slope_ds, water_value, river_th, surface_route_value
    # 提取各水体的坡面流路
    for route_start_point in surface_route_start:
        # 初始化流路追踪数组
        judge_route = [route_start_point]
        while len(judge_route) > 0:
            current_point = judge_route.pop()
            xoff = current_point[0]
            yoff = current_point[1]
            # 获取此点其汇流累积量
            acc_off = cu.off_transform(xoff, yoff, slope_ds, acc_ds)
            acc_value = cu.get_raster_float_value(acc_ds, acc_off[0], acc_off[1])
            # 获取此点在结果数据的值
            ol_value = cu.get_raster_int_value(slope_ds, xoff, yoff)
            # 若流向的点不为水体且不为河道则继续
            if ol_value != water_value and acc_value < river_th:
                # 记录此点为坡面流路
                cu.set_raster_int_value(route_ds, xoff, yoff, surface_route_value)
                # 获取此点流向
                dir_value = cu.get_raster_int_value(dir_ds, xoff, yoff)
                # 获取其流向的点
                to_point = cu.get_to_point(xoff, yoff, dir_value)
                if len(to_point) > 0:
                    to_p_a_off = cu.off_transform(to_point[0], to_point[1], slope_ds, acc_ds)
                    if cu.in_data(to_p_a_off[0], to_p_a_off[1], acc_ds.RasterXSize, acc_ds.RasterYSize):
                        # 加入判断数组
                        judge_route.append(to_point)
def spill_point_dir(inner_ras_indexes, dem_ds):
    # 内边界的高程
    inner_dem = []
    for ras_index in inner_ras_indexes:
        dem_value = cu.get_raster_float_value(dem_ds, ras_index[0], ras_index[1])
        inner_dem.append(dem_value)
    # 获得最低位置的索引
    spill_pt_index = list(map(inner_dem.index, heapq.nsmallest(1, inner_dem)))[0]
    spill_pt = inner_ras_indexes[spill_pt_index]
    # 获得溢出方向
    spill_dir = get_spill_dir(inner_ras_indexes, spill_pt_index)
    # 得到接收点索引
    reception_pt = cu.get_to_point(spill_pt[0], spill_pt[1], spill_dir)

    # # 输出到tif
    # temp_path = r'G:\Graduation\Program\Data\41\endorheic_area0\outlet_dir.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)
    # cu.set_raster_int_value(temp_ds, spill_pt[0], spill_pt[1], spill_dir)
    # temp_ds = None

    return spill_pt, spill_dir, reception_pt
def outline_upstream_search(xoff, yoff, water_buf, upstream_inflow):
    global dir_ds, slope_ds, water_value
    # 创建搜索数组
    search_inflows = [[xoff, yoff]]
    # 开始搜索
    while len(search_inflows) > 0:
        # 取出初始像元
        cell_off = search_inflows.pop()
        xoff = cell_off[0]
        yoff = cell_off[1]
        # 搜索周边像元
        ol_dir_array = cu.get_8_dir(xoff, yoff)
        for ol_n_cell in ol_dir_array:
            n_xoff = ol_n_cell[0]
            n_yoff = ol_n_cell[1]
            # 判断像元是否在数据集内且是否为有效流向
            judge_in_data = cu.in_data(n_xoff, n_yoff, dir_ds.RasterXSize, dir_ds.RasterYSize)
            if judge_in_data:
                # 判断是否在水体内
                ol_data = cu.get_raster_int_value(slope_ds, n_xoff, n_yoff)
                # 若不在水体则继续
                if ol_data != water_value:
                    dir_data_value = cu.get_raster_int_value(dir_ds, n_xoff, n_yoff)
                    to_point = cu.get_to_point(n_xoff, n_yoff, dir_data_value)
                    if len(to_point) != 0:
                        # 若为上游点
                        if to_point[0] == xoff and to_point[1] == yoff:
                            # 判断是否在外边界上,若是则记录
                            if ol_n_cell in water_buf:
                                # 则记录为外边界上的上游坡面入流点
                                upstream_inflow.append([n_xoff, n_yoff])
                            # 继续遍历相邻像元
                            search_inflows.append(ol_n_cell)
def get_to_point_ol_data(xoff, yoff):
    global dir_ds, slope_ds, no_data_value
    dir_data_value = cu.get_raster_int_value(dir_ds, xoff, yoff)
    to_point = cu.get_to_point(xoff, yoff, dir_data_value)
    if len(to_point) < 1:
        return no_data_value
    else:
        return cu.get_raster_int_value(slope_ds, to_point[0], to_point[1])
示例#5
0
def get_to_point_ol_data(xoff, yoff):
    global dataset_dir, dataset_ol, no_data_value
    dir_data_value = cu.get_raster_int_value(dataset_dir, xoff, yoff)
    to_point = cu.get_to_point(xoff, yoff, dir_data_value)
    if len(to_point) < 1:
        return no_data_value
    else:
        return cu.get_raster_int_value(dataset_ol, to_point[0], to_point[1])
def surface_merge(upstream_inflow, new_slope_surface_id):
    global slope_ds, dir_ds, water_buffer_value, water_value
    # 定义合并后的坡面分组
    slope_surface_unit = []
    # 遍历上游流入点对坡面与水体相交处的入流口分组
    for upstream_point in upstream_inflow:
        # 判断坡面入流点已参与合并
        not_in_unit = 1
        for index in range(0, len(slope_surface_unit), 1):
            if upstream_point in slope_surface_unit[index]:
                not_in_unit = 0
                break
        # 若坡面入流点未参与合并
        if not_in_unit:
            # 创建新坡面集合并添加新坡面的首个水体入流点
            slope_surface = [upstream_point]
            # 获取新坡面集合的入流点集
            slope_surface = get_new_slope_surface(upstream_point[0], upstream_point[1], upstream_inflow, slope_surface)
            # 将新坡面放入合并后的坡面集合中
            slope_surface_unit.append(slope_surface)

    # 获取合并后新坡面的id
    new_slope_surface_id += 1

    # 以各合并坡面的入口点集开始合并坡面
    for index in range(0, len(slope_surface_unit), 1):
        # print(slope_surface_unit[index])
        # 获取合并后新坡面与水体的交界点
        s_s_inflows = slope_surface_unit[index]
        for inflow_point in s_s_inflows:
            # 初始化需要更新的像元集
            to_update_points = [inflow_point]
            # 循环直到待更新数组为空
            while len(to_update_points) > 0:
                # 取出第一个点
                to_update_point = to_update_points.pop()
                # 更新此点id
                cu.set_raster_int_value(slope_ds, to_update_point[0], to_update_point[1], new_slope_surface_id)
                # 获取此点周边需要更新的像元集
                # 获取邻近像元
                neighbor_points = cu.get_8_dir(to_update_point[0], to_update_point[1])
                # 判断各像元是否需要更新
                for point in neighbor_points:
                    point_x = point[0]
                    point_y = point[1]
                    judge_in_data = cu.in_data(point_x, point_y, slope_ds.RasterXSize, slope_ds.RasterYSize)
                    if judge_in_data:
                        # 若不为水体则继续
                        ol_data = cu.get_raster_int_value(slope_ds, point_x, point_y)
                        if ol_data != water_value:
                            # 若是当前点的上游点
                            dir_point = cu.off_transform(point_x, point_y, slope_ds, dir_ds)
                            dir_value = cu.get_raster_int_value(dir_ds, dir_point[0], dir_point[1])
                            to_point = cu.get_to_point(point_x, point_y, dir_value)
                            if to_point == to_update_point:
                                # 加入待更新数组
                                to_update_points.append(point)
    return new_slope_surface_id
示例#7
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
def judge_from_water(xoff, yoff):
    global dir_ds, slope_ds, water_value
    neighbor_points = cu.get_8_dir(xoff, yoff)
    for point in neighbor_points:
        dir_value = cu.get_raster_int_value(dir_ds, point[0], point[1])
        to_point = cu.get_to_point(point[0], point[1], dir_value)
        ol_value = cu.get_raster_int_value(slope_ds, point[0], point[1])
        if ol_value == water_value and to_point[0] == xoff and to_point[1] == yoff:
            return 1
    return 0
示例#9
0
def get_no_inflow_cells(dir_tif, no_inflow_tif):
    dir_ds = gdal.Open(dir_tif)

    # 创建无流入点数据
    print("Create No inflow file...")
    file_format = "GTiff"
    driver = gdal.GetDriverByName(file_format)
    full_geotransform = dir_ds.GetGeoTransform()
    ni_ds = driver.Create(no_inflow_tif,
                          dir_ds.RasterXSize,
                          dir_ds.RasterYSize,
                          1,
                          gdal.GDT_Int32,
                          options=['COMPRESS=DEFLATE'])
    ni_ds.SetGeoTransform(full_geotransform)
    ni_ds.SetProjection(dir_ds.GetProjection())
    ni_ds.GetRasterBand(1).SetNoDataValue(0)

    # 遍历基础数据记录无流入点
    print("Get No Inflow Data...")
    for i in range(dir_ds.RasterYSize):
        for j in range(dir_ds.RasterXSize):
            c_point = [j, i]
            # 邻近像元索引
            n_points = cu.get_8_dir(c_point[0], c_point[1])
            # 初始化流入标记
            inflow_flag = 0
            for n_point in n_points:
                # 判断是否在数据内
                in_data = cu.in_data(n_point[0], n_point[1],
                                     dir_ds.RasterXSize, dir_ds.RasterYSize)
                if in_data:
                    # 判断是否流向原像元点
                    n_dir = cu.get_raster_int_value(dir_ds, n_point[0],
                                                    n_point[1])
                    to_point = cu.get_to_point(n_point[0], n_point[1], n_dir)
                    if to_point == c_point:
                        inflow_flag = 1
                        break
            # 若无流入则记录
            if not inflow_flag:
                cu.set_raster_int_value(ni_ds, c_point[0], c_point[1], 1)
def spill_point_dir(inner_ras_indexes, dem_ds):
    global temp_ds
    # 内边界的高程
    inner_dem = []
    for ras_index in inner_ras_indexes:
        dem_value = cu.get_raster_float_value(dem_ds, ras_index[0],
                                              ras_index[1])
        inner_dem.append(dem_value)
    # 获得最低位置的索引
    spill_pt_index = list(map(inner_dem.index, heapq.nsmallest(1,
                                                               inner_dem)))[0]
    spill_pt = inner_ras_indexes[spill_pt_index]
    # 获得溢出方向
    spill_dir = get_spill_dir(inner_ras_indexes, spill_pt_index)
    # 得到接收点索引
    reception_pt = cu.get_to_point(spill_pt[0], spill_pt[1], spill_dir)

    cu.set_raster_int_value(temp_ds, spill_pt[0], spill_pt[1], spill_dir)

    return spill_pt, spill_dir, reception_pt
示例#11
0
def recode_from_river(watershed_id, river_x, river_y, watershed_tif_path, dir_tif_path, water_tif_path, rivers_index):
    global water_value
    # 创建数据集
    watershed_ds = gdal.OpenEx(watershed_tif_path, 1)
    dir_ds = gdal.Open(dir_tif_path)
    water_ds = gdal.Open(water_tif_path)
    # 初始化需要赋值的像元集合
    update_cells = [[river_x, river_y]]
    # 更新区域内像元值
    # print(">>> update cell:", end='')
    while len(update_cells) > 0:
        # 取出要更新的像元索引
        update_cell = update_cells.pop()
        # print(update_cell, end='')
        # 更新像元值
        cu.set_raster_int_value(watershed_ds, update_cell[0], update_cell[1], watershed_id)
        # print('update: ', update_cell, '->', watershed_id)
        # 得到邻近像元集合
        neighbor_cells = cu.get_8_dir(update_cell[0], update_cell[1])
        # 搜索上游像元
        for neighbor_cell in neighbor_cells:
            n_x = neighbor_cell[0]
            n_y = neighbor_cell[1]
            # 判断邻近点是否在数据内
            if cu.in_data(n_x, n_y, watershed_ds.RasterXSize, watershed_ds.RasterYSize):
                # 若不为河段并不为湖泊/水库(即若为子流域)
                water_off = cu.off_transform(n_x, n_y, watershed_ds, water_ds)
                in_water = cu.is_water_cell(water_ds, water_off[0], water_off[1], water_value)
                if neighbor_cell not in rivers_index and not in_water:
                    dir_value = cu.get_raster_int_value(dir_ds, n_x, n_y)
                    to_point = cu.get_to_point(n_x, n_y, dir_value)
                    # 若为上游点
                    if to_point == update_cell:
                        # 加入更新数组
                        update_cells.append(neighbor_cell)

    watershed_ds = None
    dir_ds = None
示例#12
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
示例#13
0
def watershed_recode(river_record_path, watershed_tif_path, dir_tif_path, water_tif_path):
    # 创建数据集
    watershed_ds = gdal.Open(watershed_tif_path)
    dir_ds = gdal.Open(dir_tif_path)

    # 读取河系信息到内存
    print("Reading rivers info...")
    # 初始化河系像元索引
    rivers_index = []
    rivers_info = {}
    with open(river_record_path, 'r') as river_file:
        for line in river_file.readlines():
            river_info_str = line.strip('\n')
            river_info = river_info_str.split(',')
            # 将river像元的x,y索引作为字典的key
            river_point_str = river_info[0] + ',' + river_info[1]
            # 将river像元的流向和汇流累积量作为字典的value
            river_info_detail = float(river_info[2])
            rivers_info[river_point_str] = river_info_detail
            rivers_index.append([int(river_info[0]), int(river_info[1])])

    # 创建河段集合
    print("Building rivers group...")
    river_reaches = {}
    # 继续创建标识
    flag = 1
    # 开始创建
    while flag:
        flag = 0
        # 取汇流累积量最小的像元索引
        min_acc_river = min(rivers_info, key=rivers_info.get)
        # 获取子流域标识值
        current_cell = min_acc_river.split(',')
        watershed_value = cu.get_raster_int_value(watershed_ds, int(current_cell[0]), int(current_cell[1]))
        # 若不在子流域则继续寻找
        if watershed_value < 0:
            del rivers_info[min_acc_river]
            if rivers_info:
                flag = 1
        # 若在子流域则作为起点
        else:
            # 初始化要遍历的河流起点数组
            river_starts = [min_acc_river]
            # 若河流起点数组不为空则遍历河段
            while len(river_starts) > 0:
                # 开始追踪河段
                start = river_starts.pop()
                # 创建河段索引记录数组
                river_reach = []
                # 获得此像元索引
                start_xy = start.split(',')
                # 获取此河段对应子流域Id标识
                watershed_id = cu.get_raster_int_value(watershed_ds, int(start_xy[0]), int(start_xy[1]))
                # 初始化追踪数组
                tracking = [start]
                # 开始追踪河段的像元
                while len(tracking) > 0:
                    # 取出像元并记录
                    cell_str = tracking.pop()
                    del rivers_info[cell_str]
                    river_reach.append(cell_str)
                    # 获得像元xy索引
                    cell_xy = cell_str.split(',')
                    n_x = cell_xy[0]
                    n_y = cell_xy[1]
                    # 获得流向的像元
                    dir = cu.get_raster_int_value(dir_ds, int(n_x), int(n_y))
                    to_point = cu.get_to_point(int(n_x), int(n_y), dir)
                    to_point_str = ','.join(str(k) for k in to_point)
                    # 若下游像元在原河流数组
                    if to_point_str in rivers_info.keys():
                        # 获取此点在子流域数据的值
                        watershed_value = cu.get_raster_int_value(watershed_ds, to_point[0], to_point[1])
                        # 若在子流域内
                        if watershed_value >= 0:
                            # 若在同子流域内则记录为河段
                            if watershed_value == watershed_id:
                                tracking.append(to_point_str)
                            # 若不在同一子流域则记录为下一河段起点
                            else:
                                river_starts.append(to_point_str)
                        # 若不在子流域内则搜索下游河段的起点
                        else:
                            # 初始化搜索数组
                            find_next_start = [to_point]
                            # 开始搜索
                            while len(find_next_start) > 0:
                                # 取出像元
                                river_cell = find_next_start.pop()
                                # 在原河流数组中清除记录
                                river_cell_str = ','.join(str(k) for k in river_cell)
                                del rivers_info[river_cell_str]
                                # 获得下游像元
                                dir = cu.get_raster_int_value(dir_ds, river_cell[0], river_cell[1])
                                next_point = cu.get_to_point(dir, river_cell[0], river_cell[1])
                                # 若下游像元在原河流数组
                                next_point_str = ','.join(str(k) for k in next_point)
                                if next_point_str in rivers_info.keys():
                                    # 获取此点在子流域数据的值
                                    watershed_value = cu.get_raster_int_value(watershed_ds, next_point[0],
                                                                              next_point[1])
                                    # 若在子流域内
                                    if watershed_value >= 0:
                                        # 则记录为下一河段起点
                                        river_starts.append(next_point_str)
                                    # 若不在子流域内则继续搜索下游河段的起点
                                    else:
                                        find_next_start.append(next_point)
                # 将河段存入集合
                if watershed_id in river_reaches.keys():
                    update_array = river_reaches[watershed_id]
                    update_array.append(river_reach)
                    river_reaches[watershed_id] = update_array
                else:
                    river_reaches[watershed_id] = [river_reach]
            # 若河流像元未全部遍历则继续
            if len(rivers_info) > 0:
                flag = 1

    print("Searching rivers in watersheds need recode...")
    # 记录当前子流域标识最大值
    max_ws_id = 0
    # 初始化在需要重新编码子流域中的河段集合
    recode_ws_rivers = []
    # 筛选出涉及处理的子流域
    for watershed, watershed_rivers in river_reaches.items():
        watershed_id = int(watershed)
        if watershed_id > max_ws_id:
            max_ws_id = watershed_id
        # 若存在多个河段则需要进行重新唯一编码
        if len(watershed_rivers) > 1:
            # print("%s, %d" % (watershed, len(watershed_rivers)))
            # print(watershed_rivers)
            # 找出每组中除最长河段的其他河段
            max_len = 0
            max_river_start = ''
            for river in watershed_rivers:
                if len(river) > max_len:
                    max_len = len(river)
                    max_river_start = river[0]
            for river in watershed_rivers:
                if len(river) <= max_len and max_river_start not in river:
                    recode_ws_rivers.append(river)

    print("Recoding watersheds by rivers...")
    # 在需要重新编码的子流域中的河段
    watershed_count = 0
    for river in recode_ws_rivers:
        max_ws_id += 1
        watershed_count += 1
        total_count = len(recode_ws_rivers)
        print("\r> updating watersheds.....................%d/%d" % (watershed_count, total_count), end='')
        river_count = 0
        print('')
        for river_cell in river:
            river_count += 1
            total_r_count = len(river)
            print("\r>> update by river cell: %d/%d" % (river_count, total_r_count), end='')
            cell_xy = river_cell.split(',')
            recode_from_river(max_ws_id, int(cell_xy[0]), int(cell_xy[1]), watershed_tif_path, dir_tif_path,
                              water_tif_path, rivers_index)
        print(".")

    watershed_ds = None
    dir_ds = None
示例#14
0
def get_trace_points(dir_tif, flag_tif, trace_tif, seaside_txt=None, final_txt=None):

    coastline_value = 0
    final_value = -1

    dir_ds = gdal.Open(dir_tif)
    f_ds = gdal.Open(flag_tif)

    # 创建trace start数据
    print("Create Trace file...")
    file_format = "GTiff"
    driver = gdal.GetDriverByName(file_format)
    full_geotransform = dir_ds.GetGeoTransform()
    trace_ds = driver.Create(trace_tif, dir_ds.RasterXSize, dir_ds.RasterYSize, 1, gdal.GDT_Byte, options=['COMPRESS=DEFLATE'])
    trace_ds.SetGeoTransform(full_geotransform)
    trace_ds.SetProjection(dir_ds.GetProjection())
    trace_ds.GetRasterBand(1).SetNoDataValue(0)

    # 创建记录文件
    seaside_flag = 0
    seaside_f = None
    if seaside_txt is not None:
        print("Record Final Points.")
        seaside_flag = 1
        if os.path.exists(seaside_txt):
            os.remove(seaside_txt)
    if seaside_flag:
        seaside_f = open(seaside_txt, "a")

    final_flag = 0
    final_f = None
    if final_txt is not None:
        print("Record Final Points.")
        final_flag = 1
        if os.path.exists(final_txt):
            os.remove(final_txt)
    if final_flag:
        final_f = open(final_txt, "a")

    # 遍历基础数据记录seaside
    print("Get Trace Data...")
    for i in range(f_ds.RasterYSize):
        for j in range(f_ds.RasterXSize):
            # 获取流向的值
            flag_value = cu.get_raster_int_value(f_ds, j, i)
            # 如果是coastline
            if flag_value == coastline_value:
                # 获取周边像元索引
                neibor_cells = cu.get_8_dir(j, i)
                # 遍历
                for n_cell in neibor_cells:
                    # 判断是否在数据内
                    in_data = cu.in_data(n_cell[0], n_cell[1], dir_ds.RasterXSize, dir_ds.RasterYSize)
                    # 若在数据内
                    if in_data:
                        # 获取流向值
                        dir_value = cu.get_raster_int_value(dir_ds, n_cell[0], n_cell[1])
                        # 获取流向的像元索引
                        n_to_point = cu.get_to_point(n_cell[0], n_cell[1], dir_value)
                        # 若为当前上游像元
                        if n_to_point == [j, i]:
                            # 记录为seaside
                            cu.set_raster_int_value(trace_ds, n_cell[0], n_cell[1], 1)
                            # 记录到文件
                            if seaside_flag:
                                # 获得栅格像元左上角坐标
                                seaside_record_item = cu.off_to_coord([j, i], f_ds)
                                seaside_record_str = ','.join(str(k) for k in seaside_record_item)
                                seaside_f.write(seaside_record_str + '\n')
            # 如果是final point
            elif flag_value == final_value:
                # 记录为final points
                cu.set_raster_int_value(trace_ds, j, i, 1)
                # 记录到文件
                if final_flag:
                    final_record_item = cu.off_to_coord([j, i], f_ds)
                    final_record_str = ','.join(str(k) for k in final_record_item)
                    final_f.write(final_record_str + '\n')
    dir_ds = None
    f_ds = None
    trace_ds = None
    seaside_f = None
    final_f = None