[QGIS Commit] r13596 - trunk/qgis/src/providers/ogr

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sat May 29 14:37:36 EDT 2010


Author: jef
Date: 2010-05-29 14:37:35 -0400 (Sat, 29 May 2010)
New Revision: 13596

Modified:
   trunk/qgis/src/providers/ogr/qgsogrprovider.cpp
Log:
ogr provider update: lazy determine extent (fixes #2752)

Modified: trunk/qgis/src/providers/ogr/qgsogrprovider.cpp
===================================================================
--- trunk/qgis/src/providers/ogr/qgsogrprovider.cpp	2010-05-29 15:47:25 UTC (rev 13595)
+++ trunk/qgis/src/providers/ogr/qgsogrprovider.cpp	2010-05-29 18:37:35 UTC (rev 13596)
@@ -26,6 +26,8 @@
 #include <cpl_error.h>
 #include <cpl_conv.h>
 
+#include <limits>
+
 #include <QtDebug>
 #include <QFile>
 #include <QDir>
@@ -176,8 +178,6 @@
       ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, mLayerName.toLocal8Bit().data() );
     }
 
-    extent_ = calloc( sizeof( OGREnvelope ), 1 );
-
     ogrLayer = ogrOrigLayer;
     setSubsetString( mSubsetString );
   }
@@ -205,8 +205,13 @@
 
   OGR_DS_Destroy( ogrDataSource );
   ogrDataSource = 0;
-  free( extent_ );
-  extent_ = 0;
+
+  if ( extent_ )
+  {
+    free( extent_ );
+    extent_ = 0;
+  }
+
   if ( mSelectionRectangle )
   {
     OGR_G_DestroyGeometry( mSelectionRectangle );
@@ -273,19 +278,17 @@
   // TODO: This can be expensive, do we really need it!
   recalculateFeatureCount();
 
-  // get the extent_ (envelope) of the layer
-  QgsDebugMsg( "Starting get extent" );
-
-  // TODO: This can be expensive, do we really need it!
-  OGR_L_GetExtent( ogrLayer, ( OGREnvelope * ) extent_, true );
-
-  QgsDebugMsg( "Finished get extent" );
-
   // check the validity of the layer
   QgsDebugMsg( "checking validity" );
   loadFields();
   QgsDebugMsg( "Done checking validity" );
 
+  if ( extent_ )
+  {
+    free( extent_ );
+    extent_ = 0;
+  }
+
   return true;
 }
 
@@ -607,7 +610,53 @@
 
 QgsRectangle QgsOgrProvider::extent()
 {
-  OGREnvelope *ext = ( OGREnvelope * ) extent_;
+  if ( !extent_ )
+  {
+    extent_ = calloc( sizeof( OGREnvelope ), 1 );
+
+    // get the extent_ (envelope) of the layer
+    QgsDebugMsg( "Starting get extent" );
+
+    // TODO: This can be expensive, do we really need it!
+    if ( ogrLayer == ogrOrigLayer )
+    {
+      OGR_L_GetExtent( ogrLayer, ( OGREnvelope * ) extent_, true );
+    }
+    else
+    {
+      OGREnvelope *bb = static_cast<OGREnvelope*>( extent_ );
+
+      bb->MinX = std::numeric_limits<double>::max();
+      bb->MinY = std::numeric_limits<double>::max();
+      bb->MaxX = -std::numeric_limits<double>::max();
+      bb->MaxY = -std::numeric_limits<double>::max();
+
+      OGRFeatureH f;
+
+      OGR_L_ResetReading( ogrLayer );
+      while (( f = OGR_L_GetNextFeature( ogrLayer ) ) )
+      {
+        OGRGeometryH g = OGR_F_GetGeometryRef( f );
+        if ( g )
+        {
+          OGREnvelope env;
+          OGR_G_GetEnvelope( g, &env );
+
+          if ( env.MinX < bb->MinX ) bb->MinX = env.MinX;
+          if ( env.MinY < bb->MinY ) bb->MinY = env.MinY;
+          if ( env.MaxX > bb->MaxX ) bb->MaxX = env.MaxX;
+          if ( env.MaxY > bb->MaxY ) bb->MaxY = env.MaxY;
+        }
+
+        OGR_F_Destroy( f );
+      }
+      OGR_L_ResetReading( ogrLayer );
+    }
+
+    QgsDebugMsg( "Finished get extent" );
+  }
+
+  OGREnvelope *ext = static_cast<OGREnvelope *>( extent_ );
   mExtentRect.set( ext->MinX, ext->MinY, ext->MaxX, ext->MaxY );
   return mExtentRect;
 }
@@ -999,7 +1048,11 @@
 
   recalculateFeatureCount();
 
-  OGR_L_GetExtent( ogrOrigLayer, ( OGREnvelope * ) extent_, true );
+  if ( extent_ )
+  {
+    free( extent_ );
+    extent_ = 0;
+  }
 
   return returnvalue;
 }



More information about the QGIS-commit mailing list