[mapserver-commits] r13172 - sandbox/tb-labels

svn at osgeo.org svn at osgeo.org
Fri Feb 24 10:59:17 EST 2012


Author: tbonfort
Date: 2012-02-24 07:59:16 -0800 (Fri, 24 Feb 2012)
New Revision: 13172

Modified:
   sandbox/tb-labels/mapdraw.c
   sandbox/tb-labels/maplabel.c
   sandbox/tb-labels/maprendering.c
   sandbox/tb-labels/mapserver.h
   sandbox/tb-labels/mapsymbol.c
Log:
add real leader collision detection, also use markers of labels with no text


Modified: sandbox/tb-labels/mapdraw.c
===================================================================
--- sandbox/tb-labels/mapdraw.c	2012-02-23 19:25:10 UTC (rev 13171)
+++ sandbox/tb-labels/mapdraw.c	2012-02-24 15:59:16 UTC (rev 13172)
@@ -2610,14 +2610,14 @@
       classObj *classPtr=NULL;
       labelObj *labelPtr=NULL;
 
-      int marker_width, marker_height; /* marker is defined in POINT or ANNOTATION layer class styles */
-      int marker_offset_x, marker_offset_y;
+      double marker_width, marker_height; /* marker is defined in POINT or ANNOTATION layer class styles */
+      double marker_offset_x, marker_offset_y;
       rectObj marker_rect = {0,0,0,0};
  
       int label_offset_x, label_offset_y;
  
-      int label_marker_width, label_marker_height; /* label_marker is defined in label styles */
-      int label_marker_offset_x, label_marker_offset_y;
+      double label_marker_width, label_marker_height; /* label_marker is defined in label styles */
+      double label_marker_offset_x, label_marker_offset_y;
       rectObj label_marker_rect = {0,0,0,0};
 
       int label_mindistance=-1,
@@ -2666,22 +2666,22 @@
             if(labelPtr->type == MS_TRUETYPE) {
               int nNewlines = msCountChars(labelPtr->annotext,'\n');
               if(!nNewlines) {
-                labelPtr->offsety += MS_NINT((((r.miny + r.maxy) + size) / 2.0)/scalefactor);
-                labelPtr->offsetx += MS_NINT((r.minx / 2)/scalefactor);
+                labelPtr->offsety += ((((r.miny + r.maxy) + size) / 2.0)/scalefactor);
+                labelPtr->offsetx += ((r.minx / 2)/scalefactor);
               } else {
                 rectObj rect2; /* bbox of first line only */
                 char *firstLine = msGetFirstLine(labelPtr->annotext);
                 msGetLabelSize(map, labelPtr, firstLine, size, &rect2, NULL);
-                labelPtr->offsety += (MS_NINT(((rect2.miny+rect2.maxy) + size) / 2))/scalefactor;
-                labelPtr->offsetx += (MS_NINT(rect2.minx / 2))/scalefactor;
+                labelPtr->offsety += ((((rect2.miny+rect2.maxy) + size) / 2))/scalefactor;
+                labelPtr->offsetx += ((rect2.minx / 2))/scalefactor;
                 free(firstLine);
               }
             }
    
             label_offset_x = labelPtr->offsetx*scalefactor;
             label_offset_y = labelPtr->offsety*scalefactor;
-            label_buffer = MS_NINT(labelPtr->buffer*image->resolutionfactor);
-            label_mindistance = MS_NINT(labelPtr->mindistance*image->resolutionfactor);
+            label_buffer = (labelPtr->buffer*image->resolutionfactor);
+            label_mindistance = (labelPtr->mindistance*image->resolutionfactor);
 
             /* copy the bounds into the cache's polygon */
             msCopyShape(&(cachePtr->labelpath->bounds), cachePtr->poly);
@@ -2698,7 +2698,6 @@
             msDrawTextLine(image, labelPtr->annotext, labelPtr, cachePtr->labelpath, &(map->fontset), layerPtr->scalefactor); /* Draw the curved label */
 
           } 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));
@@ -2712,11 +2711,11 @@
               if(msGetMarkerSize(&map->symbolset, &(cachePtr->styles[0]), &marker_width, &marker_height, layerPtr->scalefactor) != MS_SUCCESS)
                 return MS_FAILURE;
 
-              marker_offset_x = MS_NINT(marker_width/2.0);
-              marker_offset_y = MS_NINT(marker_height/2.0);
+              marker_offset_x = (marker_width/2.0);
+              marker_offset_y = (marker_height/2.0);
    
-              marker_rect.minx = MS_NINT(cachePtr->point.x - .5 * marker_width);
-              marker_rect.miny = MS_NINT(cachePtr->point.y - .5 * marker_height);
+              marker_rect.minx = (cachePtr->point.x - .5 * marker_width);
+              marker_rect.miny = (cachePtr->point.y - .5 * marker_height);
               marker_rect.maxx = marker_rect.minx + (marker_width-1);
               marker_rect.maxy = marker_rect.miny + (marker_height-1); 
               msRectToPolygon(marker_rect, cachePtr->poly);
@@ -2724,8 +2723,8 @@
               marker_rect = markerPtr->poly->bounds;
               marker_width = marker_rect.maxx - marker_rect.minx;
               marker_height = marker_rect.maxy - marker_rect.miny;
-              marker_offset_x = MS_NINT(marker_width/2.0);
-              marker_offset_y = MS_NINT(marker_height/2.0);
+              marker_offset_x = (marker_width/2.0);
+              marker_offset_y = (marker_height/2.0);
               msRectToPolygon(marker_rect, cachePtr->poly);
             }
 
@@ -2734,61 +2733,79 @@
             */
             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... */
+              int drawLabelText = MS_TRUE;
               msFreeShape(poly);
               labelPtr = &(cachePtr->labels[ll]);
               labelPtr->status = MS_OFF;
 
               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;
-                size = MS_MAX(size, labelPtr->minsize*image->resolutionfactor);
-                size = MS_MIN(size, labelPtr->maxsize*image->resolutionfactor);
-                scalefactor = size / labelPtr->size;
+                 int s;
+                 for(s=0;s<labelPtr->numstyles;s++) {
+                    if(labelPtr->styles[s]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT)
+                       break;
+                 }
+                 if(s == labelPtr->numstyles) {
+                  labelPtr->status = MS_ON; /* TODO TBT, check for marker only */
+                  continue; /* skip this label (RFC 77 TODO: ok to bail here?) */
+                 }
               } else {
-                size = labelPtr->size;
-                scalefactor = 1;
+                 drawLabelText = MS_TRUE;
               }
-              if(msGetLabelSize(map, labelPtr, labelPtr->annotext, size, &r, NULL) != MS_SUCCESS)
-                return MS_FAILURE;
-        
-              /* adjust the baseline (see #1449) */
-              if(labelPtr->type == MS_TRUETYPE) {
-                int nNewlines = msCountChars(labelPtr->annotext,'\n');
-                if(!nNewlines) {
-                  labelPtr->offsety += MS_NINT((((r.miny + r.maxy) + size) / 2.0)/scalefactor);
-                  labelPtr->offsetx += MS_NINT((r.minx / 2)/scalefactor);
-                } else {
-                  rectObj rect2; /* bbox of first line only */
-                  char *firstLine = msGetFirstLine(labelPtr->annotext);
-                  msGetLabelSize(map, labelPtr, firstLine, size, &rect2, NULL);
-                  labelPtr->offsety += (MS_NINT(((rect2.miny+rect2.maxy) + size) / 2))/scalefactor;
-                  labelPtr->offsetx += (MS_NINT(rect2.minx / 2))/scalefactor;
-                  free(firstLine);
-                }
+                 drawLabelText = MS_TRUE;
+
+              if(drawLabelText) {
+                 /* compute label size */
+                 if(labelPtr->type == MS_TRUETYPE) {
+                    size = labelPtr->size * layerPtr->scalefactor;
+                    size = MS_MAX(size, labelPtr->minsize*image->resolutionfactor);
+                    size = MS_MIN(size, labelPtr->maxsize*image->resolutionfactor);
+                    scalefactor = size / labelPtr->size;
+                 } else {
+                    size = labelPtr->size;
+                    scalefactor = 1;
+                 }
+                 if(msGetLabelSize(map, labelPtr, labelPtr->annotext, size, &r, NULL) != MS_SUCCESS)
+                    return MS_FAILURE;
+
+                 /* adjust the baseline (see #1449) */
+                 if(labelPtr->type == MS_TRUETYPE) {
+                    int nNewlines = msCountChars(labelPtr->annotext,'\n');
+                    if(!nNewlines) {
+                       labelPtr->offsety += ((((r.miny + r.maxy) + size) / 2.0)/scalefactor);
+                       labelPtr->offsetx += ((r.minx / 2)/scalefactor);
+                    } else {
+                       rectObj rect2; /* bbox of first line only */
+                       char *firstLine = msGetFirstLine(labelPtr->annotext);
+                       msGetLabelSize(map, labelPtr, firstLine, size, &rect2, NULL);
+                       labelPtr->offsety += ((((rect2.miny+rect2.maxy) + size) / 2))/scalefactor;
+                       labelPtr->offsetx += ((rect2.minx / 2))/scalefactor;
+                       free(firstLine);
+                    }
+                 }
+
+                 /* apply offset and buffer settings */
+                 label_offset_x = labelPtr->offsetx*scalefactor;
+                 label_offset_y = labelPtr->offsety*scalefactor;
+                 label_buffer = (labelPtr->buffer*image->resolutionfactor);
+                 label_mindistance = (labelPtr->mindistance*image->resolutionfactor);
+
+                 if(labelPtr->autominfeaturesize && (cachePtr->featuresize != -1) && ((r.maxx-r.minx) > cachePtr->featuresize))
+                    continue; /* label too large relative to the feature */
               }
-   
-              /* apply offset and buffer settings */
-              label_offset_x = labelPtr->offsetx*scalefactor;
-              label_offset_y = labelPtr->offsety*scalefactor;
-              label_buffer = MS_NINT(labelPtr->buffer*image->resolutionfactor);
-              label_mindistance = MS_NINT(labelPtr->mindistance*image->resolutionfactor);
 
-              if(labelPtr->autominfeaturesize && (cachePtr->featuresize != -1) && ((r.maxx-r.minx) > cachePtr->featuresize))
-                continue; /* label too large relative to the feature */
-
               /* compute settings for label-based styles */
               label_marker_offset_x = label_marker_offset_y = 0; /* assume no label marker */
               label_marker_width = label_marker_height = 0;
+              double t_marker_offset_x =0;
+              double t_marker_offset_y = 0;
               if(labelPtr->numstyles > 0) {
                 for(i=0; i<labelPtr->numstyles; i++) { 
                   /* TODO: at the moment only checks the bottom (first) label style, perhaps should check all of them */ 
                   if(labelPtr->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { 
                     if(msGetMarkerSize(&map->symbolset, labelPtr->styles[i], &label_marker_width, &label_marker_height, layerPtr->scalefactor) != MS_SUCCESS) 
                       return MS_FAILURE;
+                    t_marker_offset_x = labelPtr->styles[i]->offsetx;
+                    t_marker_offset_y = labelPtr->styles[i]->offsety;
                     break; 
                   }
                 }
@@ -2806,16 +2823,16 @@
                   }
                 }
 
-                label_marker_offset_x = MS_NINT(label_marker_width/2.0); 
-                label_marker_offset_y = MS_NINT(label_marker_height/2.0); 
+                label_marker_offset_x = (label_marker_width/2.0); 
+                label_marker_offset_y = (label_marker_height/2.0); 
  
-                label_marker_rect.minx = MS_NINT(cachePtr->point.x - .5 * label_marker_width) - labelPtr->buffer; 
-                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; 
+                label_marker_rect.minx = (cachePtr->point.x - label_marker_offset_x + t_marker_offset_x ) - labelPtr->buffer; 
+                label_marker_rect.miny = (cachePtr->point.y - label_marker_offset_y + t_marker_offset_y ) - labelPtr->buffer; 
+                label_marker_rect.maxx = (cachePtr->point.x + label_marker_offset_x + t_marker_offset_x ) + labelPtr->buffer; // marker_rect.minx + (marker_width-1) + labelPtr->buffer; 
+                label_marker_rect.maxy = (cachePtr->point.y + label_marker_offset_y + t_marker_offset_y ) + labelPtr->buffer; // marker_rect.miny + (marker_height-1) + labelPtr->buffer; 
               }
               
-              if(drawLabelText && labelPtr->position == MS_AUTO) {
+              if(labelPtr->position == MS_AUTO) {
                 int positions[MS_POSITIONS_LENGTH], npositions=0;
    
                 /*
@@ -2959,7 +2976,7 @@
               msDrawText(image, labelPtr->annopoint, labelPtr->annotext, labelPtr, &(map->fontset), layerPtr->scalefactor); /* actually draw the label */
             }
 
-            /*
+           /* 
             styleObj tstyle;
             static int foo =0;
             if(!foo) {

Modified: sandbox/tb-labels/maplabel.c
===================================================================
--- sandbox/tb-labels/maplabel.c	2012-02-23 19:25:10 UTC (rev 13171)
+++ sandbox/tb-labels/maplabel.c	2012-02-24 15:59:16 UTC (rev 13172)
@@ -417,7 +417,7 @@
      /* TO DO: at the moment only checks the bottom style, perhaps should check all of them */
      /* #2347: after RFC-24 classPtr->styles could be NULL so we check it */
      rectObj rect;
-     int w, h;
+     double w, h;
      if(msGetMarkerSize(&map->symbolset, classPtr->styles[0], &w, &h, layerPtr->scalefactor) != MS_SUCCESS) 
         return(MS_FAILURE);
 
@@ -432,8 +432,8 @@
      cacheslot->markers[i].poly = (shapeObj *) msSmallMalloc(sizeof(shapeObj));
      msInitShape(cacheslot->markers[i].poly);
 
-     rect.minx = MS_NINT(point->x - .5 * w);
-     rect.miny = MS_NINT(point->y - .5 * h);
+     rect.minx = (point->x - .5 * w);
+     rect.miny = (point->y - .5 * h);
      rect.maxx = rect.minx + (w-1);
      rect.maxy = rect.miny + (h-1);
      msRectToPolygon(rect, cacheslot->markers[i].poly);    
@@ -591,7 +591,7 @@
 
   if(layerPtr->type == MS_LAYER_POINT) { /* cache the marker placement, it's already on the map */
     rectObj rect;
-    int w, h;
+    double w, h;
 
     if(cacheslot->nummarkers == cacheslot->markercachesize) { /* just add it to the end */
       cacheslot->markers = (markerCacheMemberObj *) realloc(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT));
@@ -667,7 +667,7 @@
                                 labelCacheMemberObj *cachePtr, int current_priority, 
                                 int current_label, int mindistance, double label_size)
 {
-  int i, p;
+  int i, p, ll, pp;
   labelCacheMemberObj *curCachePtr=NULL; 
 
   /* Check against image bounds first 
@@ -737,7 +737,17 @@
            /* our poly against rendered leader lines */
            /* first do a bbox check */
            if(msRectOverlap(curCachePtr->leaderbbox, &(cachePtr->poly->bounds))) {
-              return MS_FALSE;
+              /* look for intersecting line segments */
+              for(ll=0; ll<cachePtr->poly->numlines; ll++)
+                 for(pp=1; pp<cachePtr->poly->line[ll].numpoints; pp++)
+                    if(msIntersectSegments(
+                             &(cachePtr->poly->line[ll].point[pp-1]),
+                             &(cachePtr->poly->line[ll].point[pp]),
+                             &(curCachePtr->leaderline->point[0]),
+                             &(curCachePtr->leaderline->point[1])) ==  MS_TRUE)
+                    {
+                       return(MS_FALSE);
+                    }
            }
 
         }
@@ -745,7 +755,18 @@
            /* does our leader intersect current label */
            /* first do a bbox check */
            if(msRectOverlap(cachePtr->leaderbbox, &(curCachePtr->poly->bounds))) {
-              return MS_FALSE;
+              /* 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) {
               /* check intersection of leader lines ? */

Modified: sandbox/tb-labels/maprendering.c
===================================================================
--- sandbox/tb-labels/maprendering.c	2012-02-23 19:25:10 UTC (rev 13171)
+++ sandbox/tb-labels/maprendering.c	2012-02-24 15:59:16 UTC (rev 13172)
@@ -877,7 +877,7 @@
 	 p_y +=  style->offsety * scalefactor;
 
          if(symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) {
-            int sx,sy;
+            double sx,sy;
             double ox, oy;
             msGetMarkerSize(symbolset, style, &sx, &sy, scalefactor);
             ox = (0.5 - symbol->anchorpoint_x) * sx;

Modified: sandbox/tb-labels/mapserver.h
===================================================================
--- sandbox/tb-labels/mapserver.h	2012-02-23 19:25:10 UTC (rev 13171)
+++ sandbox/tb-labels/mapserver.h	2012-02-24 15:59:16 UTC (rev 13172)
@@ -2011,7 +2011,7 @@
 MS_DLL_EXPORT imageObj *msSymbolGetImageGD(symbolObj *symbol, outputFormatObj *format);
 MS_DLL_EXPORT int msSymbolSetImageGD(symbolObj *symbol, imageObj *image);
 
-MS_DLL_EXPORT int msGetMarkerSize(symbolSetObj *symbolset, styleObj *style, int *width, int *height, double scalefactor);
+MS_DLL_EXPORT int msGetMarkerSize(symbolSetObj *symbolset, styleObj *style, double *width, double *height, double scalefactor);
 /* MS_DLL_EXPORT int msGetCharacterSize(char *character, int size, char *font, rectObj *rect); */
 MS_DLL_EXPORT double msSymbolGetDefaultSize(symbolObj *s);
 MS_DLL_EXPORT void freeImageCache(struct imageCacheObj *ic);

Modified: sandbox/tb-labels/mapsymbol.c
===================================================================
--- sandbox/tb-labels/mapsymbol.c	2012-02-23 19:25:10 UTC (rev 13171)
+++ sandbox/tb-labels/mapsymbol.c	2012-02-24 15:59:16 UTC (rev 13172)
@@ -643,7 +643,7 @@
 ** layer collision avoidance. A marker is made up of a number of styles so the calling code must either do the looping
 ** itself or call this function for the bottom style which should be the largest.
 */
-int msGetMarkerSize(symbolSetObj *symbolset, styleObj *style, int *width, int *height, double scalefactor)
+int msGetMarkerSize(symbolSetObj *symbolset, styleObj *style, double *width, double *height, double scalefactor)
 {  
   rectObj rect;
   int size;
@@ -660,10 +660,10 @@
   
   symbol = symbolset->symbol[style->symbol];
   if(style->size == -1) {
-      size = MS_NINT( msSymbolGetDefaultSize(symbol) * scalefactor );
+      size = ( msSymbolGetDefaultSize(symbol) * scalefactor );
   }
   else
-      size = MS_NINT(style->size*scalefactor);
+      size = (style->size*scalefactor);
   size = MS_MAX(size, style->minsize);
   size = MS_MIN(size, style->maxsize);
 
@@ -674,8 +674,8 @@
     if(msGetTruetypeTextBBox(MS_MAP_RENDERER(symbolset->map),symbol->font,symbolset->fontset,size,symbol->character,&rect,NULL) != MS_SUCCESS) 
       return(MS_FAILURE);
 
-    *width = (int) MS_MAX(*width, rect.maxx - rect.minx);
-    *height = (int) MS_MAX(*height, rect.maxy - rect.miny);
+    *width = MS_MAX(*width, rect.maxx - rect.minx);
+    *height = MS_MAX(*height, rect.maxy - rect.miny);
 
     break;
 #endif
@@ -689,17 +689,17 @@
       *width = MS_MAX(*width, symbol->pixmap_buffer->width);
       *height = MS_MAX(*height, symbol->pixmap_buffer->height);
     } else {
-      *width = MS_MAX(*width, MS_NINT((size/symbol->pixmap_buffer->height) * symbol->pixmap_buffer->width));
+      *width = MS_MAX(*width, ((size/symbol->pixmap_buffer->height) * symbol->pixmap_buffer->width));
       *height = MS_MAX(*height, size);
     }
     break;
   default: /* vector and ellipses, scalable */
     if(style->size > 0) {
-      *width = MS_MAX(*width, MS_NINT((size/symbol->sizey) * symbol->sizex));
+      *width = MS_MAX(*width, ((size/symbol->sizey) * symbol->sizex));
       *height = MS_MAX(*height, size);
     } else { /* use symbol defaults */
-      *width = (int) MS_MAX(*width, symbol->sizex);
-      *height = (int) MS_MAX(*height, symbol->sizey);
+      *width = MS_MAX(*width, symbol->sizex);
+      *height = MS_MAX(*height, symbol->sizey);
     }
     break;
   }  



More information about the mapserver-commits mailing list