[mapserver-commits] r12911 - branches/branch-6-0/mapserver

svn at osgeo.org svn at osgeo.org
Fri Dec 23 10:03:11 EST 2011


Author: sdlime
Date: 2011-12-23 07:03:11 -0800 (Fri, 23 Dec 2011)
New Revision: 12911

Modified:
   branches/branch-6-0/mapserver/HISTORY.TXT
   branches/branch-6-0/mapserver/mapdraw.c
   branches/branch-6-0/mapserver/maplabel.c
   branches/branch-6-0/mapserver/mapserver.h
Log:
Several fixes to deal with issues regarding labels/styles and clipping with tiling (see HISTORY.TXT). Adresses tickets #4133, #3303 and #1355.

Modified: branches/branch-6-0/mapserver/HISTORY.TXT
===================================================================
--- branches/branch-6-0/mapserver/HISTORY.TXT	2011-12-23 11:43:56 UTC (rev 12910)
+++ branches/branch-6-0/mapserver/HISTORY.TXT	2011-12-23 15:03:11 UTC (rev 12911)
@@ -15,6 +15,14 @@
 Current Version (future 6.0.2, SVN branch-6-0):
 ---------------------------
 
+- Fixed a problem with calls to labelInImage() (maplabel.c) when label gutter
+  and label buffers are both used (#3303). Also changed the usage around that
+  function to make it easier to understand. At a result the
+  "labelcache_map_edge_buffer" processing option (i.e. gutter) can be provided
+  as a positive or negative value. (closes #1355 too)
+
+- Added label->style markers to collision detection (#4133)
+
 - Fixed single pixel coverages in WCS 2.0 (#4110)
 
 - Fixed subsetting in WCS 2.0 (#4099)

Modified: branches/branch-6-0/mapserver/mapdraw.c
===================================================================
--- branches/branch-6-0/mapserver/mapdraw.c	2011-12-23 11:43:56 UTC (rev 12910)
+++ branches/branch-6-0/mapserver/mapdraw.c	2011-12-23 15:03:11 UTC (rev 12911)
@@ -2395,6 +2395,7 @@
 int msDrawLabelCache(imageObj *image, mapObj *map)
 {
   int nReturnVal = MS_SUCCESS;
+
   if(image) {
     if(MS_RENDERER_PLUGIN(image->format)) {          
       pointObj p;
@@ -2429,7 +2430,7 @@
        * map image where labels can't fall
        */
       if((value = msLookupHashTable(&(map->web.metadata), "labelcache_map_edge_buffer")) != NULL) {
-        map_edge_buffer = atoi(value);
+        map_edge_buffer = MS_ABS(atoi(value));
         if(map->debug) msDebug("msDrawLabelCache(): labelcache_map_edge_buffer = %d\n", map_edge_buffer);
       }
 
@@ -2461,7 +2462,7 @@
               msRectToPolygon(marker_rect, cachePtr->poly);
                  
               if(!labelPtr->force)
-                msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, label_buffer + map_edge_buffer, cachePtr, priority, l, label_mindistance, 0);
+                msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, 0);
                  
               if(cachePtr->status == MS_FALSE)
                 continue;
@@ -2486,6 +2487,7 @@
               }
             }
           } else {
+
             if(labelPtr->type == MS_TRUETYPE) {
               size = labelPtr->size * layerPtr->scalefactor;
               size = MS_MAX(size, labelPtr->minsize*image->resolutionfactor);
@@ -2493,7 +2495,7 @@
               scalefactor = size / labelPtr->size;
             } else {
               size = labelPtr->size;
-              scalefactor = 1;
+              scalefactor = 1; /* can't scale bitmap fonts */
             }
             if(msGetLabelSize(map,labelPtr,cachePtr->text,size,&r,NULL) != MS_SUCCESS)
               return MS_FAILURE;
@@ -2532,6 +2534,7 @@
               continue; /* label too large relative to the feature */
    
             marker_offset_x = marker_offset_y = 0; /* assume no marker */
+            marker_width = marker_height = 0;
             if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0) { /* there might be a marker added to the image */
    
               /* TODO: at the moment only checks the bottom (first) marker style, perhaps should check all of them */
@@ -2553,6 +2556,33 @@
               marker_offset_y = MS_NINT(marker_height/2.0);
             }
 
+            /* TODO: might need this in the no text/empty text section above */
+            if(labelPtr->numstyles > 0) {
+              int temp_marker_width, temp_marker_height;
+
+	      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], &temp_marker_width, &temp_marker_height, layerPtr->scalefactor) != MS_SUCCESS)
+		    return MS_FAILURE;
+                  break;
+		}
+	      }
+
+	      if(temp_marker_width > marker_width || temp_marker_height > marker_height) {
+                marker_width = temp_marker_width;
+		marker_height = temp_marker_height;
+
+		marker_offset_x = MS_NINT(marker_width/2.0);
+		marker_offset_y = MS_NINT(marker_height/2.0);
+
+		marker_rect.minx = MS_NINT(cachePtr->point.x - .5 * marker_width) - labelPtr->buffer;
+		marker_rect.miny = MS_NINT(cachePtr->point.y - .5 * marker_height) - labelPtr->buffer;
+		marker_rect.maxx = MS_NINT(cachePtr->point.x + .5 * marker_width) + labelPtr->buffer; // marker_rect.minx + (marker_width-1) + labelPtr->buffer;
+		marker_rect.maxy = MS_NINT(cachePtr->point.y + .5 * marker_height) + labelPtr->buffer; // marker_rect.miny + (marker_height-1) + labelPtr->buffer;
+	      }
+            }
+
             /* handle path following labels first (position does not matter) */
             if(cachePtr->labelpath) {
               cachePtr->status = MS_TRUE;
@@ -2563,9 +2593,9 @@
    
               /* Compare against image bounds, rendered labels and markers (sets cachePtr->status), if FORCE=TRUE then skip it */
               if(!labelPtr->force)
-                msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, label_buffer + map_edge_buffer, cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+                msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
             } else {
-   
+
               if(labelPtr->position == MS_AUTO) {
                 int positions[MS_POSITIONS_LENGTH], npositions=0;
    
@@ -2589,11 +2619,12 @@
                   cachePtr->status = MS_TRUE; /* assume label *can* be drawn */
    
                   p = get_metrics(&(cachePtr->point), positions[i], r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, label_buffer, cachePtr->poly);
-                  if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0)
+
+                  if(marker_width > 0 && marker_height > 0)
                     msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon */
    
                   /* Compare against image bounds, rendered labels and markers (sets cachePtr->status) */
-                  msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, label_buffer + map_edge_buffer, cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
+                  msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));
 
                   /* found a suitable place for this label */
                   if(cachePtr->status) {
@@ -2621,18 +2652,18 @@
                   if(drawLabelPoly) get_metrics_line(&(cachePtr->point), labelPtr->position, r, (marker_offset_x + label_offset_x), (marker_offset_y + label_offset_y), labelPtr->angle, 1, labelPoly.line);
                 }
 
-                if(layerPtr->type == MS_LAYER_ANNOTATION && cachePtr->numstyles > 0)
+                if(marker_width > 0 && marker_height > 0)
                   msRectToPolygon(marker_rect, cachePtr->poly); /* save marker bounding polygon, part of overlap tests (TODO: might need to do something similar with label styles?) */
 
                 /* Compare against image bounds, rendered labels and markers (sets cachePtr->status), if FORCE=TRUE then skip the test */
                 if(!labelPtr->force)
-                  msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, label_buffer + map_edge_buffer, cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));  
+                  msTestLabelCacheCollisions(&(map->labelcache), labelPtr, image->width, image->height, (map_edge_buffer-label_buffer), cachePtr, priority, l, label_mindistance, (r.maxx-r.minx));  
               }
-            }
+            } /* end (not) POSITION FOLLOW/AUTO */
    
             if(!cachePtr->status)
               continue; /* next label */
-   
+
             /* here's where we draw the label styles */
             if(!cachePtr->labelpath && cachePtr->label.numstyles > 0) {
               for(i=0; i<cachePtr->label.numstyles; i++) {

Modified: branches/branch-6-0/mapserver/maplabel.c
===================================================================
--- branches/branch-6-0/mapserver/maplabel.c	2011-12-23 11:43:56 UTC (rev 12910)
+++ branches/branch-6-0/mapserver/maplabel.c	2011-12-23 15:03:11 UTC (rev 12911)
@@ -446,6 +446,28 @@
   return(MS_SUCCESS);
 }
 
+
+/*
+** Is a label completely in the image, reserving a gutter (in pixels) inside 
+** image for no labels (effectively making image larger. The gutter can be 
+** negative in cases where a label has a buffer around it.
+*/
+static int labelInImage(int width, int height, shapeObj *lpoly, int gutter)
+{
+  int i,j;
+
+  for(i=0; i<lpoly->numlines; i++) {
+    for(j=1; j<lpoly->line[i].numpoints; j++) {
+      if(lpoly->line[i].point[j].x < gutter) return(MS_FALSE);
+      if(lpoly->line[i].point[j].x >= width-gutter) return(MS_FALSE);
+      if(lpoly->line[i].point[j].y < gutter) return(MS_FALSE);
+      if(lpoly->line[i].point[j].y >= height-gutter) return(MS_FALSE);
+    }
+  }
+
+  return(MS_TRUE);
+}
+
 /* msTestLabelCacheCollisions()
 **
 ** Compares current label against labels already drawn and markers from cache and discards it
@@ -956,26 +978,6 @@
 }
 
 /*
-** is a label completely in the image (excluding label buffer)
-*/
-/* static int labelInImage(int width, int height, shapeObj *lpoly, int buffer) */
-int labelInImage(int width, int height, shapeObj *lpoly, int buffer)
-{
-  int i,j;
-
-  for(i=0; i<lpoly->numlines; i++) {
-    for(j=1; j<lpoly->line[i].numpoints; j++) {
-      if(lpoly->line[i].point[j].x < -buffer) return(MS_FALSE);
-      if(lpoly->line[i].point[j].x >= width+buffer) return(MS_FALSE);
-      if(lpoly->line[i].point[j].y < -buffer) return(MS_FALSE);
-      if(lpoly->line[i].point[j].y >= height+buffer) return(MS_FALSE);
-    }
-  }
-
-  return(MS_TRUE);
-}
-
-/*
 ** Variation on msIntersectPolygons. Label polygons aren't like shapefile polygons. They
 ** have no holes, and often do have overlapping parts (i.e. road symbols).
 */

Modified: branches/branch-6-0/mapserver/mapserver.h
===================================================================
--- branches/branch-6-0/mapserver/mapserver.h	2011-12-23 11:43:56 UTC (rev 12910)
+++ branches/branch-6-0/mapserver/mapserver.h	2011-12-23 15:03:11 UTC (rev 12911)
@@ -1733,7 +1733,6 @@
 MS_DLL_EXPORT int getClassIndex(layerObj *layer, char *str);
 
 /* For maplabel */
-int labelInImage(int width, int height, shapeObj *lpoly, int buffer);
 int intersectLabelPolygons(shapeObj *p1, shapeObj *p2);
 pointObj get_metrics_line(pointObj *p, int position, rectObj rect, int ox, int oy, double angle, int buffer, lineObj *poly);
 pointObj get_metrics(pointObj *p, int position, rectObj rect, int ox, int oy, double angle, int buffer, shapeObj *poly);



More information about the mapserver-commits mailing list