[QGIS Commit] r14172 - in trunk/qgis/src: app/legend core plugins/delimited_text providers/delimitedtext

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Sep 1 04:48:55 EDT 2010


Author: mhugent
Date: 2010-09-01 08:48:55 +0000 (Wed, 01 Sep 2010)
New Revision: 14172

Modified:
   trunk/qgis/src/app/legend/qgslegendlayer.cpp
   trunk/qgis/src/core/qgis.h
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp
   trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
   trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h
Log:
Support for non-spatial tables with delimited text provider. Legend shows a table icon for non-spatial layers (also possible with ogr)

Modified: trunk/qgis/src/app/legend/qgslegendlayer.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegendlayer.cpp	2010-08-31 11:16:07 UTC (rev 14171)
+++ trunk/qgis/src/app/legend/qgslegendlayer.cpp	2010-09-01 08:48:55 UTC (rev 14172)
@@ -209,72 +209,82 @@
 
 void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double widthScale )
 {
+  if ( !layer )
+  {
+    return;
+  }
+
   SymbologyList itemList;
+  if ( layer->geometryType() != QGis::NoGeometry )
+  {
+    //add the new items
+    QString lw, uv, label;
+    const QgsRenderer* renderer = layer->renderer();
+    const QList<QgsSymbol*> sym = renderer->symbols();
 
-  //add the new items
-  QString lw, uv, label;
-  const QgsRenderer* renderer = layer->renderer();
-  const QList<QgsSymbol*> sym = renderer->symbols();
-
-  //create an item for each classification field (only one for most renderers)
-  QSettings settings;
-  if ( settings.value( "/qgis/showLegendClassifiers", false ).toBool() )
-  {
-    if ( renderer->needsAttributes() )
+    //create an item for each classification field (only one for most renderers)
+    QSettings settings;
+    if ( settings.value( "/qgis/showLegendClassifiers", false ).toBool() )
     {
-      QgsAttributeList classfieldlist = renderer->classificationAttributes();
-      const QgsFieldMap& fields = layer->pendingFields();
-      for ( QgsAttributeList::iterator it = classfieldlist.begin(); it != classfieldlist.end(); ++it )
+      if ( renderer->needsAttributes() )
       {
-        QString classfieldname = layer->attributeAlias( *it );
-        if ( classfieldname.isEmpty() )
+        QgsAttributeList classfieldlist = renderer->classificationAttributes();
+        const QgsFieldMap& fields = layer->pendingFields();
+        for ( QgsAttributeList::iterator it = classfieldlist.begin(); it != classfieldlist.end(); ++it )
         {
-          classfieldname = fields[*it].name();
+          QString classfieldname = layer->attributeAlias( *it );
+          if ( classfieldname.isEmpty() )
+          {
+            classfieldname = fields[*it].name();
+          }
+          itemList.append( qMakePair( classfieldname, QPixmap() ) );
         }
-        itemList.append( qMakePair( classfieldname, QPixmap() ) );
       }
     }
-  }
 
-  for ( QList<QgsSymbol*>::const_iterator it = sym.begin(); it != sym.end(); ++it )
-  {
-    QImage img;
-    if (( *it )->type() == QGis::Point )
+    for ( QList<QgsSymbol*>::const_iterator it = sym.begin(); it != sym.end(); ++it )
     {
-      img = ( *it )->getPointSymbolAsImage( widthScale );
-    }
-    else if (( *it )->type() == QGis::Line )
-    {
-      img = ( *it )->getLineSymbolAsImage();
-    }
-    else //polygon
-    {
-      img = ( *it )->getPolygonSymbolAsImage();
-    }
+      QImage img;
+      if (( *it )->type() == QGis::Point )
+      {
+        img = ( *it )->getPointSymbolAsImage( widthScale );
+      }
+      else if (( *it )->type() == QGis::Line )
+      {
+        img = ( *it )->getLineSymbolAsImage();
+      }
+      else  if (( *it )->type() == QGis::Line )//polygon
+      {
+        img = ( *it )->getPolygonSymbolAsImage();
+      }
+      else //must be a layer without geometry then
+      {
 
-    QString values;
-    lw = ( *it )->lowerValue();
-    if ( !lw.isEmpty() )
-    {
-      values += lw;
+      }
+
+      QString values;
+      lw = ( *it )->lowerValue();
+      if ( !lw.isEmpty() )
+      {
+        values += lw;
+      }
+      uv = ( *it )->upperValue();
+      if ( !uv.isEmpty() && lw != uv )
+      {
+        values += " - ";
+        values += uv;
+      }
+      label = ( *it )->label();
+      if ( !label.isEmpty() )
+      {
+        values += " ";
+        values += label;
+      }
+
+      QPixmap pix = QPixmap::fromImage( img ); // convert to pixmap
+      itemList.append( qMakePair( values, pix ) );
     }
-    uv = ( *it )->upperValue();
-    if ( !uv.isEmpty() && lw != uv )
-    {
-      values += " - ";
-      values += uv;
-    }
-    label = ( *it )->label();
-    if ( !label.isEmpty() )
-    {
-      values += " ";
-      values += label;
-    }
-
-    QPixmap pix = QPixmap::fromImage( img ); // convert to pixmap
-    itemList.append( qMakePair( values, pix ) );
   }
-
   changeSymbologySettings( layer, itemList );
 }
 
@@ -359,6 +369,8 @@
         case QGis::Polygon:
           return QgisApp::getThemePixmap( "/mIconPolygonLayer.png" );
           break;
+        case QGis::NoGeometry:
+          return QgisApp::getThemePixmap( "mActionOpenTable.png" );
         default:
           return QgisApp::getThemePixmap( "/mIconLayer.png" );
       }
@@ -366,7 +378,7 @@
     else if ( theLayer->type() == QgsMapLayer::RasterLayer )
     {
       QSettings s;
-      if( s.value( "/qgis/createRasterLegendIcons", true ).toBool() )
+      if ( s.value( "/qgis/createRasterLegendIcons", true ).toBool() )
       {
         QgsRasterLayer* rlayer = qobject_cast<QgsRasterLayer *>( theLayer );
         QPixmap myPixmap( 32, 32 );
@@ -397,7 +409,7 @@
     theMenu.addAction( tr( "&Zoom to best scale (100%)" ), legend(), SLOT( legendLayerZoomNative() ) );
 
     QgsRasterLayer *rasterLayer =  qobject_cast<QgsRasterLayer *>( lyr );
-    if( rasterLayer && rasterLayer->rasterType() != QgsRasterLayer::Palette )
+    if ( rasterLayer && rasterLayer->rasterType() != QgsRasterLayer::Palette )
     {
       theMenu.addAction( tr( "&Stretch using current extent" ), legend(), SLOT( legendLayerStretchUsingCurrentExtent() ) );
     }

Modified: trunk/qgis/src/core/qgis.h
===================================================================
--- trunk/qgis/src/core/qgis.h	2010-08-31 11:16:07 UTC (rev 14171)
+++ trunk/qgis/src/core/qgis.h	2010-09-01 08:48:55 UTC (rev 14172)
@@ -46,26 +46,28 @@
     // Feature types
     enum WkbType
     {
+      WKBUnknown = 0,
       WKBPoint = 1,
       WKBLineString,
       WKBPolygon,
       WKBMultiPoint,
       WKBMultiLineString,
       WKBMultiPolygon,
-      WKBUnknown,
+      WKBNoGeometry = 100, //attributes only
       WKBPoint25D = 0x80000001,
       WKBLineString25D,
       WKBPolygon25D,
       WKBMultiPoint25D,
       WKBMultiLineString25D,
-      WKBMultiPolygon25D
+      WKBMultiPolygon25D,
     };
     enum GeometryType
     {
       Point,
       Line,
       Polygon,
-      UnknownGeometry
+      UnknownGeometry,
+      NoGeometry
     };
 
     // String representation of geometry types (set in qgis.cpp)

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp	2010-08-31 11:16:07 UTC (rev 14171)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp	2010-09-01 08:48:55 UTC (rev 14172)
@@ -168,6 +168,11 @@
           cmbXField->addItem( field );
           cmbYField->addItem( field );
         }
+
+        //x/y fields might be missing
+        cmbXField->addItem( "" );
+        cmbYField->addItem( "" );
+
         // Have a go at setting the selected items in the X and Y
         // combo boxes to something sensible.
         int indexX = cmbXField->findText( "lon", Qt::MatchContains );
@@ -181,11 +186,17 @@
         {
           indexX = cmbXField->findText( "x", Qt::MatchContains );
           indexY = cmbXField->findText( "y", Qt::MatchContains );
-          if ( indexX != -1 && indexY != -1 )
+          //leave x- and y-field empty by default if no match found
+          if ( indexX == -1 )
           {
-            cmbXField->setCurrentIndex( indexX );
-            cmbYField->setCurrentIndex( indexY );
+            indexX = cmbXField->findText( "" );
           }
+          if ( indexY == -1 )
+          {
+            indexY = cmbYField->findText( "" );
+          }
+          cmbXField->setCurrentIndex( indexX );
+          cmbYField->setCurrentIndex( indexY );
         }
         // enable the buttons
         enableButtons();

Modified: trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
===================================================================
--- trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp	2010-08-31 11:16:07 UTC (rev 14171)
+++ trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp	2010-09-01 08:48:55 UTC (rev 14172)
@@ -108,7 +108,7 @@
 QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
     : QgsVectorDataProvider( uri ),
     mXFieldIndex( -1 ), mYFieldIndex( -1 ),
-    mShowInvalidLines( true )
+    mShowInvalidLines( true ), mWkbType( QGis::WKBPoint )
 {
   // Get the file name and mDelimiter out of the uri
   mFileName = uri.left( uri.indexOf( "?" ) );
@@ -150,7 +150,7 @@
   mSelectionRectangle = QgsRectangle();
   // assume the layer is invalid until proven otherwise
   mValid = false;
-  if ( mFileName.isEmpty() || mDelimiter.isEmpty() || xField.isEmpty() || yField.isEmpty() )
+  if ( mFileName.isEmpty() || mDelimiter.isEmpty() )
   {
     // uri is invalid so the layer must be too...
     QString( "Data source is invalid" );
@@ -233,7 +233,7 @@
       QgsDebugMsg( "Field count for the delimited text file is " + QString::number( attributeFields.size() ) );
       hasFields = true;
     }
-    else if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
+    else //field names already read
     {
       mNumberFeatures++;
 
@@ -248,8 +248,12 @@
 
       // Get the x and y values, first checking to make sure they
       // aren't null.
-      QString sX = parts[mXFieldIndex];
-      QString sY = parts[mYFieldIndex];
+      QString sX, sY;
+      if ( mXFieldIndex >= 0 && mYFieldIndex >= 0 )
+      {
+        sX = parts[mXFieldIndex];
+        sY = parts[mYFieldIndex];
+      }
 
       bool xOk = true;
       bool yOk = true;
@@ -285,6 +289,11 @@
     }
   }
 
+  if ( mXFieldIndex < 0 || mYFieldIndex < 0 )
+  {
+    mWkbType = QGis::WKBNoGeometry;
+  }
+
   // now it's time to decide the types for the fields
   for ( QgsFieldMap::iterator it = attributeFields.begin(); it != attributeFields.end(); ++it )
   {
@@ -300,20 +309,7 @@
     }
   }
 
-  if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
-  {
-    QgsDebugMsg( "Data store is valid" );
-    QgsDebugMsg( "Number of features " + QString::number( mNumberFeatures ) );
-    QgsDebugMsg( "Extents " + mExtent.toString() );
-
-    mValid = true;
-  }
-  else
-  {
-    QgsDebugMsg( "Data store is invalid. Specified x,y fields do not match those in the database" );
-  }
-  QgsDebugMsg( "Done checking validity" );
-
+  mValid = true;
 }
 
 QgsDelimitedTextProvider::~QgsDelimitedTextProvider()
@@ -346,26 +342,20 @@
 
     bool xOk = false;
     bool yOk = false;
+    bool geometryOk = false;
 
     // Skip indexing malformed lines.
-    if ( attributeFields.size() == tokens.size() )
+    if ( mXFieldIndex < 0 || mYFieldIndex < 0 )
     {
+      geometryOk = false;
+    }
+    else if ( attributeFields.size() == tokens.size() )
+    {
       x = tokens[mXFieldIndex].toDouble( &xOk );
       y = tokens[mYFieldIndex].toDouble( &yOk );
+      geometryOk = ( xOk && yOk );
     }
 
-    if ( !( xOk && yOk ) )
-    {
-      // Accumulate any lines that weren't ok, to report on them
-      // later, and look at the next line in the file, but only if
-      // we need to.
-      QgsDebugMsg( "Malformed line : " + line );
-      if ( mShowInvalidLines )
-        mInvalidLines << line;
-
-      continue;
-    }
-
     // Give every valid line in the file an id, even if it's not
     // in the current extent or bounds.
     ++mFid;             // increment to next feature ID
@@ -405,11 +395,18 @@
     s << x;
     s << y;
 
-    unsigned char* geometry = new unsigned char[buffer.size()];
-    memcpy( geometry, buffer.data(), buffer.size() );
+    unsigned char* geometry = 0;
+    if ( geometryOk )
+    {
+      geometry = new unsigned char[buffer.size()];
+      memcpy( geometry, buffer.data(), buffer.size() );
+      feature.setGeometryAndOwnership( geometry, sizeof( wkbPoint ) );
+    }
+    else
+    {
+      feature.setGeometryAndOwnership( 0, 0 );
+    }
 
-    feature.setGeometryAndOwnership( geometry, sizeof( wkbPoint ) );
-
     for ( QgsAttributeList::const_iterator i = mAttributesToFetch.begin();
           i != mAttributesToFetch.end();
           ++i )
@@ -502,7 +499,7 @@
  */
 QGis::WkbType QgsDelimitedTextProvider::geometryType() const
 {
-  return QGis::WKBPoint;
+  return mWkbType;
 }
 
 /**
@@ -547,8 +544,8 @@
  */
 bool QgsDelimitedTextProvider::boundsCheck( double x, double y )
 {
-  // no selection rectangle => always in the bounds
-  if ( mSelectionRectangle.isEmpty() )
+  // no selection rectangle or geometry => always in the bounds
+  if ( mSelectionRectangle.isEmpty() || !mFetchGeom )
     return true;
 
   return ( x <= mSelectionRectangle.xMaximum() ) && ( x >= mSelectionRectangle.xMinimum() ) &&

Modified: trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h
===================================================================
--- trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h	2010-08-31 11:16:07 UTC (rev 14171)
+++ trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h	2010-09-01 08:48:55 UTC (rev 14172)
@@ -219,6 +219,8 @@
     };
     wkbPoint mWKBpt;
 
+    QGis::WkbType mWkbType; //can be WKBPoint or NoGeometry
+
     QStringList splitLine( QString line );
 
 };



More information about the QGIS-commit mailing list