[mapserver-commits] r13169 - sandbox/tb-labels
svn at osgeo.org
svn at osgeo.org
Thu Feb 23 14:03:13 EST 2012
Author: tbonfort
Date: 2012-02-23 11:03:13 -0800 (Thu, 23 Feb 2012)
New Revision: 13169
Modified:
sandbox/tb-labels/mapdraw.c
sandbox/tb-labels/mapfile.c
sandbox/tb-labels/maplabel.c
sandbox/tb-labels/mapprimitive.c
sandbox/tb-labels/mapprimitive.h
sandbox/tb-labels/mapserver.h
Log:
modify msTestLabelCacheCollisions to not modify cachePtr->status.
add offseted labels with leader lines
Modified: sandbox/tb-labels/mapdraw.c
===================================================================
--- sandbox/tb-labels/mapdraw.c 2012-02-23 13:58:25 UTC (rev 13168)
+++ sandbox/tb-labels/mapdraw.c 2012-02-23 19:03:13 UTC (rev 13169)
@@ -2343,44 +2343,216 @@
return MS_SUCCESS;
}
+/* private shortcut function to try a leader offsetted label */
+void offsetAndTest(imageObj*image, mapObj *map, labelCacheMemberObj *cachePtr, double ox, double oy,
+ int priority, int label_idx, shapeObj *unoffsetedpoly) {
+ /* offset cachePtr->poly and cachePtr->point */
+ int i,j;
+ for(i=cachePtr->poly->numlines-1;i>=0;i--) {
+ for(j=cachePtr->poly->line[i].numpoints-1;j>=0;j--) {
+ cachePtr->poly->line[i].point[j].x = unoffsetedpoly->line[i].point[j].x + ox;
+ cachePtr->poly->line[i].point[j].y = unoffsetedpoly->line[i].point[j].y + oy;
+ }
+ }
+ cachePtr->poly->bounds.minx = unoffsetedpoly->bounds.minx + ox;
+ cachePtr->poly->bounds.miny = unoffsetedpoly->bounds.miny + oy;
+ cachePtr->poly->bounds.maxx = unoffsetedpoly->bounds.maxx + ox;
+ cachePtr->poly->bounds.maxy = unoffsetedpoly->bounds.maxy + oy;
+ cachePtr->point.x = cachePtr->leaderline->point[0].x + ox;
+ cachePtr->point.y = cachePtr->leaderline->point[0].y + oy;
+
+ /* set the second point of the leader line */
+ cachePtr->leaderline->point[1].x = cachePtr->point.x;
+ cachePtr->leaderline->point[1].y = cachePtr->point.y;
+
+ /* compute leader line bbox */
+ if(ox>0) {
+ cachePtr->leaderbbox->minx = cachePtr->leaderline->point[0].x;
+ cachePtr->leaderbbox->maxx = cachePtr->point.x;
+ } else {
+ cachePtr->leaderbbox->maxx = cachePtr->leaderline->point[0].x;
+ cachePtr->leaderbbox->minx = cachePtr->point.x;
+ }
+ if(oy>0) {
+ cachePtr->leaderbbox->miny = cachePtr->leaderline->point[0].y;
+ cachePtr->leaderbbox->maxy = cachePtr->point.y;
+ } else {
+ cachePtr->leaderbbox->maxy = cachePtr->leaderline->point[0].y;
+ cachePtr->leaderbbox->miny = cachePtr->point.y;
+ }
+ cachePtr->status = msTestLabelCacheCollisions(&(map->labelcache), &(cachePtr->labels[0]), image->width, image->height, 0 /* todo map_edge_buffer */,
+ cachePtr, priority, -label_idx, 0, 0);
+ if(cachePtr->status) {
+ int ll;
+ for(ll=0;ll<cachePtr->numlabels;ll++) {
+ cachePtr->labels[ll].annopoint.x += ox;
+ cachePtr->labels[ll].annopoint.y += oy;
+ }
+ }
+}
+
int msDrawOffsettedLabels(imageObj *image, mapObj *map, int priority) {
assert(MS_RENDERER_PLUGIN(image->format));
int retval = MS_SUCCESS;
- int l;
+ int l,map_edge_buffer;
labelCacheSlotObj *cacheslot;
labelCacheMemberObj *cachePtr;
cacheslot = &(map->labelcache.slots[priority]);
+ char *value;
+ if((value = msLookupHashTable(&(map->web.metadata), "labelcache_map_edge_buffer")) != NULL) {
+ map_edge_buffer = atoi(value);
+ }
for(l=cacheslot->numlabels-1; l>=0; l--) {
cachePtr = &(cacheslot->labels[l]); /* point to right spot in the label cache */
- if(cachePtr->status == MS_FALSE) { /* only test labels that haven't been rendered */
+ if(cachePtr->status == MS_FALSE && !cachePtr->labelpath) {
+ /* only test regular labels that haven't been rendered */
classObj *classPtr = (GET_CLASS(map,cachePtr->layerindex,cachePtr->classindex));
+ layerObj *layerPtr = (GET_LAYER(map,cachePtr->layerindex));
if(classPtr->leader.maxdistance) { /* only test labels that can be offsetted */
-
- /* if the entry has a single label and it has position != CC,
+ if(cachePtr->point.x <= -map_edge_buffer ||
+ cachePtr->point.y <= -map_edge_buffer ||
+ cachePtr->point.x >= image->width + map_edge_buffer ||
+ cachePtr->point.y >= image->height + map_edge_buffer) {
+ /* don't look for leaders if point is in edge buffer as the leader line would end up chopped off */
+ continue;
+ }
+
+ /* TODO: if the entry has a single label and it has position != CC,
* recompute the cachePtr->poly and labelPtr->annopoint using POSITION CC */
shapeObj origPoly;
msInitShape(&origPoly);
msCopyShape(cachePtr->poly,&origPoly);
+
+ cachePtr->leaderline = msSmallMalloc(sizeof(lineObj));
+ cachePtr->leaderline->numpoints = 2;
+ cachePtr->leaderline->point = msSmallMalloc(2*sizeof(pointObj));
+ cachePtr->leaderline->point[0] = cachePtr->point;
+ cachePtr->leaderbbox = msSmallMalloc(sizeof(rectObj));
+ int steps = classPtr->leader.maxdistance / classPtr->leader.gridstep;
+ int i;
+#define x0 (cachePtr->leaderline->point[0].x)
+#define y0 (cachePtr->leaderline->point[0].y)
+#define gridstepsc (classPtr->leader.gridstep)
+
+#define otest(ox,oy) offsetAndTest(image,map,cachePtr,(ox),(oy),priority,l,&origPoly); \
+ if(cachePtr->status) break;
+
/* loop through possible offsetted positions */
- {
- /* offset cachePtr->poly and cachePtr->point*/
+ for(i=1;i<=steps;i++) {
- /* test for collision of offsetted label ( and leader line ) */
- /* if no collision */
- {
- /* mark label as rendered */
- /* add leader line to cachePtr */
- /* render label group and leader line */
- /* continue to next label is slot */
+ /* test the 4 cardinal points on the ring */
+
+ /* (points marked "0" are the ones being tested)
+
+ XXX0XXX
+ XXXXXXX
+ XXXXXXX
+ 0XX.XX0
+ XXXXXXX
+ XXXXXXX
+ XXX0XXX
+
+ * (x0+i*gridtep,y0), pos cr
+
+ * (x0-i*gridstep,y0), pos cl
+ * (x0,y0-i*gridstep), pos uc
+ * (x0,y0+i*gridstep), pos lc
+ */
+ otest(i*gridstepsc,0);
+ otest(-i*gridstepsc,0);
+ otest(0,-i*gridstepsc);
+ otest(0,i*gridstepsc);
+ otest(i*gridstepsc,i*gridstepsc);
+ otest(-i*gridstepsc,-i*gridstepsc);
+ otest(i*gridstepsc,-i*gridstepsc);
+ otest(-i*gridstepsc,i*gridstepsc);
+
+
+ /* test the intermediate points on the ring */
+
+ /* (points marked "0" are the ones being tested)
+
+ X00X00X
+ 0XXXXX0
+ 0XXXXX0
+ XXX.XXX
+ 0XXXXX0
+ 0XXXXX0
+ X00X00X
+
+ */
+
+ /* test the extreme diagonal points */
+
+ /* (points marked "0" are the ones being tested)
+
+ 0XXXXX0
+ XXXXXXX
+ XXXXXXX
+ XXX.XXX
+ XXXXXXX
+ XXXXXXX
+ 0XXXXX0
+
+ (x0+i*gridstep, y0+i*gridstep), pos lr
+ (x0-i*gridstep, y0-i*gridstep), pos ul
+ (x0+i*gridstep, y0-i*gridstep), pos ur
+ (x0-i*gridstep, y0+i*gridstep), pos ll
+
+ */
+ }
+ if(cachePtr->status) {
+ shapeObj labelLeader; /* label polygon (bounding box, possibly rotated) */
+ labelLeader.line = cachePtr->leaderline; /* setup the label polygon structure */
+ labelLeader.numlines = 1;
+
+ int ll;
+ for(ll=0;ll<classPtr->leader.numstyles;ll++) {
+ msDrawLineSymbol(&map->symbolset, image,&labelLeader , classPtr->leader.styles[ll], layerPtr->scalefactor);
}
- /* else */
- {
- /* reset cachePtr->poly and cachePtr->point */
+ for(ll=0; ll<cachePtr->numlabels; ll++) {
+ labelObj *labelPtr = &(cachePtr->labels[ll]);
+
+ /* here's where we draw the label styles */
+ if(labelPtr->numstyles > 0) {
+ for(i=0; i<labelPtr->numstyles; i++) {
+ if(labelPtr->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT)
+ msDrawMarkerSymbol(&map->symbolset, image, &(cachePtr->point), labelPtr->styles[i], layerPtr->scalefactor);
+ else if(labelPtr->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) {
+ msDrawShadeSymbol(&map->symbolset, image, labelPtr->annopoly, labelPtr->styles[i], layerPtr->scalefactor);
+ } else {
+ /* TODO: need error msg about unsupported geomtransform */
+ return MS_FAILURE;
+ }
+ }
+ }
+ msDrawText(image, labelPtr->annopoint, labelPtr->annotext, labelPtr, &(map->fontset), layerPtr->scalefactor); /* actually draw the label */
}
+
+ /*
+ styleObj tstyle;
+ static int foo =0;
+ if(!foo) {
+ srand(time(NULL));
+ foo = 1;
+ initStyle(&tstyle);
+ tstyle.width = 1;
+ tstyle.color.alpha = 255;
+ }
+ tstyle.color.red = random()%255;
+ tstyle.color.green = random()%255;
+ tstyle.color.blue =random()%255;
+ msDrawLineSymbol(&map->symbolset, image, cachePtr->poly, &tstyle, layerPtr->scalefactor);
+ */
+ } else {
+ msFree(cachePtr->leaderline->point);
+ msFree(cachePtr->leaderline);
+ msFree(cachePtr->leaderbbox);
+ cachePtr->leaderline = NULL;
}
msFreeShape(&origPoly);
}
@@ -2486,9 +2658,9 @@
/* compare against image bounds, rendered labels and markers (sets cachePtr->status), if FORCE=TRUE then skip it */
cachePtr->status = MS_TRUE;
if(!labelPtr->force)
- msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+ cachePtr->status = msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
- if(!cachePtr->status)
+ if(!cachePtr->status)
continue;
msDrawTextLine(image, labelPtr->annotext, labelPtr, cachePtr->labelpath, &(map->fontset), layerPtr->scalefactor); /* Draw the curved label */
@@ -2496,7 +2668,7 @@
} else { /* point-based label */
int drawLabelText=MS_TRUE; // unused
shapeObj *poly=NULL; /* hold label polygon for one label, cachePtr->poly holds label polygon for the whole group */
-
+ shapeObj *tmppoly;
poly = (shapeObj *) msSmallMalloc(sizeof(shapeObj));
msInitShape(poly);
@@ -2528,14 +2700,16 @@
/*
** all other cases *could* have multiple labels defined
*/
- cachePtr->status = MS_FALSE; /* assume this cache element *can't* be placed */
-
+ cachePtr->status = MS_OFF; /* assume this cache element *can't* be placed */
for(ll=0; ll<cachePtr->numlabels; ll++) { /* RFC 77 TODO: Still may want to step through backwards... */
msFreeShape(poly);
labelPtr = &(cachePtr->labels[ll]);
+ labelPtr->status = MS_OFF;
- if(!labelPtr->annotext || strlen(labelPtr->annotext) == 0) continue; /* skip this label (RFC 77 TODO: ok to bail here?) */
-
+ if(!labelPtr->annotext || strlen(labelPtr->annotext) == 0) {
+ labelPtr->status = MS_ON; /* TODO TBT, check for marker only */
+ continue; /* skip this label (RFC 77 TODO: ok to bail here?) */
+ }
/* compute label size */
if(labelPtr->type == MS_TRUETYPE) {
size = labelPtr->size * layerPtr->scalefactor;
@@ -2585,7 +2759,7 @@
return MS_FAILURE;
break;
}
- }
+ }
for(i=0; i<labelPtr->numstyles; i++) {
if(labelPtr->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) {
@@ -2597,7 +2771,7 @@
labelPtr->annopoly->line->point = (pointObj *) malloc(5*sizeof(pointObj));
labelPtr->annopoly->line->numpoints = 5;
break;
- }
+ }
}
label_marker_offset_x = MS_NINT(label_marker_width/2.0);
@@ -2607,8 +2781,8 @@
label_marker_rect.miny = MS_NINT(cachePtr->point.y - .5 * label_marker_height) - labelPtr->buffer;
label_marker_rect.maxx = MS_NINT(cachePtr->point.x + .5 * label_marker_width) + labelPtr->buffer; // marker_rect.minx + (marker_width-1) + labelPtr->buffer;
label_marker_rect.maxy = MS_NINT(cachePtr->point.y + .5 * label_marker_height) + labelPtr->buffer; // marker_rect.miny + (marker_height-1) + labelPtr->buffer;
- }
-
+ }
+
if(drawLabelText && labelPtr->position == MS_AUTO) {
int positions[MS_POSITIONS_LENGTH], npositions=0;
@@ -2634,40 +2808,44 @@
// RFC 77 TODO: take label_marker_offset_x/y into account
labelPtr->annopoint = get_metrics(&(cachePtr->point), positions[i], r, (MS_MAX(label_marker_offset_x, marker_offset_x) + label_offset_x), (MS_MAX(label_marker_offset_y, marker_offset_y) + label_offset_y), labelPtr->angle, label_buffer, poly);
- if(labelPtr->force != MS_LABEL_FORCE_GROUP) {
- /* check for collisions inside the label group unless the label is FORCE GROUP */
+ if(labelPtr->force == MS_OFF) {
+ /* check for collisions inside the label group */
/* if cachePtr->status we're still working on the first valid label with a valid status value */
/* was: if((ll != 0) && intersectLabelPolygons(poly, cachePtr->poly) == MS_TRUE) */
- if(cachePtr->status != MS_FALSE && intersectLabelPolygons(poly, cachePtr->poly) == MS_TRUE) {
+ if(ll && intersectLabelPolygons(poly, cachePtr->poly) == MS_TRUE) {
+ /* there was a self intersection, remove the label bbox added by get_metrics ? */
msShapeDeleteLine(poly, poly->numlines-1);
- cachePtr->status = MS_FALSE;
- continue; /* next position */
+ msComputeBounds(poly);
+ continue; /* next position, labelPtr->status is left to MS_OFF */
}
}
- msCopyShape(poly, cachePtr->poly); // RFC 77 - HMMM, this isn't right (need to save existing cache->poly value in case there's a collision)...
- msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+ tmppoly = cachePtr->poly;
+ cachePtr->poly = poly;
+ labelPtr->status = msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+ cachePtr->poly = tmppoly;
/* found a suitable place for this label */
- if(cachePtr->status) {
+ if(labelPtr->status) {
if(labelPtr->annopoly) get_metrics_line(&(cachePtr->point), positions[i], r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, 1, labelPtr->annopoly->line);
break; /* ...out of position loop */
- } else {
- /* reset some things */
- msShapeDeleteLine(cachePtr->poly, cachePtr->poly->numlines-1);
- if(poly->numlines == 2) msShapeDeleteLine(cachePtr->poly, cachePtr->poly->numlines-1); /* marker too */
+ } else {
+ /* reset some things */
+ /* TB->SDL: this block seemed wrong, shouldn't the marker be deleted only once *all* auto positions have been tested? */
+
+ /* there was a collision with a previous label, remove current label bbox before trying another position */
msShapeDeleteLine(poly, poly->numlines-1);
+ msComputeBounds(poly);
}
} /* next position */
- if(!cachePtr->status && labelPtr->force == MS_TRUE) {
+ if(!labelPtr->status && labelPtr->force == MS_TRUE) {
if(labelPtr->annopoly) get_metrics_line(&(cachePtr->point), positions[npositions-1], r, (MS_MAX(label_marker_offset_x, marker_offset_x) + label_offset_x), (MS_MAX(label_marker_offset_y, marker_offset_y) + label_offset_y), labelPtr->angle, 1, labelPtr->annopoly->line);
- cachePtr->status = MS_TRUE; /* draw in spite of collisions based on last position, need a *best* position */
+ labelPtr->status = MS_TRUE; /* draw in spite of collisions based on last position, need a *best* position */
}
} else { /* explicit position */
- msFreeShape(poly);
if(labelPtr->position == MS_CC) { /* don't need the marker_offset */
labelPtr->annopoint = get_metrics(&(cachePtr->point), labelPtr->position, r, label_offset_x, label_offset_y, labelPtr->angle, label_buffer, poly);
@@ -2682,30 +2860,47 @@
if(labelPtr->force == MS_TRUE) {
msCopyShape(poly, cachePtr->poly);
- cachePtr->status = MS_TRUE;
+ labelPtr->status = MS_TRUE;
} else {
- if(labelPtr->force != MS_LABEL_FORCE_GROUP) {
- /* check for collisions inside the label group unless the label is FORCE GROUP */
+ if(labelPtr->force == MS_OFF) {
+ /* check for collisions inside the label group unless the label is FORCE GROUP */
- /* if cachePtr->status we're still working on the first valid label with a valid status value */
- if(cachePtr->status != MS_FALSE && intersectLabelPolygons(poly, cachePtr->poly) == MS_TRUE) {
- cachePtr->status = MS_FALSE;
- break; /* collision within the group, done... */
- }
- }
- msCopyShape(poly, cachePtr->poly);
- msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+ /* if cachePtr->status we're still working on the first valid label with a valid status value */
+ if(ll && intersectLabelPolygons(poly, cachePtr->poly) == MS_TRUE) {
+ break; /* collision within the group */
+ }
+ }
+ tmppoly = cachePtr->poly;
+ cachePtr->poly = poly;
+ /* TODO: in case we have leader lines and multiple labels, there's no use in testing for labelcache collisions
+ * once a first collision has been found. we only need to know that the label group has collided, and the
+ * poly of the whole label group: if(label_group) testLabelCacheCollisions */
+ labelPtr->status = msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+ cachePtr->poly = tmppoly;
}
- } /* end else */
+ } /* end POSITION AUTO vs Fixed POSITION */
- if(!cachePtr->status && classPtr->leader.maxdistance == 0) {
+ if(!labelPtr->status && classPtr->leader.maxdistance == 0) {
break; /* no point looking at more labels, unless their is a leader defined, in which
- case we want to compute the full cachePt->poly to be used for offset tests */
+ case we still want to compute the full cachePtr->poly to be used for offset tests */
+ } else {
+ msCopyShape(poly, cachePtr->poly);
}
} /* next label in the group */
-
- if(!cachePtr->status)
- continue; /* next label */
+
+ /*
+ * with multiple labels and leader lines, cachePtr->status can be set back to ON if the last label
+ * didn't collide. we set it back to OFF in that case so it can become a candidate for leader offsetting
+ */
+ cachePtr->status = MS_ON;
+ for(ll=0;ll<cachePtr->numlabels; ll++) {
+ if(cachePtr->labels[ll].status == MS_OFF) {
+ cachePtr->status = MS_OFF;
+ break;
+ }
+ }
+ if(cachePtr->status == MS_OFF)
+ continue; /* next label, as we had a collision */
if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0) { /* need to draw a marker */
for(i=0; i<cachePtr->numstyles; i++)
@@ -2731,25 +2926,28 @@
msDrawText(image, labelPtr->annopoint, labelPtr->annotext, labelPtr, &(map->fontset), layerPtr->scalefactor); /* actually draw the label */
}
+
+ /*
styleObj tstyle;
- initStyle(&tstyle);
static int foo =0;
if(!foo) {
- srand(time(NULL));
- foo = 1;
+ srand(time(NULL));
+ foo = 1;
+ initStyle(&tstyle);
+ tstyle.width = 1;
+ tstyle.color.alpha = 255;
}
- tstyle.width = 1;
tstyle.color.red = random()%255;
tstyle.color.green = random()%255;
tstyle.color.blue =random()%255;
- tstyle.color.alpha = 255;
msDrawLineSymbol(&map->symbolset, image, cachePtr->poly, &tstyle, layerPtr->scalefactor);
+ */
msFreeShape(poly); /* clean up label polygon */
msFree(poly);
} /* end else */
} /* next label(group) from cacheslot */
- //msDrawOffsettedLabels(image, map, priority);
+ msDrawOffsettedLabels(image, map, priority);
} /* next priority */
return MS_SUCCESS; /* necessary? */
Modified: sandbox/tb-labels/mapfile.c
===================================================================
--- sandbox/tb-labels/mapfile.c 2012-02-23 13:58:25 UTC (rev 13168)
+++ sandbox/tb-labels/mapfile.c 2012-02-23 19:03:13 UTC (rev 13169)
@@ -1675,6 +1675,14 @@
return;
}
+static int freeLabelLeader(labelLeaderObj *leader) {
+ int i;
+ for(i=0;i<leader->numstyles;i++) {
+ msFree(leader->styles[i]);
+ }
+
+ return MS_SUCCESS;
+}
static int freeLabel(labelObj *label)
{
int i;
@@ -1704,6 +1712,8 @@
msFree(label->annopoly);
}
+ freeLabelLeader(&(label->leader));
+
return MS_SUCCESS;
}
@@ -3048,6 +3058,7 @@
msFree(class->labels);
msFree(class->keyimage);
+ freeLabelLeader(&(class->leader));
return MS_SUCCESS;
}
Modified: sandbox/tb-labels/maplabel.c
===================================================================
--- sandbox/tb-labels/maplabel.c 2012-02-23 13:58:25 UTC (rev 13168)
+++ sandbox/tb-labels/maplabel.c 2012-02-23 19:03:13 UTC (rev 13169)
@@ -365,6 +365,8 @@
cachePtr->point.x = MS_NINT(cachePtr->point.x);
cachePtr->point.y = MS_NINT(cachePtr->point.y);
cachePtr->labelpath = NULL;
+ cachePtr->leaderline = NULL;
+ cachePtr->leaderbbox = NULL;
// cachePtr->text = msStrdup(string); /* the actual text */
@@ -527,6 +529,8 @@
cachePtr->layerindex = layerindex; /* so we can get back to this *raw* data if necessary */
cachePtr->classindex = classindex;
+ cachePtr->leaderline = NULL;
+ cachePtr->leaderbbox = NULL;
if(shape) {
cachePtr->tileindex = shape->tileindex;
@@ -658,7 +662,7 @@
**
** This function is used by the various msDrawLabelCacheXX() implementations.
*/
-void msTestLabelCacheCollisions(labelCacheObj *labelcache, labelObj *labelPtr,
+int msTestLabelCacheCollisions(labelCacheObj *labelcache, labelObj *labelPtr,
int mapwidth, int mapheight, int buffer,
labelCacheMemberObj *cachePtr, int current_priority,
int current_label, int mindistance, double label_size)
@@ -666,15 +670,12 @@
int i, p;
labelCacheMemberObj *curCachePtr=NULL;
- cachePtr->status = MS_TRUE; /* by default */
-
/* Check against image bounds first
** Pass mapwidth=-1 to skip this test
*/
if(!labelPtr->partials && mapwidth > 0 && mapheight > 0) {
if(labelInImage(mapwidth, mapheight, cachePtr->poly, buffer) == MS_FALSE) {
- cachePtr->status = MS_FALSE;
- return;
+ return MS_FALSE;
}
}
@@ -688,8 +689,7 @@
for ( i = 0; i < markerslot->nummarkers; i++ ) {
if ( !(p == current_priority && (current_label == markerslot->markers[i].id || -current_label == markerslot->markers[i].id) ) ) { /* labels can overlap their own marker */
if ( intersectLabelPolygons(markerslot->markers[i].poly, cachePtr->poly ) == MS_TRUE ) {
- cachePtr->status = MS_FALSE; /* polys intersect */
- return;
+ return MS_FALSE;
}
}
}
@@ -727,19 +727,33 @@
(cachePtr->classindex == curCachePtr->classindex) &&
(strcmp(cachePtr->labels[0].annotext, curCachePtr->labels[0].annotext) == 0) &&
(msDistancePointToPoint(&(cachePtr->point), &(curCachePtr->point)) <= (mindistance + label_size))) { /* label is a duplicate */
- cachePtr->status = MS_FALSE;
- return;
+ return MS_FALSE;
}
if(intersectLabelPolygons(curCachePtr->poly, cachePtr->poly) == MS_TRUE) { /* polys intersect */
- cachePtr->status = MS_FALSE;
- return;
+ return MS_FALSE;
}
+ if(curCachePtr->leaderline) {
+ /* our poly against rendered leader lines */
+ /* first do a bbox check */
+ if(msRectOverlap(curCachePtr->leaderbbox, &(cachePtr->poly->bounds))) {
+ return MS_FALSE;
+ }
+
+ }
+ if(cachePtr->leaderline) {
+ /* does our leader intersect current label */
+ /* first do a bbox check */
+ if(msRectOverlap(cachePtr->leaderbbox, &(curCachePtr->poly->bounds))) {
+ return MS_FALSE;
+ }
+ }
}
} /* i */
i = 0; /* Start over with 1st label of next slot */
} /* p */
+ return MS_TRUE;
}
/* msGetLabelCacheMember()
@@ -1235,7 +1249,6 @@
/* STEP 0: check bounding boxes */
if(!msRectOverlap(&p1->bounds, &p2->bounds)) /* from alans at wunderground.com */
{
- msDebug("reject 1 %d %d\n",p1,p2);
return(MS_FALSE);
}
@@ -1246,7 +1259,6 @@
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)
{
- msDebug("reject 2 %d %d/n",p1,p2);
return(MS_TRUE);
}
Modified: sandbox/tb-labels/mapprimitive.c
===================================================================
--- sandbox/tb-labels/mapprimitive.c 2012-02-23 13:58:25 UTC (rev 13168)
+++ sandbox/tb-labels/mapprimitive.c 2012-02-23 19:03:13 UTC (rev 13169)
@@ -115,19 +115,27 @@
}
int msCopyShape(shapeObj *from, shapeObj *to) {
- int i;
+ int i,copybounds=0;
if(!from || !to) return(-1);
+ if(to->numlines <= 0) copybounds=1;
for(i=0; i<from->numlines; i++)
msAddLine(to, &(from->line[i])); /* copy each line */
to->type = from->type;
- to->bounds.minx = MS_MIN(to->bounds.minx,from->bounds.minx);
- to->bounds.miny = MS_MIN(to->bounds.miny,from->bounds.miny);
- to->bounds.maxx = MS_MAX(to->bounds.maxx,from->bounds.maxx);
- to->bounds.maxy = MS_MAX(to->bounds.maxy,from->bounds.maxy);
+ if(copybounds) {
+ to->bounds.minx = from->bounds.minx;
+ to->bounds.miny = from->bounds.miny;
+ to->bounds.maxx = from->bounds.maxx;
+ to->bounds.maxy = from->bounds.maxy;
+ } else {
+ to->bounds.minx = MS_MIN(to->bounds.minx,from->bounds.minx);
+ to->bounds.miny = MS_MIN(to->bounds.miny,from->bounds.miny);
+ to->bounds.maxx = MS_MAX(to->bounds.maxx,from->bounds.maxx);
+ to->bounds.maxy = MS_MAX(to->bounds.maxy,from->bounds.maxy);
+ }
if(from->text) to->text = msStrdup(from->text);
Modified: sandbox/tb-labels/mapprimitive.h
===================================================================
--- sandbox/tb-labels/mapprimitive.h 2012-02-23 13:58:25 UTC (rev 13168)
+++ sandbox/tb-labels/mapprimitive.h 2012-02-23 19:03:13 UTC (rev 13169)
@@ -86,6 +86,7 @@
long index;
int tileindex;
int classindex;
+ char **texts;
char *text;
int scratch;
Modified: sandbox/tb-labels/mapserver.h
===================================================================
--- sandbox/tb-labels/mapserver.h 2012-02-23 13:58:25 UTC (rev 13168)
+++ sandbox/tb-labels/mapserver.h 2012-02-23 19:03:13 UTC (rev 13169)
@@ -1107,7 +1107,7 @@
int shapetype; /* source geometry type */
pointObj point; /* label point */
- shapeObj *poly; /* label bounding box */
+ shapeObj *poly; /* label bounding box, accumulation of individual label's bounding boxes */
int status; /* has this label been drawn or not */
@@ -1116,6 +1116,8 @@
#endif /* SWIG */
int markerid; /* corresponding marker (POINT layers only) */
+ lineObj *leaderline;
+ rectObj *leaderbbox;
} labelCacheMemberObj;
/************************************************************************/
@@ -2034,7 +2036,7 @@
MS_DLL_EXPORT int msAddLabel(mapObj *map, labelObj *label, int layerindex, int classindex, shapeObj *shape, pointObj *point, labelPathObj *labelpath, double featuresize);
MS_DLL_EXPORT int msAddLabelGroup(mapObj *map, int layerindex, int classindex, shapeObj *shape, pointObj *point, double featuresize);
-MS_DLL_EXPORT void msTestLabelCacheCollisions(labelCacheObj *labelcache, labelObj *labelPtr, int mapwidth, int mapheight, int buffer, labelCacheMemberObj *cachePtr, int current_priority, int current_label, int mindistance, double label_size);
+MS_DLL_EXPORT int __attribute__((warn_unused_result)) msTestLabelCacheCollisions(labelCacheObj *labelcache, labelObj *labelPtr, int mapwidth, int mapheight, int buffer, labelCacheMemberObj *cachePtr, int current_priority, int current_label, int mindistance, double label_size);
MS_DLL_EXPORT labelCacheMemberObj *msGetLabelCacheMember(labelCacheObj *labelcache, int i);
MS_DLL_EXPORT gdFontPtr msGetBitmapFont(int size);
More information about the mapserver-commits
mailing list