[mapserver-commits] r8453 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Sun Jan 25 12:10:04 EST 2009


Author: tbonfort
Date: 2009-01-25 12:10:04 -0500 (Sun, 25 Jan 2009)
New Revision: 8453

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/mapdraw.c
   trunk/mapserver/mapfile.c
   trunk/mapserver/maplabel.c
   trunk/mapserver/mapserver.h
Log:
RFC 49 implementation (#2865)

Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2009-01-23 20:08:00 UTC (rev 8452)
+++ trunk/mapserver/HISTORY.TXT	2009-01-25 17:10:04 UTC (rev 8453)
@@ -11,6 +11,7 @@
 
 Current Version (5.3-dev, SVN trunk):
 ------------------------------------
+- RFC49 implementation (#2865)
 
 - Fixed Blobs not filtered in OracleSpatial Attribute/WFS queries (#2829)
 

Modified: trunk/mapserver/mapdraw.c
===================================================================
--- trunk/mapserver/mapdraw.c	2009-01-23 20:08:00 UTC (rev 8452)
+++ trunk/mapserver/mapdraw.c	2009-01-25 17:10:04 UTC (rev 8453)
@@ -890,7 +890,7 @@
     }
   
     cache = MS_FALSE;
-    if(layer->type == MS_LAYER_LINE && layer->class[shape.classindex]->numstyles > 1) 
+    if(layer->type == MS_LAYER_LINE && (layer->class[shape.classindex]->numstyles > 1||layer->class[shape.classindex]->styles[0]->outlinewidth>0))
       cache = MS_TRUE; /* only line layers with multiple styles need be cached (I don't think POLYLINE layers need caching - SDL) */
          
     /* With 'STYLEITEM AUTO', we will have the datasource fill the class' */
@@ -908,8 +908,54 @@
     if(annotate && (layer->class[shape.classindex]->text.string || layer->labelitem) && layer->class[shape.classindex]->label.size != -1)
       shape.text = msShapeGetAnnotation(layer, &shape);
 
-    if(cache)
-      status = msDrawShape(map, layer, &shape, image, 0, MS_FALSE); /* draw only the first style */
+    if (cache) {
+        int i;
+        for (i = 0; i < layer->class[shape.classindex]->numstyles; i++) {
+            styleObj *pStyle = layer->class[shape.classindex]->styles[i];
+            colorObj tmp;
+            if (pStyle->outlinewidth > 0) {
+                /* 
+                 * RFC 49 implementation
+                 * if an outlinewidth is used:
+                 *  - augment the style's width to account for the outline width
+                 *  - swap the style color and outlinecolor
+                 *  - draw the shape (the outline) in the first pass of the
+                 *    caching mechanism
+                 */
+                
+                /* adapt width (must take scalefactor into account) */
+                pStyle->width += (pStyle->outlinewidth / layer->scalefactor) * 2;
+                pStyle->minwidth += pStyle->outlinewidth * 2;
+                pStyle->maxwidth += pStyle->outlinewidth * 2;
+                
+                /*swap color and outlinecolor*/
+                tmp = pStyle->color;
+                pStyle->color = pStyle->outlinecolor;
+                pStyle->outlinecolor = tmp;
+            }
+            if (i == 0 || pStyle->outlinewidth > 0) {
+                status = msDrawShape(map, layer, &shape, image, i, MS_TRUE); /* draw a single style */
+            }
+            if (pStyle->outlinewidth > 0) {
+                /*
+                 * RFC 49 implementation: switch back the styleobj to its
+                 * original state, so the line fill will be drawn in the
+                 * second pass of the caching mechanism
+                 */
+                
+                /* reset widths to original state */
+                pStyle->width -= (pStyle->outlinewidth / layer->scalefactor) * 2;
+                pStyle->minwidth -= pStyle->outlinewidth * 2;
+                pStyle->maxwidth -= pStyle->outlinewidth * 2;
+                
+                /*reswap colors to original state*/
+                tmp = pStyle->color;
+                pStyle->color = pStyle->outlinecolor;
+                pStyle->outlinecolor = tmp;
+            }
+        }
+    }
+
     else
       status = msDrawShape(map, layer, &shape, image, -1, MS_FALSE); /* all styles  */
     if(status != MS_SUCCESS) {
@@ -944,12 +990,23 @@
   
   if(shpcache) {
     int s;
-    for(s=1; s<maxnumstyles; s++) {
-      for(current=shpcache; current; current=current->next) {        
-        if(layer->class[current->shape.classindex]->numstyles > s &&
-            layer->class[current->shape.classindex]->styles[s]->_geomtransform==MS_GEOMTRANSFORM_NONE) {
-          msDrawLineSymbol(&map->symbolset, image, &current->shape, layer->class[current->shape.classindex]->styles[s], layer->scalefactor);
-       }
+    for(s=0; s<maxnumstyles; s++) {
+      for(current=shpcache; current; current=current->next) {
+        if(layer->class[current->shape.classindex]->numstyles > s) {
+          styleObj *pStyle = layer->class[current->shape.classindex]->styles[s];
+          if(pStyle->_geomtransform!=MS_GEOMTRANSFORM_NONE)
+        	continue; /*skip this as it has already been rendered*/
+          if(map->scaledenom > 0) {
+            if((pStyle->maxscaledenom != -1) && (map->scaledenom >= pStyle->maxscaledenom))
+              continue;
+            if((pStyle->minscaledenom != -1) && (map->scaledenom < pStyle->minscaledenom))
+              continue;
+          }
+          if(s==0 && pStyle->outlinewidth>0) {
+            msDrawLineSymbol(&map->symbolset, image, &current->shape, pStyle, layer->scalefactor);  
+          } else if(s>0)
+            msDrawLineSymbol(&map->symbolset, image, &current->shape, pStyle, layer->scalefactor);
+        }
       }
     }
     
@@ -1134,8 +1191,16 @@
   
     for(s=1; s<maxnumstyles; s++) {
       for(current=shpcache; current; current=current->next) {        
-        if(layer->class[current->shape.classindex]->numstyles > s)
-	  msDrawLineSymbol(&map->symbolset, image, &current->shape, (layer->class[current->shape.classindex]->styles[s]), layer->scalefactor);
+        if(layer->class[current->shape.classindex]->numstyles > s) {
+          styleObj *curStyle = layer->class[current->shape.classindex]->styles[s];
+          if(map->scaledenom > 0) {
+            if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+              continue;
+            if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+              continue;
+          }
+	      msDrawLineSymbol(&map->symbolset, image, &current->shape, (layer->class[current->shape.classindex]->styles[s]), layer->scalefactor);
+        }
       }
     }
     
@@ -1353,7 +1418,6 @@
   if(shape->text && (layer->class[c]->label.encoding || layer->class[c]->label.wrap
           ||layer->class[c]->label.maxlength)) {
       char *newtext=msTransformLabelText(map,image,&(layer->class[c]->label),shape->text);
-      if(!newtext) return MS_FAILURE;
       free(shape->text);
       shape->text = newtext;
   }
@@ -1382,11 +1446,15 @@
       msOffsetPointRelativeTo(&center, layer);
 
     /* shade symbol drawing will call outline function if color not set */
-    if(style != -1)
-      msCircleDrawShadeSymbol(&map->symbolset, image, &center, r, (layer->class[c]->styles[style]), layer->scalefactor);
-    else {
-      for(s=0; s<layer->class[c]->numstyles; s++)
-        msCircleDrawShadeSymbol(&map->symbolset, image, &center, r, (layer->class[c]->styles[s]), layer->scalefactor);
+    for(s=0; s<layer->class[c]->numstyles; s++) {
+      styleObj *curStyle = layer->class[c]->styles[s];
+      if(map->scaledenom > 0) {
+        if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+          continue;
+        if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+          continue;
+      }
+      msCircleDrawShadeSymbol(&map->symbolset, image, &center, r, curStyle, layer->scalefactor);
     }
 
     /* TO DO: need to handle circle annotation */
@@ -1479,8 +1547,16 @@
             if(msAddLabel(map, layer->index, c, shape->index, shape->tileindex, &annopnt, NULL, shape->text, length, &label) != MS_SUCCESS) return(MS_FAILURE);
 	  } else {
             if(layer->class[c]->numstyles > 0 && MS_VALID_COLOR(layer->class[c]->styles[0]->color)) {
-              for(s=0; s<layer->class[c]->numstyles; s++)
-                msDrawMarkerSymbol(&map->symbolset, image, &annopnt, (layer->class[c]->styles[s]), layer->scalefactor);
+              for(s=0; s<layer->class[c]->numstyles; s++) {
+                styleObj *curStyle = layer->class[c]->styles[s];
+                if(map->scaledenom > 0) {
+                  if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+                    continue;
+                  if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+                    continue;
+                }
+                msDrawMarkerSymbol(&map->symbolset, image, &annopnt, curStyle, layer->scalefactor);
+              }
 	    }
 	    msDrawLabel(map, image, annopnt, shape->text, &label, layer->scalefactor);
           }
@@ -1515,8 +1591,16 @@
           if(msAddLabel(map, layer->index, c, shape->index, shape->tileindex, &annopnt, NULL, shape->text, MS_MIN(shape->bounds.maxx-shape->bounds.minx,shape->bounds.maxy-shape->bounds.miny), &label) != MS_SUCCESS) return(MS_FAILURE);
         } else {
 	  if(layer->class[c]->numstyles > 0 && MS_VALID_COLOR(layer->class[c]->styles[0]->color)) {
-            for(s=0; s<layer->class[c]->numstyles; s++)
-	      msDrawMarkerSymbol(&map->symbolset, image, &annopnt, (layer->class[c]->styles[s]), layer->scalefactor);
+        for(s=0; s<layer->class[c]->numstyles; s++) {
+          styleObj *curStyle = layer->class[c]->styles[s];
+          if(map->scaledenom > 0) {
+            if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+              continue;
+            if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+              continue;
+          }
+	      msDrawMarkerSymbol(&map->symbolset, image, &annopnt, curStyle, layer->scalefactor);
+        }
 	  }
 	  msDrawLabel(map, image, annopnt, shape->text, &label, layer->scalefactor);
         }
@@ -1544,8 +1628,16 @@
 	      if(msAddLabel(map, layer->index, c, shape->index, shape->tileindex, point, NULL, shape->text, -1, &label) != MS_SUCCESS) return(MS_FAILURE);
 	    } else {
 	      if(layer->class[c]->numstyles > 0 && MS_VALID_COLOR(layer->class[c]->styles[0]->color)) {
-                for(s=0; s<layer->class[c]->numstyles; s++)
-	          msDrawMarkerSymbol(&map->symbolset, image, point, (layer->class[c]->styles[s]), layer->scalefactor);
+            for(s=0; s<layer->class[c]->numstyles; s++) {
+              styleObj *curStyle = layer->class[c]->styles[s];
+              if(map->scaledenom > 0) {
+                if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+                  continue;
+                if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+                  continue;
+              }
+	          msDrawMarkerSymbol(&map->symbolset, image, point, curStyle, layer->scalefactor);
+            }
 	      }
 	      msDrawLabel(map, image, *point, shape->text, &label, layer->scalefactor);
 	    }
@@ -1575,8 +1667,16 @@
 	} else
           msOffsetPointRelativeTo(point, layer);
 
-	for(s=0; s<layer->class[c]->numstyles; s++)
-  	  msDrawMarkerSymbol(&map->symbolset, image, point, (layer->class[c]->styles[s]), layer->scalefactor);
+  for(s=0; s<layer->class[c]->numstyles; s++) {
+    styleObj *curStyle = layer->class[c]->styles[s];
+    if(map->scaledenom > 0) {
+      if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+        continue;
+      if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+        continue;
+    }
+    msDrawMarkerSymbol(&map->symbolset, image, point, (layer->class[c]->styles[s]), layer->scalefactor);
+  }
 
 	if(shape->text) {
           labelObj label = layer->class[c]->label;
@@ -1650,17 +1750,25 @@
         msTransformShape(&nonClippedShape, map->extent, map->cellsize, image);
     } else {
       msOffsetShapeRelativeTo(shape, layer);
-      if(hasGeomTransform)
-        msOffsetShapeRelativeTo(&nonClippedShape, layer);
     }
     
+	if(hasGeomTransform)
+      msOffsetShapeRelativeTo(&nonClippedShape, layer);
+	
     /*RFC48: loop through the styles, and pass off to the type-specific
     function if the style has an appropriate type*/
     for(s=0; s<layer->class[c]->numstyles; s++) {
-        if(layer->class[c]->styles[s]->_geomtransform != MS_GEOMTRANSFORM_NONE)
-          msDrawTransformedShape(map, &map->symbolset, image, &nonClippedShape, (layer->class[c]->styles[s]), layer->scalefactor);
-        else if(style==-1 || s==style)
-          msDrawLineSymbol(&map->symbolset, image, shape, (layer->class[c]->styles[s]), layer->scalefactor);
+      styleObj *curStyle = layer->class[c]->styles[s];
+      if(map->scaledenom > 0) {
+        if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+          continue;
+        if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+          continue;
+      }
+      if(curStyle->_geomtransform != MS_GEOMTRANSFORM_NONE)
+        msDrawTransformedShape(map, &map->symbolset, image, &nonClippedShape, curStyle, layer->scalefactor);
+      else if(style==-1 || s==style)
+        msDrawLineSymbol(&map->symbolset, image, shape, curStyle, layer->scalefactor);
     }
     
     /*RFC48: free non clipped shape if it was previously alloced/used*/
@@ -1778,13 +1886,22 @@
         msTransformShape(&nonClippedShape, map->extent, map->cellsize, image);
     }
  
-    for(s=0; s<layer->class[c]->numstyles; s++)
-      if(layer->class[c]->styles[s]->_geomtransform != MS_GEOMTRANSFORM_NONE)
-        msDrawTransformedShape(map, &map->symbolset, image, &nonClippedShape, (layer->class[c]->styles[s]), layer->scalefactor);
+    for(s=0; s<layer->class[c]->numstyles; s++) {
+      styleObj *curStyle = layer->class[c]->styles[s];
+      if(map->scaledenom > 0) {
+        if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+          continue;
+        if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+          continue;
+      }
+      if(curStyle->_geomtransform==MS_GEOMTRANSFORM_NONE)
+    	msDrawShadeSymbol(&map->symbolset, image, shape, curStyle, layer->scalefactor);
       else
-        msDrawShadeSymbol(&map->symbolset, image, shape, (layer->class[c]->styles[s]), layer->scalefactor);
-    if(hasGeomTransform)
+    	msDrawTransformedShape(map, &map->symbolset, image, &nonClippedShape, curStyle, layer->scalefactor);
+    }
+	if(hasGeomTransform)
       msFreeShape(&nonClippedShape);
+
     if(shape->text) {
       if((bLabelNoClip == MS_TRUE && annocallret == MS_SUCCESS) ||
          (msPolygonLabelPoint(shape, &annopnt, layer->class[c]->label.minfeaturesize) == MS_SUCCESS)) {
@@ -1847,8 +1964,16 @@
         if(msAddLabel(map, layer->index, classindex, -1, -1, point, NULL, newtext, -1,NULL) != MS_SUCCESS) return(MS_FAILURE);
       } else {
 	if(theclass->numstyles > 0 && MS_VALID_COLOR(theclass->styles[0]->color)) {
-          for(s=0; s<theclass->numstyles; s++)
-  	    msDrawMarkerSymbol(&map->symbolset, image, point, (theclass->styles[s]), layer->scalefactor);
+      for(s=0; s<theclass->numstyles; s++) {
+        styleObj *curStyle = theclass->styles[s];
+        if(map->scaledenom > 0) {
+        if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+          continue;
+        if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+          continue;
+        }
+  	    msDrawMarkerSymbol(&map->symbolset, image, point, (curStyle), layer->scalefactor);
+      }
 	}
 	msDrawLabel(map, image, *point, newtext, label, layer->scalefactor);
       }
@@ -1863,9 +1988,16 @@
     } else
       msOffsetPointRelativeTo(point, layer);
 
-    for(s=0; s<theclass->numstyles; s++)
-      msDrawMarkerSymbol(&map->symbolset, image, point, (theclass->styles[s]), layer->scalefactor);
-
+    for(s=0; s<theclass->numstyles; s++) {
+      styleObj *curStyle = theclass->styles[s];
+      if(map->scaledenom > 0) {
+        if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+          continue;
+        if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+          continue;
+      }
+      msDrawMarkerSymbol(&map->symbolset, image, point, (curStyle), layer->scalefactor);
+    }
     if(labeltext) {
       if(layer->labelcache) {
         if(msAddLabel(map, layer->index, classindex, -1, -1, point, NULL, newtext, -1,NULL) != MS_SUCCESS) return(MS_FAILURE);

Modified: trunk/mapserver/mapfile.c
===================================================================
--- trunk/mapserver/mapfile.c	2009-01-23 20:08:00 UTC (rev 8452)
+++ trunk/mapserver/mapfile.c	2009-01-25 17:10:04 UTC (rev 8453)
@@ -1206,7 +1206,8 @@
   label->maxsize = MS_MAXFONTSIZE;
   label->buffer = 0;
   label->offsetx = label->offsety = 0;
-
+  label->minscaledenom=-1;
+  label->maxscaledenom=-1;
   label->minfeaturesize = -1; /* no limit */
   label->autominfeaturesize = MS_FALSE;
   label->mindistance = -1; /* no limit */
@@ -1329,6 +1330,9 @@
     case(MAXSIZE):      
       if(getInteger(&(label->maxsize)) == -1) return(-1);
       break;
+    case(MAXSCALEDENOM):
+      if(getDouble(&(label->maxscaledenom)) == -1) return(-1);
+      break;
     case(MAXLENGTH):
       if(getInteger(&(label->maxlength)) == -1) return(-1);
       break;
@@ -1347,6 +1351,9 @@
       else
 	label->autominfeaturesize = MS_TRUE;
       break;
+    case(MINSCALEDENOM):
+      if(getDouble(&(label->minscaledenom)) == -1) return(-1);
+      break;
     case(MINSIZE):
       if(getInteger(&(label->minsize)) == -1) return(-1);
       break;
@@ -1375,7 +1382,7 @@
         label->priority = (int) msyynumber;
         if(label->priority < 1 || label->priority > MS_MAX_LABEL_PRIORITY) {
             msSetError(MS_MISCERR, "Invalid PRIORITY, must be an integer between 1 and %d." , 
-                       "loadStyle()", MS_MAX_LABEL_PRIORITY);
+                       "loadLabel()", MS_MAX_LABEL_PRIORITY);
             return(-1);
         }
       } else {
@@ -1765,8 +1772,10 @@
   style->minsize = MS_MINSYMBOLSIZE;
   style->maxsize = MS_MAXSYMBOLSIZE;
   style->width = 1; /* in pixels */
+  style->outlinewidth = 0; /* in pixels */
   style->minwidth = MS_MINSYMBOLWIDTH;
   style->maxwidth = MS_MAXSYMBOLWIDTH;
+  style->minscaledenom=style->maxscaledenom = -1.0;
   style->offsetx = style->offsety = 0; /* no offset */
   style->antialias = MS_FALSE;
   style->angle = 360;
@@ -1843,6 +1852,12 @@
     case(END):     
       return(MS_SUCCESS); /* done */
       break;
+    case(MAXSCALEDENOM):
+      if(getDouble(&(style->maxscaledenom)) == -1) return(MS_FAILURE);
+      break;
+    case(MINSCALEDENOM):
+      if(getDouble(&(style->minscaledenom)) == -1) return(MS_FAILURE);
+      break;
     case(GEOMTRANSFORM):
       {
         char *expr=NULL;
@@ -1874,6 +1889,13 @@
       if(loadColor(&(style->outlinecolor), &(style->bindings[MS_STYLE_BINDING_OUTLINECOLOR])) != MS_SUCCESS) return(MS_FAILURE);
       if(style->bindings[MS_STYLE_BINDING_OUTLINECOLOR].item) style->numbindings++;
       break;
+    case(OUTLINEWIDTH):
+      if(getDouble(&(style->outlinewidth)) == -1) return(MS_FAILURE);
+      if(style->outlinewidth < 0) {
+          msSetError(MS_MISCERR, "Invalid WIDTH, must be greater than 0" , "loadStyle()");
+          return(MS_FAILURE);
+      }
+      break;
     case(SIZE):
       if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE);
       if(symbol == MS_NUMBER)

Modified: trunk/mapserver/maplabel.c
===================================================================
--- trunk/mapserver/maplabel.c	2009-01-23 20:08:00 UTC (rev 8452)
+++ trunk/mapserver/maplabel.c	2009-01-25 17:10:04 UTC (rev 8453)
@@ -318,6 +318,12 @@
   classObj *classPtr=NULL;
 
   if(!string) return(MS_SUCCESS); /* not an error */ 
+  if(map->scaledenom > 0) {
+    if((label->maxscaledenom != -1) && (map->scaledenom >= label->maxscaledenom))
+        return(MS_SUCCESS);
+    if((label->minscaledenom != -1) && (map->scaledenom < label->minscaledenom))
+        return(MS_SUCCESS);
+  }
 
   layerPtr = (GET_LAYER(map, layerindex)); /* set up a few pointers for clarity */
   classPtr = GET_LAYER(map, layerindex)->class[classindex];

Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h	2009-01-23 20:08:00 UTC (rev 8452)
+++ trunk/mapserver/mapserver.h	2009-01-25 17:10:04 UTC (rev 8453)
@@ -616,6 +616,8 @@
   int minfeaturesize; /* minimum feature size (in pixels) to label */
   int autominfeaturesize; /* true or false */
 
+  double minscaledenom,maxscaledenom;
+  
   int mindistance;
   int partials; /* can labels run of an image */
 
@@ -721,6 +723,7 @@
   double minsize, maxsize;
 
   double width;
+  double outlinewidth;
   double minwidth, maxwidth;
 
   int offsetx, offsety; /* for shadows, hollow symbols, etc... */
@@ -729,6 +732,8 @@
 
   int antialias;
 
+  double minscaledenom, maxscaledenom;
+
 #ifndef SWIG
   attributeBindingObj bindings[MS_STYLE_BINDING_LENGTH];
   int numbindings;



More information about the mapserver-commits mailing list