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); }
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); }
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); }
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; }