[mapserver-commits] r9083 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Fri Jun 5 19:03:22 EDT 2009


Author: pramsey
Date: 2009-06-05 19:03:22 -0400 (Fri, 05 Jun 2009)
New Revision: 9083

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/mapdraw.c
   trunk/mapserver/mapserver.h
   trunk/mapserver/maputil.c
Log:
Do pre-emptive test for map.extent/layer.extent interaction (#3043)



Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2009-06-05 09:03:03 UTC (rev 9082)
+++ trunk/mapserver/HISTORY.TXT	2009-06-05 23:03:22 UTC (rev 9083)
@@ -13,6 +13,9 @@
 
 Current Version (SVN trunk):
 ----------------------------
+
+- Do pre-emptive test for map.extent/layer.extent interaction (#3043)
+
 - Add centroid geomtransform (#2825)
 
 - Test database connections before using them (#2932)

Modified: trunk/mapserver/mapdraw.c
===================================================================
--- trunk/mapserver/mapdraw.c	2009-06-05 09:03:03 UTC (rev 9082)
+++ trunk/mapserver/mapdraw.c	2009-06-05 23:03:22 UTC (rev 9083)
@@ -616,6 +616,11 @@
 
   if(layer->type == MS_LAYER_QUERY || layer->type == MS_LAYER_TILEINDEX) return(MS_FALSE);
   if((layer->status != MS_ON) && (layer->status != MS_DEFAULT)) return(MS_FALSE);
+
+  /* Only return MS_FALSE if it is definitely false. Sometimes it will return MS_UNKNOWN, which we 
+  ** consider true, for this use case (it might be visible, try and draw it, see what happens). */
+  if ( msExtentsOverlap(map, layer) == MS_FALSE ) return(MS_FALSE);  
+  
   if(msEvalContext(map, layer, layer->requires) == MS_FALSE) return(MS_FALSE);
 
   if(map->scaledenom > 0) {

Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h	2009-06-05 09:03:03 UTC (rev 9082)
+++ trunk/mapserver/mapserver.h	2009-06-05 23:03:22 UTC (rev 9083)
@@ -136,6 +136,7 @@
 
 #define MS_TRUE 1 /* logical control variables */
 #define MS_FALSE 0
+#define MS_UNKNOWN -1
 #define MS_ON 1
 #define MS_OFF 0
 #define MS_DEFAULT 2
@@ -2028,6 +2029,9 @@
 /* ==================================================================== */
 /*      Prototypes for functions in maputil.c                           */
 /* ==================================================================== */
+
+MS_DLL_EXPORT int msExtentsOverlap(mapObj *map, layerObj *layer);
+
 /* For mappdf */
 MS_DLL_EXPORT int getRgbColor(mapObj *map,int i,int *r,int *g,int *b); /* maputil.c */
 MS_DLL_EXPORT int msBindLayerToShape(layerObj *layer, shapeObj *shape, int querymapMode);

Modified: trunk/mapserver/maputil.c
===================================================================
--- trunk/mapserver/maputil.c	2009-06-05 09:03:03 UTC (rev 9082)
+++ trunk/mapserver/maputil.c	2009-06-05 23:03:22 UTC (rev 9083)
@@ -39,6 +39,7 @@
 #include "mapparser.h"
 #include "mapthread.h"
 #include "mapfile.h"
+#include "mapcopy.h"
 
 #ifdef _WIN32
 #include <fcntl.h>
@@ -1785,3 +1786,61 @@
     return MS_SUCCESS;
 }
 
+/*
+** Issue #3043: Layer extent comparison short circuit.
+**
+** msExtentsOverlap()
+**
+** Returns MS_TRUE if map extent and layer extent overlap, 
+** MS_FALSE if they are disjoint, and MS_UNKNOWN if there is 
+** not enough info to calculate a deterministic answer.
+**
+*/
+int msExtentsOverlap(mapObj *map, layerObj *layer)
+{
+    rectObj map_extent;
+    rectObj layer_extent;
+    
+    /* No extent info? Nothing we can do, return MS_UNKNOWN. */
+    if( (map->extent.minx == -1) && (map->extent.miny == -1) && (map->extent.maxx == -1 ) && (map->extent.maxy == -1) ) return MS_UNKNOWN;
+    if( (layer->extent.minx == -1) && (layer->extent.miny == -1) && (layer->extent.maxx == -1 ) && (layer->extent.maxy == -1) ) return MS_UNKNOWN;
+        
+#ifdef USE_PROJ
+
+    /* No map projection? Let someone else sort this out. */
+    if( ! (map->projection.numargs > 0) ) 
+        return MS_UNKNOWN;
+
+    /* No layer projection? Perform naive comparison, because they are 
+    ** in the same projection. */
+    if( ! (layer->projection.numargs > 0) ) 
+        return msRectOverlap( &(map->extent), &(layer->extent) );
+    
+    /* We need to transform our rectangles for comparison, 
+    ** so we will work with copies and leave the originals intact. */
+    MS_COPYRECT(&map_extent, &(map->extent) );
+    MS_COPYRECT(&layer_extent, &(layer->extent) );
+
+    /* Transform map extents into geographics for comparison. */
+    if( msProjectRect(&(map->projection), &(map->latlon), &map_extent) )
+        return MS_UNKNOWN;
+        
+    /* Transform layer extents into geographics for comparison. */
+    if( msProjectRect(&(layer->projection), &(map->latlon), &layer_extent) )
+        return MS_UNKNOWN;
+
+    /* Simple case? Return simple answer. */
+    if ( map_extent.minx < map_extent.maxx && layer_extent.minx < layer_extent.maxx )
+        return msRectOverlap( &(map_extent), &(layer_extent) );
+        
+    /* Uh oh, one of the rects crosses the dateline!
+    ** Let someone else handle it. */
+    return MS_UNKNOWN;
+   
+#else
+    /* No proj? Naive comparison. */
+    if( msRectOverlap( &(map->extent), &(layer->extent) ) return MS_TRUE;
+    return MS_FALSE;
+#endif
+
+}



More information about the mapserver-commits mailing list