Beispiel #1
0
static void graph_unit(int t, int b, int l, int r, char *n1, char *n2,
		       char *n3, double *mx, int fmask)
{
    int x0 = 0, y0 = 0, xp, yp, ux[250], uy[250], u_w, u_l, btn = 0, k = 0,
	w_w = 0, w_l = 0, *row_buf, at, ab, al, ar, circle = 0,
	tmpw, tmpl, au_w, au_l, lap = 0, l0 = 0, r0 = 0, t0 = 0, b0 = 0;
    FILE *fp;
    double tmp, radius = 0.0;
    register int i, j;

    /*  VARIABLES:
       COORDINATES IN THIS ROUTINE ARE IN CELLS

       t    =       top row of sampling frame
       b    =       bottom row of sampling frame
       l    =       left col of sampling frame
       r    =       right col of sampling frame
       n1   =
       n2   =
       n3   =
       mx[0]        =       cols of region/width of screen
       mx[1]        =       rows of region/height of screen
       xp   =       mouse x location in screen coordinates (col)
       yp   =       mouse y location in screen coordinates (row)
       ar   =       mouse x location in map coordinates (col)
       al   =       mouse y location in map coordinates (row)

     */


    l0 = l;
    r0 = r;
    t0 = t;
    b0 = b;

    l = (int)((double)(l * mx[0]) + 0.5);
    r = (int)((double)(r * mx[0]) + 0.5);
    t = (int)((double)(t * mx[1]) + 0.5);
    b = (int)((double)(b * mx[1]) + 0.5);
    w_w = r - l;
    w_l = b - t;

    /* draw the sampling frame */

    R_open_driver();
    R_standard_color(D_translate_color("grey"));
    draw_box((int)(l / mx[0]), (int)(t / mx[1]), (int)(r / mx[0]),
	     (int)(b / mx[1]), 1);
    R_close_driver();

    fp = fopen0("r.le.para/units", "w");
    G_sleep_on_error(0);

    /* get the number of scales */

    do {
	fprintf(stderr,
		"\n    How many different SCALES do you want? (1-15)  ");

	numtrap(1, &tmp);
	if (tmp < 1 || tmp > 15)
	    fprintf(stderr,
		    "    Too many (>15) or too few scales, try again.\n");
    }
    while (tmp < 1 || tmp > 15);
    fprintf(fp, "%10d    # of scales\n", (int)(tmp));

    /* for each scale */

    for (i = 0; i < tmp; i++) {
	G_system("clear");

	radius = 0.0;
	circle = 0;

	/* if sampling using circles */

	fprintf(stderr, "\n    SCALE %d\n", i + 1);
	fprintf(stderr, "\n    Do you want to sample using rectangles");

	if (!G_yes("\n       (including squares) (y) or circles (n)?   ", 1)) {
	    circle = 1;
	    fprintf(stderr,
		    "\n    Draw a rectangular area to contain a standard circular");
	    fprintf(stderr,
		    "\n    sampling unit of scale %d.  First select upper left",
		    i + 1);
	    fprintf(stderr, "\n    corner, then lower right:\n");
	    fprintf(stderr, "       Left button:     Check unit size\n");
	    fprintf(stderr,
		    "       Middle button:   Upper left corner of area here\n");
	    fprintf(stderr,
		    "       Right button:    Lower right corner of area here\n");

	}

	else {
	    fprintf(stderr,
		    "\n    Draw a standard rectangular unit of scale %d.",
		    i + 1);
	    fprintf(stderr,
		    "\n    First select upper left corner, then lower right:\n");
	    fprintf(stderr, "       Left button:     Check unit size\n");
	    fprintf(stderr,
		    "       Middle button:   Upper left corner of unit here\n");
	    fprintf(stderr,
		    "       Right button:    Lower right corner of unit here\n");

	}

	R_open_driver();

	do {
	  back1:
	    R_get_location_with_box(x0, y0, &xp, &yp, &btn);

	    /* convert the upper left screen coordinate
	       (x0, y0) and the mouse position (xp, yp)
	       on the screen to the nearest row and
	       column; do the same for the sampling
	       unit width (u_w) and height (u_l);
	       then convert back */

	    ar = (int)((double)(xp) * mx[0] + 0.5);
	    xp = (int)((double)(ar) / mx[0] + 0.5);
	    al = (int)((double)(x0) * mx[0] + 0.5);
	    x0 = (int)((double)(al) / mx[0] + 0.5);
	    au_w = ar - al;
	    u_w = (int)((double)(au_w) / mx[0] + 0.5);
	    ab = (int)((double)(yp) * mx[1] + 0.5);
	    yp = (int)((double)(ab) / mx[1] + 0.5);
	    at = (int)((double)(y0) * mx[1] + 0.5);
	    y0 = (int)((double)(at) / mx[1] + 0.5);
	    au_l = ab - at;
	    u_l = (int)((double)(au_l) / mx[1] + 0.5);


	    /* left button, check the size of the rubber
	       box in array system */

	    if (btn == 1) {
		if (ar > r || ab > b || ar < l || ab < t) {
		    fprintf(stderr,
			    "\n    This point is not in the sampling frame; try again\n");

		    goto back1;
		}
		if (x0 < l || y0 < t) {
		    fprintf(stderr,
			    "\n    Use the middle button to first put the upper left");
		    fprintf(stderr,
			    "\n    corner inside the sampling frame\n");

		    goto back1;
		}
		if (ar <= al || ab <= at) {
		    fprintf(stderr,
			    "\n    Please put the lower right corner down and to");
		    fprintf(stderr,
			    "\n    the right of the upper left corner\n");

		    goto back1;
		}
		else {
		    fprintf(stderr,
			    "\n    Unit would be %d columns wide by %d rows long\n",
			    abs(au_w), abs(au_l));
		    fprintf(stderr,
			    "    Width/length would be %5.2f and size %d pixels\n",
			    (double)abs((au_w)) / (double)abs((au_l)),
			    abs(au_w) * abs(au_l));

		}
	    }

	    /* mid button, move the start point of the
	       rubber box */

	    else if (btn == 2) {
		if (ar > r || ab > b || ar < l || ab < t) {
		    fprintf(stderr,
			    "\n    Point is not in the sampling frame; try again\n");

		    goto back1;
		}
		else {
		    R_move_abs(xp, yp);
		    x0 = xp;
		    y0 = yp;
		}
	    }

	    /* right button, outline the unit */

	    else if (btn == 3) {

		if (circle) {
		    if (u_w > u_l) {
			al = al + ((ar - al) - (ab - at)) / 2;
			ar = al + (ab - at);
			x0 = (int)((double)(al) / mx[0] + 0.5);
			xp = (int)((double)(ar) / mx[0] + 0.5);
			au_w = ar - al;
			u_w = u_l = (int)((double)(au_w) / mx[0] + 0.5);
		    }
		    if (u_l > u_w) {
			at = at + ((ab - at) - (ar - al)) / 2;
			ab = at + (ar - al);
			y0 = (int)((double)(at) / mx[1] + 0.5);
			yp = (int)((double)(ab) / mx[1] + 0.5);
			au_l = ab - at;
			u_w = u_l = (int)((double)(au_l) / mx[1] + 0.5);
		    }
		}

		if (ar > r || ab > b || al < l || at < t) {
		    fprintf(stderr,
			    "\n    The unit extends outside the sampling frame or map;");
		    fprintf(stderr, "\n       try again\n");

		    goto back1;
		}

		if (au_w > w_w || au_l > w_l) {
		    fprintf(stderr,
			    "\n    The unit is too big for the sampling frame; ");
		    fprintf(stderr, "try again\n");

		    goto back1;
		}

		/* if there is a mask, check to see that
		   the unit will be within the mask area,
		   by checking to see whether the four
		   corners of the unit are in the mask */

		if (fmask > 0) {
		    row_buf = Rast_allocate_c_buf();
		    Rast_get_c_row_nomask(fmask, row_buf, at);
		    if (!(*(row_buf + al) && *(row_buf + ar - 1))) {
			fprintf(stderr,
				"\n    The unit would be outside the mask; ");
			fprintf(stderr, "try again\n");

			G_free(row_buf);
			goto back1;
		    }
		    Rast_zero_c_buf(row_buf);
		    Rast_get_c_row_nomask(fmask, row_buf, ab - 1);
		    if (!(*(row_buf + al) && *(row_buf + ar - 1))) {
			fprintf(stderr,
				"\n    The unit would be outside the mask; ");
			fprintf(stderr, "try again\n");

			G_free(row_buf);
			goto back1;
		    }
		    G_free(row_buf);
		}

		if (xp - x0 > 0 && yp - y0 > 0) {
		    R_standard_color(D_translate_color("red"));
		    if (circle)
			draw_circle(x0, y0, xp, yp, 3);
		    else
			draw_box(x0, y0, xp, yp, 1);
		    G_system("clear");
		    if (circle) {
			fprintf(stderr,
				"\n\n    The standard circular sampling unit has:\n");
			fprintf(stderr, "       radius = %f pixels\n",
				(double)(ar - al) / 2.0);

		    }
		    else {
			fprintf(stderr,
				"\n\n    The standard sampling unit has:\n");
			fprintf(stderr, "       columns=%d    rows=%d\n",
				abs(ar - al), abs(ab - at));
			fprintf(stderr, "       width/length ratio=%5.2f\n",
				(double)abs(ar - al) / (double)abs(ab - at));
			fprintf(stderr, "       size=%d pixels\n",
				abs(ar - al) * abs(ab - at));

		    }
		    k = 0;
		    ux[0] = al;
		    uy[0] = at;
		}
		else if (xp - x0 == 0 || yp - y0 == 0) {
		    fprintf(stderr,
			    "\n    Unit has 0 rows and/or 0 columns; try again\n");

		    goto back1;
		}
		else {
		    fprintf(stderr,
			    "\n    You did not put the lower right corner below");
		    fprintf(stderr,
			    "\n       and to the right of the upper left corner. Please try again");

		    goto back1;
		}
	    }
	}
	while (btn != 3);
	R_close_driver();

	/* use the size and shape of the
	   standard unit to outline more units
	   in that scale */

	fprintf(stderr, "\n    Outline more sampling units of scale %d?\n",
		i + 1);
	fprintf(stderr, "       Left button:     Exit\n");
	fprintf(stderr, "       Middle button:   Check unit position\n");
	fprintf(stderr,
		"       Right button:    Lower right corner of next unit here\n");

	R_open_driver();

	/* if not the left button (to exit) */

      back2:
	while (btn != 1) {
	    R_get_location_with_box(xp - u_w, yp - u_l, &xp, &yp, &btn);

	    /* convert the left (x0), right (y0),
	       top (y0), bottom (yp) coordinates in
	       screen pixels to the nearest row and
	       column; do the same for the sampling
	       unit width (u_w) and height (u_l);
	       then convert back */

	    ar = (int)((double)(xp) * mx[0] + 0.5);
	    ab = (int)((double)(yp) * mx[1] + 0.5);
	    xp = (int)((double)(ar) / mx[0] + 0.5);
	    yp = (int)((double)(ab) / mx[1] + 0.5);
	    al = (int)((double)(xp - u_w) * mx[0] + 0.5);
	    at = (int)((double)(yp - u_l) * mx[0] + 0.5);
	    x0 = (int)((double)(al) / mx[0] + 0.5);
	    y0 = (int)((double)(at) / mx[1] + 0.5);


	    /* if right button, outline the unit */

	    if (btn == 3) {

		if (ar > r || ab > b || al < l || at < t) {
		    fprintf(stderr,
			    "\n    The unit would be outside the map; try again");
		    goto back2;

		}

		/* if there is a mask, check to see that
		   the unit will be within the mask area */

		if (fmask > 0) {
		    row_buf = Rast_allocate_c_buf();
		    Rast_get_c_row_nomask(fmask, row_buf, at);
		    if (!(*(row_buf + al) && *(row_buf + ar - 1))) {
			fprintf(stderr,
				"\n    The unit would be outside the mask; ");
			fprintf(stderr, "try again");

			G_free(row_buf);
			goto back2;
		    }
		    Rast_zero_c_buf(row_buf);
		    Rast_get_c_row_nomask(fmask, row_buf, ab - 1);
		    if (!(*(row_buf + al) && *(row_buf + ar - 1))) {
			fprintf(stderr,
				"\n    The unit would be outside the mask; ");
			fprintf(stderr, "try again");
			G_free(row_buf);
			goto back2;
		    }
		    G_free(row_buf);
		}

		/* check for sampling unit overlap */

		lap = 0;
		for (j = 0; j < k + 1; j++) {
		    if (overlap(al, at, ux[j], uy[j], au_w, au_l)) {
			fprintf(stderr,
				"\n    The unit would overlap a previously drawn ");
			fprintf(stderr, "unit; try again");

			lap = 1;
		    }
		}
		if (lap)
		    goto back2;

		k++;
		fprintf(stderr, "\n    %d sampling units have been placed",
			(k + 1));

		ux[k] = al;
		uy[k] = at;
		R_standard_color(D_translate_color("red"));
		if (circle)
		    draw_circle(x0, y0, xp, yp, 3);
		else
		    draw_box(x0, y0, xp, yp, 1);
	    }
	}
	R_close_driver();

	/* save the sampling units in the
	   r.le.para/units file */

	if (circle)
	    radius = (double)(ar - al) / 2.0;
	else
	    radius = 0.0;
	fprintf(fp, "%10d    # of units of scale %d\n", k + 1, i + 1);
	fprintf(fp, "%10d%10d   u_w, u_l of units in scale %d\n",
		(int)(u_w * mx[0]), (int)(u_l * mx[1]), i + 1);
	fprintf(fp, "%10.1f             radius of circles in scale %d\n",
		radius, (i + 1));
	for (j = 0; j < k + 1; j++)
	    fprintf(fp, "%10d%10d   left, top of unit[%d]\n", ux[j], uy[j],
		    j + 1);

	if (i < tmp - 1 && G_yes("\n    Refresh the screen?   ", 1)) {
	    paint_map(n1, n2, n3);
	    R_open_driver();
	    R_standard_color(D_translate_color("red"));
	    R_close_driver();
	}
    }

    fclose(fp);
    return;
}
Beispiel #2
0
/* DEFINE SAMPLING UNITS MANUALLY */
static void man_unit(int t, int b, int l, int r, char *n1, char *n2, char *n3,
		     double *mx, int fmask)
{
    int i, j, dx, dy, w_w, w_l, u_w, u_l,
	method, l0, t0, randflag = 0, unit_num, num = 0, scales,
	h_d = 1, v_d = 1, itmp, thick, sites, *row_buf, fr, k,
	count = 0, maxsize = 0, nx = 0, ny = 0, numx = 0, numy = 0,
	al = 0, ar = 0, at = 0, ab = 0, au_w = 0, au_l = 0;
    double *ux, *uy;
    FILE *fp;
    double dtmp, ratio, size, intv = 0.0, start[2], cnt = 0, radius = 0.0;
    char *sites_mapset;
    struct Cell_head wind;

    /*  VARIABLES:
       COORDINATES IN THIS ROUTINE ARE IN CELLS

       t    =       top row of sampling frame
       b    =       bottom row of sampling frame
       l    =       left col of sampling frame
       r    =       right col of sampling frame
       n1   =
       n2   =
       n3   =
       start[0]=    row of UL corner of starting pt for strata
       start[1]=    col of UL corner of starting pt for strata
       mx[0]        =       cols of region/width of screen
       mx[1]        =       rows of region/height of screen

     */


    start[0] = 0.0;
    start[1] = 0.0;

    l = (int)((double)(l * mx[0]) + 0.5);
    r = (int)((double)(r * mx[0]) + 0.5);
    t = (int)((double)(t * mx[1]) + 0.5);
    b = (int)((double)(b * mx[1]) + 0.5);
    w_w = r - l;
    w_l = b - t;

    /* draw the sampling frame */

    R_open_driver();
    R_standard_color(D_translate_color("grey"));
    draw_box((int)(l / mx[0] + 0.5), (int)(t / mx[1] + 0.5),
	     (int)(r / mx[0] + 0.5), (int)(b / mx[1] + 0.5), 1);
    R_close_driver();

    /* open the units file for output */

    fp = fopen0("r.le.para/units", "w");
    G_sleep_on_error(0);

    /* get the number of scales */

    do {
	fprintf(stderr,
		"\n    How many different SCALES do you want (1-15)?   ");

	numtrap(1, &dtmp);
	if (dtmp > 15 || dtmp < 1) {
	    fprintf(stderr,
		    "\n    Too many (>15) or too few scales; try again");

	}
    }
    while (dtmp < 1 || dtmp > 15);

    fprintf(fp, "%10d    # of scales\n", (scales = (int)dtmp));


    /* for each scale */

    for (i = 0; i < scales; i++) {
	for (;;) {
	    G_system("clear");

	    radius = 0.0;

	    fprintf(stderr, "\n\n    TYPE IN PARAMETERS FOR SCALE %d:\n",
		    i + 1);


	    /* get the distribution method */

	    fprintf(stderr,
		    "\n    Choose method of sampling unit DISTRIBUTION  \n");
	    fprintf(stderr, "       Random nonoverlapping       1\n");
	    fprintf(stderr, "       Systematic contiguous       2\n");
	    fprintf(stderr, "       Systematic noncontiguous    3\n");
	    fprintf(stderr, "       Stratified random           4\n");
	    fprintf(stderr, "       Centered over sites         5\n");
	    fprintf(stderr, "       Exit to setup option menu   6\n\n");

	    do {
		fprintf(stderr, "                       Which Number?   ");

		numtrap(1, &dtmp);
		if ((method = fabs(dtmp)) > 6 || method < 1) {
		    fprintf(stderr,
			    "\n    Choice must between 1-5; try again");

		}
	    }
	    while (method > 6 || method < 1);

	    if (method == 6)
		return;

	    /* for stratified random distribution,
	       determine the number of strata */

	    if (method == 4) {
	      getstrata:
		fprintf(stderr,
			"\n    Number of strata along the x-axis? (1-60)  ");

		numtrap(1, &dtmp);
		h_d = fabs(dtmp);

		fprintf(stderr,
			"\n    Number of strata along the y-axis? (1-60)  ");

		numtrap(1, &dtmp);
		v_d = fabs(dtmp);

		if (h_d < 1 || v_d < 1 || h_d > 60 || v_d > 60) {
		    fprintf(stderr,
			    "\n    Number must be between 1-60; try again.");

		    goto getstrata;
		}
	    }

	    /* for methods with strata */

	    if (method == 2 || method == 3 || method == 4) {
	      strata:
		fprintf(stderr,
			"\n    Sampling frame row & col for upper left corner of");
		fprintf(stderr,
			" the strata?\n       Rows are numbered down and columns");
		fprintf(stderr,
			" are numbered to the right\n       Enter 1 1 to start in");
		fprintf(stderr, " upper left corner of sampling frame:  ");

		numtrap(2, start);
		start[0] = start[0] - 1.0;
		start[1] = start[1] - 1.0;
		if (start[0] > w_l || start[0] < 0 ||
		    start[1] > w_w || start[1] < 0) {
		    fprintf(stderr,
			    "\n    The starting row and col you entered are outside");
		    fprintf(stderr,
			    " the sampling frame\n       Try again\n");

		    goto strata;
		}
	    }


	    if (method == 4) {

		/* call draw_grid with the left, top, width,
		   length, the number of horizontal and
		   vertical strata, and the starting row
		   and col for the strata */

		draw_grid((int)(l / mx[0] + 0.5), (int)(t / mx[1] + 0.5),
			  (int)(w_w / mx[0] + 0.5), (int)(w_l / mx[1] + 0.5),
			  h_d, v_d, (int)(start[0] / mx[1] + 0.5),
			  (int)(start[1] / mx[0] + 0.5), mx[0], mx[1]);
		if (!G_yes("    Are these strata OK?   ", 1)) {
		    if (G_yes("\n\n    Refresh the screen?   ", 1)) {
			paint_map(n1, n2, n3);
			R_open_driver();
			R_standard_color(D_translate_color("grey"));
			draw_box((int)(l / mx[0] + 0.5),
				 (int)(t / mx[1] + 0.5),
				 (int)(r / mx[0] + 0.5),
				 (int)(b / mx[1] + 0.5), 1);
			R_close_driver();
		    }
		    goto getstrata;
		}
	    }

	    /* if sampling using circles */

	    fprintf(stderr, "\n    Do you want to sample using rectangles");

	    if (!G_yes
		("\n       (including squares) (y) or circles (n)?   ", 1)) {
	      getradius:
		fprintf(stderr,
			"\n    What radius do you want for the circles?  Radius");
		fprintf(stderr,
			"\n       is in pixels; add 0.5 pixels, for the center");
		fprintf(stderr,
			"\n       pixel, to the number of pixels outside the");
		fprintf(stderr,
			"\n       center pixel.  Type a real number with one");
		fprintf(stderr,
			"\n       decimal place ending in .5 (e.g., 4.5):        ");

		numtrap(1, &radius);
		if (radius > 100.0) {
		    fprintf(stderr,
			    "\n    Are you sure that you want such a large");

		    if (!G_yes("\n       radius (> 100 pixels)?   ", 1))
			goto getradius;
		}

		ratio = 1.0;
		u_w = (int)(2 * radius);
		u_l = (int)(2 * radius);

		if (fmask > 0) {
		    count = 0;
		    row_buf = Rast_allocate_buf(CELL_TYPE);
		    fr = Rast_open_old(n1, G_mapset());
		    for (j = t; j < b; j++) {
			Rast_zero_buf(row_buf, CELL_TYPE);
			Rast_get_row(fr, row_buf, j, CELL_TYPE);
			for (k = l; k < r; k++) {
			    if (*(row_buf + k))
				count++;
			}
		    }
		    G_free(row_buf);
		    Rast_close(fr);
		    cnt = (double)(count);
		    if (cnt)
			cnt = sqrt(cnt);
		    else
			cnt = 0;
		}
		else {
		    count = (w_l - (int)(start[0])) * (w_w - (int)(start[1]));
		}
	    }

	    /* if sampling using rectangles/squares */

	    else {

		/* get the width/length ratio */

	      getratio:
		fprintf(stderr,
			"\n    Sampling unit SHAPE (aspect ratio, #cols/#rows) "
			"expressed as real number"
			"\n    (e.g., 10 cols/5 rows = 2.0) for sampling units "
			"of scale %d? ", i + 1);

		numtrap(1, &ratio);
		if (ratio < 0)
		    ratio = -ratio;
		else if (ratio > 25.0)
		    if (!G_yes
			("\n    Are you sure you want such a large ratio?   ",
			 1))
			goto getratio;

		/* determine the recommended maximum size
		   for sampling units */

	      getsize:
		dtmp = (ratio > 1) ? 1 / ratio : ratio;
		dtmp /= (h_d > v_d) ? h_d * h_d : v_d * v_d;

	      tryagain:
		if (method == 1) {

		    if (fmask > 0) {
			count = 0;
			row_buf = Rast_allocate_buf(CELL_TYPE);
			fr = Rast_open_old(n1, G_mapset());
			for (j = t; j < b; j++) {
			    Rast_zero_buf(row_buf, CELL_TYPE);
			    Rast_get_row(fr, row_buf, j, CELL_TYPE);
			    for (k = l; k < r; k++) {
				if (*(row_buf + k))
				    count++;
			    }
			}
			G_free(row_buf);
			Rast_close(fr);
			cnt = (double)(count);
			if (cnt)
			    cnt = sqrt(cnt);
			else
			    cnt = 0;
			maxsize =
			    ((cnt * dtmp / 2) * (cnt * dtmp / 2) >
			     1.0 / dtmp) ? (cnt * dtmp / 2) * (cnt * dtmp /
							       2) : 1.0 /
			    dtmp;
			fprintf(stderr,
				"\n    Recommended maximum SIZE is %d in %d cell total",
				maxsize, count);
			fprintf(stderr, " area\n");

		    }

		    else {
			fprintf(stderr, "\n    Recommended maximum SIZE is");
			fprintf(stderr, " %d in %d pixel total area\n",
				(int)((w_l - (int)(start[0])) * (w_w -
								 (int)(start
								       [1])) *
				      dtmp / 2),
				(w_l - (int)(start[0])) * (w_w -
							   (int)(start[1])));

			count =
			    (w_l - (int)(start[0])) * (w_w - (int)(start[1]));
			maxsize =
			    (int)((w_l - (int)(start[0])) * (w_w -
							     (int)(start[1]))
				  * dtmp / 2);
		    }
		}

		else if (method == 2 || method == 3 || method == 5) {
		    fprintf(stderr,
			    "\n    Recommended maximum SIZE is %d in %d pixel total",
			    (int)((w_l - (int)(start[0])) * (w_w -
							     (int)(start[1]))
				  * dtmp / 2),
			    (w_l - (int)(start[0])) * (w_w -
						       (int)(start[1])));
		    fprintf(stderr, " area\n");

		}

		else if (method == 4) {
		    fprintf(stderr, "\n    Recommended maximum SIZE is");
		    fprintf(stderr, " %d in %d pixel individual",
			    (int)(w_w * w_l * dtmp / 2),
			    ((w_w - (int)(start[1])) / h_d) * ((w_l -
								(int)(start
								      [0])) /
							       v_d));
		    fprintf(stderr, " stratum area\n");

		}

		/* get the unit size, display the calculated
		   size, and ask if it is OK */

		fprintf(stderr,
			"    What size (in pixels) for each sampling unit of scale %d?  ",
			i + 1);

		numtrap(1, &size);
		thick = 1;
		if (size < 15 || ratio < 0.2 || ratio > 5)
		    thick = 0;
		u_w = sqrt(size * ratio);
		u_l = sqrt(size / ratio);
		fprintf(stderr,
			"\n    The nearest size is %d cells wide X %d cells high = %d",
			u_w, u_l, u_w * u_l);
		fprintf(stderr, " cells\n");

		if (!u_w || !u_l) {
		    fprintf(stderr,
			    "\n    0 cells wide or high is not acceptable; try again");

		    goto tryagain;
		}
		if (!G_yes("    Is this SIZE OK?   ", 1))
		    goto getsize;
	    }

	    /* for syst. noncontig. distribution, get
	       the interval between units */

	    if (method == 3) {
		fprintf(stderr,
			"\n    The interval, in pixels, between the units of scale");
		fprintf(stderr, " %d?  ", i + 1);

		numtrap(1, &intv);
	    }

	    /* if the unit dimension + the interval
	       is too large, print a warning and
	       try getting another size */

	    if (u_w + intv > w_w / h_d || u_l + intv > w_l / v_d) {
		fprintf(stderr,
			"\n    Unit size too large for sampling frame; try again\n");

		if (radius)
		    goto getradius;
		else
		    goto getsize;

	    }

	    /* for stratified random distribution,
	       the number of units is the same as
	       the number of strata */

	    if (method == 4)
		num = h_d * v_d;

	    /* for the other distributions, calculate the
	       maximum number of units, then get the
	       number of units */

	    else if (method == 1 || method == 2 || method == 3) {

		if (method == 1) {
		    if (!
			(unit_num =
			 calc_num(w_w, w_l, ratio, u_w, u_l, method, intv,
				  (int)(start[1]), (int)(start[0]), u_w * u_l,
				  count))) {
			fprintf(stderr,
				"\n    Something wrong with sampling unit size, try again\n");

			if (radius)
			    goto getradius;
			else
			    goto getsize;
		    }
		    fprintf(stderr,
			    "\n    Maximum NUMBER of units in scale %d is %d\n",
			    i + 1, unit_num);
		    fprintf(stderr,
			    "    Usually 1/2 of this number can be successfully");
		    fprintf(stderr,
			    " distributed\n    More than 1/2 can sometimes be");
		    fprintf(stderr, " distributed\n");

		}

		else if (method == 2 || method == 3) {
		    numx = floor((double)(w_w - start[1]) / (u_w + intv));
		    numy = floor((double)(w_l - start[0]) / (u_l + intv));
		    if (((w_w -
			  (int)(start[1])) % (numx * (u_w + (int)(intv)))) >=
			u_w)
			numx++;
		    if (((w_l -
			  (int)(start[0])) % (numy * (u_l + (int)(intv)))) >=
			u_l)
			numy++;
		    unit_num = numx * numy;
		    fprintf(stderr,
			    "\n    Maximum NUMBER of units in scale %d is %d as %d",
			    i + 1, unit_num, numy);
		    fprintf(stderr, " rows with %d units per row", numx);

		}

		do {
		    fprintf(stderr,
			    "\n    What NUMBER of sampling units do you want to try");
		    fprintf(stderr, " to use?  ");

		    numtrap(1, &dtmp);

		    if ((num = dtmp) > unit_num || num < 1) {
			fprintf(stderr,
				"\n    %d is greater than the maximum number of",
				num);
			fprintf(stderr, " sampling units; try again\n");

		    }

		    else if (method == 2 || method == 3) {
			fprintf(stderr,
				"\n    How many sampling units do you want per row?  ");

			numtrap(1, &dtmp);
			if ((nx = dtmp) > num) {
			    fprintf(stderr,
				    "\n    Number in each row > number requested; try");
			    fprintf(stderr, " again\n");

			}
			else {
			    if (nx > numx) {
				fprintf(stderr,
					"\n    Can't fit %d units in each row, try",
					nx);
				fprintf(stderr, " again\n");

			    }
			    else {
				if (num % nx)
				    ny = num / nx + 1;
				else
				    ny = num / nx;
				if (ny > numy) {
				    fprintf(stderr,
					    "\n    Can't fit the needed %d rows, try",
					    ny);
				    fprintf(stderr, " again\n");

				}
			    }
			}
		    }
		}
		while (num > unit_num || num < 1 || nx > num || nx > numx ||
		       ny > numy);
	    }

	    /* dynamically allocate storage for arrays to
	       store the upper left corner of sampling
	       units */

	    if (method != 5) {
		ux = G_calloc(num + 1, sizeof(double));
		uy = G_calloc(num + 1, sizeof(double));
	    }

	    else {
		ux = G_calloc(250, sizeof(double));
		uy = G_calloc(250, sizeof(double));
	    }

	    /* calculate the upper left corner of sampling
	       units and store them in arrays ux and uy */

	    if (!calc_unit_loc
		(radius, t, b, l, r, ratio, u_w, u_l, method, intv, num, h_d,
		 v_d, ux, uy, &sites, (int)(start[1]), (int)(start[0]), fmask,
		 nx, mx[0], mx[1]))
		goto last;

	    signal(SIGINT, SIG_DFL);
	    if (method == 5)
		num = sites;

	    /* draw the sampling units on the
	       screen */

	    if (method == 2 || method == 3 || method == 5) {
		R_open_driver();
		R_standard_color(D_translate_color("red"));
		for (j = 0; j < num; j++) {
		    if (radius) {
			draw_circle((int)((double)(ux[j]) / mx[0]),
				    (int)((double)(uy[j]) / mx[1]),
				    (int)((double)(ux[j] + u_w) / mx[0]),
				    (int)((double)(uy[j] + u_l) / mx[1]), 3);
		    }
		    else {
			draw_box((int)((double)(ux[j]) / mx[0]),
				 (int)((double)(uy[j]) / mx[1]),
				 (int)((double)(ux[j] + u_w) / mx[0]),
				 (int)((double)(uy[j] + u_l) / mx[1]), 1);
		    }
		}
		R_close_driver();
	    }

	    if (G_yes("\n    Is this set of sampling units OK?   ", 1))
		break;
	  last:
	    signal(SIGINT, SIG_DFL);
	    if (G_yes("\n    Refresh the screen?   ", 1)) {
		paint_map(n1, n2, n3);
		R_open_driver();
		R_standard_color(D_translate_color("grey"));
		draw_box((int)(l / mx[0]), (int)(t / mx[1]), (int)(r / mx[0]),
			 (int)(b / mx[1]), 1);
		R_close_driver();
	    }
	}

	/* save the sampling unit parameters
	   in r.le.para/units file */

	fprintf(fp, "%10d    # of units of scale %d.\n", num, (i + 1));
	fprintf(fp, "%10d%10d   u_w, u_l of units in scale %d\n", u_w, u_l,
		(i + 1));
	fprintf(fp, "%10.1f             radius of circles in scale %d\n",
		radius, (i + 1));

	for (j = 0; j < num; j++)
	    fprintf(fp, "%10d%10d   left, top of unit[%d]\n", (int)ux[j],
		    (int)uy[j], j + 1);

	if (i < scales - 1 && G_yes("\n\n    Refresh the screen?   ", 1)) {
	    paint_map(n1, n2, n3);
	    R_open_driver();
	    R_standard_color(D_translate_color("grey"));
	    draw_box((int)(l / mx[0]), (int)(t / mx[1]), (int)(r / mx[0]),
		     (int)(b / mx[1]), 1);
	    R_close_driver();
	}
    }

    /* free dynamically allocated memory */

    G_free(ux);
    G_free(uy);
    fclose(fp);
    return;
}
Beispiel #3
0
int main(int argc, char *argv[])
{

    struct GModule *module;
    struct Option *input, *vect;

    struct Cell_head window;
    int bot, right, t0, b0, l0, r0, clear = 0;
    double Rw_l, Rscr_wl;
    char *map_name = NULL, *v_name = NULL, *s_name = NULL;

    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    /* must run in a term window */
    G_putenv("GRASS_UI_TERM", "1");

    module = G_define_module();
    module->keywords = _("raster, landscape structure analysis, patch index");
    module->description =
	_("Interactive tool used to setup the sampling and analysis framework "
	 "that will be used by the other r.le programs.");

    input = G_define_standard_option(G_OPT_R_MAP);
    input->description = _("Raster map to use to setup sampling");

    vect = G_define_standard_option(G_OPT_V_INPUT);
    vect->key = "vect";
    vect->description = _("Vector map to overlay");
    vect->required = NO;

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    setbuf(stdout, NULL);	/* unbuffered */
    setbuf(stderr, NULL);

    G_sleep_on_error(1);	/* error messages get lost on clear screen */


    map_name = input->answer;
    v_name = vect->answer;
    s_name = NULL;		/* sites not used in GRASS 6 */

    /* setup the r.le.para directory */
    get_pwd();

    /* query for the map to be setup */
    if (R_open_driver() != 0)
	G_fatal_error("No graphics device selected");

    /* setup the current window for display & clear screen */
    D_setup(1);

    Rw_l = (double)G_window_cols() / G_window_rows();
    /*R_open_driver(); */
    /* R_font("romant"); */
    G_get_set_window(&window);
    t0 = R_screen_top();
    b0 = R_screen_bot();
    l0 = R_screen_left();
    r0 = R_screen_rite();
    Rscr_wl = (double)(r0 - l0) / (b0 - t0);

    if (Rscr_wl > Rw_l) {
	bot = b0;
	right = l0 + (b0 - t0) * Rw_l;
    }

    else {
	right = r0;
	bot = t0 + (r0 - l0) / Rw_l;
    }
    D_new_window("a", t0, bot, l0, right);
    D_set_cur_wind("a");
    D_show_window(D_translate_color("green"));
    D_setup(clear);
    R_close_driver();

    /* invoke the setup modules */
    set_map(map_name, v_name, s_name, window, t0, bot, l0, right);

    return (EXIT_SUCCESS);
}
Beispiel #4
0
int
main (int argc, char *argv[])
{
	struct GModule *module;
	struct
	{
		struct Option *input; /* name of input site map */
		struct Option *output; /* name of output site map */
		struct Option *type;
		struct Option *where;
		struct Option *size; /* size of sample (%input) */
		struct Option *map; /* optional raster to check for NULL */
		struct Option *cachesize;
	}
	parm;
	struct
	{
		struct Flag *quiet;
		struct Flag *all; /* disregard region settings */	
	}
	flag;
	int processing_mode = 0;
	int vect_types;

	/* setup some basic GIS stuff */
	G_gisinit (argv[0]);
	module = G_define_module ();
	module->description = "Generates a random sample from a map of vector objects";
	/* do not pause after a warning message was displayed */
	G_sleep_on_error (0);

	
	/* Module Parameters: */
	
	parm.input = G_define_standard_option (G_OPT_V_INPUT);
	parm.input->key = "input";
	parm.input->type = TYPE_STRING;
	parm.input->required = YES;
	parm.input->description = "Vector map to draw sample from";
	
	/* name of output map */
	parm.output = G_define_standard_option (G_OPT_V_OUTPUT);
	parm.output->key = "output";
	parm.output->type = TYPE_STRING;
	parm.output->required = YES;
	parm.output->description = "Vector map to store random sample in";
	
	/* type of objects */
	parm.type = G_define_standard_option (G_OPT_V_TYPE);
	
	/* filter objects by sql statement */
	parm.where = G_define_standard_option (G_OPT_WHERE);

	/* percentage of input objects to include for random sample */
	parm.size = G_define_option ();
	parm.size->key = "size";
	parm.size->type = TYPE_DOUBLE;
	parm.size->required = YES;
	parm.size->description = "Size of the sample (% of input vector objects)";
	parm.size->options = "0-100";

	/* map = an optional raster map. Samples will not be generated */
	/*       in cells where this map fprintf (stderr, "HI\n");is NULL */
	parm.map = G_define_standard_option (G_OPT_R_INPUT);
	parm.map->key = "raster";
	parm.map->type = TYPE_STRING;
	parm.map->required = NO;
	parm.map->description = "Sampling cannot be done on NULL cells in this raster map";
	
	/* number of lines to store in cache */
	parm.cachesize = G_define_option ();
	parm.cachesize->key = "cachesize";
	parm.cachesize->type = TYPE_INTEGER;
	parm.cachesize->answer = "-1";
	parm.cachesize->required = NO;
	parm.cachesize->description = "Number of raster rows to store in cache (-1 for auto)";
	
	flag.all = G_define_flag ();
	flag.all->key = 'a';
	flag.all->description = "Sample outside the current region's limits";

	flag.quiet = G_define_flag ();
	flag.quiet->key = 'q';
	flag.quiet->description = "Quiet operation: no progress display";
	
	/* parse command line */
	if (G_parser (argc, argv))
	{
		exit (-1);
	}

	vect_types = Vect_option_to_types (parm.type);

	/* check if given parameters are valid */
	processing_mode =
		check_parms (parm.map->answer, parm.input->answer, parm.output->answer, flag.all->answer);				
	
	if ( parm.map->answer != NULL ) {
		/* set cachesize */
		cachesize = atoi (parm.cachesize->answer);
		if ( (cachesize<-1) || (cachesize > G_window_rows ()) ) {
			/* if cache size is invalid, just set to auto-mode (-1) */
			G_warning ("Invalid cache size requested (must be between 0 and %i or -1).\n", G_window_rows());
			cachesize = -1;
		}
	}
		
    do_split_sample ( parm.input->answer, parm.output->answer, vect_types, atof (parm.size->answer),
	                  parm.map->answer, flag.all->answer, processing_mode, flag.quiet->answer );
	
	return (EXIT_SUCCESS);
}
Beispiel #5
0
int
main (int argc, char *argv[])
{
	FILE *kb;
	
	struct GModule *module;
	struct
	{
		struct Option *file;
		struct Option *log;
	}
	parm;
	struct
	{
		struct Flag *all;
	}
	flag;

	/* setup some basic GIS stuff */
	G_gisinit (argv[0]);	
	module = G_define_module ();
	module->description = "Displays structured contents of a Dempster-Shafer knowledge base";
	
	/* do not pause after a warning message was displayed */
	G_sleep_on_error (0);

	/* Parameters */
	parm.file = G_define_option ();
	parm.file->key = "file";
	parm.file->type = TYPE_STRING;
	parm.file->required = YES;
	parm.file->description = "Name of the knowledge base file to display";

	parm.log = G_define_option ();
	parm.log->key = "output";
	parm.log->type = TYPE_STRING;
	parm.log->required = NO;
	parm.log->description = "File to write contents to (default: display on screen)";
	
	/* Flags */
	flag.all = G_define_flag ();
	flag.all->key='a';
	flag.all->description = "Show all hypotheses (including type AUTO)";
	
	/* parse command line */
	if (G_parser (argc, argv))
	{
		exit (-1);
	}

	/* check if we have read/write access to knowledge base */
	errno = 0;
	kb = fopen (parm.file->answer, "r");
	if ( kb == NULL ) {
		G_fatal_error ("Cannot open knowledge base file for reading.\nReason: %s.", strerror (errno));
	} else {
		fclose(kb);
	}
	
	open_xml_file ( parm.file->answer );
	
	if ( parm.log->answer != NULL ) {
		errno = 0;
		lp = fopen (parm.log->answer,"w+");
		if ( lp == NULL ) {
			G_fatal_error ("Cannot create output file for writing.\nReason: %s.", strerror (errno));
		}
	} else {	
		/* send output to terminal */
		lp = stdout;
	}
	
	/* now output information */
	print_header ( parm.file->answer );
	print_hypotheses ( flag.all->answer );
	print_const_evidence ();
	print_rast_evidence ();
	print_vect_evidence ();
	print_groups ();

	exit (EXIT_SUCCESS);
}
Beispiel #6
0
int
main (int argc, char *argv[]) {
	struct GModule *module;
	struct Option *map; /* raster map to work on */
	struct Option *sites; /* output map to write */
	struct Option *mode; /* Categorisation mode */
	struct Option *min; /* range of values to categorise ... */
	struct Option *max; /*   .. anything outside will be NULL in output */
	struct Option *logfile; /* log output to this file instead of stdout */
	struct Option *precision; /* decimal digits precision for log file */
	struct Option *cachesize;
	struct Flag *null; /* also count NULL values? */
	struct Flag *all; /* disregard region when reporting total percentages */			
	struct Flag *zeroskip;	/* also show categories with 0 count? */
	struct Flag *uncat; /* also show cells outside category range? */	
	struct Flag *background; /* show background distribution? */
	struct Flag *gain; /* calculate Kvamme's gain for each category? */
	struct Flag *quiet; /* no status display on screen */				
	
	char *mapset;
	int show_progress = 1; /* enable progress display by default */
	/* these vars are used to store information about the input map */
	int cats; /* number of categories in input map */
	long null_count; /* number of NULL cells */
	long nocat_count; /* number of cells that do not fall into the category range [0 .. n] */	
	/* use to create command line for r.categorize call */
	char *sysstr, *tmpfile, *input_map;	
	int error;
	
	sysstr = NULL;
	tmpfile = NULL;
	
	/* setup some basic GIS stuff */
	G_gisinit (argv[0]);
	module = G_define_module ();
	module->description = "Analyses distribution of vector sample over a raster map";
	/* do not pause after a warning message was displayed */
	G_sleep_on_error (0);
		
	/* DEFINE OPTIONS AND FLAGS */
	/* raster map to sample */
	map = G_define_standard_option (G_OPT_R_INPUT);
	map->key = "raster";
	map->type = TYPE_STRING;
	map->required = YES;
	map->description = "Raster map to sample";

	/* site map for sampling positions */
	sites = G_define_standard_option (G_OPT_V_INPUT);
	sites->key = "positions";
	sites->type = TYPE_STRING;
	sites->required = YES;
	sites->description = "Vector map with sampling positions";
		
	/* Categorisation mode */
	mode = G_define_option ();
	mode->key = "mode";
	mode->type = TYPE_STRING;
	mode->required = NO;
	mode->description = "Categorisation mode (see manual)";

	/* min raster value to categorise */
	min = G_define_option ();
	min->key = "min";
	min->type = TYPE_DOUBLE;
	min->required = NO;
	min->description = "Minimum value to include in categorisation";

	/* max raster value to categorise */
	max = G_define_option ();
	max->key = "max";
	max->type = TYPE_DOUBLE;
	max->required = NO;
	max->description = "Maximum value to include in categorisation.";

	/* optional name of logfile */
	logfile = G_define_option ();
	logfile->key = "logfile";
	logfile->type = TYPE_DOUBLE;
	logfile->required = NO;
	logfile->description = "Name of ASCII logfile, if desired.";
	
	/* optional number of decimal digitis to store in logfile/show on screen */
	precision = G_define_option ();
	precision->key = "precision";
	precision->type = TYPE_DOUBLE;
	precision->required = NO;
	precision->answer = "2";
	precision->description = "Number of decimal digits for statistics/logfile";		
	
	/* number of lines to store in cache */
	cachesize = G_define_option ();
	cachesize->key = "cachesize";
	cachesize->type = TYPE_INTEGER;
	cachesize->answer = "-1";
	cachesize->required = NO;
	cachesize->description = "Number of raster rows to store in cache (-1 for auto)";	
		
	null = G_define_flag ();
	null->key = 'n';
	null->description = "Include NULL cells in report.";
	
	uncat = G_define_flag ();
	uncat->key = 'u';
	uncat->description = "Include uncategorised cells in statistics.";
	
	all = G_define_flag ();
	all->key = 'a';
	all->description = "Disregard region setting for counts.";	
	
	zeroskip = G_define_flag ();
	zeroskip->key = 'z';
	zeroskip->description = "Also show categories with zero count/percentage.";

	background = G_define_flag ();
	background->key = 'b';
	background->description = "Show background distribution of categories in raster input map.";

	gain = G_define_flag ();
	gain->key = 'g';
	gain->description = "Calculate Kvamme's Gain Factor for each category.";

	quiet = G_define_flag ();
	quiet->key = 'q';
	quiet->description = "Quiet operation: do not show progress display.";	

	
	/* parse command line */
	if (G_parser (argc, argv))
	{
		exit (-1);
	}

	/* check for 'quiet' flag */
	if ( quiet->answer ) {
		show_progress = 0;
	}
	
	PROGNAME = argv[0];		

	/* copy the 'map' option string to another buffer and use that */
	/* from now on. We do this because we might want to manipulate */
	/* that string and that is dangerous with GRASS Option->answer strings! */
	input_map = G_calloc (255, sizeof (char));
	G_strcpy (input_map, map->answer);
	
	mapset = G_calloc (255, sizeof (char));
	/* check if input map is a fully categorised raster map */
	mapset = G_find_cell (input_map,"");
	if ( mapset == NULL) {
		G_fatal_error ("The input map does not exist in the current database.");
	}

	if ( mode->answer == NULL ) {		
		cats = GT_get_stats (input_map,mapset,&null_count, &nocat_count, show_progress);
		if ( cats < 0 ) {
			G_fatal_error ("Could not stat input map. Do you have read access?");
		}
		if ( ((cats == 0) && (mode->answer==NULL)) ) {
			G_fatal_error ("No categories defined in input map.\nPlease specify a mode to create a fully classified map.");
		}
	}

	/* a classification mode was given: call r.categorize and save output
	   in a tmp file */
	if ( mode->answer != NULL ) {
		srand ((unsigned long) time(NULL));
		tmpfile = G_calloc (255, sizeof(char));
		sysstr = G_calloc (255, sizeof(char));
		/* create tmp file name from current PID and system time */		
		sprintf (tmpfile,"tmp.%i.%i", getpid(),(rand())/10000);
		if ( getenv("GISBASE") == NULL ) {
			G_fatal_error ("GISBASE not set. Unable to call GRASS module 'r.categorise'.");
		}		
		if ( quiet->answer ) {
			sprintf (sysstr,"%s/bin/r.categorize input=%s@%s output=%s mode=%s min=%s max=%s -q", getenv("GISBASE"), map->answer, 
					mapset, tmpfile, mode->answer, min->answer, max->answer);
		} else {
			sprintf (sysstr,"%s/bin/r.categorize input=%s@%s output=%s mode=%s min=%s max=%s", getenv("GISBASE"), map->answer, 
					mapset, tmpfile, mode->answer, min->answer, max->answer);
		}
		/* now create fully classified map using r.categorize and store */
		/* it in a temporary raster map */
		error = system (sysstr);
		if ( error < 0 ) {
			G_fatal_error ("Calling r.categorize has failed. Check your installation.");
		}
				
		/* store name of temporary file as new input map */
		G_strcpy (input_map, tmpfile);
		
		/* check categories of tmpfile */
		cats = GT_get_stats (input_map,mapset,&null_count, &nocat_count, show_progress);
		if (cats < 1) {
			G_fatal_error ("Could not create a fully categorised temporary file.\nTry another categorisation mode.");
		}
	}
	
	/* initialise cache structure */
	if ( input_map != NULL ) {
		/* set cachesize */
		CACHESIZE = atoi (cachesize->answer);
		if ( (CACHESIZE<-1) || (CACHESIZE > G_window_rows ()) ) {
			/* if cache size is invalid, just set to auto-mode (-1) */
			G_warning ("Invalid cache size requested (must be between 0 and %i or -1).\n", G_window_rows());
			CACHESIZE = -1;
		}
	}			
	
	if ( G_raster_map_is_fp (input_map, mapset))  {
		do_report_DCELL (input_map, mapset, sites->answer,
				atoi (precision->answer),null->answer, uncat->answer,
	           	all->answer, quiet->answer, zeroskip->answer,
			   	logfile->answer, background->answer, gain->answer, show_progress);
	} else {
		do_report_CELL (input_map, mapset, sites->answer,
				atoi (precision->answer),null->answer, uncat->answer,
	           	all->answer, quiet->answer, zeroskip->answer,
			   	logfile->answer, background->answer, gain->answer, show_progress);		
	}

		
	/* delete temporary file, if needed */
	if ( mode->answer != NULL ) {
		delete_tmpfile (tmpfile);
		G_free (tmpfile);
	}
	
	if ( sysstr != NULL ) {
		G_free (sysstr);
	}
	G_free (input_map);

	return (EXIT_SUCCESS);
}
Beispiel #7
0
int main( int argc, char *argv[] )
{
	Shypothesis **samples; /* Data to be combined */
	unsigned int i;
	FILE *kb;
	char **groups;
	int norm = 1; /* turn on normalisation of evidence by default */
	/* these are for time keeping in the logfile */	
	time_t systime;
	clock_t proctime;
	unsigned long timeused;
	unsigned int days, hours, mins, secs;
	
	xmlDocPtr dstXMLFile;
	Sfp_struct* file_pointers;	
	
	G_gisinit ( argv[0] );		
	
	module = G_define_module ();
	module->description = "Combines evidences from a DST knowledge base";
		
	parm.file = G_define_option ();
	parm.file->key = "file";
	parm.file->type = TYPE_STRING;
	parm.file->required = YES;
	parm.file->description = "Name of the knowledge base that contains the evidence";
	
	parm.groups = G_define_option ();
	parm.groups->key = "sources";
	parm.groups->type = TYPE_STRING;
	parm.groups->required = NO;
	parm.groups->multiple = YES;
	parm.groups->description = "Evidences to be combined (default: all)";
			
	parm.type = G_define_option ();
	parm.type->key = "type";
	parm.type->type = TYPE_STRING;
	parm.type->required = NO;
	parm.type->options = "const,rast,vect";
	parm.type->answer = "rast";
	parm.type->description = "Type(s) of evidences to combine";	
	
	parm.output = G_define_option ();
	parm.output->key = "output";
	parm.output->type = TYPE_STRING;
	parm.output->required = NO;
	parm.output->answer = G_location ();
	parm.output->description = "Prefix for result maps (dflt: location name)";

	parm.vals = G_define_option ();
	parm.vals->key = "values";
	parm.vals->type = TYPE_STRING;
	parm.vals->required = NO;
	parm.vals->multiple = YES;
	parm.vals->options = "bel,pl,doubt,common,bint,woc,maxbpa,minbpa,maxsrc,minsrc";
	parm.vals->answer = "bel";
	parm.vals->description = "Dempster-Shafer values to map";

	parm.hyps = G_define_option ();
	parm.hyps->key = "hypotheses";
	parm.hyps->type = TYPE_STRING;
	parm.hyps->required = NO;
	parm.hyps->multiple = NO;
	parm.hyps->description = "Hypotheses to map (default: all)";

	parm.logfile = G_define_option ();
	parm.logfile->key = "logfile";
	parm.logfile->type = TYPE_STRING;
	parm.logfile->required = NO;
	parm.logfile->description = "Name of logfile";

	/* TODO: not implemented yet
	parm.warnings = G_define_option ();
	parm.warnings->key = "warnings";
	parm.warnings->type = TYPE_STRING;
	parm.warnings->required = NO;
	parm.warnings->description = "Name of site list to store locations of warnings." ;
	*/

	flag.norm = G_define_flag ();
	flag.norm->key = 'n';
	flag.norm->description = "Turn off normalisation";

	flag.quiet = G_define_flag ();
	flag.quiet->key = 'q';
	flag.quiet->description = "Quiet operation: no progress diplay";

	/* append output to existing logfile ? */
	flag.append = G_define_flag ();
	flag.append->key = 'a';
	flag.append->description = "Append log output to existing file";
	
	no_assigns = 0;
	
	/* INIT GLOBAL VARS */
	WOC_MIN = 0;
	WOC_MAX = 0;
	
	/* do not pause after a warning message was displayed */
	G_sleep_on_error (0);
	
	/* parse command line */
	if (G_parser (argc, argv))
	{
		exit (-1);
	}			
	
	/* check if given parameters are valid */
	if (G_legal_filename (parm.file->answer) == -1) {
		G_fatal_error ("Please provide the name of an existing DST knowledge base.\n");
	}
	
	if (G_find_file ("DST",parm.file->answer,G_mapset()) == NULL) {
		G_fatal_error ("Knowledge base does not exist in user's MAPSET!\n");
	}
	
	/* check logfile */
	if (parm.logfile->answer != NULL) {		
		if ( !G_legal_filename (parm.logfile->answer) ) {
			G_fatal_error ("Please specify a legal filename for the logfile.\n");
		}
		/* attempt to write to logfile */
		if (flag.append->answer) {
			if (fopen (parm.logfile->answer, "r") == NULL) {
				lp = fopen (parm.logfile->answer, "w+");
				if (lp == NULL) {
					G_fatal_error ("Logfile error: %s\n", strerror (errno));
				}				
			} else {
				lp = fopen (parm.logfile->answer, "a");
				if (lp == NULL) {
					G_fatal_error ("Logfile error: %s\n", strerror (errno));
				}
				fprintf (lp,"\n\n * * * * * \n\n");
			}
		} else {
			if ( (lp = fopen ( parm.logfile->answer, "w+" ) ) == NULL ) {
				G_fatal_error ("Logfile error: %s\n", strerror (errno));
			}
		}
		/* we want unbuffered output for the logfile */
		setvbuf (lp,NULL,_IONBF,0);
	} else {		
		/* log output to stderr by default */
		lp = stderr;
	}
		
	/* setup coordinate file storage, if desired */
	/* try to create a sites file to store coordinates */
	/* set 'warn' to point to the user-defined sites file */	
	/*
	warn = NULL;
	if ( parm.warnings != NULL ) {
	}
	*/
			
	/* check if we have read/write access to knowledge base */
	kb = G_fopen_old ("DST",parm.file->answer,G_mapset());
	if ( kb == NULL ) {
		G_fatal_error ("Cannot open knowledge base file for reading and writing!\n");
	}
	fclose(kb);
	
	/* start logfile */
	if ( parm.logfile->answer != NULL) {
		fprintf (lp,"This is %s, version %.2f\n",argv[0],PROGVERSION);
		systime = time (NULL);
		fprintf (lp,"Calculation started on %s\n",ctime(&systime));
	}		
		
	/* open DST file and get basic evidence group information */
	dstXMLFile = stat_XML ( parm.file->answer, &NO_SINGLETONS, &N );
	groups = get_groups_XML ( N, dstXMLFile );
	
	if ( NO_SINGLETONS == 1 ) {
		G_fatal_error ("Knowledge base does not contain any user-supplied hypotheses.\n");
	}

	if ( parm.groups->answer != NULL ) {
		/* user specified a subset of groups */
		N = check_groups ( groups );
	}
		
	if ( N < 2 ) {
		G_fatal_error ("At least two groups of evidences must be present in the knowledge base.\n");
	}				

	/* allocate memory for all samples 
	 a sample holds one double for bel, pl and bpn for each
	 piece of evidence. The number of pieces of evidence is
	 the number of possible subsets in Theta 
	 = 2^NO_SINGLETONS ! 
	
	 The number of samples is = number of groups in the XML
	 knowledge base file (N) !
	*/
	samples = (Shypothesis**) G_malloc ((N * sizeof(Shypothesis*)));
	for ( i=0; i < N; i ++ ) {
		samples[i] = (Shypothesis*) G_malloc (sizeof(Shypothesis));
	}
	
	
	/* turn off normalisation if user wants it so */
	if ( flag.norm->answer == 1 ) {
		norm = 0;
	}	
			
	/* do some type-dependant checking */
	/* and open file pointers for all the maps to read! */
	file_pointers = NULL;
	if ( !strcmp (parm.type->answer,"rast") ) {
		if ( parm.groups->answer != NULL ) {
			/* check only user-specified groups */
			file_pointers = test_rast_XML ( parm.groups->answers, dstXMLFile );			
		} else {
			/* check all groups */
			file_pointers = test_rast_XML ( groups, dstXMLFile );
		}
	}	
	
	/* read in all samples in a type-dependant manner */
	if ( parm.groups->answer != NULL ) {
		/* read only user-specified groups */
		if ( !strcmp (parm.type->answer,"const") ) {
			if ( strcmp (parm.output->answer,G_location ()) != 0) {
				G_warning ("Ignoring parameter 'output='.\n");
			}
			if ( strcmp (parm.vals->answer,"bel") !=0 ) {
				G_warning ("Ignoring parameter 'values='.\n");
			}
			if ( parm.hyps->answer != NULL ) {
				G_warning ("Ignoring parameter 'hypotheses='.\n");
			}
			do_calculations_const (samples,parm.groups->answers, norm, dstXMLFile);
		}
		if ( !strcmp (parm.type->answer,"rast") ) {
			do_calculations_rast (samples,parm.groups->answers, norm,
								  parm.output->answer, parm.vals->answers, 
								  parm.hyps->answer, flag.quiet->answer,
							      parm.logfile->answer, dstXMLFile, file_pointers );
		}			
	} else {
		/* read all groups */
		if ( !strcmp (parm.type->answer,"const") ) {
			if ( strcmp (parm.output->answer,G_location ()) != 0) {
				G_warning ("Ignoring parameter 'output='.\n");
			}
			if ( strcmp (parm.vals->answer,"bel") !=0 ) {
				G_warning ("Ignoring parameter 'values='.\n");
			}
			if ( parm.hyps->answer != NULL ) {
				G_warning ("Ignoring parameter 'hypotheses='.\n");
			}
			do_calculations_const (samples,groups, norm, dstXMLFile);
		}
		if ( !strcmp (parm.type->answer,"rast") ) {
			do_calculations_rast (samples,groups, norm,
								  parm.output->answer, parm.vals->answers, 
							      parm.hyps->answer, flag.quiet->answer,
								  parm.logfile->answer, dstXMLFile, file_pointers );
		}			
	}	
		
	/* close logfile */
	/* write processing time to logfile */
	proctime = clock ();
	timeused = (unsigned long) proctime / CLOCKS_PER_SEC;
	days = timeused / 86400;
	hours = (timeused - (days * 86400)) / 3600;
	mins = (timeused - (days * 86400) - (hours * 3600)) / 60;		
	secs = (timeused - (days * 86400) - (hours * 3600) - (mins * 60));
	systime = time (NULL);
	
	if ( parm.logfile->answer != NULL ) {
		fprintf (lp,"\nCalculation finished on %s",ctime(&systime));		
		fprintf (lp,"Processing time: %id, %ih, %im, %is\n",
				days, hours, mins, secs );
		fflush (lp);
	}
	
	for (i=0; i<N; i++) {
		G_free (groups[i]);		
	}
	G_free (groups);
	
	return (EXIT_SUCCESS);
}