示例#1
0
def run_flow(real_elev, scanned_elev, scanned_calib_elev, env, **kwargs):
    threshold = 30
    flowacc = 'flowacc'
    drain = 'drainage'
    stream = 'stream'
    basin = 'basin'

    env2 = get_environment(raster=scanned_calib_elev)
    change_detection(before=scanned_calib_elev, after=scanned_elev,
                              change='change', height_threshold=[150, 1000], cells_threshold=[20, 140], add=True, max_detected=10, debug=True, env=env)
    # detected points
    points = gscript.read_command('v.out.ascii', input='change',
                                      type='point', format='point').strip().splitlines()
    if points:
        x, y, cat = points[0].split('|')
        gscript.run_command('r.stream.snap', input='change', output='outlet',
                            stream_rast=stream, accumulation=flowacc, radius=10, env=env2)
        outlets = gscript.read_command('v.out.ascii', input='outlet',
                                       type='point', format='point').strip().splitlines()
        x2, y2, cat2 = outlets[0].split('|')
        gscript.run_command('r.water.outlet', input=drain, output=basin, coordinates=(x2, y2), env=env2)
        gscript.write_command('r.colors', map=basin, rules='-', stdin='0% indigo\n100% indigo', env=env2)
        # drain
        gscript.run_command('r.drain', input="hydrodem", output="drain", drain="drain",
                            start_coordinates=(x2, y2), env=env2)
    else:
        gscript.mapcalc('basin = null()', env=env)
        gscript.run_command('v.edit', tool='create', map='drain', env=env)
        gscript.run_command('r.watershed', elevation=scanned_elev, accumulation=flowacc,
                            stream=stream,  drainage=drain, threshold=threshold, env=env)
        gscript.run_command('r.hydrodem', input=scanned_elev, output="hydrodem", mod=30, env=env)
        gs.run_command("g.copy", raster=[scanned_elev, scanned_calib_elev], env=env)
def run_function_with_points(scanned_elev, env, points=None, **kwargs):
    if not points:
        points = "points"
        import analyses

        analyses.change_detection(
            "scan_saved",
            scanned_elev,
            points,
            height_threshold=[10, 100],
            cells_threshold=[5, 50],
            add=True,
            max_detected=5,
            debug=True,
            env=env,
        )
    # read coordinates into a list
    point_list = []
    data = (gs.read_command(
        "v.out.ascii",
        input=points,
        type="point",
        format="point",
        separator="comma",
        env=env,
    ).strip().splitlines())
    for point in data:
        point_list.append([float(p) for p in point.split(",")])
def run_LCP(scanned_elev, env, points=None, **kwargs):
    if not points:
        points = "points"
        import analyses

        analyses.change_detection(
            "scan_saved",
            scanned_elev,
            points,
            height_threshold=[6, 100],
            cells_threshold=[5, 100],
            add=True,
            max_detected=2,
            debug=True,
            env=env,
        )
    # read coordinates into a list
    point_list = []
    data = (gs.read_command(
        "v.out.ascii",
        input=points,
        type="point",
        format="point",
        separator="comma",
        env=env,
    ).strip().splitlines())
    for point in data:
        point_list.append([float(p) for p in point.split(",")[:2]])

    if len(point_list) < 2:
        return
    start_coordinate = point_list[0]
    end_coordinate = point_list[1]

    gs.run_command("r.slope.aspect",
                   elevation=scanned_elev,
                   slope="slope",
                   env=env)
    gs.run_command(
        "r.cost",
        input="slope",
        output="cost",
        start_coordinates=start_coordinate,
        outdir="outdir",
        flags="k",
        env=env,
    )
    gs.run_command("r.colors", map="cost", color="gyr", env=env)
    gs.run_command(
        "r.drain",
        input="cost",
        output="drain",
        direction="outdir",
        drain="drain",
        flags="d",
        start_coordinates=end_coordinate,
        env=env,
    )
示例#4
0
def run_trail_points(scanned_elev, env, **kwargs):
    analyses.change_detection('scan_saved',
                              scanned_elev,
                              'change',
                              height_threshold=[35, 70],
                              cells_threshold=[5, 50],
                              add=True,
                              max_detected=2,
                              debug=True,
                              env=env)
def run_function_with_points(scanned_elev, env, points=None, **kwargs):
    if not points:
        points = 'points'
        import analyses
        analyses.change_detection('scan_saved', scanned_elev, points,
                                  height_threshold=[10, 100], cells_threshold=[5, 50],
                                  add=True, max_detected=5, debug=True, env=env)
    # read coordinates into a list
    point_list = []
    data = gs.read_command('v.out.ascii', input=points, type='point',
                           format='point', separator='comma', env=env).strip().splitlines()
    for point in data:
        point_list.append([float(p) for p in point.split(',')])
def run_LCP(scanned_elev, env, points=None, **kwargs):
    if not points:
        points = 'points'
        import analyses
        analyses.change_detection('scan_saved',
                                  scanned_elev,
                                  points,
                                  height_threshold=[10, 100],
                                  cells_threshold=[5, 50],
                                  add=True,
                                  max_detected=5,
                                  debug=True,
                                  env=env)
    # read coordinates into a list
    point_list = []
    data = gs.read_command('v.out.ascii',
                           input=points,
                           type='point',
                           format='point',
                           separator='comma',
                           env=env).strip().splitlines()
    for point in data:
        if point:
            point_list.append([float(p) for p in point.split(',')[:2]])
    gs.run_command('r.slope.aspect',
                   elevation=scanned_elev,
                   slope='slope',
                   env=env)
    start_coordinate = point_list[0]
    end_coordinate = point_list[1]
    gs.run_command('r.cost',
                   input='slope',
                   output='cost',
                   start_coordinates=start_coordinate,
                   outdir='outdir',
                   flags='k',
                   env=env)
    gs.run_command('r.colors', map='cost', color='gyr', env=env)
    gs.run_command('r.drain',
                   input='cost',
                   output='drain',
                   direction='outdir',
                   drain='drain',
                   flags='d',
                   start_coordinates=end_coordinate,
                   env=env)
def compute_zoomed_region(real_elev, scanned_elev, zoom_name, env):
    if not zoom_name:
        return

    new_change = 'new_change'
    old_change = 'old_change'
    analyses.change_detection(before='scan_saved',
                              after=scanned_elev,
                              change=new_change,
                              height_threshold=[10000, 30000],
                              cells_threshold=[5, 100],
                              add=True,
                              max_detected=5,
                              debug=True,
                              env=env)
    new_points = get_points(new_change)
    if len(new_points) == 2:
        try:
            if compare_points(new_change, old_change, real_elev, env):
                minp, maxp = adjust_coordinates(new_points, real_elev)
                gscript.run_command('g.region',
                                    flags='u',
                                    n=maxp[1],
                                    s=minp[1],
                                    e=maxp[0],
                                    w=minp[0],
                                    save=zoom_name,
                                    env=env)
                gscript.run_command('g.remove',
                                    type='vector',
                                    flags='f',
                                    name=old_change,
                                    env=env)
            else:
                gscript.run_command('g.copy',
                                    vector=[new_change, old_change],
                                    env=env)
        except CalledModuleError as e:
            print(e)
            gscript.run_command('g.copy',
                                vector=[new_change, old_change],
                                env=env)
            #gscript.run_command('v.edit', map=tmp_adjusted, tool='create', env=env)

    else:
        pass
def run_drain(real_elev, scanned_elev, eventHandler, env, subTask, **kwargs):
    before = 'scan_saved'
    analyses.change_detection(before=before,
                              after=scanned_elev,
                              change='change',
                              height_threshold=[60, 220],
                              cells_threshold=[4, 80],
                              add=True,
                              max_detected=1,
                              debug=True,
                              env=env)
    point = gscript.read_command('v.out.ascii',
                                 input='change',
                                 type='point',
                                 format='point',
                                 env=env).strip()
    drain = 'drain_line'
    env2 = get_environment(raster=real_elev)
    if point:
        x, y, cat = point.split('|')
        gscript.run_command('r.drain',
                            input=real_elev,
                            output=drain,
                            drain=drain,
                            start_coordinates='{},{}'.format(x, y),
                            env=env2)
    else:
        gscript.run_command('v.edit', map=drain, tool='create', env=env)

    # copy results
    if point:
        postfix = datetime.now().strftime('%H_%M_%S')
        prefix = 'drain'
        gscript.run_command('g.copy',
                            vector=[
                                'change', '{}_change_{}_{}'.format(
                                    prefix, subTask, postfix)
                            ],
                            env=env)
def run_drain(scanned_elev, env, points=None, **kwargs):
    drain = "drain"
    if not points:
        elev_no_points = "scan_saved"
        points = "points"
        import analyses
        from tangible_utils import get_environment

        env2 = get_environment(raster=elev_no_points)
        analyses.change_detection(
            "scan_saved",
            scanned_elev,
            points,
            height_threshold=[10, 100],
            cells_threshold=[5, 50],
            add=True,
            max_detected=5,
            debug=True,
            env=env,
        )
    else:
        elev_no_points = scanned_elev
        env2 = env
    # if points detected
    if gs.vector_info_topo("points")["points"]:
        gs.run_command(
            "r.drain",
            input=elev_no_points,
            output=drain,
            drain=drain,
            start_points=points,
            env=env2,
        )
    else:
        # create empty vector
        gs.run_command("v.edit", map=drain, tool="create", env=env)
def run_trails(real_elev, scanned_elev, blender_path, eventHandler, env,
               **kwargs):
    resulting = "trail"
    trail = "trail"
    before = "scan_saved"
    # trim the edges to avoid noise being detected as markers
    info = gs.raster_info("scan")
    edge = (info["north"] - info["south"]) / 20
    env2 = get_environment(
        raster=scanned_elev,
        n="n-{}".format(edge),
        s="s+{}".format(edge),
        e="e-{}".format(edge),
        w="w+{}".format(edge),
    )
    analyses.change_detection(
        before=before,
        after=scanned_elev,
        change="change",
        height_threshold=[min_threshold, max_threshold],
        cells_threshold=[10, 100],
        add=True,
        max_detected=max_number_of_markers,
        debug=True,
        env=env2,
    )
    points = {}
    # if we have 'trail_points' vector, use this:
    # data = gs.read_command('v.out.ascii', input='trail_points', type='point', format='point', env=env).strip()
    # c1, c2 = data.splitlines()
    # c1 = c1.split('|')
    # c2 = c2.split('|')
    # points[0] = (float(c1[0]), float(c1[1]))
    # points[1] = (float(c2[0]), float(c2[1]))
    # otherwise we will generate them on the fly:
    points[0], points[1] = create_end_points(env)

    gs.run_command("v.edit", tool="create", map=trail, env=env)
    # detected points
    points_raw = (gs.read_command("v.out.ascii",
                                  input="change",
                                  type="point",
                                  format="point").strip().split())
    i = 2
    for point in points_raw:
        point = point.split("|")
        point = (float(point[0]), float(point[1]))
        points[i] = point
        i += 1
    length = len(points)
    if length == 2:
        gs.mapcalc("{} = null()".format(resulting), env=env)
        event = updateProfile(points=[])
        eventHandler.postEvent(receiver=eventHandler.activities_panel,
                               event=event)
        return

    # distance matrix
    D = []
    for i in range(length):
        D.append([0] * length)
    for p1 in range(0, length - 1):
        for p2 in range(p1 + 1, length):
            d = dist(points, p1, p2)
            D[p1][p2] = d
            D[p2][p1] = d
    # 0 distance for start and end to make sure it's always connected
    D[0][1] = 0
    D[1][0] = 0

    # solve
    solution = solve_tsp_numpy(D, optim_steps=10)
    # rearange solutions to start in start point
    ind1 = solution.index(0)
    ind2 = solution.index(1)
    if ind2 > ind1:
        solution = solution[::-1]
    ind = solution.index(0)
    solution = solution[ind:] + solution[:ind]
    profile_points = []
    for i in solution:
        profile_points.append(points[i])

    # friction
    friction = "friction"
    gs.mapcalc("{} = 0".format(friction), env=env)
    tmp_dir = "tmp_dir"
    tmp_cost = "tmp_cost"
    tmp_drain = "tmp_drain"

    gs.run_command("v.edit", tool="create", map=trail, env=env)
    for i in range(len(solution) - 1):
        gs.run_command(
            "r.walk",
            elevation=before,
            friction=friction,
            output=tmp_cost,
            outdir=tmp_dir,
            start_coordinates=points[solution[i]],
            stop_coordinates=points[solution[i + 1]],
            flags="k",
            env=env,
        )
        gs.run_command(
            "r.drain",
            input=tmp_cost,
            direction=tmp_dir,
            output=tmp_drain,
            drain=tmp_drain,
            start_coordinates=points[solution[i + 1]],
            flags="d",
            env=env,
        )
        gs.run_command("v.patch",
                       input=tmp_drain,
                       output=trail,
                       flags="a",
                       env=env)

    env2 = get_environment(raster=before)
    # slope along line
    gs.run_command("v.to.rast",
                   input=trail,
                   type="line",
                   output="trail_dir",
                   use="dir",
                   env=env2)
    gs.run_command(
        "r.slope.aspect",
        elevation=before,
        slope="saved_slope",
        aspect="saved_aspect",
        env=env2,
    )
    gs.mapcalc(
        "slope_dir = abs(atan(tan({slope}) * cos({aspect} - {trail_dir})))".
        format(slope="saved_slope",
               aspect="saved_aspect",
               trail_dir="trail_dir"),
        env=env2,
    )
    # set new color table
    colors = [
        "0 green", "5 green", "5 yellow", "10 yellow", "10 red", "90 red"
    ]
    gs.write_command("r.colors",
                     map="slope_dir",
                     rules="-",
                     stdin="\n".join(colors),
                     env=env2)
    # increase thickness
    gs.run_command("r.grow",
                   input="slope_dir",
                   radius=1.1,
                   output=resulting,
                   env=env2)

    # update profile
    event = updateProfile(points=profile_points)
    eventHandler.postEvent(receiver=eventHandler.activities_panel, event=event)
示例#11
0
def run_trails(real_elev, scanned_elev, eventHandler, env, **kwargs):
    resulting = "trails2_slopedir"
    before = 'scan_saved'
    #env_crop = get_environment(raster=real_elev, n='n-100', s='s+100', e='e-100', w='w+100')
    analyses.change_detection(before=before,
                              after=scanned_elev,
                              change='change',
                              height_threshold=[60, 335],
                              cells_threshold=[3, 100],
                              add=True,
                              max_detected=10,
                              debug=True,
                              env=env)
    points = {}
    # start and end
    data = gscript.read_command('v.out.ascii',
                                input='trails2_points',
                                type='point',
                                format='point',
                                env=env).strip()
    c1, c2 = data.splitlines()
    c1 = c1.split('|')
    c2 = c2.split('|')
    points[0] = (float(c1[0]), float(c1[1]))
    points[1] = (float(c2[0]), float(c2[1]))

    # detected points
    points_raw = gscript.read_command('v.out.ascii',
                                      input='change',
                                      type='point',
                                      format='point').strip().split()
    i = 2
    for point in points_raw:
        point = point.split('|')
        point = (float(point[0]), float(point[1]))
        points[i] = point
        i += 1
    length = len(points)
    if length == 2:
        gscript.mapcalc("{} = null()".format(resulting), env=env)
        event = updateProfile(points=[])
        eventHandler.postEvent(receiver=eventHandler.activities_panel,
                               event=event)
        return

    # distance matrix
    D = []
    for i in range(length):
        D.append([0] * length)
    for p1 in range(0, length - 1):
        for p2 in range(p1 + 1, length):
            d = dist(points, p1, p2)
            D[p1][p2] = d
            D[p2][p1] = d
    # 0 distance for start and end to make sure it's always connected
    D[0][1] = 0
    D[1][0] = 0

    # solve
    solution = solve_tsp_numpy(D, optim_steps=10)
    # rearange solutions to start in start point
    ind1 = solution.index(0)
    ind2 = solution.index(1)
    if ind2 > ind1:
        solution = solution[::-1]
    ind = solution.index(0)
    solution = solution[ind:] + solution[:ind]

    # export line
    profile_points = []
    line = 'L {} 1\n'.format(len(solution))
    for i in solution:
        line += '{} {}\n'.format(points[i][0], points[i][1])
        profile_points.append(points[i])
    line += '1 1'
    gscript.write_command('v.in.ascii',
                          input='-',
                          stdin=line,
                          output='line',
                          format='standard',
                          flags='n',
                          env=env)

    env2 = get_environment(raster=before)
    # slope along line
    gscript.run_command('v.to.rast',
                        input='line',
                        type='line',
                        output='line_dir',
                        use='dir',
                        env=env2)
    gscript.run_command('r.slope.aspect',
                        elevation=before,
                        slope='saved_slope',
                        aspect='saved_aspect',
                        env=env2)
    gscript.mapcalc(
        "slope_dir = abs(atan(tan({slope}) * cos({aspect} - {line_dir})))".
        format(slope='saved_slope', aspect='saved_aspect',
               line_dir='line_dir'),
        env=env2)
    # set new color table
    colors = [
        '0 green', '7 green', '7 yellow', '15 yellow', '15 red', '90 red'
    ]
    gscript.write_command('r.colors',
                          map='slope_dir',
                          rules='-',
                          stdin='\n'.join(colors),
                          env=env2)
    # increase thickness
    gscript.run_command('r.grow',
                        input='slope_dir',
                        radius=2.1,
                        output=resulting,
                        env=env2)

    # update profile
    event = updateProfile(points=profile_points)
    eventHandler.postEvent(receiver=eventHandler.activities_panel, event=event)
    # copy results
    postfix = datetime.now().strftime('%H_%M_%S')
    prefix = 'trails2'
    gscript.run_command(
        'g.copy',
        raster=['slope_dir', '{}_slope_dir_{}'.format(prefix, postfix)],
        vector=['line', '{}_line_{}'.format(prefix, postfix)],
        env=env)
def run_road(real_elev, scanned_elev, eventHandler, env, **kwargs):
    env2 = get_environment(raster=real_elev)
    before = 'scan_saved'
    analyses.change_detection(before=before,
                              after=scanned_elev,
                              change='change',
                              height_threshold=[12, 80],
                              cells_threshold=[3, 70],
                              add=True,
                              max_detected=1,
                              debug=True,
                              env=env)
    point = gscript.read_command('v.out.ascii',
                                 input='change',
                                 type='point',
                                 format='point',
                                 env=env).strip()

    conn = 'transfer_connection'
    drain = 'transfer_drain'
    resulting = "transfer_slopedir"
    if point:
        x, y, cat = point.split('|')
        gscript.run_command('r.drain',
                            input='transfer_cost',
                            direction='transfer_costdir',
                            output=conn,
                            start_points='change',
                            drain=conn,
                            flags='d',
                            env=env2)

        gscript.run_command('v.to.rast',
                            input=conn,
                            type='line',
                            output=conn + '_dir',
                            use='dir',
                            env=env2)
        gscript.mapcalc(
            "slope_dir = abs(atan(tan({slope}) * cos({aspect} - {line_dir})))".
            format(slope='transfer_slope',
                   aspect='transfer_aspect',
                   line_dir=conn + '_dir'),
            env=env2)
        # set new color table
        colors = [
            '0 green', '5 green', '5 yellow', '12 yellow', '12 red', '90 red'
        ]
        gscript.write_command('r.colors',
                              map='slope_dir',
                              rules='-',
                              stdin='\n'.join(colors),
                              env=env2)
        # increase thickness

        gscript.run_command('r.grow',
                            input='slope_dir',
                            radius=1.8,
                            output=resulting,
                            env=env2)

        # drain
        gscript.run_command('r.drain',
                            input=real_elev,
                            output=drain,
                            start_points='change',
                            drain=drain,
                            env=env2)

        gscript.run_command('r.viewshed',
                            input=real_elev,
                            output='transfer_viewshed',
                            observer_elevation=67,
                            coordinates=[x, y],
                            flags='b',
                            env=env2)
        gscript.write_command('r.colors',
                              map='transfer_viewshed',
                              rules='-',
                              stdin='0 black',
                              env=env2)

        env3 = get_environment(raster='transfer_road')
        gscript.mapcalc(
            'visible_road = if(transfer_viewshed == 1 && ! isnull(transfer_road), 1, null())',
            env=env3)
        #road_full = float(gscript.parse_command('r.univar', map='transfer_road', flags='g', env=env3)['n'])
        road_full = 500  # number of road cells
        try:
            road_v = float(
                gscript.parse_command('r.univar',
                                      map='visible_road',
                                      flags='g',
                                      env=env3)['n'])
        except KeyError:
            road_v = 0
        event = updateDisplay(value=int(100 * road_v / road_full))

        with VectorTopo(conn, mode='r') as v:
            try:
                line = v.read(1)
                event2 = updateProfile(
                    points=[(line[0].x, line[0].y), (line[-1].x, line[-1].y)])
            except IndexError:
                event2 = updateProfile(points=[])
    else:
        gscript.run_command('v.edit', map=conn, tool='create', env=env)
        gscript.run_command('v.edit', map=drain, tool='create', env=env)
        gscript.mapcalc('{} = null()'.format(resulting), env=env)
        gscript.mapcalc('{} = null()'.format('transfer_viewshed'), env=env)
        event = updateDisplay(value=None)
        event2 = updateProfile(points=[])

    # update viewshed score
    eventHandler.postEvent(receiver=eventHandler.activities_panel, event=event)
    eventHandler.postEvent(receiver=eventHandler.activities_panel,
                           event=event2)

    # copy results
    if point:
        postfix = datetime.now().strftime('%H_%M_%S')
        prefix = 'transfer1'
        gscript.run_command(
            'g.copy',
            vector=['change', '{}_change_{}'.format(prefix, postfix)],
            raster=[
                'visible_road', '{}_visible_road_{}'.format(prefix, postfix)
            ],
            env=env)
        gscript.run_command(
            'g.copy',
            raster=['slope_dir', '{}_slope_dir_{}'.format(prefix, postfix)],
            env=env)
示例#13
0
def run_trails(real_elev, scanned_elev, blender_path, eventHandler, env, **kwargs):
    env2 = get_environment(raster=scanned_elev, n='n-100', s='s+100', e='e-100', w='w+100')
    resulting = 'trail'
    trail = 'trail'
    before = 'scan_saved'
    topo_saved = 'topo_saved'
    #env_crop = get_environment(raster=real_elev, n='n-100', s='s+100', e='e-100', w='w+100')
    analyses.change_detection(before=before, after=scanned_elev,
                              change='change', height_threshold=[15, 100], cells_threshold=[5, 100], add=True, max_detected=13, debug=True, env=env2)
    points = {}
    # start and end
    data = gscript.read_command('v.out.ascii', input='trail_points', type='point', format='point', env=env).strip()
    c1, c2 = data.splitlines()
    c1 = c1.split('|')
    c2 = c2.split('|')
    points[0] = (float(c1[0]), float(c1[1]))
    points[1] = (float(c2[0]), float(c2[1]))

    gscript.run_command('v.edit', tool='create', map=trail, env=env)
    # detected points
    points_raw = gscript.read_command('v.out.ascii', input='change',
                                      type='point', format='point').strip().split()
    i = 2
    for point in points_raw:
        point = point.split('|')
        point = (float(point[0]), float(point[1]))
        points[i] = point
        i += 1
    length = len(points)
    if length == 2:
        gscript.mapcalc("{} = null()".format(resulting), env=env)
        event = updateProfile(points=[])
        eventHandler.postEvent(receiver=eventHandler.activities_panel, event=event)
        return

    # distance matrix
    D = []
    for i in range(length):
        D.append([0] * length)
    for p1 in range(0, length - 1):
        for p2 in range(p1 + 1, length):
            d = dist(points, p1, p2)
            D[p1][p2] = d
            D[p2][p1] = d
    # 0 distance for start and end to make sure it's always connected
    D[0][1] = 0
    D[1][0] = 0

    # solve
    solution = solve_tsp_numpy(D, optim_steps=10)
    # rearange solutions to start in start point
    ind1 = solution.index(0)
    ind2 = solution.index(1)
    if ind2 > ind1:
        solution = solution[::-1]
    ind = solution.index(0)
    solution = solution[ind :] + solution[:ind ]
    profile_points = []
    for i in solution:
        profile_points.append(points[i])
    #return
    # friction
    friction = 'friction'
    #gscript.mapcalc('{} = if(isnull(water), 0, null())'.format(friction), env=env)
    gscript.mapcalc('{} = 0'.format(friction), env=env)
    tmp_dir = 'tmp_dir'
    tmp_cost = 'tmp_cost'
    tmp_drain = 'tmp_drain'
    
    gscript.run_command('v.edit', tool='create', map=trail, env=env)
    for i in range(len(solution) - 1):
        gscript.run_command('r.walk', elevation=topo_saved, friction=friction, output=tmp_cost, outdir=tmp_dir,
                            start_coordinates=points[solution[i]], stop_coordinates=points[solution[i+1]], flags='k',
                            env=env)
        gscript.run_command('r.drain', input=tmp_cost, direction=tmp_dir, output=tmp_drain,
                            drain=tmp_drain, start_coordinates=points[solution[i+1]], flags='d', env=env)
        gscript.run_command('v.patch', input=tmp_drain, output=trail, flags='a', env=env)


    env2 = get_environment(raster=topo_saved)
    # slope along line
    gscript.run_command('v.to.rast', input=trail, type='line', output='trail_dir', use='dir', env=env2)
    gscript.run_command('r.slope.aspect', elevation=topo_saved, slope='saved_slope', aspect='saved_aspect', env=env2)
    gscript.mapcalc("slope_dir = abs(atan(tan({slope}) * cos({aspect} - {trail_dir})))".format(slope='saved_slope', aspect='saved_aspect',
                    trail_dir='trail_dir'), env=env2)
    # set new color table
    colors = ['0 green', '5 green', '5 yellow', '15 yellow', '15 red', '90 red']
    gscript.write_command('r.colors', map='slope_dir', rules='-', stdin='\n'.join(colors), env=env2)
    # increase thickness
    gscript.run_command('r.grow', input='slope_dir', radius=1.1, output=resulting, env=env2)
    

    # update profile
    event = updateProfile(points=profile_points)
    eventHandler.postEvent(receiver=eventHandler.activities_panel, event=event)
    
    gscript.mapcalc('toponds = if ( isnull(ponds), {t}, ponds + {t})'.format(t=topo_saved), env=env)
    gscript.run_command('v.generalize', input=trail, type='line', output=trail + 'gen', method='snakes', threshold=100, env=env)
    gscript.run_command('g.rename', vector=[trail + 'gen', trail], env=env)
    gscript.run_command('v.drape', input=trail, output=trail + '3d', elevation='toponds', env=env)
    blender_export_vector(vector=trail + '3d', name=trail, z=True, vtype='line', path=blender_path, time_suffix=False, env=env)