Beispiel #1
0
void *dig_falloc(int nelem, int elsize)
{
    void *ret;

    if ((ret = dig__falloc(nelem, elsize)) == NULL) {
	fprintf(stderr, "Out of Memory.\n");
	G_sleep(2);
	exit(EXIT_FAILURE);
    }
    return (ret);
}
Beispiel #2
0
/*!
 * \brief Build topo for area from lines
 *
 * Area is built in clockwise order.
 * Take a given line and start off to the RIGHT/LEFT and try to complete
 * an area. 
 * 
 * Possible Scenarios:
 *  - I.    path runs into first line.                              : AREA!
 *  - II.   path runs into a dead end (no other area lines at node) : no area
 *  - III.  path runs into a previous line that is not 1st line or to 1st line but not to start node : no area
 *
 * After we find an area then we call point_in_area() to see if the
 * specified point is w/in the area
 *
 * Old returns  -1:  error   0:  no area    (1:  point in area)
 *              -2: island  !!
 *
 * \param[in] plus pointer to Plus_head structure
 * \param[in] first_line line id of first line
 * \param[in] side side of line to build area on (GV_LEFT | GV_RIGHT)
 * \param[in] lines pointer to array of lines
 *
 * \return  -1 on error   
 * \return   0 no area
 * \return   number of lines
 */
int
dig_build_area_with_line(struct Plus_head *plus, plus_t first_line, int side,
			 plus_t ** lines)
{
    register int i;
    int prev_line, next_line;
    static plus_t *array;
    char *p;
    static int array_size;	/* 0 on startup */
    int n_lines;
    struct P_line *Line;
    struct P_topo_b *topo;
    int node;

    if (debug_level == -1) {
	const char *dstr = G__getenv("DEBUG");

	if (dstr != NULL)
	    debug_level = atoi(dstr);
	else
	    debug_level = 0;
    }

    G_debug(3, "dig_build_area_with_line(): first_line = %d, side = %d",
	    first_line, side);

    /* First check if line is not degenerated (degenerated lines have angle -9) 
     *  Following degenerated lines are skip by dig_angle_next_line() */
    Line = plus->Line[first_line];
    if (Line->type != GV_BOUNDARY)
	return -1;

    topo = (struct P_topo_b *)Line->topo;
    node = topo->N1;		/* to check one is enough, because if degenerated N1 == N2 */
    if (dig_node_line_angle(plus, node, first_line) == -9.) {
	G_debug(3, "First line degenerated");
	return (0);
    }

    if (array_size == 0) {	/* first time */
	array_size = 1000;
	array = (plus_t *) dig__falloc(array_size, sizeof(plus_t));
	if (array == NULL)
	    return (dig_out_of_memory());
    }

    if (side == GV_LEFT) {
	first_line = -first_line;	/* start at node1, reverse direction */
    }
    array[0] = first_line;
    prev_line = -first_line;	/* start at node2 for direct and node1 for
				   reverse direction */
    /* angle of first line */
    n_lines = 1;
    while (1) {
	next_line =
	    dig_angle_next_line(plus, prev_line, GV_RIGHT, GV_BOUNDARY);
	G_debug(3, "next_line = %d", next_line);

	if (next_line == 0)
	    return (-1);	/* Not found */

	/* Check if adjacent lines do not have the same angle */
	if (!dig_node_angle_check(plus, next_line, GV_BOUNDARY)) {
	    G_debug(3,
		    "Cannot build area, a neighbour of the line %d has the same angle at the node",
		    next_line);
	    return 0;
	}

	/*  I. Area closed. This also handles the problem w/ 1 single area line */
	if (first_line == next_line) {
	    /* GOT ONE!  fill area struct  and return */
	    G_debug(3, "Got one! :");

	    /* avoid loop when not debugging */
	    if (debug_level > 2) {
		for (i = 0; i < n_lines; i++) {
		    G_debug(3, " area line (%d) = %d", i, array[i]);
		}
	    }

	    *lines = array;
	    return (n_lines);
	}

	/* II. Note this is a dead end */
	/* ( if prev_line != -first_line so it goes after the previous test) ? */
	if (prev_line == next_line) {
	    G_debug(3, "Dead_end:");
	    return (0);		/* dead end */
	}

	/* III. Unclosed ?, I would say started from free end */
	for (i = 0; i < n_lines; i++)
	    if (abs(next_line) == abs(array[i])) {
		G_debug(3, "Unclosed area:");
		return (0);	/* ran into a different area */
	    }

	/* otherwise keep going */
	if (n_lines >= array_size) {
	    p = dig__frealloc(array, array_size + 100, sizeof(plus_t),
			      array_size);
	    if (p == NULL)
		return (dig_out_of_memory());
	    array = (plus_t *) p;
	    array_size += 100;
	}
	array[n_lines++] = next_line;
	prev_line = -next_line;
    }

    return 0;
}