Ticket #344: r.w2.diff

File r.w2.diff, 31.7 KB (added by hamish, 16 years ago)

cleaned-up diff of r.watershed2 and 1 in today's devbr6 SVN

  • ./Makefile

    diff -u -u r.watershed/./Makefile r.watershed2/./Makefile
    old new  
    11MODULE_TOPDIR = ../..
    22
    33SUBDIRS = \
     4        front \
    45        ram \
    5         seg \
    6         front
     6        seg
    77# inter unused:
    88#       shed
    99
  • front/description.html

    Only in r.watershed2/.: README
    diff -u -u r.watershed/front/description.html r.watershed2/front/description.html
    old new  
    419419</em>
    420420
    421421
    422 <h2>AUTHOR</h2>
     422<h2>AUTHORS</h2>
    423423
     424Original version:
    424425Charles Ehlschlaeger, U.S. Army Construction Engineering Research Laboratory
     426<br>
     427Speedups: Markus Metz <markus.metz.giswork at gmail.com>
     428
    425429<p>
    426 <i>Last changed: $Date: 2008-05-17 07:11:45 +1200 (Sat, 17 May 2008) $</i>
     430<i>Last changed: $Date: 2008-09-28 01:36:15 +0200 (Sun, 28 Sep 2008) $</i>
  • front/main.c

    diff -u -u r.watershed/front/main.c r.watershed2/front/main.c
    old new  
    3939    struct Option *opt13;
    4040    struct Option *opt14;
    4141    struct Option *opt15;
     42    struct Option *opt16;
    4243    struct Flag *flag_flow;
    4344    struct Flag *flag_seg;
    4445    struct GModule *module;
     
    176177    opt15->gisprompt = "new,cell,raster";
    177178    opt15->guisection = _("Output_options");
    178179
     180    opt16 = G_define_option() ;
     181    opt16->key         = "memory";
     182    opt16->type        = TYPE_INTEGER;
     183    opt16->required    = NO;
     184    opt16->answer      = "300"; /* 300MB default value, please keep in sync with r.terraflow */
     185    opt16->description = _("Maximum memory to be used with -m flag (in MB)");
     186
    179187    flag_flow = G_define_flag();
    180188    flag_flow->key = '4';
    181189    flag_flow->description =
     
    335343        strcat(command, "\"");
    336344    }
    337345
     346    if (flag_seg->answer && opt16->answer) {
     347        strcat(command, " mb=");
     348        strcat(command, "\"");
     349        strcat(command, opt16->answer);
     350        strcat(command, "\"");
     351    }
     352
    338353    G_debug(1, "Mode: %s", flag_seg->answer ? "Segmented" : "All in RAM");
    339354    G_debug(1, "Running: %s", command);
    340355
  • ram/Gwater.h

    diff -u -u r.watershed/ram/Gwater.h r.watershed2/ram/Gwater.h
    old new  
    5454
    5555GLOBAL struct Cell_head window;
    5656
     57GLOBAL int *heap_index, heap_size;
    5758GLOBAL int first_astar, first_cum, nxt_avail_pt, total_cells, do_points;
    5859GLOBAL SHORT nrows, ncols;
    5960GLOBAL double half_res, diag, max_length, dep_slope;
     
    104105/* do_astar.c */
    105106int do_astar(void);
    106107int add_pt(SHORT, SHORT, SHORT, SHORT, CELL, CELL);
     108int drop_pt(void);
    107109double get_slope(SHORT, SHORT, SHORT, SHORT, CELL, CELL);
    108110int replace(SHORT, SHORT, SHORT, SHORT);
    109111
  • ram/do_astar.c

    diff -u -u r.watershed/ram/do_astar.c r.watershed2/ram/do_astar.c
    old new  
    11#include "Gwater.h"
     2#include "do_astar.h"
    23#include <grass/gis.h>
    34#include <grass/glocale.h>
    45
     6int sift_up(int, CELL);
    57
    68int do_astar(void)
    79{
     
    1012    SHORT upr, upc, r, c, ct_dir;
    1113    CELL alt_val, alt_up, asp_up, wat_val;
    1214    CELL in_val, drain_val;
     15    int index_doer, index_up;
     16
    1317
    1418    G_message(_("SECTION 2: A * Search."));
    1519
    1620    count = 0;
     21    first_astar = heap_index[1];
     22
     23    /* A * Search: search uphill, get downhill path */
    1724    while (first_astar != -1) {
    1825        G_percent(count++, do_points, 1);
    19         doer = first_astar;
     26
     27        /* start with point with lowest elevation, in case of equal elevation
     28         * of following points, oldest point = point added earliest */
     29        /* old routine: astar_pts[first_astar] (doer = first_astar) */
     30        /* new routine: astar_pts[heap_index[1]] */
     31
     32        doer = heap_index[1];
     33
    2034        point = &(astar_pts[doer]);
    21         first_astar = point->nxt;
     35
     36        /* drop astar_pts[doer] from heap */
     37        /* necessary to protect the current point (doer) from modification */
     38        /* equivalent to first_astar = point->next in old code */
     39        drop_pt();
     40
     41        /* can go, dragged on from old code */
     42        first_astar = heap_index[1];
     43
     44        /* downhill path for flow accumulation is set here */
     45        /* this path determines the order for flow accumulation calculation */
    2246        point->nxt = first_cum;
     47        first_cum = doer;
     48
     49        r = point->r;
     50        c = point->c;
    2351
    24         r = astar_pts[doer].r = point->r;
    25         c = astar_pts[doer].c = point->c;
    2652        G_debug(3, "R:%2d C:%2d, ", r, c);
    2753
    28         astar_pts[doer].downr = point->downr;
    29         astar_pts[doer].downc = point->downc;
    30         astar_pts[doer].nxt = point->nxt;
    31         first_cum = doer;
     54        index_doer = SEG_INDEX(alt_seg, r, c);
     55        alt_val = alt[index_doer];
     56        wat_val = wat[index_doer];
     57
    3258        FLAG_SET(worked, r, c);
    33         alt_val = alt[SEG_INDEX(alt_seg, r, c)];
     59
     60        /* check all neighbours */
    3461        for (ct_dir = 0; ct_dir < sides; ct_dir++) {
     62            /* get r, c (upr, upc) for this neighbour */
    3563            upr = r + nextdr[ct_dir];
    3664            upc = c + nextdc[ct_dir];
     65            index_up = SEG_INDEX(alt_seg, upr, upc);
     66            /* check that r, c are within region */
    3767            if (upr >= 0 && upr < nrows && upc >= 0 && upc < ncols) {
     68                /* check if neighbour is in the list */
     69                /* if not, add as new point */
    3870                in_val = FLAG_GET(in_list, upr, upc);
    3971                if (in_val == 0) {
    40                     alt_up = alt[SEG_INDEX(alt_seg, upr, upc)];
     72                    alt_up = alt[index_up];
     73                    /* flow direction is set here */
    4174                    add_pt(upr, upc, r, c, alt_up, alt_val);
    4275                    drain_val = drain[upr - r + 1][upc - c + 1];
    43                     asp[SEG_INDEX(asp_seg, upr, upc)] = drain_val;
     76                    asp[index_up] = drain_val;
     77
    4478                }
    4579                else {
     80                    /* check if neighbour has not been worked on,
     81                     * update values for asp and wat */
    4682                    in_val = FLAG_GET(worked, upr, upc);
    4783                    if (in_val == 0) {
    48                         asp_up = asp[SEG_INDEX(asp_seg, upr, upc)];
     84                        asp_up = asp[index_up];
    4985                        if (asp_up < -1) {
    50                             asp[SEG_INDEX(asp_seg, upr, upc)] =
    51                                 drain[upr - r + 1][upc - c + 1];
    52                             wat_val = wat[SEG_INDEX(wat_seg, r, c)];
     86                            asp[index_up] = drain[upr - r + 1][upc - c + 1];
     87
    5388                            if (wat_val > 0)
    54                                 wat[SEG_INDEX(wat_seg, r, c)] = -wat_val;
    55                             alt_up = alt[SEG_INDEX(alt_seg, upr, upc)];
     89                                wat[index_doer] = -wat_val;
     90
    5691                            replace(upr, upc, r, c);    /* alt_up used to be */
    5792                        }
    5893                    }
     
    6095            }
    6196        }
    6297    }
    63     G_percent(count, do_points, 3);     /* finish it */
     98    G_percent(count, do_points, 1);     /* finish it */
    6499    flag_destroy(worked);
    65100    flag_destroy(in_list);
     101    G_free(heap_index);
    66102
    67103    return 0;
    68104}
    69105
     106/* new add point routine for min heap */
    70107int add_pt(SHORT r, SHORT c, SHORT downr, SHORT downc, CELL ele, CELL downe)
    71108{
    72     int p;
    73     CELL check_ele;
    74     POINT point;
    75109
    76110    FLAG_SET(in_list, r, c);
    77     if (first_astar == -1) {
    78         astar_pts[nxt_avail_pt].r = r;
    79         astar_pts[nxt_avail_pt].c = c;
    80         astar_pts[nxt_avail_pt].downr = downr;
    81         astar_pts[nxt_avail_pt].downc = downc;
    82         astar_pts[nxt_avail_pt].nxt = -1;
    83         first_astar = nxt_avail_pt;
    84         nxt_avail_pt++;
     111
     112    /* add point to next free position */
     113
     114    heap_size++;
     115
     116    if (heap_size > do_points)
     117        G_fatal_error(_("heapsize too large"));
     118
     119    heap_index[heap_size] = nxt_avail_pt;
     120
     121    astar_pts[nxt_avail_pt].r = r;
     122    astar_pts[nxt_avail_pt].c = c;
     123    astar_pts[nxt_avail_pt].downr = downr;
     124    astar_pts[nxt_avail_pt].downc = downc;
     125
     126    nxt_avail_pt++;
     127
     128    /* sift up: move new point towards top of heap */
     129
     130    sift_up(heap_size, ele);
     131
     132    return 0;
     133}
     134
     135/* new drop point routine for min heap */
     136int drop_pt(void)
     137{
     138    int child, childr, parent;
     139    CELL ele, eler;
     140    int i;
     141
     142    if (heap_size == 1) {
     143        heap_index[1] = -1;
     144        heap_size = 0;
    85145        return 0;
    86146    }
    87     p = first_astar;;
    88     while (1) {
    89         point.r = astar_pts[p].r;
    90         point.c = astar_pts[p].c;
    91         check_ele = alt[SEG_INDEX(alt_seg, point.r, point.c)];
    92         if (check_ele > ele) {
    93             point.downr = astar_pts[p].downr;
    94             point.downc = astar_pts[p].downc;
    95             point.nxt = astar_pts[p].nxt;
    96             astar_pts[p].r = r;
    97             astar_pts[p].c = c;
    98             astar_pts[p].downr = downr;
    99             astar_pts[p].downc = downc;
    100             astar_pts[p].nxt = nxt_avail_pt;
    101             astar_pts[nxt_avail_pt].r = point.r;
    102             astar_pts[nxt_avail_pt].c = point.c;
    103             astar_pts[nxt_avail_pt].downr = point.downr;
    104             astar_pts[nxt_avail_pt].downc = point.downc;
    105             astar_pts[nxt_avail_pt].nxt = point.nxt;
    106             nxt_avail_pt++;
    107             return 0;
     147
     148    /* start with root */
     149    parent = 1;
     150
     151    /* sift down: move hole back towards bottom of heap */
     152    /* sift-down routine customised for A * Search logic */
     153
     154    while ((child = GET_CHILD(parent)) <= heap_size) {
     155        /* select child with lower ele, if equal, older child
     156         * older child is older startpoint for flow path, important
     157         * chances are good that the left child will be the older child,
     158         * but just to make sure we test */
     159        ele =
     160            alt[SEG_INDEX
     161                (alt_seg, astar_pts[heap_index[child]].r,
     162                 astar_pts[heap_index[child]].c)];
     163        if (child < heap_size) {
     164            childr = child + 1;
     165            i = 1;
     166            while (childr <= heap_size && i < 3) {
     167                eler =
     168                    alt[SEG_INDEX
     169                        (alt_seg, astar_pts[heap_index[childr]].r,
     170                         astar_pts[heap_index[childr]].c)];
     171                if (eler < ele) {
     172                    child = childr;
     173                    ele = eler;
     174                    /* make sure we get the oldest child */
     175                }
     176                else if (ele == eler &&
     177                         heap_index[child] > heap_index[childr]) {
     178                    child = childr;
     179                }
     180                childr++;
     181                i++;
     182            }
    108183        }
    109         point.nxt = astar_pts[p].nxt;
    110         if (point.nxt == -1) {
    111             astar_pts[p].nxt = nxt_avail_pt;
    112             astar_pts[nxt_avail_pt].r = r;
    113             astar_pts[nxt_avail_pt].c = c;
    114             astar_pts[nxt_avail_pt].downr = downr;
    115             astar_pts[nxt_avail_pt].downc = downc;
    116             astar_pts[nxt_avail_pt].nxt = -1;
    117             nxt_avail_pt++;
    118184
    119             return 0;
     185        /* move hole down */
     186
     187        heap_index[parent] = heap_index[child];
     188        parent = child;
     189
     190    }
     191
     192    /* hole is in lowest layer, move to heap end */
     193    if (parent < heap_size) {
     194        heap_index[parent] = heap_index[heap_size];
     195
     196        ele =
     197            alt[SEG_INDEX
     198                (alt_seg, astar_pts[heap_index[parent]].r,
     199                 astar_pts[heap_index[parent]].c)];
     200        /* sift up last swapped point, only necessary if hole moved to heap end */
     201        sift_up(parent, ele);
     202
     203    }
     204
     205    /* the actual drop */
     206    heap_size--;
     207
     208    return 0;
     209}
     210
     211/* standard sift-up routine for d-ary min heap */
     212int sift_up(int start, CELL ele)
     213{
     214    int parent, parentp, child, childp;
     215    CELL elep;
     216
     217    child = start;
     218    childp = heap_index[child];
     219
     220    while (child > 1) {
     221        parent = GET_PARENT(child);
     222        parentp = heap_index[parent];
     223
     224        elep =
     225            alt[SEG_INDEX
     226                (alt_seg, astar_pts[parentp].r, astar_pts[parentp].c)];
     227        /* parent ele higher */
     228        if (elep > ele) {
     229
     230            /* push parent point down */
     231            heap_index[child] = parentp;
     232            child = parent;
     233
    120234        }
    121         p = astar_pts[p].nxt;
     235        /* same ele, but parent is younger */
     236        else if (elep == ele && parentp > childp) {
     237
     238            /* push parent point down */
     239            heap_index[child] = parentp;
     240            child = parent;
     241
     242        }
     243        else
     244            /* no more sifting up, found new slot for child */
     245            break;
     246    }
     247
     248    /* set heap_index for child */
     249    if (child < start) {
     250        heap_index[child] = childp;
    122251    }
    123252
    124253    return 0;
     254
    125255}
    126256
    127257double
     
    135265        slope = (ele - downe) / window.ns_res;
    136266    else
    137267        slope = (ele - downe) / diag;
     268
    138269    if (slope < MIN_SLOPE)
    139270        return (MIN_SLOPE);
     271
    140272    return (slope);
    141273}
    142274
     275
     276/* new replace */
    143277int replace(                    /* ele was in there */
    144278               SHORT upr, SHORT upc, SHORT r, SHORT c)
    145279/* CELL ele;  */
    146280{
    147     int now;
     281    int now, heap_run;
     282
     283    /* find the current neighbour point and
     284     * set flow direction to focus point */
     285
     286    heap_run = 0;
    148287
    149     now = first_astar;
    150     while (now != -1) {
     288    while (heap_run <= heap_size) {
     289        now = heap_index[heap_run];
    151290        if (astar_pts[now].r == upr && astar_pts[now].c == upc) {
    152291            astar_pts[now].downr = r;
    153292            astar_pts[now].downc = c;
    154293            return 0;
    155294        }
    156         now = astar_pts[now].nxt;
     295        heap_run++;
    157296    }
    158297    return 0;
    159298}
  • ram/find_pour.c

    Only in r.watershed2/ram: do_astar.h
    diff -u -u r.watershed/ram/find_pour.c r.watershed2/ram/find_pour.c
    old new  
    88
    99    basin_num = 0;
    1010    for (row = 0; row < nrows; row++) {
     11        G_percent(row, nrows, 3);
    1112        northing = window.north - (row + .5) * window.ns_res;
    1213        for (col = 0; col < ncols; col++) {
    1314            value = FLAG_GET(swale, row, col);
     
    3334            }
    3435        }
    3536    }
     37    G_percent(nrows, nrows, 1); /* finish it */
    3638
    3739    return 0;
    3840}
  • ram/flag_create.c

    diff -u -u r.watershed/ram/flag_create.c r.watershed2/ram/flag_create.c
    old new  
    1515        (unsigned char **)G_malloc(nrows * sizeof(unsigned char *));
    1616
    1717    temp =
    18         (unsigned char *)G_calloc(nrows * new_flag->leng,
     18        (unsigned char *)G_malloc(nrows * new_flag->leng *
    1919                                  sizeof(unsigned char));
    2020
    2121    for (i = 0; i < nrows; i++) {
  • ram/init_vars.c

    diff -u -u r.watershed/ram/init_vars.c r.watershed2/ram/init_vars.c
    old new  
    170170                wat[SEG_INDEX(wat_seg, r, c)] = 1;
    171171        }
    172172    }
    173     asp = (CELL *) G_calloc(size_array(&asp_seg, nrows, ncols), sizeof(CELL));
     173    asp = (CELL *) G_malloc(size_array(&asp_seg, nrows, ncols) * sizeof(CELL));
    174174
    175175    if (pit_flag) {
    176176        pit_mapset = do_exist(pit_name);
     
    247247                               sizeof(double));
    248248    }
    249249
     250    /* heap_index will track astar_pts in the binary min-heap */
     251    /* heap_index is one-based */
     252    heap_index = (int *)G_malloc((do_points + 1) * sizeof(int));
     253
    250254    G_message(_("SECTION 1b (of %1d): Determining Offmap Flow."), tot_parts);
    251255
     256    /* heap is empty */
     257    heap_size = 0;
     258
    252259    first_astar = first_cum = -1;
    253260    if (MASK_flag) {
    254261        for (r = 0; r < nrows; r++) {
  • ram/main.c

    diff -u -u r.watershed/ram/main.c r.watershed2/ram/main.c
    old new  
    55 * AUTHOR(S):    Charles Ehlschlaeger, CERL (original contributor)
    66 *               Markus Neteler <neteler itc.it>, Roberto Flor <flor itc.it>,
    77 *               Brad Douglas <rez touchofmadness.com>, Hamish Bowman <hamish_nospam yahoo.com>
     8 *               Markus Metz <markus.metz.giswork gmail.com>
    89 * PURPOSE:      Watershed determination
    910 * COPYRIGHT:    (C) 1999-2006 by the GRASS Development Team
    1011 *
  • seg/Gwater.h

    diff -u -u r.watershed/seg/Gwater.h r.watershed2/seg/Gwater.h
    old new  
    1818#define MIN_GRADIENT_DEGREES    1
    1919#define DEG_TO_RAD              ((2 * M_PI) / 360.)
    2020#define METER_TO_FOOT           (1 / 0.3048)
    21 #define MAX_BYTES               2000000
    22 #define PAGE_BLOCK              512
    23 #define SROW                    9
    24 #define SCOL                    13
     21#define MAX_BYTES               10485760
     22#define PAGE_BLOCK              1024
     23#define SROW                    200
     24#define SCOL                    200
    2525#define RITE                    1
    2626#define LEFT                    2
    2727#define NEITHER                 0
     
    4949#define NEXTDCVAR
    5050#endif
    5151
     52#define HEAP    struct heap_item
     53HEAP {
     54   int point;
     55   CELL ele;
     56};
     57
    5258GLOBAL struct Cell_head window;
    5359
     60GLOBAL SSEG heap_index;
     61GLOBAL int heap_size;
    5462GLOBAL int first_astar, first_cum, nxt_avail_pt, total_cells, do_points;
    5563GLOBAL SHORT nrows, ncols;
    5664GLOBAL double half_res, diag, max_length, dep_slope;
     
    97105/* do_astar.c */
    98106int do_astar(void);
    99107int add_pt(SHORT, SHORT, SHORT, SHORT, CELL, CELL);
     108int drop_pt(void);
    100109double get_slope(SHORT, SHORT, SHORT, SHORT, CELL, CELL);
    101110int replace(SHORT, SHORT, SHORT, SHORT);
    102111
  • seg/do_astar.c

    diff -u -u r.watershed/seg/do_astar.c r.watershed2/seg/do_astar.c
    old new  
    11#include <stdlib.h>
    22#include <unistd.h>
    3 #include "Gwater.h"
    43#include <grass/gis.h>
    54#include <grass/glocale.h>
     5#include "Gwater.h"
     6#include "do_astar.h"
    67
     8int sift_up(int, CELL);
    79
    810int do_astar(void)
    911{
    1012    POINT point;
    1113    int doer, count;
    12     double get_slope();
    1314    SHORT upr, upc, r, c, ct_dir;
    1415    CELL work_val, alt_val, alt_up, asp_up, wat_val;
    1516    CELL in_val, drain_val;
    16     double slope;
     17    HEAP heap_pos;
     18
     19    /* double slope; */
    1720
    1821    G_message(_("SECTION 2: A * Search."));
    1922
    2023    count = 0;
     24    seg_get(&heap_index, (char *)&heap_pos, 0, 1);
     25    first_astar = heap_pos.point;
     26
     27    /* A * Search: downhill path through all not masked cells */
    2128    while (first_astar != -1) {
    2229        G_percent(count++, do_points, 1);
    23         doer = first_astar;
     30
     31        seg_get(&heap_index, (char *)&heap_pos, 0, 1);
     32        doer = heap_pos.point;
     33
    2434        seg_get(&astar_pts, (char *)&point, 0, doer);
    25         first_astar = point.nxt;
     35
     36        /* drop astar_pts[doer] from heap */
     37        drop_pt();
     38
     39        seg_get(&heap_index, (char *)&heap_pos, 0, 1);
     40        first_astar = heap_pos.point;
     41
    2642        point.nxt = first_cum;
    2743        seg_put(&astar_pts, (char *)&point, 0, doer);
     44
    2845        first_cum = doer;
    2946        r = point.r;
    3047        c = point.c;
     48
    3149        bseg_put(&worked, &one, r, c);
    3250        cseg_get(&alt, &alt_val, r, c);
     51
     52        /* check all neighbours, breadth first search */
    3353        for (ct_dir = 0; ct_dir < sides; ct_dir++) {
     54            /* get r, c (upr, upc) for this neighbour */
    3455            upr = r + nextdr[ct_dir];
    3556            upc = c + nextdc[ct_dir];
     57            /* check that upr, upc are within region */
    3658            if (upr >= 0 && upr < nrows && upc >= 0 && upc < ncols) {
     59                /* check if neighbour is in the list */
     60                /* if not, add as new point */
    3761                bseg_get(&in_list, &in_val, upr, upc);
    3862                if (in_val == 0) {
    3963                    cseg_get(&alt, &alt_up, upr, upc);
    4064                    add_pt(upr, upc, r, c, alt_up, alt_val);
     65                    /* flow direction is set here */
    4166                    drain_val = drain[upr - r + 1][upc - c + 1];
    4267                    cseg_put(&asp, &drain_val, upr, upc);
    4368                }
    4469                else {
     70                    /* check if neighbour has not been worked on,
     71                     * update values for asp, wat and slp */
    4572                    bseg_get(&worked, &work_val, upr, upc);
    4673                    if (!work_val) {
    4774                        cseg_get(&asp, &asp_up, upr, upc);
     
    5481                            cseg_put(&wat, &wat_val, r, c);
    5582                            cseg_get(&alt, &alt_up, upr, upc);
    5683                            replace(upr, upc, r, c);    /* alt_up used to be */
    57                             slope =
    58                                 get_slope(upr, upc, r, c, alt_up, alt_val);
    59                             dseg_put(&slp, &slope, upr, upc);
     84                            /* slope = get_slope (upr, upc, r, c, alt_up, alt_val);
     85                               dseg_put (&slp, &slope, upr, upc); */
    6086                        }
    6187                    }
    6288                }
     
    6591    }
    6692    bseg_close(&worked);
    6793    bseg_close(&in_list);
     94    seg_close(&heap_index);
    6895
    6996    G_percent(count, do_points, 1);     /* finish it */
    7097    return 0;
    7198}
    7299
     100/* new add point routine for min heap */
    73101int add_pt(SHORT r, SHORT c, SHORT downr, SHORT downc, CELL ele, CELL downe)
    74102{
    75     int p;
    76     CELL check_ele;
    77     POINT point, new_point;
    78     double slp_value, get_slope();
     103    POINT point;
     104    HEAP heap_pos;
    79105
    80     if (nxt_avail_pt == do_points)
    81         G_fatal_error(_("problem w/ astar algorithm"));
     106    /* double slp_value; */
    82107
    83     slp_value = get_slope(r, c, downr, downc, ele, downe);
    84     dseg_put(&slp, &slp_value, r, c);
     108    /* slp_value = get_slope(r, c, downr, downc, ele, downe);
     109       dseg_put (&slp, &slp_value, r, c); */
    85110    bseg_put(&in_list, &one, r, c);
    86     new_point.r = r;
    87     new_point.c = c;
    88     new_point.downr = downr;
    89     new_point.downc = downc;
    90     if (first_astar == -1) {
    91         new_point.nxt = -1;
    92         seg_put(&astar_pts, (char *)&new_point, 0, nxt_avail_pt);
    93         first_astar = nxt_avail_pt;
    94         nxt_avail_pt++;
     111
     112    /* add point to next free position */
     113
     114    heap_size++;
     115
     116    if (heap_size > do_points)
     117        G_fatal_error(_("heapsize too large"));
     118
     119    heap_pos.point = nxt_avail_pt;
     120    heap_pos.ele = ele;
     121    seg_put(&heap_index, (char *)&heap_pos, 0, heap_size);
     122
     123    point.r = r;
     124    point.c = c;
     125    point.downr = downr;
     126    point.downc = downc;
     127
     128    seg_put(&astar_pts, (char *)&point, 0, nxt_avail_pt);
     129
     130    nxt_avail_pt++;
     131
     132    /* sift up: move new point towards top of heap */
     133
     134    sift_up(heap_size, ele);
     135
     136    return 0;
     137}
     138
     139/* drop point routine for min heap */
     140int drop_pt(void)
     141{
     142    int child, childr, parent;
     143    int childp, childrp, parentp;
     144    CELL ele, eler;
     145    int i;
     146    POINT point;
     147    HEAP heap_pos;
     148
     149    if (heap_size == 1) {
     150        parent = -1;
     151        heap_pos.point = -1;
     152        heap_pos.ele = 0;
     153        seg_put(&heap_index, (char *)&heap_pos, 0, 1);
     154        heap_size = 0;
    95155        return 0;
    96156    }
    97     p = first_astar;;
    98     while (1) {
    99         seg_get(&astar_pts, (char *)&point, 0, p);
    100         cseg_get(&alt, &check_ele, point.r, point.c);
    101         if (check_ele > ele) {
    102             new_point.nxt = nxt_avail_pt;
    103             seg_put(&astar_pts, (char *)&new_point, 0, p);
    104             seg_put(&astar_pts, (char *)&point, 0, nxt_avail_pt);
    105             nxt_avail_pt++;
    106             return 0;
     157
     158    /* start with heap root */
     159    parent = 1;
     160
     161    /* sift down: move hole back towards bottom of heap */
     162    /* sift-down routine customised for A * Search logic */
     163
     164    while ((child = GET_CHILD(parent)) <= heap_size) {
     165        /* select child with lower ele, if both are equal, older child
     166         * older child is older startpoint for flow path, important */
     167        seg_get(&heap_index, (char *)&heap_pos, 0, child);
     168        childp = heap_pos.point;
     169        ele = heap_pos.ele;
     170        if (child < heap_size) {
     171            childr = child + 1;
     172            i = 1;
     173            while (childr <= heap_size && i < 3) {
     174                seg_get(&heap_index, (char *)&heap_pos, 0, childr);
     175                childrp = heap_pos.point;
     176                eler = heap_pos.ele;
     177                if (eler < ele) {
     178                    child = childr;
     179                    childp = childrp;
     180                    ele = eler;
     181                }
     182                /* make sure we get the oldest child */
     183                else if (ele == eler && childp > childrp) {
     184                    child = childr;
     185                    childp = childrp;
     186                }
     187                childr++;
     188                i++;
     189            }
    107190        }
    108         if (point.nxt == -1) {
    109             point.nxt = nxt_avail_pt;
    110             seg_put(&astar_pts, (char *)&point, 0, p);
    111             new_point.nxt = -1;
    112             seg_put(&astar_pts, (char *)&new_point, 0, nxt_avail_pt);
    113             nxt_avail_pt++;
    114191
    115             return 0;
     192        /* move hole down */
     193        heap_pos.point = childp;
     194        heap_pos.ele = ele;
     195        seg_put(&heap_index, (char *)&heap_pos, 0, parent);
     196        parent = child;
     197
     198    }
     199
     200    /* hole is in lowest layer, move to heap end */
     201    if (parent < heap_size) {
     202        seg_get(&heap_index, (char *)&heap_pos, 0, heap_size);
     203        seg_put(&heap_index, (char *)&heap_pos, 0, parent);
     204
     205        ele = heap_pos.ele;
     206
     207        /* sift up last swapped point, only necessary if hole moved to heap end */
     208        sift_up(parent, ele);
     209
     210    }
     211
     212    /* the actual drop */
     213    heap_size--;
     214
     215    return 0;
     216
     217}
     218
     219/* standard sift-up routine for d-ary min heap */
     220int sift_up(int start, CELL ele)
     221{
     222    int parent, parentp, child, childp;
     223    POINT point;
     224    CELL elep;
     225    HEAP heap_pos;
     226
     227    child = start;
     228    seg_get(&heap_index, (char *)&heap_pos, 0, child);
     229    childp = heap_pos.point;
     230
     231    while (child > 1) {
     232        parent = GET_PARENT(child);
     233        seg_get(&heap_index, (char *)&heap_pos, 0, parent);
     234        parentp = heap_pos.point;
     235        elep = heap_pos.ele;
     236
     237        /* parent ele higher */
     238        if (elep > ele) {
     239
     240            /* push parent point down */
     241            seg_put(&heap_index, (char *)&heap_pos, 0, child);
     242            child = parent;
     243
    116244        }
    117         p = point.nxt;
     245        /* same ele, but parent is younger */
     246        else if (elep == ele && parentp > childp) {
     247
     248            /* push parent point down */
     249            seg_put(&heap_index, (char *)&heap_pos, 0, child);
     250            child = parent;
     251
     252        }
     253        else
     254            /* no more sifting up, found new slot for child */
     255            break;
    118256    }
    119257
     258    /* no more sifting up, found new slot for child */
     259    if (child < start) {
     260        heap_pos.point = childp;
     261        heap_pos.ele = ele;
     262        seg_put(&heap_index, (char *)&heap_pos, 0, child);
     263    }
    120264    return 0;
    121265}
    122266
     
    140284               SHORT upr, SHORT upc, SHORT r, SHORT c)
    141285/* CELL ele;  */
    142286{
    143     int now;
     287    int now, heap_run;
    144288    POINT point;
     289    HEAP heap_pos;
     290
     291    heap_run = 0;
    145292
    146     now = first_astar;
    147     while (now != -1) {
     293    while (heap_run <= heap_size) {
     294        seg_get(&heap_index, (char *)&heap_pos, 0, heap_run);
     295        now = heap_pos.point;
    148296        seg_get(&astar_pts, (char *)&point, 0, now);
    149297        if (point.r == upr && point.c == upc) {
    150298            point.downr = r;
     
    152300            seg_put(&astar_pts, (char *)&point, 0, now);
    153301            return 0;
    154302        }
    155         now = point.nxt;
     303        heap_run++;;
    156304    }
    157305    return 0;
    158306}
  • seg/find_pour.c

    Only in r.watershed2/seg: do_astar.h
    diff -u -u r.watershed/seg/find_pour.c r.watershed2/seg/find_pour.c
    old new  
    88
    99    basin_num = 0;
    1010    for (row = 0; row < nrows; row++) {
     11        G_percent(row, nrows, 3);
    1112        northing = window.north - (row + .5) * window.ns_res;
    1213        for (col = 0; col < ncols; col++) {
    1314            /* cseg_get (&wat, &value, row, col);
     
    3940            }
    4041        }
    4142    }
     43    G_percent(nrows, nrows, 1); /* finish it */
    4244
    4345    return 0;
    4446}
  • seg/init_vars.c

    diff -u -u r.watershed/seg/init_vars.c r.watershed2/seg/init_vars.c
    old new  
    88int init_vars(int argc, char *argv[])
    99{
    1010    SHORT r, c;
    11     int fd, num_cseg_total, num_cseg, num_cseg_bytes;
     11    int fd, num_cseg_total, num_open_segs;
     12    int seg_rows, seg_cols;
     13    double segs_mb;
     14    char *mb_opt;
     15
     16    /* int page_block, num_cseg; */
     17    int max_bytes;
    1218    CELL *buf, alt_value, wat_value, asp_value, worked_value;
    1319    extern FILE *fopen();
    1420    char MASK_flag, *do_exist();
     
    2228    max_length = dzero = 0.0;
    2329    ril_value = -1.0;
    2430    /* dep_slope = 0.0; */
    25     num_cseg_bytes = MAX_BYTES - 4 * PAGE_BLOCK;
     31    max_bytes = 0;
    2632    sides = 8;
    2733    for (r = 1; r < argc; r++) {
    2834        if (sscanf(argv[r], "el=%[^\n]", ele_name) == 1)
     
    5561            ls_flag++;
    5662        else if (sscanf(argv[r], "ob=%[^\n]", ob_name) == 1)
    5763            ob_flag++;
     64        else if (sscanf(argv[r], "mb=%[^\n]", mb_opt) == 1) {
     65            if (sscanf(mb_opt, "%lf", &segs_mb) == 0) {
     66                segs_mb = 300;
     67            }
     68        }
    5869        else if (sscanf(argv[r], "r=%[^\n]", ril_name) == 1) {
    5970            if (sscanf(ril_name, "%lf", &ril_value) == 0) {
    6071                ril_value = -1.0;
     
    127138                window.ns_res * window.ns_res);
    128139    if (sides == 4)
    129140        diag *= 0.5;
    130     if (ls_flag)
    131         num_cseg_bytes -= PAGE_BLOCK;
    132     if (sg_flag)
    133         num_cseg_bytes -= PAGE_BLOCK;
    134     if (ril_flag)
    135         num_cseg_bytes -= PAGE_BLOCK;
    136     /* if (dep_flag == -1) num_cseg_bytes -= PAGE_BLOCK; */
    137     if (sl_flag)
    138         num_cseg_bytes -= sizeof(double) * SROW * SCOL * 4;
    139     num_cseg = sizeof(CELL) * 3 + sizeof(double);
    140     num_cseg_bytes /= num_cseg * 4 * SROW * SCOL;
     141
     142    /* segment parameters: one size fits all. Fine tune? */
     143    /* Segment rows and cols: 200 */
     144    /* 1 segment open for all rasters: 2.86 MB */
     145    /* num_open_segs = segs_mb / 2.86 */
     146
     147    seg_rows = SROW;
     148    seg_cols = SCOL;
     149
     150    if (segs_mb < 3.0) {
     151        segs_mb = 300;
     152        G_warning(_("Maximum memory to be used was smaller than 3 MB, set to default = 300 MB."));
     153    }
     154
     155    num_open_segs = segs_mb / 2.86;
     156
     157    G_debug(1, "segs MB: %.0f", segs_mb);
     158    G_debug(1, "seg cols: %d", seg_cols);
     159    G_debug(1, "seg rows: %d", seg_rows);
     160
    141161    num_cseg_total = nrows / SROW + 1;
    142     G_debug(1, "    segments in row:\t%d", num_cseg_total);
     162    G_debug(1, "   row segments:\t%d", num_cseg_total);
    143163
    144164    num_cseg_total = ncols / SCOL + 1;
    145     G_debug(1, "segments in columns:\t%d", num_cseg_total);
     165    G_debug(1, "column segments:\t%d", num_cseg_total);
    146166
    147     num_cseg_total = (ncols / SCOL + 1) * (nrows / SROW + 1);
    148     G_debug(1, "     total segments:\t%d", num_cseg_total);
    149     G_debug(1, "      open segments:\t%d", num_cseg_bytes);
     167    num_cseg_total = (ncols / seg_cols + 1) * (nrows / seg_rows + 1);
     168    G_debug(1, " total segments:\t%d", num_cseg_total);
     169    G_debug(1, "  open segments:\t%d", num_open_segs);
     170
     171    /* nonsense to have more segments open than exist */
     172    if (num_open_segs > nrows)
     173        num_open_segs = nrows;
     174    G_debug(1, "  open segments after adjusting:\t%d", num_open_segs);
    150175
    151     cseg_open(&alt, SROW, SCOL, num_cseg_bytes);
    152     cseg_open(&r_h, SROW, SCOL, 4);
     176    cseg_open(&alt, seg_rows, seg_cols, num_open_segs);
     177    cseg_open(&r_h, seg_rows, seg_cols, num_open_segs);
    153178    cseg_read_cell(&alt, ele_name, ele_mapset);
    154179    cseg_read_cell(&r_h, ele_name, ele_mapset);
    155     cseg_open(&wat, SROW, SCOL, num_cseg_bytes);
     180    cseg_open(&wat, seg_rows, seg_cols, num_open_segs);
    156181
    157182    if (run_flag) {
    158183        run_mapset = do_exist(run_name);
     
    165190                    exit(EXIT_FAILURE);
    166191        }
    167192    }
    168     cseg_open(&asp, SROW, SCOL, num_cseg_bytes);
     193    cseg_open(&asp, seg_rows, seg_cols, num_open_segs);
    169194    if (pit_flag) {
    170195        pit_mapset = do_exist(pit_name);
    171196        cseg_read_cell(&asp, pit_name, pit_mapset);
     
    177202                    exit(EXIT_FAILURE);
    178203        }
    179204    }
    180     bseg_open(&swale, SROW, SCOL, num_cseg_bytes);
     205    bseg_open(&swale, seg_rows, seg_cols, num_open_segs);
    181206    if (ob_flag) {
    182207        ob_mapset = do_exist(ob_name);
    183208        bseg_read_cell(&swale, ob_name, ob_mapset);
     
    190215    }
    191216    if (ril_flag) {
    192217        ril_mapset = do_exist(ril_name);
    193         dseg_open(&ril, 1, (int)PAGE_BLOCK / sizeof(double), 1);
     218        dseg_open(&ril, 1, seg_rows * seg_cols, num_open_segs);
    194219        dseg_read_cell(&ril, ril_name, ril_mapset);
    195220    }
    196     bseg_open(&in_list, SROW, SCOL, num_cseg_bytes);
    197     bseg_open(&worked, SROW, SCOL, num_cseg_bytes);
     221    bseg_open(&in_list, seg_rows, seg_cols, num_open_segs);
     222    bseg_open(&worked, seg_rows, seg_cols, num_open_segs);
    198223    MASK_flag = 0;
    199224    do_points = nrows * ncols;
    200225    if (NULL != G_find_file("cell", "MASK", G_mapset())) {
     
    218243            G_free(buf);
    219244        }
    220245    }
    221     dseg_open(&slp, SROW, SCOL, num_cseg_bytes);
    222     dseg_open(&s_l, SROW, SCOL, 4);
     246    /* dseg_open(&slp, SROW, SCOL, num_open_segs); */
     247    dseg_open(&s_l, seg_rows, seg_cols, num_open_segs);
    223248    if (sg_flag)
    224         dseg_open(&s_g, 1, (int)PAGE_BLOCK / sizeof(double), 1);
     249        dseg_open(&s_g, 1, seg_rows * seg_cols, num_open_segs);
    225250    if (ls_flag)
    226         dseg_open(&l_s, 1, (int)PAGE_BLOCK / sizeof(double), 1);
    227     seg_open(&astar_pts, 1, do_points, 1, PAGE_BLOCK / sizeof(POINT),
    228              4, sizeof(POINT));
    229     first_astar = first_cum = -1;
     251        dseg_open(&l_s, 1, seg_rows * seg_cols, num_open_segs);
     252    seg_open(&astar_pts, 1, do_points, 1, seg_rows * seg_cols,
     253             num_open_segs, sizeof(POINT));
     254
     255    /* heap_index will track astar_pts in the binary min-heap */
     256    /* heap_index is one-based */
     257    seg_open(&heap_index, 1, do_points + 1, 1, seg_rows * seg_cols,
     258             num_open_segs, sizeof(HEAP));
     259
    230260    G_message(_("SECTION 1b (of %1d): Determining Offmap Flow."), tot_parts);
    231261
     262    /* heap is empty */
     263    heap_size = 0;
     264
     265    first_astar = first_cum = -1;
     266
    232267    if (MASK_flag) {
    233268        for (r = 0; r < nrows; r++) {
    234269            G_percent(r, nrows, 3);
     
    364399                    }
    365400                    else {
    366401                        bseg_put(&in_list, &zero, r, c);
    367                         dseg_put(&slp, &dzero, r, c);
     402                        /* dseg_put(&slp, &dzero, r, c); */
    368403                    }
    369404                }
    370405            }
    371406        }
    372         G_percent(r, nrows, 3); /* finish it */
    373407    }
    374408    else {
    375409        for (r = 0; r < nrows; r++) {
     410            G_percent(r, nrows, 3);
    376411            for (c = 0; c < ncols; c++) {
    377412                bseg_put(&worked, &zero, r, c);
    378413                dseg_put(&s_l, &half_res, r, c);
     
    402437                }
    403438                else {
    404439                    bseg_put(&in_list, &zero, r, c);
    405                     dseg_put(&slp, &dzero, r, c);
     440                    /* dseg_put(&slp, &dzero, r, c); */
    406441                }
    407442            }
    408443        }
    409444    }
     445    G_percent(r, nrows, 3);     /* finish it */
    410446
    411447    return 0;
    412448}
  • seg/main.c

    diff -u -u r.watershed/seg/main.c r.watershed2/seg/main.c
    old new  
    77 *               Roberto Flor <flor itc.it>,
    88 *               Brad Douglas <rez touchofmadness.com>,
    99 *               Hamish Bowman <hamish_nospam yahoo.com>
     10 *               Markus Metz <markus.metz.giswork gmail.com>
    1011 * PURPOSE:      Watershed determination using the GRASS segmentation lib
    1112 * COPYRIGHT:    (C) 1999-2006 by the GRASS Development Team
    1213 *