Ejemplo n.º 1
0
int main()
{
    RTREENODE* root = RTreeCreate();
    
    int i, nhits;
    
    fprintf (stdout, "nrects = %d ", nrects);
    
    /* Insert all the testing data rects */
    for(i=0; i<nrects; i++){
        RTreeInsertRect(&rects[i],  /* the mbr being inserted */
                        i+10,        /* i+1 is mbr ID. ID MUST NEVER BE ZERO */
                        &root,        /* the address of rtree's root since root can change undernieth*/
                        0            /* always zero which means to add from the root */
            );
    }

    nhits = RTreeSearch(root, &search_rect, MySearchCallback, 0);
    
    fprintf (stdout, "Search resulted in %d hits ", nhits);

    RTreeDestroy (root);

    return 0;
}
Ejemplo n.º 2
0
/* RTreeSearch in an index tree or subtree for all data retangles that
** overlap the argument rectangle.
** Returns the number of qualifying data rects.
*/
LeafList_t *RTreeSearch(RTree_t * rtp, Node_t * n, Rect_t * r)
{
    register int i;
    LeafList_t *llp = 0;

    assert(n);
    assert(n->level >= 0);
    assert(r);

    rtp->SeTouchCount++;

    if (n->level > 0) {		/* this is an internal node in the tree */
	for (i = 0; i < NODECARD; i++)
	    if (n->branch[i].child && Overlap(r, &n->branch[i].rect)) {
		LeafList_t *tlp = RTreeSearch(rtp, n->branch[i].child, r);
		if (llp) {
		    LeafList_t *xlp = llp;
		    while (xlp->next)
			xlp = xlp->next;
		    xlp->next = tlp;
		} else
		    llp = tlp;
	    }
    } else {			/* this is a leaf node */
	for (i = 0; i < NODECARD; i++) {
	    if (n->branch[i].child && Overlap(r, &n->branch[i].rect)) {
		llp = RTreeLeafListAdd(llp, (Leaf_t *) & n->branch[i]);
#				ifdef RTDEBUG
		PrintRect(&n->branch[i].rect);
#				endif
	    }
	}
    }
    return llp;
}
Ejemplo n.º 3
0
/*ARGS ARE AVAILABLE*/
void *RtreeUdiSearch (control_t *control)
{
  rect_t r;
  int i;
  struct ClauseList clauselist;
  struct CallbackM cm;
  callback_m_t c;
  YAP_Term Constraints;

  /*RTreePrint ((*control)[0].tree);*/

  for (i = 0; i < NARGS && (*control)[i].arg != 0 ; i++)
    if (YAP_IsAttVar(YAP_A((*control)[i].arg)))
      {

        /*get the constraits rect*/
        Constraints = YAP_AttsOfVar(YAP_A((*control)[i].arg));
        /*        Yap_DebugPlWrite(Constraints); */
        r = RectOfTerm(YAP_ArgOfTerm(2,Constraints));

        c = &cm;
        c->cl = Yap_ClauseListInit(&clauselist);
        c->pred = (*control)[i].pred;
        if (!c->cl)
          return NULL; /*? or fail*/
        RTreeSearch((*control)[i].tree, r, callback, c);
        Yap_ClauseListClose(c->cl);

        if (Yap_ClauseListCount(c->cl) == 0)
          {
            Yap_ClauseListDestroy(c->cl);
            return Yap_FAILCODE();
          }

        if (Yap_ClauseListCount(c->cl) == 1)
          {
            return Yap_ClauseListToClause(c->cl);
          }

        return Yap_ClauseListCode(c->cl);
      }
  
  return NULL; /*YAP FALLBACK*/
}
Ejemplo n.º 4
0
/* break polygons using a file-based search index */
void Vect_break_polygons_file(struct Map_info *Map, int type, struct Map_info *Err)
{
    struct line_pnts *BPoints, *Points;
    struct line_cats *Cats, *ErrCats;
    int i, j, k, ret, ltype, broken, last, nlines;
    int nbreaks;
    struct RTree *RTree;
    int npoints, nallpoints, nmarks;
    XPNT2 XPnt;
    double dx, dy, a1 = 0, a2 = 0;
    int closed, last_point;
    char cross;
    int fd, xpntfd;
    char *filename;
    static struct RTree_Rect rect;
    static int rect_init = 0;

    if (!rect_init) {
	rect.boundary = G_malloc(6 * sizeof(RectReal));
	rect_init = 6;
    }
    
    G_debug(1, "File-based version of Vect_break_polygons()");

    filename = G_tempfile();
    fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
    RTree = RTreeCreateTree(fd, 0, 2);
    remove(filename);

    filename = G_tempfile();
    xpntfd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
    remove(filename);

    BPoints = Vect_new_line_struct();
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    ErrCats = Vect_new_cats_struct();

    nlines = Vect_get_num_lines(Map);

    G_debug(3, "nlines =  %d", nlines);
    /* Go through all lines in vector, and add each point to structure of points,
     * if such point already exists check angles of segments and if differ mark for break */

    nmarks = 0;
    npoints = 1;		/* index starts from 1 ! */
    nallpoints = 0;
    XPnt.used = 0;

    G_message(_("Breaking polygons (pass 1: select break points)..."));

    for (i = 1; i <= nlines; i++) {
	G_percent(i, nlines, 1);
	G_debug(3, "i =  %d", i);
	if (!Vect_line_alive(Map, i))
	    continue;

	ltype = Vect_read_line(Map, Points, Cats, i);
	if (!(ltype & type))
	    continue;

	/* This would be confused by duplicate coordinates (angle cannot be calculated) ->
	 * prune line first */
	Vect_line_prune(Points);

	/* If first and last point are identical it is close polygon, we don't need to register last point
	 * and we can calculate angle for first.
	 * If first and last point are not identical we have to mark for break both */
	last_point = Points->n_points - 1;
	if (Points->x[0] == Points->x[last_point] &&
	    Points->y[0] == Points->y[last_point])
	    closed = 1;
	else
	    closed = 0;

	for (j = 0; j < Points->n_points; j++) {
	    G_debug(3, "j =  %d", j);
	    nallpoints++;

	    if (j == last_point && closed)
		continue;	/* do not register last of close polygon */

	    /* Box */
	    rect.boundary[0] = Points->x[j];
	    rect.boundary[3] = Points->x[j];
	    rect.boundary[1] = Points->y[j];
	    rect.boundary[4] = Points->y[j];
	    rect.boundary[2] = 0;
	    rect.boundary[5] = 0;

	    /* Already in DB? */
	    fpoint = -1;
	    RTreeSearch(RTree, &rect, (void *)srch, NULL);
	    G_debug(3, "fpoint =  %d", fpoint);

	    if (Points->n_points <= 2 ||
		(!closed && (j == 0 || j == last_point))) {
		cross = 1;	/* mark for cross in any case */
	    }
	    else {		/* calculate angles */
		cross = 0;
		if (j == 0 && closed) {	/* closed polygon */
		    dx = Points->x[last_point] - Points->x[0];
		    dy = Points->y[last_point] - Points->y[0];
		    a1 = atan2(dy, dx);
		    dx = Points->x[1] - Points->x[0];
		    dy = Points->y[1] - Points->y[0];
		    a2 = atan2(dy, dx);
		}
		else {
		    dx = Points->x[j - 1] - Points->x[j];
		    dy = Points->y[j - 1] - Points->y[j];
		    a1 = atan2(dy, dx);
		    dx = Points->x[j + 1] - Points->x[j];
		    dy = Points->y[j + 1] - Points->y[j];
		    a2 = atan2(dy, dx);
		}
	    }

	    if (fpoint > 0) {	/* Found */
		/* read point */
		lseek(xpntfd, (off_t) (fpoint - 1) * sizeof(XPNT2), SEEK_SET);
		read(xpntfd, &XPnt, sizeof(XPNT2));
		if (XPnt.cross == 1)
		    continue;	/* already marked */

		/* Check angles */
		if (cross) {
		    XPnt.cross = 1;
		    nmarks++;
		    /* write point */
		    lseek(xpntfd, (off_t) (fpoint - 1) * sizeof(XPNT2), SEEK_SET);
		    write(xpntfd, &XPnt, sizeof(XPNT2));
		}
		else {
		    G_debug(3, "a1 = %f xa1 = %f a2 = %f xa2 = %f", a1,
			    XPnt.a1, a2, XPnt.a2);
		    if ((a1 == XPnt.a1 && a2 == XPnt.a2) ||
		        (a1 == XPnt.a2 && a2 == XPnt.a1)) {	/* identical */

		    }
		    else {
			XPnt.cross = 1;
			nmarks++;
			/* write point */
			lseek(xpntfd, (off_t) (fpoint - 1) * sizeof(XPNT2), SEEK_SET);
			write(xpntfd, &XPnt, sizeof(XPNT2));
		    }
		}
	    }
	    else {
		/* Add to tree and to structure */
		RTreeInsertRect(&rect, npoints, RTree);
		if (j == 0 || j == (Points->n_points - 1) ||
		    Points->n_points < 3) {
		    XPnt.a1 = 0;
		    XPnt.a2 = 0;
		    XPnt.cross = 1;
		    nmarks++;
		}
		else {
		    XPnt.a1 = a1;
		    XPnt.a2 = a2;
		    XPnt.cross = 0;
		}
		/* write point */
		lseek(xpntfd, (off_t) (npoints - 1) * sizeof(XPNT2), SEEK_SET);
		write(xpntfd, &XPnt, sizeof(XPNT2));

		npoints++;
	    }
	}
    }

    nbreaks = 0;

    /* Second loop through lines (existing when loop is started, no need to process lines written again)
     * and break at points marked for break */

    G_message(_("Breaking polygons (pass 2: break at selected points)..."));

    for (i = 1; i <= nlines; i++) {
	int n_orig_points;

	G_percent(i, nlines, 1);
	G_debug(3, "i =  %d", i);
	if (!Vect_line_alive(Map, i))
	    continue;

	ltype = Vect_read_line(Map, Points, Cats, i);
	if (!(ltype & type))
	    continue;
	if (!(ltype & GV_LINES))
	    continue;		/* Nonsense to break points */

	/* Duplicates would result in zero length lines -> prune line first */
	n_orig_points = Points->n_points;
	Vect_line_prune(Points);

	broken = 0;
	last = 0;
	G_debug(3, "n_points =  %d", Points->n_points);
	for (j = 1; j < Points->n_points; j++) {
	    G_debug(3, "j =  %d", j);
	    nallpoints++;

	    /* Box */
	    rect.boundary[0] = Points->x[j];
	    rect.boundary[3] = Points->x[j];
	    rect.boundary[1] = Points->y[j];
	    rect.boundary[4] = Points->y[j];
	    rect.boundary[2] = 0;
	    rect.boundary[5] = 0;

	    if (Points->n_points <= 1 ||
		(j == (Points->n_points - 1) && !broken))
		break;
	    /* One point only or 
	     * last point and line is not broken, do nothing */

	    RTreeSearch(RTree, &rect, (void *)srch, 0);
	    G_debug(3, "fpoint =  %d", fpoint);

	    /* read point */
	    lseek(xpntfd, (off_t) (fpoint - 1) * sizeof(XPNT2), SEEK_SET);
	    read(xpntfd, &XPnt, sizeof(XPNT2));

	    /* break or write last segment of broken line */
	    if ((j == (Points->n_points - 1) && broken) ||
		XPnt.cross) {
		Vect_reset_line(BPoints);
		for (k = last; k <= j; k++) {
		    Vect_append_point(BPoints, Points->x[k], Points->y[k],
				      Points->z[k]);
		}

		/* Result may collapse to one point */
		Vect_line_prune(BPoints);
		if (BPoints->n_points > 1) {
		    ret = Vect_write_line(Map, ltype, BPoints, Cats);
		    G_debug(3,
			    "Line %d written j = %d n_points(orig,pruned) = %d n_points(new) = %d",
			    ret, j, Points->n_points, BPoints->n_points);
		}

		if (!broken)
		    Vect_delete_line(Map, i);	/* not yet deleted */

		/* Write points on breaks */
		if (Err) {
		    if (XPnt.cross && !XPnt.used) {
			Vect_reset_line(BPoints);
			Vect_append_point(BPoints, Points->x[j], Points->y[j], 0);
			Vect_write_line(Err, GV_POINT, BPoints, ErrCats);
		    }
		    if (!XPnt.used) {
			XPnt.used = 1;
			/* write point */
			lseek(xpntfd, (off_t) (fpoint - 1) * sizeof(XPNT2), SEEK_SET);
			write(xpntfd, &XPnt, sizeof(XPNT2));
		    }
		}

		last = j;
		broken = 1;
		nbreaks++;
	    }
	}
	if (!broken && n_orig_points > Points->n_points) {	/* was pruned before -> rewrite */
	    if (Points->n_points > 1) {
		Vect_rewrite_line(Map, i, ltype, Points, Cats);
		G_debug(3, "Line %d pruned, npoints = %d", i,
			Points->n_points);
	    }
	    else {
		Vect_delete_line(Map, i);
		G_debug(3, "Line %d was deleted", i);
	    }
	}
	else {
	    G_debug(3, "Line %d was not changed", i);
	}
    }

    close(RTree->fd);
    RTreeDestroyTree(RTree);
    close(xpntfd);
    Vect_destroy_line_struct(Points);
    Vect_destroy_line_struct(BPoints);
    Vect_destroy_cats_struct(Cats);
    Vect_destroy_cats_struct(ErrCats);
    G_verbose_message(_("Breaks: %d"), nbreaks);
}
Ejemplo n.º 5
0
/*
 * Search in an index tree or subtree for all data rectangles that
 * overlap the argument rectangle.
 * Return the number of qualifying data rects.
 */
int RTreeSearch(struct Node *N, struct Rect *R, SearchHitCallback shcb, void* cbarg, int mode)
{
        register struct Node *n = N;
        register struct Rect *r = R; /* NOTE: Suspected bug was R sent in as Node* and cast to Rect* here.*/
                                     /*        Fix not yet tested. */
        register int hitCount = 0;
        register int i;

        long  index;

        int sdebug = 0;

        if(mode == ID)
        {
           index = (long)N;

           n = &nodes[index];
        }

        if(sdebug)
        {
           if (n->level > 0)
              printf("\nChecking internal node %ld\n", index);
           else
              printf("\nChecking leaf node %ld\n", index);
        }

        assert(n);
        assert(n->level >= 0);
        assert(r);

        if (n->level > 0) /* this is an internal node in the tree */
        {
                for (i=0; i<NODECARD; i++)
                {
                        if (sdebug && n->branch[i].child)
                        {
                                printf("\nNODECARD %ld\n", (long)n->branch[i].child);
                                fflush(stdout);
                        }

                        if (n->branch[i].child &&
                            RTreeOverlap(r,&n->branch[i].rect))
                        {
                                if(RTreeContained(&n->branch[i].rect, r))
                                   hitCount += RTreeSearch(n->branch[i].child, R, shcb, cbarg, mode);

                                else
                                   hitCount += RTreeSearch(n->branch[i].child, R, shcb, cbarg, mode);
                        }
                }
        }
        else /* this is a leaf node */
        {
                for (i=0; i<LEAFCARD; i++)
                {
                        if (sdebug && n->branch[i].child)
                        {
                                printf("\nLEAFCARD %ld\n", (long)n->branch[i].child);
                                fflush(stdout);
                        }

                        if (n->branch[i].child &&
                            RTreeOverlap(r,&n->branch[i].rect))
                        {
                                hitCount++;

                                if(sdebug)
                                   printf("---> Found\n");

                                if(shcb) /* call the user-provided callback */
                                        if( ! shcb((long)n->branch[i].child, cbarg))
                                                return hitCount; /* callback wants to terminate search early */
                        }
                }
        }
        return hitCount;
}
Ejemplo n.º 6
0
/**
 * Responds to a new day event by releasing any pending infections and
 * stochastically generating infections.
 *
 * @param self the model.
 * @param herds a list of herds.
 * @param event a new day event.
 * @param rng a random number generator.
 * @param queue for any new events the model creates.
 */
void
handle_new_day_event (struct ergadm_model_t_ *self, HRD_herd_list_t * herds,
                      EVT_new_day_event_t * event, RAN_gen_t * rng, EVT_event_queue_t * queue)
{
  local_data_t *local_data;
  HRD_herd_t *herd1;
  unsigned int nherds;          /* number of herds */
  unsigned int herd1_index, herd2_index;
  gboolean herd1_can_be_source;
  double distance;
  GQueue *q;
  EVT_event_t *pending_event;
  struct Rect search_rect;      /* for narrowing down radius searches using the
                                   R-tree (spatial index) */
  double mult;                  /* to account for latitude */
  callback_t callback_data;
#if DEBUG
  GString *s;
#endif

#if DEBUG
  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "----- ENTER handle_new_day_event (%s)", MODEL_NAME);
#endif

  local_data = (local_data_t *) (self->model_data);

  /* Release any pending (due to airborne transport delays) events. */
  local_data->rotating_index =
    (local_data->rotating_index + 1) % local_data->pending_infections->len;
  q = (GQueue *) g_ptr_array_index (local_data->pending_infections, local_data->rotating_index);
  while (!g_queue_is_empty (q))
    {
      /* Remove the event from this model's internal queue and place it in the
       * simulation's event queue. */
      pending_event = (EVT_event_t *) g_queue_pop_head (q);
      EVT_event_enqueue (queue, pending_event);
      local_data->npending_infections--;
    }

  if (
#if defined(USE_RTREE) && USE_RTREE == 1
       /* For debugging purposes, you can #define USE_RTREE to 0 to never use
        * the spatial index, or 1 to always use it. */
       TRUE ||
#endif
       local_data->use_rtree_index)
    {
      /* Initialize a data structure used by the callback function. */
      callback_data.self = self;
      callback_data.herds = herds;
      callback_data.event = event;
      callback_data.rng = rng;
      callback_data.queue = queue;
    }

  nherds = HRD_herd_list_length (herds);
  for (herd1_index = 0; herd1_index < nherds; herd1_index++)
    {
      herd1 = HRD_herd_list_get (herds, herd1_index);

      /* Can this herd be the source of an exposure? */
#if DEBUG
      s = g_string_new (NULL);
      g_string_sprintf (s, "unit \"%s\" is %s, state is %s: ",
                        herd1->official_id, herd1->production_type_name,
                        HRD_status_name[herd1->status]);
#endif
      herd1_can_be_source =
        local_data->param_block[herd1->production_type] != NULL
        && (herd1->status == InfectiousSubclinical || herd1->status == InfectiousClinical);
#if DEBUG
      g_string_sprintfa (s, "%s be source", herd1_can_be_source ? "can" : "cannot");
      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s", s->str);
      g_string_free (s, TRUE);
#endif
      if (!herd1_can_be_source)
        continue;

      if (local_data->use_rtree_index[herd1->production_type])
        {
          distance = local_data->max_spread[herd1->production_type] / GIS_DEGREE_DISTANCE;
          mult = 1.0 / MIN (cos (DEG2RAD * (herd1->lat + distance)), cos(DEG2RAD * (herd1->lat - distance))); 
          search_rect.boundary[0] = herd1->lon - (distance * mult) - EPSILON;
          search_rect.boundary[1] = herd1->lat - distance - EPSILON;
          search_rect.boundary[2] = herd1->lon + (distance * mult) + EPSILON;
          search_rect.boundary[3] = herd1->lat + distance + EPSILON;
          callback_data.herd1 = herd1;
          RTreeSearch (herds->spatial_index, &search_rect, callback, &callback_data);
        }
      else
        for (herd2_index = 0; herd2_index < nherds; herd2_index++)
          check_and_infect (self, herds, herd1,
                            HRD_herd_list_get (herds, herd2_index), event, rng, queue);
    }

#if DEBUG
  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "----- EXIT handle_new_day_event (%s)", MODEL_NAME);
#endif

  return;
}