[mapserver-commits] r10998 - in trunk/mapserver: . mapscript/php mapscript/swiginc

svn at osgeo.org svn at osgeo.org
Fri Feb 18 10:51:47 EST 2011


Author: aboudreault
Date: 2011-02-18 07:51:47 -0800 (Fri, 18 Feb 2011)
New Revision: 10998

Modified:
   trunk/mapserver/mapdraw.c
   trunk/mapserver/mapogroutput.c
   trunk/mapserver/mapquery.c
   trunk/mapserver/mapscale.c
   trunk/mapserver/mapscript/php/class.c
   trunk/mapserver/mapscript/php/layer.c
   trunk/mapserver/mapscript/php/mapscript_i.c
   trunk/mapserver/mapscript/php/php_mapscript.h
   trunk/mapserver/mapscript/swiginc/layer.i
   trunk/mapserver/mapserver.h
   trunk/mapserver/maptemplate.c
   trunk/mapserver/maputil.c
Log:
Minfeaturesize in layer/class level support for draw and query

Modified: trunk/mapserver/mapdraw.c
===================================================================
--- trunk/mapserver/mapdraw.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapdraw.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -787,6 +787,7 @@
   featureListNodeObjPtr shpcache=NULL, current=NULL;
   int nclasses = 0;
   int *classgroup = NULL;
+  double minfeaturesize = -1;
 
 /* ==================================================================== */
 /*      For Flash, we use a metadata called SWFOUTPUT that              */
@@ -867,9 +868,22 @@
   if (layer->classgroup && layer->numclasses > 0)
       classgroup = msAllocateValidClassGroups(layer, &nclasses);
 
+  if (layer->minfeaturesize > 0)
+      minfeaturesize = Pix2LayerGeoref(map, layer, layer->minfeaturesize);
+  
   while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) {
 
-      shape.classindex = msShapeGetClass(layer, &shape, map->scaledenom, classgroup, nclasses);
+      /* Check if the shape size is ok to be drawn */
+      if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) && 
+          (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE))
+      {
+          if( layer->debug >= MS_DEBUGLEVEL_V )
+              msDebug("msDrawVectorLayer(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+          msFreeShape(&shape);
+          continue;
+      }
+      
+      shape.classindex = msShapeGetClass(layer, map, &shape, classgroup, nclasses);
     if((shape.classindex == -1) || (layer->class[shape.classindex]->status == MS_OFF)) {
        msFreeShape(&shape);
        continue;
@@ -1372,7 +1386,7 @@
   double r; /* circle radius */
   int csz; /* clip over size */
   double buffer;
-  int shapeMinfeaturesize = -1, labelMinfeaturesize;
+  int minfeaturesize;
   int numpaths = 1, numpoints = 1, numRegularLines = 0;
 
   labelPathObj **annopaths = NULL; /* Curved label path. Bug #1620 implementation */
@@ -1431,7 +1445,7 @@
   cliprect.miny = map->extent.miny - csz*map->cellsize;
   cliprect.maxx = map->extent.maxx + csz*map->cellsize;
   cliprect.maxy = map->extent.maxy + csz*map->cellsize;
-  labelMinfeaturesize = layer->class[c]->label.minfeaturesize*image->resolutionfactor;
+  minfeaturesize = layer->class[c]->label.minfeaturesize*image->resolutionfactor;
 
   if(msBindLayerToShape(layer, shape, querymapMode) != MS_SUCCESS)
     return MS_FAILURE; /* error message is set in msBindLayerToShape() */
@@ -1507,9 +1521,9 @@
         msTransformShape(&annoshape, map->extent, map->cellsize, image);
 
         if(layer->class[c]->label.anglemode == MS_FOLLOW ) {
-          annopaths = msPolylineLabelPath(map,image,&annoshape, labelMinfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
+          annopaths = msPolylineLabelPath(map,image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
         } else {
-            annopoints = msPolylineLabelPoint(&annoshape, labelMinfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
+            annopoints = msPolylineLabelPoint(&annoshape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
         }
         
         msFreeShape(&annoshape);
@@ -1538,7 +1552,7 @@
             free(regularLines);
             regularLines =  NULL;
           }
-          annopaths = msPolylineLabelPath(map,image,shape, labelMinfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
+          annopaths = msPolylineLabelPath(map,image,shape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
         }
 
         for (i = 0; i < numpaths; i++)
@@ -1573,7 +1587,7 @@
         if (numRegularLines > 0)
         {
 
-          annopoints = msPolylineLabelPointExtended(shape, labelMinfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, regularLines, numRegularLines, MS_FALSE);
+          annopoints = msPolylineLabelPointExtended(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, regularLines, numRegularLines, MS_FALSE);
           
           for (i = 0; i < numpoints; i++)
             {
@@ -1611,7 +1625,7 @@
               angles = NULL;
               lengths = NULL;
             }
-            annopoints = msPolylineLabelPoint(shape, labelMinfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
+            annopoints = msPolylineLabelPoint(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
           }
           
           for (i = 0; i < numpoints; i++) {
@@ -1675,8 +1689,8 @@
       /* No-clip labeling support */
       if(shape->text && msLayerGetProcessingKey(layer, "LABEL_NO_CLIP") != NULL) {
         bLabelNoClip = MS_TRUE;
-        if (labelMinfeaturesize > 0)
-          annocallret = msPolygonLabelPoint(shape, &annopnt, map->cellsize*labelMinfeaturesize);
+        if (minfeaturesize > 0)
+          annocallret = msPolygonLabelPoint(shape, &annopnt, map->cellsize*minfeaturesize);
         else
           annocallret = msPolygonLabelPoint(shape, &annopnt, -1);
 
@@ -1692,7 +1706,7 @@
 	msOffsetShapeRelativeTo(shape, layer);
 
       if ((bLabelNoClip == MS_TRUE && annocallret == MS_SUCCESS) ||
-          (msPolygonLabelPoint(shape, &annopnt, labelMinfeaturesize) == MS_SUCCESS)) {
+          (msPolygonLabelPoint(shape, &annopnt, minfeaturesize) == MS_SUCCESS)) {
         labelObj label = layer->class[c]->label;
 
         if(label.angle != 0)
@@ -1820,18 +1834,6 @@
       layer->project = MS_FALSE;
 #endif
 
-    if (layer->minfeaturesize > 0)
-        shapeMinfeaturesize = layer->minfeaturesize;
-    if (layer->class[c]->minfeaturesize > 0)
-        shapeMinfeaturesize = layer->class[c]->minfeaturesize;
-
-    if (shapeMinfeaturesize > 0) {
-        double dx = (shape->bounds.maxx-shape->bounds.minx);
-        double dy = (shape->bounds.maxy-shape->bounds.miny);
-        if (pow(shapeMinfeaturesize*image->resolutionfactor*map->cellsize,2.0) > (pow(dx,2.0)+pow(dy,2.0)))
-            return MS_SUCCESS;
-    }
-
     /* No-clip labeling support. For lines we copy the shape, though this is */
     /* inefficient. msPolylineLabelPath/msPolylineLabelPoint require that    */
     /* the shape is transformed prior to calling them                        */
@@ -1844,9 +1846,9 @@
       msTransformShape(&annoshape, map->extent, map->cellsize, image);
 
       if(layer->class[c]->label.anglemode == MS_FOLLOW) {
-        annopaths = msPolylineLabelPath(map,image,&annoshape, labelMinfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
+        annopaths = msPolylineLabelPath(map,image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
       } else {
-        annopoints = msPolylineLabelPoint(&annoshape, labelMinfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
+        annopoints = msPolylineLabelPoint(&annoshape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
       }
       msFreeShape(&annoshape);
     }
@@ -1920,7 +1922,7 @@
             free(regularLines);
             regularLines =  NULL;
           }
-          annopaths = msPolylineLabelPath(map,image,shape, labelMinfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
+          annopaths = msPolylineLabelPath(map,image,shape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
         }
 
         for (i = 0; i < numpaths; i++)
@@ -1946,7 +1948,7 @@
         if (numRegularLines > 0)
         {
 
-          annopoints = msPolylineLabelPointExtended(shape, labelMinfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, regularLines, numRegularLines, MS_FALSE);
+          annopoints = msPolylineLabelPointExtended(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, regularLines, numRegularLines, MS_FALSE);
           
           for (i = 0; i < numpoints; i++)
           {
@@ -1981,7 +1983,7 @@
             angles = NULL;
             lengths = NULL;
           }
-          annopoints = msPolylineLabelPoint(shape, labelMinfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
+          annopoints = msPolylineLabelPoint(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, layer->class[c]->label.anglemode);
         }
 
         for (i = 0; i < numpoints; i++) {
@@ -2049,23 +2051,11 @@
       layer->project = MS_FALSE;
 #endif
 
-    if (layer->minfeaturesize > 0)
-        shapeMinfeaturesize = layer->minfeaturesize;
-    if (layer->class[c]->minfeaturesize > 0)
-        shapeMinfeaturesize = layer->class[c]->minfeaturesize;
-    
-    if (shapeMinfeaturesize > 0) {
-        double dx = (shape->bounds.maxx-shape->bounds.minx);
-        double dy = (shape->bounds.maxy-shape->bounds.miny);
-        if (pow(shapeMinfeaturesize*image->resolutionfactor*map->cellsize,2.0) > (pow(dx,2.0)+pow(dy,2.0)))
-            return MS_SUCCESS;
-    }
-
     /* No-clip labeling support */
     if(shape->text && msLayerGetProcessingKey(layer, "LABEL_NO_CLIP") != NULL) {
       bLabelNoClip = MS_TRUE;
       if (layer->class[c]->label.minfeaturesize > 0)
-        annocallret = msPolygonLabelPoint(shape, &annopnt, map->cellsize*labelMinfeaturesize);
+        annocallret = msPolygonLabelPoint(shape, &annopnt, map->cellsize*minfeaturesize);
       else
         annocallret = msPolygonLabelPoint(shape, &annopnt, -1);
 
@@ -2121,16 +2111,16 @@
           continue;
       }
       if(curStyle->_geomtransform.type == MS_GEOMTRANSFORM_NONE)
-            msDrawShadeSymbol(&map->symbolset, image, shape, curStyle, layer->scalefactor); 
+    	msDrawShadeSymbol(&map->symbolset, image, shape, curStyle, layer->scalefactor);
       else
-          msDrawTransformedShape(map, &map->symbolset, image, &nonClippedShape, curStyle, layer->scalefactor);
+    	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, labelMinfeaturesize) == MS_SUCCESS)) {
+         (msPolygonLabelPoint(shape, &annopnt, minfeaturesize) == MS_SUCCESS)) {
         labelObj label = layer->class[c]->label;
 
         if(label.angle != 0)

Modified: trunk/mapserver/mapogroutput.c
===================================================================
--- trunk/mapserver/mapogroutput.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapogroutput.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -784,8 +784,7 @@
             ** Perform classification, and some annotation related magic.
             */
             resultshape.classindex = 
-                msShapeGetClass(layer, &resultshape, 
-                                map->scaledenom, NULL, -1);
+                msShapeGetClass(layer, map, &resultshape, NULL, -1);
 
             if( resultshape.classindex >= 0 
                 && (layer->class[resultshape.classindex]->text.string 

Modified: trunk/mapserver/mapquery.c
===================================================================
--- trunk/mapserver/mapquery.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapquery.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -461,6 +461,7 @@
   resultObj record;
 
   shapeObj shape;
+  double minfeaturesize = -1;
 
   if(map->query.type != MS_QUERY_BY_INDEX) {
     msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByIndex()");
@@ -512,7 +513,23 @@
     return(MS_FAILURE);
   }
 
-  shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, NULL, 0);
+  if (lp->minfeaturesize > 0)
+      minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+
+  /* Check if the shape size is ok to be drawn */
+  if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+  {
+
+      if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+      {
+          msSetError(MS_NOTFOUND, "Requested shape not valid against layer minfeaturesize.", "msQueryByIndex()");
+          msFreeShape(&shape);
+          msLayerClose(lp);
+          return(MS_FAILURE);
+      }
+  }
+
+  shape.classindex = msShapeGetClass(lp, map, &shape, NULL, 0);
   if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
     msSetError(MS_NOTFOUND, "Requested shape not valid against layer classification scheme.", "msQueryByIndex()");
     msFreeShape(&shape);
@@ -568,6 +585,7 @@
   
   int nclasses = 0;
   int *classgroup = NULL;
+  double minfeaturesize = -1; 
 
   if(map->query.type != MS_QUERY_BY_ATTRIBUTE) {
     msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByAttribute()");
@@ -663,9 +681,24 @@
   if (lp->classgroup && lp->numclasses > 0)
     classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
+  if (lp->minfeaturesize > 0)
+      minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+
   while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
+      
+    /* Check if the shape size is ok to be drawn */
+    if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+    {
+        if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+        {
+            if( lp->debug >= MS_DEBUGLEVEL_V )
+                msDebug("msQueryByAttributes(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+            msFreeShape(&shape);
+            continue;
+        }
+    }
 
-    shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+    shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses);
     if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
       msFreeShape(&shape);
       continue;
@@ -732,6 +765,7 @@
   
   int nclasses = 0;
   int *classgroup = NULL;
+  double minfeaturesize = -1;
 
   if(map->query.type != MS_QUERY_BY_FILTER) {
     msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByFilter()");
@@ -818,6 +852,10 @@
     if (lp->classgroup && lp->numclasses > 0)
       classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
+
+    if (lp->minfeaturesize > 0)
+        minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+
     while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
 
       if(!msLayerSupportsCommonFilters(lp)) { /* we have to apply the filter here instead of within the driver */
@@ -827,7 +865,19 @@
         }
       }
 
-      shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+      /* Check if the shape size is ok to be drawn */
+      if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+      {
+          if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+          {
+              if( lp->debug >= MS_DEBUGLEVEL_V )
+                  msDebug("msQueryByFilter(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+              msFreeShape(&shape);
+              continue;
+          }
+      }
+      
+      shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses);
       if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
         msFreeShape(&shape);
         continue;
@@ -889,6 +939,7 @@
   
   int nclasses = 0;
   int *classgroup = NULL;
+  double minfeaturesize = -1;
 
   if(map->query.type != MS_QUERY_BY_RECT) {
     msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByRect()");
@@ -987,8 +1038,24 @@
     if (lp->classgroup && lp->numclasses > 0)
       classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
+    if (lp->minfeaturesize > 0)
+        minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+    
     while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
-      shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+        
+      /* Check if the shape size is ok to be drawn */
+      if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+      {
+          if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+          {
+              if( lp->debug >= MS_DEBUGLEVEL_V )
+                  msDebug("msQueryByRect(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+              msFreeShape(&shape);
+              continue;      
+          }
+      }
+
+      shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses);
       if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
         msFreeShape(&shape);
         continue;
@@ -1072,6 +1139,7 @@
   shapeObj shape, selectshape;
   int nclasses = 0;
   int *classgroup = NULL;
+  double minfeaturesize = -1;
 
   if(map->debug) msDebug("in msQueryByFeatures()\n");
 
@@ -1215,12 +1283,28 @@
       if (lp->classgroup && lp->numclasses > 0)
         classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
+      if (lp->minfeaturesize > 0)
+          minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+
       while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
-
+          
 	/* check for dups when there are multiple selection shapes */
 	if(i > 0 && is_duplicate(lp->resultcache, shape.index, shape.tileindex)) continue;
+        
 
-	shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+        /* Check if the shape size is ok to be drawn */
+        if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+        {
+            if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+            {
+                if( lp->debug >= MS_DEBUGLEVEL_V )
+                    msDebug("msQueryByFeature(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+                msFreeShape(&shape);
+                continue;      
+            }
+        }
+
+	shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses);
 	if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
 	  msFreeShape(&shape);
 	  continue;
@@ -1362,6 +1446,7 @@
   shapeObj shape;
   int nclasses = 0;
   int *classgroup = NULL;
+  double minfeaturesize = -1;
 
   if(map->query.type != MS_QUERY_BY_POINT) {
     msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByPoint()");
@@ -1376,7 +1461,7 @@
     start = stop = map->query.layer;
 
   for(l=start; l>=stop; l--) {
-    lp = (GET_LAYER(map, l));    
+      lp = (GET_LAYER(map, l));    
 
     /* conditions may have changed since this layer last drawn, so set 
        layer->project true to recheck projection needs (Bug #673) */ 
@@ -1466,9 +1551,24 @@
     if (lp->classgroup && lp->numclasses > 0)
       classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
+    if (lp->minfeaturesize > 0)
+        minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+
     while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
-
-      shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+        
+      /* Check if the shape size is ok to be drawn */
+      if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+      {
+          if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+          {
+              if( lp->debug >= MS_DEBUGLEVEL_V )
+                  msDebug("msQueryByPoint(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+              msFreeShape(&shape);
+              continue;      
+          }
+      }
+      
+      shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses);
       if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
 	msFreeShape(&shape);
 	continue;
@@ -1537,6 +1637,7 @@
 
   int nclasses = 0;
   int *classgroup = NULL;
+  double minfeaturesize = -1;
 
   if(map->query.type != MS_QUERY_BY_SHAPE) {
     msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByShape()");
@@ -1651,9 +1752,24 @@
     if (lp->classgroup && lp->numclasses > 0)
       classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
+    if (lp->minfeaturesize > 0)
+        minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+
     while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
 
-      shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+      /* Check if the shape size is ok to be drawn */
+      if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+      {
+          if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+          {
+              if( lp->debug >= MS_DEBUGLEVEL_V )
+                  msDebug("msQueryByShape(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+              msFreeShape(&shape);
+              continue;      
+          }
+      }
+
+      shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses);
       if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
 	msFreeShape(&shape);
 	continue;
@@ -1783,6 +1899,7 @@
   int nclasses = 0;
   int *classgroup = NULL;
   double dfValue;
+  double minfeaturesize = -1;
 
   if(map->query.type != MS_QUERY_BY_OPERATOR) {
     msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByOperator()");
@@ -1879,9 +1996,24 @@
     if (lp->classgroup && lp->numclasses > 0)
       classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
+    if (lp->minfeaturesize > 0)
+        minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize);
+
     while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
 
-      shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+      /* Check if the shape size is ok to be drawn */
+      if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) )
+      {
+          if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)
+          {
+              if( lp->debug >= MS_DEBUGLEVEL_V )
+                  msDebug("msQueryByOperator(): Skipping shape (%d) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index);
+              msFreeShape(&shape);
+              continue;      
+          }
+      }
+
+      shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses);
       if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
         msFreeShape(&shape);
         continue;

Modified: trunk/mapserver/mapscale.c
===================================================================
--- trunk/mapserver/mapscale.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapscale.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -528,3 +528,20 @@
     }
     return (dfPosGeo);
 }
+
+/* This function converts a pixel value in geo ref. The return value is in
+ * layer units. This function has been added for the purpose of the ticket #1340 */
+
+double Pix2LayerGeoref(mapObj *map, layerObj *layer, int value)
+{
+    double cellsize = MS_MAX(MS_CELLSIZE(map->extent.minx, map->extent.maxx, map->width), 
+                             MS_CELLSIZE(map->extent.miny, map->extent.maxy, map->height));
+    
+    double resolutionFactor = map->resolution/map->defresolution;
+    double unitsFactor = 1;
+    
+    if (layer->sizeunits != MS_PIXELS)
+        unitsFactor = msInchesPerUnit(map->units,0)/msInchesPerUnit(layer->sizeunits,0);
+    
+    return value*cellsize*resolutionFactor*unitsFactor;
+}

Modified: trunk/mapserver/mapscript/php/class.c
===================================================================
--- trunk/mapserver/mapscript/php/class.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapscript/php/class.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -164,6 +164,7 @@
     else IF_GET_LONG("status", php_class->class->status) 
     else IF_GET_DOUBLE("minscaledenom", php_class->class->minscaledenom) 
     else IF_GET_DOUBLE("maxscaledenom", php_class->class->maxscaledenom) 
+    else IF_GET_LONG("minfeaturesize", php_class->class->minfeaturesize) 
     else IF_GET_STRING("template", php_class->class->template)
     else IF_GET_STRING("keyimage", php_class->class->keyimage)
     else IF_GET_STRING("group", php_class->class->group)
@@ -200,6 +201,7 @@
     else IF_SET_LONG("status", php_class->class->status, value) 
     else IF_SET_DOUBLE("minscaledenom", php_class->class->minscaledenom, value) 
     else IF_SET_DOUBLE("maxscaledenom", php_class->class->maxscaledenom, value) 
+    else IF_SET_LONG("minfeaturesize", php_class->class->minfeaturesize, value) 
     else IF_SET_STRING("template", php_class->class->template, value)
     else IF_SET_STRING("keyimage", php_class->class->keyimage, value)
     else IF_SET_STRING("group", php_class->class->group, value)

Modified: trunk/mapserver/mapscript/php/layer.c
===================================================================
--- trunk/mapserver/mapscript/php/layer.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapscript/php/layer.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -57,7 +57,6 @@
 
 ZEND_BEGIN_ARG_INFO_EX(layer_getClassIndex_args, 0, 0, 2)
   ZEND_ARG_OBJ_INFO(0, shape, shapeObj, 0)
-  ZEND_ARG_INFO(0, scaledenom)
   ZEND_ARG_INFO(0, classGroup)
   ZEND_ARG_INFO(0, numClasses)
 ZEND_END_ARG_INFO()
@@ -265,6 +264,7 @@
     else IF_GET_DOUBLE("maxscaledenom", php_layer->layer->maxscaledenom)
     else IF_GET_DOUBLE("labelminscaledenom", php_layer->layer->labelminscaledenom)
     else IF_GET_DOUBLE("labelmaxscaledenom", php_layer->layer->labelmaxscaledenom)
+    else IF_GET_LONG("minfeaturesize", php_layer->layer->minfeaturesize)
     else IF_GET_LONG("maxfeatures", php_layer->layer->maxfeatures)
     else IF_GET_LONG("annotate", php_layer->layer->annotate)
     else IF_GET_LONG("transform", php_layer->layer->transform)
@@ -327,6 +327,7 @@
     else IF_SET_DOUBLE("symbolscaledenom", php_layer->layer->symbolscaledenom, value)
     else IF_SET_DOUBLE("minscaledenom", php_layer->layer->minscaledenom, value)
     else IF_SET_DOUBLE("maxscaledenom", php_layer->layer->maxscaledenom, value)
+    else IF_SET_LONG("minfeaturesize", php_layer->layer->minfeaturesize, value)
     else IF_SET_DOUBLE("labelminscaledenom", php_layer->layer->labelminscaledenom, value)
     else IF_SET_DOUBLE("labelmaxscaledenom", php_layer->layer->labelmaxscaledenom, value)
     else IF_SET_LONG("maxfeatures", php_layer->layer->maxfeatures, value)
@@ -694,7 +695,7 @@
 }
 /* }}} */
 
-/* {{{ proto int layer.getClassIndex(shapeObj shape, int scaledenom [, string classGroup, int numClasses])
+/* {{{ proto int layer.getClassIndex(shapeObj shape [, string classGroup, int numClasses])
    Returns the class index for the shape */
 PHP_METHOD(layerObj, getClassIndex)
 {
@@ -703,15 +704,15 @@
     int numElements, *classGroups = NULL;
     int retval = -1, i = 0;
     long numClasses = 0;
-    double scaledenom;
     HashTable *classgroup_hash = NULL;
     php_shape_object *php_shape;
     php_layer_object *php_layer;
+    php_map_object *php_map;
 
     PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Od|a!l",
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a!l",
                               &zshape, mapscript_ce_shape,
-                              &scaledenom, &zclassgroup,
+                              &zclassgroup,
                               &numClasses) == FAILURE) {
         PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
         return;
@@ -721,6 +722,14 @@
     php_layer = (php_layer_object *) zend_object_store_get_object(zobj TSRMLS_CC);
     php_shape = (php_shape_object *) zend_object_store_get_object(zshape TSRMLS_CC);
 
+    if (!php_layer->parent.val)
+    {
+        mapscript_throw_exception("No map object associated with this layer object." TSRMLS_CC);
+        return;
+    }
+    
+    php_map = (php_map_object *) zend_object_store_get_object(php_layer->parent.val TSRMLS_CC);
+
     if (zclassgroup)
     {
         classgroup_hash = Z_ARRVAL_P(zclassgroup);
@@ -736,7 +745,7 @@
         }
     }
     
-    retval = layerObj_getClassIndex(php_layer->layer, php_shape->shape, scaledenom, classGroups, numClasses);
+    retval = layerObj_getClassIndex(php_layer->layer, php_map->map, php_shape->shape, classGroups, numClasses);
   
     if (zclassgroup)
         free(classGroups);

Modified: trunk/mapserver/mapscript/php/mapscript_i.c
===================================================================
--- trunk/mapserver/mapscript/php/mapscript_i.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapscript/php/mapscript_i.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -498,9 +498,9 @@
       return(NULL);
   }
 
-int layerObj_getClassIndex(layerObj *self, shapeObj *shape, double scaledenom, 
+int layerObj_getClassIndex(layerObj *self, mapObj *map, shapeObj *shape, 
                            int *classgroup, int numclasses) {
-    return msShapeGetClass(self, shape, scaledenom, classgroup, numclasses);
+    return msShapeGetClass(self, map, shape, classgroup, numclasses);
 }
 
 int layerObj_draw(layerObj *self, mapObj *map, imageObj *img) {

Modified: trunk/mapserver/mapscript/php/php_mapscript.h
===================================================================
--- trunk/mapserver/mapscript/php/php_mapscript.h	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapscript/php/php_mapscript.h	2011-02-18 15:51:47 UTC (rev 10998)
@@ -565,7 +565,8 @@
                                   int tileindex, int shapeindex);
 resultObj *layerObj_getResult(layerObj *self, int i);
 classObj       *layerObj_getClass(layerObj *self, int i);
-int             layerObj_getClassIndex(layerObj *self, shapeObj *shape, double scaledenom, int *classgroup, int numclasses);
+int layerObj_getClassIndex(layerObj *self, mapObj *map, shapeObj *shape, 
+                           int *classgroup, int numclasses);
 int             layerObj_draw(layerObj *self, mapObj *map, imageObj *img);
 int             layerObj_drawQuery(layerObj *self, mapObj *map, imageObj *img);
 int             layerObj_queryByAttributes(layerObj *self, mapObj *map, 

Modified: trunk/mapserver/mapscript/swiginc/layer.i
===================================================================
--- trunk/mapserver/mapscript/swiginc/layer.i	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapscript/swiginc/layer.i	2011-02-18 15:51:47 UTC (rev 10998)
@@ -622,8 +622,8 @@
         return msConnectLayer(self, connectiontype, library_str);
     }
 
-    int getClassIndex(shapeObj *shape, double scaledenom, int *classgroup=NULL, int numclasses=0) {
-        return msShapeGetClass(self, shape, scaledenom, classgroup, numclasses);
+    int getClassIndex(mapObj *map, shapeObj *shape, int *classgroup=NULL, int numclasses=0) {
+        return msShapeGetClass(self, map, shape, classgroup, numclasses);
     }
 
 }

Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/mapserver.h	2011-02-18 15:51:47 UTC (rev 10998)
@@ -1774,6 +1774,7 @@
 MS_DLL_EXPORT int msCalculateScale(rectObj extent, int units, int width, int height, double resolution, double *scaledenom);
 MS_DLL_EXPORT double GetDeltaExtentsUsingScale(double scale, int units, double centerLat, int width, double resolution);
 MS_DLL_EXPORT double Pix2Georef(int nPixPos, int nPixMin, int nPixMax, double dfGeoMin, double dfGeoMax, int bULisYOrig);
+MS_DLL_EXPORT double Pix2LayerGeoref(mapObj *map, layerObj *layer, int value);
 MS_DLL_EXPORT double msInchesPerUnit(int units, double center_lat);
 MS_DLL_EXPORT int msEmbedScalebar(mapObj *map, imageObj *img);
 
@@ -2226,8 +2227,9 @@
 MS_DLL_EXPORT int msValidateContexts(mapObj *map);
 MS_DLL_EXPORT int msEvalContext(mapObj *map, layerObj *layer, char *context);
 MS_DLL_EXPORT int msEvalExpression(layerObj *layer, shapeObj *shape, expressionObj *expression, int itemindex);
-MS_DLL_EXPORT int msShapeGetClass(layerObj *layer, shapeObj *shape, double scaledenom, int *classgroup, int numclasses);
+MS_DLL_EXPORT int msShapeGetClass(layerObj *layer, mapObj *map, shapeObj *shape, int *classgroup, int numclasses);
 MS_DLL_EXPORT char *msShapeGetAnnotation(layerObj *layer, shapeObj *shape);
+MS_DLL_EXPORT int msShapeCheckSize(shapeObj *shape, double minfeaturesize);
 MS_DLL_EXPORT int msAdjustImage(rectObj rect, int *width, int *height);
 MS_DLL_EXPORT double msAdjustExtent(rectObj *rect, int width, int height);
 MS_DLL_EXPORT int msConstrainExtent(rectObj *bounds, rectObj *rect, double overlay);

Modified: trunk/mapserver/maptemplate.c
===================================================================
--- trunk/mapserver/maptemplate.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/maptemplate.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -917,8 +917,8 @@
     status = msLayerGetShape(layer, &(mapserv->resultshape), &(layer->resultcache->results[i]));
     if(status != MS_SUCCESS) return status;
 
-    mapserv->resultshape.classindex = msShapeGetClass(layer, &mapserv->resultshape, 
-                                                      layer->map->scaledenom, NULL, -1);
+    mapserv->resultshape.classindex = msShapeGetClass(layer, layer->map, &mapserv->resultshape,  NULL, -1);
+
     if ( mapserv->resultshape.classindex>=0 &&
          (layer->class[mapserv->resultshape.classindex]->text.string || layer->labelitem) && 
          layer->class[mapserv->resultshape.classindex]->label.size != -1)

Modified: trunk/mapserver/maputil.c
===================================================================
--- trunk/mapserver/maputil.c	2011-02-17 18:57:43 UTC (rev 10997)
+++ trunk/mapserver/maputil.c	2011-02-18 15:51:47 UTC (rev 10998)
@@ -446,20 +446,19 @@
         
 }       
 
-int msShapeGetClass(layerObj *layer, shapeObj *shape, double scaledenom, int *classgroup, int numclasses)
+int msShapeGetClass(layerObj *layer, mapObj *map, shapeObj *shape, int *classgroup, int numclasses)
 {
   int i, iclass;
 
-
   /* INLINE features do not work with expressions, allow the classindex */
   /* value set prior to calling this function to carry through. */
   if(layer->connectiontype == MS_INLINE) {
     if(shape->classindex < 0 || shape->classindex >= layer->numclasses) return(-1);
 
-    if(scaledenom > 0) {  /* verify scaledenom here */
-      if((layer->class[shape->classindex]->maxscaledenom > 0) && (scaledenom > layer->class[shape->classindex]->maxscaledenom))
+    if(map->scaledenom > 0) {  /* verify scaledenom here */
+      if((layer->class[shape->classindex]->maxscaledenom > 0) && (map->scaledenom > layer->class[shape->classindex]->maxscaledenom))
         return(-1); /* can skip this feature */
-      if((layer->class[shape->classindex]->minscaledenom > 0) && (scaledenom <= layer->class[shape->classindex]->minscaledenom))
+      if((layer->class[shape->classindex]->minscaledenom > 0) && (map->scaledenom <= layer->class[shape->classindex]->minscaledenom))
         return(-1); /* can skip this feature */
     }
 
@@ -479,13 +478,22 @@
        if (iclass < 0 || iclass >= layer->numclasses)        
          continue; /* this should never happen but just in case */
 
-       if(scaledenom > 0) { /* verify scaledenom here  */
-         if((layer->class[iclass]->maxscaledenom > 0) && (scaledenom > layer->class[iclass]->maxscaledenom))
+       if(map->scaledenom > 0) { /* verify scaledenom here  */
+         if((layer->class[iclass]->maxscaledenom > 0) && (map->scaledenom > layer->class[iclass]->maxscaledenom))
            continue; /* can skip this one, next class */
-         if((layer->class[iclass]->minscaledenom > 0) && (scaledenom <= layer->class[iclass]->minscaledenom))
+         if((layer->class[iclass]->minscaledenom > 0) && (map->scaledenom <= layer->class[iclass]->minscaledenom))
            continue; /* can skip this one, next class */
         }
 
+       /* verify the minfeaturesize */
+       if ((shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) && (layer->class[iclass]->minfeaturesize > 0))
+       {
+           double minfeaturesize = Pix2LayerGeoref(map, layer,
+                                                   layer->class[iclass]->minfeaturesize);
+           if (msShapeCheckSize(shape, minfeaturesize) == MS_FALSE)
+               continue; //skip this one, next class
+       }
+
        if(layer->class[iclass]->status != MS_DELETE && msEvalExpression(layer, shape, &(layer->class[iclass]->expression), layer->classitemindex) == MS_TRUE)
 	 return(iclass);
     }
@@ -534,6 +542,22 @@
   return(tmpstr);
 }
 
+/* Check if the shape is enough big to be drawn with the
+   layer::minfeaturesize setting. The minfeaturesize parameter should be
+   the value in geo ref (not in pixel) and should have been multiplied by
+   the resolution factor.
+ */
+int msShapeCheckSize(shapeObj *shape, double minfeaturesize)
+{
+    double dx = (shape->bounds.maxx-shape->bounds.minx);
+    double dy = (shape->bounds.maxy-shape->bounds.miny);
+
+    if (pow(minfeaturesize,2.0) > (pow(dx,2.0)+pow(dy,2.0)))
+        return MS_FALSE;
+    
+    return MS_TRUE;
+}
+
 /*
 ** Adjusts an image size in one direction to fit an extent.
 */



More information about the mapserver-commits mailing list