Beispiel #1
0
int msIntersectPolygons(shapeObj *p1, shapeObj *p2) {
  int c1,v1,c2,v2;

  /* STEP 1: polygon 1 completely contains 2 (only need to check one point from each part) */
  for(c2=0; c2<p2->numlines; c2++) {
    if(msIntersectPointPolygon(&(p2->line[c2].point[0]), p1) == MS_TRUE) // this considers holes and multiple parts
      return(MS_TRUE);
  }

  /* STEP 2: polygon 2 completely contains 1 (only need to check one point from each part) */
  for(c1=0; c1<p1->numlines; c1++) {
    if(msIntersectPointPolygon(&(p1->line[c1].point[0]), p2) == MS_TRUE) // this considers holes and multiple parts
      return(MS_TRUE);
  }

  /* STEP 3: look for intersecting line segments */
  for(c1=0; c1<p1->numlines; c1++)
    for(v1=1; v1<p1->line[c1].numpoints; v1++)
      for(c2=0; c2<p2->numlines; c2++)
	for(v2=1; v2<p2->line[c2].numpoints; v2++)
	  if(msIntersectSegments(&(p1->line[c1].point[v1-1]), &(p1->line[c1].point[v1]), &(p2->line[c2].point[v2-1]), &(p2->line[c2].point[v2])) ==  MS_TRUE)	    
	    return(MS_TRUE);

  /*
  ** At this point we know there are are no intersections between edges. There may be other tests necessary
  ** but I haven't run into any cases that require them.
  */

  return(MS_FALSE);
}
Beispiel #2
0
int msIntersectPolylines(shapeObj *line1, shapeObj *line2) {
  int c1,v1,c2,v2;

  for(c1=0; c1<line1->numlines; c1++)
    for(v1=1; v1<line1->line[c1].numpoints; v1++)
      for(c2=0; c2<line2->numlines; c2++)
	for(v2=1; v2<line2->line[c2].numpoints; v2++)
	  if(msIntersectSegments(&(line1->line[c1].point[v1-1]), &(line1->line[c1].point[v1]), &(line2->line[c2].point[v2-1]), &(line2->line[c2].point[v2])) ==  MS_TRUE)
	    return(MS_TRUE);

  return(MS_FALSE);
}
Beispiel #3
0
int msIntersectPolylinePolygon(shapeObj *line, shapeObj *poly) {
  int c1,v1,c2,v2;

  // STEP 1: polygon might competely contain the polyline or one of it's parts (only need to check one point from each part)
  for(c1=0; c1<line->numlines; c1++) {
    if(msIntersectPointPolygon(&(line->line[c1].point[0]), poly) == MS_TRUE) // this considers holes and multiple parts
      return(MS_TRUE);
  }


  // STEP 2: look for intersecting line segments
  for(c1=0; c1<line->numlines; c1++)
    for(v1=1; v1<line->line[c1].numpoints; v1++)
      for(c2=0; c2<poly->numlines; c2++)
	for(v2=1; v2<poly->line[c2].numpoints; v2++)
	  if(msIntersectSegments(&(line->line[c1].point[v1-1]), &(line->line[c1].point[v1]), &(poly->line[c2].point[v2-1]), &(poly->line[c2].point[v2])) ==  MS_TRUE)
	    return(MS_TRUE);
  
  return(MS_FALSE);
}
/* static int intersectLabelPolygons(shapeObj *p1, shapeObj *p2) { */
int intersectLabelPolygons(shapeObj *p1, shapeObj *p2)
{
  int c1,v1,c2,v2;
  pointObj *point;

  /* STEP 0: check bounding boxes */
  if(!msRectOverlap(&p1->bounds, &p2->bounds)) { /* from [email protected] */
    return(MS_FALSE);
  }

  /* STEP 1: look for intersecting line segments */
  for(c1=0; c1<p1->numlines; c1++)
    for(v1=1; v1<p1->line[c1].numpoints; v1++)
      for(c2=0; c2<p2->numlines; c2++)
        for(v2=1; v2<p2->line[c2].numpoints; v2++)
          if(msIntersectSegments(&(p1->line[c1].point[v1-1]), &(p1->line[c1].point[v1]), &(p2->line[c2].point[v2-1]), &(p2->line[c2].point[v2])) ==  MS_TRUE) {
            return(MS_TRUE);
          }

  /* STEP 2: polygon one completely contains two (only need to check one point from each part) */
  for(c2=0; c2<p2->numlines; c2++) {
    point = &(p2->line[c2].point[0]);
    for(c1=0; c1<p1->numlines; c1++) {
      if(msPointInPolygon(point, &p1->line[c1]) == MS_TRUE) /* ok, the point is in a polygon */
        return(MS_TRUE);
    }
  }

  /* STEP 3: polygon two completely contains one (only need to check one point from each part) */
  for(c1=0; c1<p1->numlines; c1++) {
    point = &(p1->line[c1].point[0]);
    for(c2=0; c2<p2->numlines; c2++) {
      if(msPointInPolygon(point, &p2->line[c2]) == MS_TRUE) /* ok, the point is in a polygon */
        return(MS_TRUE);
    }
  }

  return(MS_FALSE);
}
Beispiel #5
0
double msDistanceShapeToShape(shapeObj *shape1, shapeObj *shape2)
{
  int i,j,k,l;
  double dist, minDist=-1;

  switch(shape1->type) {
  case(MS_SHAPE_POINT): // shape1
    for(i=0;i<shape1->numlines;i++) {
      for(j=0; j<shape1->line[i].numpoints; j++) {
        dist = msDistancePointToShape(&(shape1->line[i].point[j]), shape2);
        if((dist < minDist) || (minDist < 0)) 
	  minDist = dist;
      }
    }
    break;
  case(MS_SHAPE_LINE): // shape1
    switch(shape2->type) {
    case(MS_SHAPE_POINT):
      for(i=0;i<shape2->numlines;i++) {
        for(j=0; j<shape2->line[i].numpoints; j++) {
          dist = msDistancePointToShape(&(shape2->line[i].point[j]), shape1);
          if((dist < minDist) || (minDist < 0)) 
	    minDist = dist;
        }
      }
      break;
    case(MS_SHAPE_LINE):
      for(i=0;i<shape1->numlines;i++) {
        for(j=1; j<shape1->line[i].numpoints; j++) {
          for(k=0;k<shape2->numlines;k++) {
            for(l=1; l<shape2->line[k].numpoints; l++) {
              // check intersection (i.e. dist=0)
	      if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) 
                return(0);

	      // no intersection, compute distance
	      dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l]));
	      if((dist < minDist) || (minDist < 0)) 
		minDist = dist;
	    }
	  }
 	}
      }
      break;    
    case(MS_SHAPE_POLYGON):
      // shape2 (the polygon) could contain shape1 or one of it's parts      
      for(i=0; i<shape1->numlines; i++) {
        if(msIntersectPointPolygon(&(shape1->line[0].point[0]), shape2) == MS_TRUE) // this considers holes and multiple parts
          return(0);
      }
      
      // check segment intersection and, if necessary, distance between segments
      for(i=0;i<shape1->numlines;i++) {
        for(j=1; j<shape1->line[i].numpoints; j++) {
          for(k=0;k<shape2->numlines;k++) {
            for(l=1; l<shape2->line[k].numpoints; l++) {
	      // check intersection (i.e. dist=0)
	      if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) 
                return(0);

	      // no intersection, compute distance
	      dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l]));
	      if((dist < minDist) || (minDist < 0)) 
		minDist = dist;
	    }
	  }
 	}
      }
      break;
    }
    break;
  case(MS_SHAPE_POLYGON): // shape1
    switch(shape2->type) {
    case(MS_SHAPE_POINT):
      for(i=0;i<shape2->numlines;i++) {
        for(j=0; j<shape2->line[i].numpoints; j++) {
          dist = msDistancePointToShape(&(shape2->line[i].point[j]), shape1);
          if((dist < minDist) || (minDist < 0)) 
	    minDist = dist;
        }
      }
      break;
    case(MS_SHAPE_LINE):
      // shape1 (the polygon) could contain shape2 or one of it's parts      
      for(i=0; i<shape2->numlines; i++) {
        if(msIntersectPointPolygon(&(shape2->line[i].point[0]), shape1) == MS_TRUE) // this considers holes and multiple parts
          return(0);
      }
      
      // check segment intersection and, if necessary, distance between segments
      for(i=0;i<shape1->numlines;i++) {      
        for(j=1; j<shape1->line[i].numpoints; j++) {
          for(k=0;k<shape2->numlines;k++) {
            for(l=1; l<shape2->line[k].numpoints; l++) {
	      // check intersection (i.e. dist=0)
	      if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) 
                return(0);

	      // no intersection, compute distance
	      dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l]));
	      if((dist < minDist) || (minDist < 0)) 
		minDist = dist;
	    }
	  }
 	}
      }
      break; 
    case(MS_SHAPE_POLYGON): 
      // shape1 completely contains shape2 (only need to check one point from each part)
      for(i=0; i<shape2->numlines; i++) {
        if(msIntersectPointPolygon(&(shape2->line[i].point[0]), shape1) == MS_TRUE) // this considers holes and multiple parts
          return(0);
      }

      // shape2 completely contains shape1 (only need to check one point from each part)
      for(i=0; i<shape1->numlines; i++) {
        if(msIntersectPointPolygon(&(shape1->line[i].point[0]), shape2) == MS_TRUE) // this considers holes and multiple parts
          return(0);
      }

      // check segment intersection and, if necessary, distance between segments
      for(i=0;i<shape1->numlines;i++) {        
        for(j=1; j<shape1->line[i].numpoints; j++) {
          for(k=0;k<shape2->numlines;k++) {
            for(l=1; l<shape2->line[k].numpoints; l++) {
	      // check intersection (i.e. dist=0)
	      if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) 
                return(0);	      

	      // no intersection, compute distance
	      dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l]));
	      if((dist < minDist) || (minDist < 0)) 
		minDist = dist;
	    }
	  }
 	}
      }
      break;
    }
    break;
  }

  return(minDist);
}
int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, shapeObj *poly,
                               int mindistance, int current_priority, int current_label)
{
  labelCacheObj *labelcache = &(map->labelcache);
  int i, p, ll, pp;
  double label_width = 0;
  labelCacheMemberObj *curCachePtr=NULL;

  /*
   * Check against image bounds first
   */
  if(!cachePtr->labels[0].partials) {
    if(labelInImage(map->width, map->height, poly, labelcache->gutter) == MS_FALSE) {
      return MS_FALSE;
    }
  }

  /* compute start index of first label to test: only test against rendered labels */
  if(current_label>=0) {
    i = current_label+1;
  } else {
    i = 0;
    current_label = -current_label;
  }

  /* Compare against all rendered markers from this priority level and higher.
  ** Labels can overlap their own marker and markers from lower priority levels
  */
  for (p=current_priority; p < MS_MAX_LABEL_PRIORITY; p++) {
    labelCacheSlotObj *markerslot;
    markerslot = &(labelcache->slots[p]);

    for ( ll = 0; ll < markerslot->nummarkers; ll++ ) {
      if ( !(p == current_priority && current_label == markerslot->markers[ll].id ) ) {  /* labels can overlap their own marker */
        if ( intersectLabelPolygons(markerslot->markers[ll].poly, poly ) == MS_TRUE ) {
          return MS_FALSE;
        }
      }
    }
  }

  if(mindistance > 0)
    label_width = poly->bounds.maxx - poly->bounds.minx;

  for(p=current_priority; p<MS_MAX_LABEL_PRIORITY; p++) {
    labelCacheSlotObj *cacheslot;
    cacheslot = &(labelcache->slots[p]);

    for(  ; i < cacheslot->numlabels; i++) {
      curCachePtr = &(cacheslot->labels[i]);

      if(curCachePtr->status == MS_TRUE) { /* compare bounding polygons and check for duplicates */

        /* skip testing against ourself */
        assert(p!=current_priority || i != current_label);

        /*
        ** Note 1: We add the label_size to the mindistance value when comparing because we do want the mindistance
        ** value between the labels and not only from point to point.
        **
        ** Note 2: We only check the first label (could be multiples (RFC 77)) since that is *by far* the most common
        ** use case. Could change in the future but it's not worth the overhead at this point.
        */
        if(mindistance >0  &&
            (cachePtr->layerindex == curCachePtr->layerindex) &&
            (cachePtr->classindex == curCachePtr->classindex) &&
            (cachePtr->labels[0].annotext && curCachePtr->labels[0].annotext &&
             strcmp(cachePtr->labels[0].annotext, curCachePtr->labels[0].annotext) == 0) &&
            (msDistancePointToPoint(&(cachePtr->point), &(curCachePtr->point)) <= (mindistance + label_width))) { /* label is a duplicate */
          return MS_FALSE;
        }

        if(intersectLabelPolygons(curCachePtr->poly, poly) == MS_TRUE) { /* polys intersect */
          return MS_FALSE;
        }
        if(curCachePtr->leaderline) {
          /* our poly against rendered leader lines */
          /* first do a bbox check */
          if(msRectOverlap(curCachePtr->leaderbbox, &(poly->bounds))) {
            /* look for intersecting line segments */
            for(ll=0; ll<poly->numlines; ll++)
              for(pp=1; pp<poly->line[ll].numpoints; pp++)
                if(msIntersectSegments(
                      &(poly->line[ll].point[pp-1]),
                      &(poly->line[ll].point[pp]),
                      &(curCachePtr->leaderline->point[0]),
                      &(curCachePtr->leaderline->point[1])) ==  MS_TRUE) {
                  return(MS_FALSE);
                }
          }

        }
        if(cachePtr->leaderline) {
          /* does our leader intersect current label */
          /* first do a bbox check */
          if(msRectOverlap(cachePtr->leaderbbox, &(curCachePtr->poly->bounds))) {
            /* look for intersecting line segments */
            for(ll=0; ll<curCachePtr->poly->numlines; ll++)
              for(pp=1; pp<curCachePtr->poly->line[ll].numpoints; pp++)
                if(msIntersectSegments(
                      &(curCachePtr->poly->line[ll].point[pp-1]),
                      &(curCachePtr->poly->line[ll].point[pp]),
                      &(cachePtr->leaderline->point[0]),
                      &(cachePtr->leaderline->point[1])) ==  MS_TRUE) {
                  return(MS_FALSE);
                }

          }
          if(curCachePtr->leaderline) {
            /* TODO: check intersection of leader lines, not only bbox test ? */
            if(msRectOverlap(curCachePtr->leaderbbox, cachePtr->leaderbbox)) {
              return MS_FALSE;
            }

          }
        }
      }
    } /* i */

    i = 0; /* Start over with 1st label of next slot */
  } /* p */
  return MS_TRUE;
}