[QGIS Commit] r15074 - in trunk/qgis: python/core src/core src/plugins/delimited_text src/providers/delimitedtext src/providers/memory

svn_qgis at osgeo.org svn_qgis at osgeo.org
Tue Jan 25 00:50:42 EST 2011


Author: gsherman
Date: 2011-01-24 21:50:42 -0800 (Mon, 24 Jan 2011)
New Revision: 15074

Modified:
   trunk/qgis/python/core/qgscoordinatereferencesystem.sip
   trunk/qgis/src/core/qgscoordinatereferencesystem.cpp
   trunk/qgis/src/core/qgscoordinatereferencesystem.h
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui
   trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
   trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h
   trunk/qgis/src/providers/memory/qgsmemoryprovider.cpp
   trunk/qgis/src/providers/memory/qgsmemoryprovider.h
Log:
Patch for delimited text, ticket #3414. Submitted by ccrook.

Modified: trunk/qgis/python/core/qgscoordinatereferencesystem.sip
===================================================================
--- trunk/qgis/python/core/qgscoordinatereferencesystem.sip	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/python/core/qgscoordinatereferencesystem.sip	2011-01-25 05:50:42 UTC (rev 15074)
@@ -23,11 +23,12 @@
 
         ~QgsCoordinateReferenceSystem();
         
-        /*! 
-         * Constructs a CRS object from a Wkt string
-         * @param theWkt A String containing a valid Wkt def
+        /*!
+         * Constructs a CRS object from a string definition as defined in the createFromString 
+         * member function (by default a WKT definition).
+         * @param theDefinition A String containing a coordinate reference system definition.
          */
-        explicit QgsCoordinateReferenceSystem(QString theWkt);
+        explicit QgsCoordinateReferenceSystem( QString theDefinition );
 
         /*! Use this constructor when you want to create a CRS object using 
          *  a postgis SRID, an Epsg Id id or a QGIS CRS_ID.
@@ -38,7 +39,7 @@
 
         // Misc helper functions -----------------------
 
-        void createFromId(const long theId, CrsType theType=PostgisCrsId);
+        bool createFromId(const long theId, CrsType theType=PostgisCrsId);
 
         /**
          * \brief Set up this CRS from the given OGC CRS
@@ -70,6 +71,15 @@
          * @return bool TRUE if sucess else false
          */
         bool createFromWkt(const QString theWkt);
+        
+        /*! Set up this srs from a string definition, by default a WKT definition.  Otherwise
+         * the string defines a authority, followed by a colon, followed by the definition.
+         * The authority can be one of "epsg", "postgis", "internal" for integer definitions,
+         * and "wkt" or "proj4" for string definitions.  The implementation of each authority
+         * uses the corresponding createFrom... function.
+         * @param theDefinition A String containing a coordinate reference system definition.
+         */
+        bool createFromString( const QString theDefinition );
 
         /*! Set up this srs by fetching the appropriate information from the 
          * sqlite backend. First the system level read only srs.db will be checked

Modified: trunk/qgis/src/core/qgscoordinatereferencesystem.cpp
===================================================================
--- trunk/qgis/src/core/qgscoordinatereferencesystem.cpp	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/core/qgscoordinatereferencesystem.cpp	2011-01-25 05:50:42 UTC (rev 15074)
@@ -51,13 +51,13 @@
   mCRS = OSRNewSpatialReference( NULL );
 }
 
-QgsCoordinateReferenceSystem::QgsCoordinateReferenceSystem( QString theWkt )
+QgsCoordinateReferenceSystem::QgsCoordinateReferenceSystem( QString theDefinition )
     : mMapUnits( QGis::UnknownUnit )
     , mIsValidFlag( 0 )
     , mValidationHint( "" )
 {
   mCRS = OSRNewSpatialReference( NULL );
-  createFromWkt( theWkt );
+  createFromString( theDefinition );
 }
 
 
@@ -75,25 +75,58 @@
   OSRDestroySpatialReference( mCRS );
 }
 
-void QgsCoordinateReferenceSystem::createFromId( const long theId, CrsType theType )
+bool QgsCoordinateReferenceSystem::createFromId( const long theId, CrsType theType )
 {
+  bool result = false;
   switch ( theType )
   {
     case InternalCrsId:
-      createFromSrsId( theId );
+      result = createFromSrsId( theId );
       break;
     case PostgisCrsId:
-      createFromSrid( theId );
+      result = createFromSrid( theId );
       break;
     case EpsgCrsId:
-      createFromEpsg( theId );
+      result = createFromEpsg( theId );
       break;
     default:
       //THIS IS BAD...THIS PART OF CODE SHOULD NEVER BE REACHED...
       QgsDebugMsg( "Unexpected case reached!" );
   };
+  return result;
 }
 
+bool QgsCoordinateReferenceSystem::createFromString( const QString theDefinition )
+{
+  bool result = false;
+  QRegExp reCrsId("^(epsg|postgis|internal)\\:(\\d+)$",Qt::CaseInsensitive);
+  if( reCrsId.indexIn(theDefinition) == 0)
+  {
+      QString authName = reCrsId.cap(1).toLower();
+      CrsType type = InternalCrsId;
+      if( authName == "epsg" ) type = EpsgCrsId;
+      if( authName == "postgis" ) type = PostgisCrsId;
+      long id = reCrsId.cap(2).toLong();
+      result = createFromId(id,type);
+  }
+  else
+  {
+      QRegExp reCrsStr("^(?:(wkt|proj4)\\:)?(.+)$",Qt::CaseInsensitive);
+      if( reCrsStr.indexIn(theDefinition) == 0 )
+      {
+          if( reCrsStr.cap(1).toLower() == "proj4" )
+          {
+             result = createFromProj4(reCrsStr.cap(2));
+          }
+          else
+          {
+              result = createFromWkt(reCrsStr.cap(2));
+          }
+      }
+  }
+  return result;
+}
+
 bool QgsCoordinateReferenceSystem::createFromOgcWmsCrs( QString theCrs )
 {
   if ( loadFromDb( QgsApplication::srsDbFilePath(), "lower(auth_name||':'||auth_id)", theCrs.toLower() ) )

Modified: trunk/qgis/src/core/qgscoordinatereferencesystem.h
===================================================================
--- trunk/qgis/src/core/qgscoordinatereferencesystem.h	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/core/qgscoordinatereferencesystem.h	2011-01-25 05:50:42 UTC (rev 15074)
@@ -57,10 +57,11 @@
     ~QgsCoordinateReferenceSystem();
 
     /*!
-     * Constructs a CRS object from a Wkt string
-     * @param theWkt A String containing a valid Wkt def
+     * Constructs a CRS object from a string definition as defined in the createFromString 
+     * member function (by default a WKT definition).
+     * @param theDefinition A String containing a coordinate reference system definition.
      */
-    explicit QgsCoordinateReferenceSystem( QString theWkt );
+    explicit QgsCoordinateReferenceSystem( QString theDefinition );
 
     /*! Use this constructor when you want to create a CRS object using
      *  a postgis SRID, an EpsgCrsId id or a QGIS CRS_ID.
@@ -79,7 +80,7 @@
 
     // Misc helper functions -----------------------
 
-    void createFromId( const long theId, CrsType theType = PostgisCrsId );
+    bool createFromId( const long theId, CrsType theType = PostgisCrsId );
 
     /**
      * \brief Set up this CRS from the given OGC CRS
@@ -161,6 +162,15 @@
      * @return bool TRUE if sucess else false
      */
     bool createFromProj4( const QString theProjString );
+    
+    /*! Set up this srs from a string definition, by default a WKT definition.  Otherwise
+     * the string defines a authority, followed by a colon, followed by the definition.
+     * The authority can be one of "epsg", "postgis", "internal" for integer definitions,
+     * and "wkt" or "proj4" for string definitions.  The implementation of each authority
+     * uses the corresponding createFrom... function.
+     * @param theDefinition A String containing a coordinate reference system definition.
+     */
+    bool createFromString( const QString theDefinition );
 
     /*! Find out whether this CRS is correctly initialised and usable */
     bool isValid() const;

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp	2011-01-25 05:50:42 UTC (rev 15074)
@@ -25,6 +25,7 @@
 #include <QRegExp>
 #include <QMessageBox>
 #include <QTextStream>
+#include <QUrl>
 #include "qgslogger.h"
 
 QgsDelimitedTextPluginGui::QgsDelimitedTextPluginGui( QgisInterface * _qI, QWidget * parent, Qt::WFlags fl )
@@ -56,6 +57,13 @@
     delimiterRegexp->setChecked( true );
   }
 
+  QString delimiterChars = settings.value( key + "/delimiterChars", " " ).toString();
+  cbxDelimSpace->setChecked( delimiterChars.contains(" "));
+  cbxDelimTab->setChecked( delimiterChars.contains("\\t"));
+  cbxDelimColon->setChecked( delimiterChars.contains(":"));
+  cbxDelimSemicolon->setChecked( delimiterChars.contains(":"));
+  cbxDelimComma->setChecked( delimiterChars.contains(","));
+
   cmbXField->setDisabled( true );
   cmbYField->setDisabled( true );
   cmbWktField->setDisabled( true );
@@ -99,34 +107,33 @@
     else if ( delimiterRegexp->isChecked() )
       delimiterType = "regexp";
 
-    QString uri = QString( "%1?delimiter=%2&delimiterType=%3" )
-                  .arg( txtFilePath->text() )
-                  .arg( txtDelimiter->text() )
-                  .arg( delimiterType );
+    QUrl url(txtFilePath->text());
+    url.addQueryItem("delimiter",txtDelimiter->text());
+    url.addQueryItem("delimiterType",delimiterType);
 
     if ( geomTypeXY->isChecked() )
     {
       if ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() )
       {
-        uri += QString( "&xField=%1&yField=%2" )
-               .arg( cmbXField->currentText() )
-               .arg( cmbYField->currentText() );
+          url.addQueryItem("xField",cmbXField->currentText());
+          url.addQueryItem("yField",cmbYField->currentText());
       }
     }
     else
     {
       if ( ! cmbWktField->currentText().isEmpty() )
       {
-        uri += QString( "&wktField=%1" )
-               .arg( cmbWktField->currentText() );
+        url.addQueryItem("wktField",cmbWktField->currentText());
       }
     }
 
     int skipLines = rowCounter->value();
     if ( skipLines > 0 )
-      uri += QString( "&skipLines=%1" ).arg( skipLines );
+        url.addQueryItem("skipLines",QString( "%1" ).arg( skipLines ));
 
     // add the layer to the map
+
+    QString uri(url.toEncoded());
     emit drawVectorLayer( uri, txtLayerName->text(), "delimitedtext" );
     // store the settings
 
@@ -138,10 +145,11 @@
 
     if ( delimiterSelection->isChecked() )
       settings.setValue( key + "/delimiterType", "selection" );
-    if ( delimiterPlain->isChecked() )
+    else if ( delimiterPlain->isChecked() )
       settings.setValue( key + "/delimiterType", "plain" );
     else
       settings.setValue( key + "/delimiterType", "regexp" );
+    settings.setValue( key + "/delimiterChars", selectedChars());
 
     accept();
   }
@@ -156,6 +164,17 @@
   reject();
 }
 
+QString QgsDelimitedTextPluginGui::selectedChars()
+{
+    QString chars = "";
+    if ( cbxDelimSpace->isChecked() ) chars += " ";
+    if ( cbxDelimTab->isChecked() ) chars += "\\t";
+    if ( cbxDelimSemicolon->isChecked() ) chars += ";";
+    if ( cbxDelimComma->isChecked() ) chars += ",";
+    if ( cbxDelimColon->isChecked() ) chars += ":";
+    return chars;
+}
+
 QStringList QgsDelimitedTextPluginGui::splitLine( QString line )
 {
   QStringList fieldList;
@@ -171,11 +190,7 @@
   else if ( delimiterSelection->isChecked() )
   {
     delimiter = "[";
-    if ( cbxDelimSpace->isChecked() ) delimiter += " ";
-    if ( cbxDelimTab->isChecked() ) delimiter += "\t";
-    if ( cbxDelimSemicolon->isChecked() ) delimiter += ";";
-    if ( cbxDelimComma->isChecked() ) delimiter += ",";
-    if ( cbxDelimColon->isChecked() ) delimiter += ":";
+    delimiter += selectedChars();
     delimiter += "]";
     txtDelimiter->setText( delimiter );
     fieldList = line.split( QRegExp( delimiter ) );

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h	2011-01-25 05:50:42 UTC (rev 15074)
@@ -37,6 +37,7 @@
     bool haveValidFileAndDelimiters();
     void updateFieldLists();
     void getOpenFileName();
+    QString selectedChars();
 
     QgisInterface * qI;
     QAbstractButton *pbnOK;

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui	2011-01-25 05:50:42 UTC (rev 15074)
@@ -331,7 +331,7 @@
            <string>Name of the field containing x values. Choose a field from the list. The list is generated by parsing the header row of the delimited text file.</string>
           </property>
           <property name="editable">
-           <bool>true</bool>
+           <bool>false</bool>
           </property>
          </widget>
         </item>
@@ -366,7 +366,7 @@
            <string>Name of the field containing y values. Choose a field from the list. The list is generated by parsing the header row of the delimited text file.</string>
           </property>
           <property name="editable">
-           <bool>true</bool>
+           <bool>false</bool>
           </property>
          </widget>
         </item>
@@ -409,7 +409,7 @@
          <string>Name of the field containing y values. Choose a field from the list. The list is generated by parsing the header row of the delimited text file.</string>
         </property>
         <property name="editable">
-         <bool>true</bool>
+         <bool>false</bool>
         </property>
        </widget>
       </item>

Modified: trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
===================================================================
--- trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp	2011-01-25 05:50:42 UTC (rev 15074)
@@ -18,7 +18,6 @@
 
 #include "qgsdelimitedtextprovider.h"
 
-
 #include <QtGlobal>
 #include <QFile>
 #include <QDataStream>
@@ -135,49 +134,42 @@
     : QgsVectorDataProvider( uri )
     , mHasWktField( false )
     , mFieldCount( 0 )
-    , mXFieldIndex( -1 ), mYFieldIndex( -1 )
+    , mXFieldIndex( -1 ) 
+    , mYFieldIndex( -1 )
     , mWktFieldIndex( -1 )
+    , mDelimiterType( "plain" )
+    , mDelimiter( "," )
+    , mDelimiterRegexp()
     , mWktHasZM( false )
     , mWktZMRegexp( "\\s+(?:z|m|zm)(?=\\s*\\()", Qt::CaseInsensitive )
     , mWktCrdRegexp( "(\\-?\\d+(?:\\.\\d*)?\\s+\\-?\\d+(?:\\.\\d*)?)\\s[\\s\\d\\.\\-]+" )
+    , mSkipLines(0)
     , mFirstDataLine( 0 )
     , mShowInvalidLines( true )
     , mWkbType( QGis::WKBNoGeometry )
+    , mCrs()
 {
-  // Get the file name and mDelimiter out of the uri
-  mFileName = uri.left( uri.indexOf( "?" ) );
-  // split the string up on & to get the individual parameters
-  QStringList parameters = uri.mid( uri.indexOf( "?" ) ).split( "&", QString::SkipEmptyParts );
 
-  QgsDebugMsg( "Parameter count after split on &" + QString::number( parameters.size() ) );
+  QUrl url = QUrl::fromEncoded(uri.toUtf8());
 
-  // get the individual parameters and assign values
-  QStringList temp = parameters.filter( "delimiter=" );
-  mDelimiter = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
-  temp = parameters.filter( "delimiterType=" );
-  mDelimiterType = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
-  temp = parameters.filter( "wktField=" );
-  QString wktField = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
-  temp = parameters.filter( "xField=" );
-  QString xField = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
-  temp = parameters.filter( "yField=" );
-  QString yField = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
-  temp = parameters.filter( "skipLines=" );
-  QString skipLines = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "0";
-  // Decode the parts of the uri. Good if someone entered '=' as a delimiter, for instance.
-  mFileName  = QUrl::fromPercentEncoding( mFileName.toUtf8() );
-  mDelimiter = QUrl::fromPercentEncoding( mDelimiter.toUtf8() );
-  mDelimiterType = QUrl::fromPercentEncoding( mDelimiterType.toUtf8() );
-  wktField = QUrl::fromPercentEncoding( wktField.toUtf8() );
-  xField = QUrl::fromPercentEncoding( xField.toUtf8() );
-  yField = QUrl::fromPercentEncoding( yField.toUtf8() );
+  // Extract the provider definition from the url
 
-  mHasWktField = wktField != "";
+  mFileName = url.path();
 
-  skipLines = QUrl::fromPercentEncoding( skipLines.toUtf8() );
+  QString wktField("");
+  QString xField("");
+  QString yField("");
 
-  mSkipLines = skipLines.toInt();
+  if( url.hasQueryItem("delimiter")) mDelimiter = url.queryItemValue("delimiter");
+  if( url.hasQueryItem("delimiterType")) mDelimiterType = url.queryItemValue("delimiterType");
+  if( url.hasQueryItem("wktField")) wktField = url.queryItemValue("wktField");
+  if( url.hasQueryItem("xField")) xField = url.queryItemValue("xField");
+  if( url.hasQueryItem("yField")) yField = url.queryItemValue("yField");
+  if( url.hasQueryItem("skipLines")) mSkipLines = url.queryItemValue("skipLines").toInt();
+  if( url.hasQueryItem("crs")) mCrs.createFromString( url.queryItemValue("crs"));
 
+  mHasWktField = wktField != "";
+
   QgsDebugMsg( "Data source uri is " + uri );
   QgsDebugMsg( "Delimited text file is: " + mFileName );
   QgsDebugMsg( "Delimiter is: " + mDelimiter );
@@ -481,7 +473,7 @@
         geom = 0;
       }
       mFid++;
-      if ( !boundsCheck( geom ) )
+      if ( geom && !boundsCheck( geom ) )
       {
         delete geom;
         geom = 0;
@@ -682,8 +674,7 @@
 
 QgsCoordinateReferenceSystem QgsDelimitedTextProvider::crs()
 {
-  // TODO: make provider projection-aware
-  return QgsCoordinateReferenceSystem(); // return default CRS
+  return mCrs;
 }
 
 

Modified: trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h
===================================================================
--- trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h	2011-01-25 05:50:42 UTC (rev 15074)
@@ -241,6 +241,9 @@
     };
     wkbPoint mWKBpt;
 
+    // Coordinate reference sytem
+    QgsCoordinateReferenceSystem mCrs;
+
     QGis::WkbType mWkbType;
 
     QString readLine( QTextStream *stream );

Modified: trunk/qgis/src/providers/memory/qgsmemoryprovider.cpp
===================================================================
--- trunk/qgis/src/providers/memory/qgsmemoryprovider.cpp	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/providers/memory/qgsmemoryprovider.cpp	2011-01-25 05:50:42 UTC (rev 15074)
@@ -22,7 +22,10 @@
 #include "qgsspatialindex.h"
 #include "qgscoordinatereferencesystem.h"
 
+#include <QUrl>
+#include <QRegExp>
 
+
 static const QString TEXT_PROVIDER_KEY = "memory";
 static const QString TEXT_PROVIDER_DESCRIPTION = "Memory provider";
 
@@ -31,21 +34,41 @@
     mSelectRectGeom( NULL ),
     mSpatialIndex( NULL )
 {
-  if ( uri == "Point" )
+  // Initiallize the geometry with the uri to support old style uri's 
+  // (ie, just 'point', 'line', 'polygon')
+  QUrl url = QUrl::fromEncoded(uri.toUtf8());
+  QString geometry;
+  if( url.hasQueryItem("geometry")) 
+  {
+      geometry = url.queryItemValue("geometry");
+  }
+  else
+  {
+      geometry = url.path();
+  }
+
+  geometry = geometry.toLower();
+  if ( geometry == "point" )
     mWkbType = QGis::WKBPoint;
-  else if ( uri == "LineString" )
+  else if ( geometry == "linestring" )
     mWkbType = QGis::WKBLineString;
-  else if ( uri == "Polygon" )
+  else if ( geometry == "polygon" )
     mWkbType = QGis::WKBPolygon;
-  else if ( uri == "MultiPoint" )
+  else if ( geometry == "multipoint" )
     mWkbType = QGis::WKBMultiPoint;
-  else if ( uri == "MultiLineString" )
+  else if ( geometry == "multilinestring" )
     mWkbType = QGis::WKBMultiLineString;
-  else if ( uri == "MultiPolygon" )
+  else if ( geometry == "multipolygon" )
     mWkbType = QGis::WKBMultiPolygon;
   else
     mWkbType = QGis::WKBUnknown;
 
+  if( url.hasQueryItem("crs"))
+  {
+      QString crsDef = url.queryItemValue("crs");
+      mCrs.createFromString(crsDef);
+  }
+
   mNextFeatureId = 1;
 
   mNativeTypes
@@ -53,6 +76,63 @@
   << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), "double", QVariant::Double, 1, 20, 0, 5 )
   << QgsVectorDataProvider::NativeType( tr( "Text (string)" ), "string", QVariant::String, 1, 255 )
   ;
+
+  if( url.hasQueryItem("field"))
+  {
+    QList<QgsField> attributes;
+    QRegExp reFieldDef("\\:" 
+                       "(int|integer|real|double|string)" // type
+                       "(?:\\((\\d+)"                // length
+                       "(?:\\,(\\d+))?"                // precision
+                       "\\))?"
+                       "$", Qt::CaseInsensitive);
+    QStringList fields = url.allQueryItemValues("field");
+    for( int i = 0; i < fields.size(); i++ )
+    {
+        QString name = fields.at(i);
+        QVariant::Type type = QVariant::String;
+        QString typeName("string");
+        int length = 255;
+        int precision = 0;
+        
+        int pos = reFieldDef.indexIn(name);
+        if( pos >= 0 )
+        {
+            name = name.mid(0,pos);
+            typeName = reFieldDef.cap(1).toLower();
+            if( typeName == "int" || typeName == "integer" )
+            {
+                type = QVariant::Int;
+                typeName = "integer";
+                length = 10;
+            }
+            else if( typeName == "real" || typeName == "double" )
+            {
+                type = QVariant::Double;
+                typeName = "double";
+                length=20;
+                precision = 5;
+            }
+
+            if( reFieldDef.cap(2) != "" )
+            {
+                length = reFieldDef.cap(2).toInt();
+            }
+            if( reFieldDef.cap(3) != "" )
+            {
+                precision = reFieldDef.cap(3).toInt();
+            }
+        }
+       if( name != "" ) attributes.append(QgsField(name,type,typeName,length,precision));
+    }
+    addAttributes(attributes);
+  }
+
+  if( url.hasQueryItem("index") && url.queryItemValue("index") == "yes" )
+  {
+      createSpatialIndex();
+  }
+
 }
 
 QgsMemoryProvider::~QgsMemoryProvider()
@@ -61,6 +141,69 @@
   delete mSelectRectGeom;
 }
 
+QString QgsMemoryProvider::dataSourceUri() const
+{
+    QUrl uri("memory");
+    QString geometry("");
+    switch(mWkbType)
+    {
+    case QGis::WKBPoint :
+        geometry="Point";
+        break;
+    case QGis::WKBLineString :
+        geometry="LineString";
+        break;
+    case QGis::WKBPolygon :
+        geometry="Polygon";
+        break;
+    case QGis::WKBMultiPoint :
+        geometry="MultiPoint";
+        break;
+    case QGis::WKBMultiLineString :
+        geometry="MultiLineString";
+        break;
+    case QGis::WKBMultiPolygon :
+        geometry="MultiPolygon";
+        break;
+    }
+    uri.addQueryItem("geometry",geometry);
+
+    if( mCrs.isValid())
+    {
+        QString crsDef("");
+        long srid = mCrs.epsg();
+        if( srid )
+        {
+            crsDef = QString("epsg:%1").arg(srid);
+        }
+        else if(  srid=mCrs.postgisSrid() )
+        {
+            crsDef = QString("postgis:%1").arg(srid);
+        }
+        else
+        {
+            crsDef = QString("wkt:%1").arg(mCrs.toWkt());
+        }
+        uri.addQueryItem("crs",crsDef);
+    }
+    if( mSpatialIndex )
+    {
+        uri.addQueryItem("index","yes");
+    }
+
+    QgsAttributeList attrs = const_cast<QgsMemoryProvider *>(this)->attributeIndexes();
+    for( int i = 0; i < attrs.size(); i++ )
+    {
+        QgsField field = mFields[attrs[i]];
+        QString fieldDef = field.name();
+        fieldDef.append(QString(":%2(%3,%4)").arg(field.typeName()).arg(field.length()).arg(field.precision()));
+        uri.addQueryItem("field",fieldDef);
+    }
+
+    return QString(uri.toEncoded());
+
+}
+
 QString QgsMemoryProvider::storageType() const
 {
   return "Memory storage";
@@ -231,7 +374,7 @@
 QgsCoordinateReferenceSystem QgsMemoryProvider::crs()
 {
   // TODO: make provider projection-aware
-  return QgsCoordinateReferenceSystem(); // return default CRS
+  return mCrs; // return default CRS
 }
 
 

Modified: trunk/qgis/src/providers/memory/qgsmemoryprovider.h
===================================================================
--- trunk/qgis/src/providers/memory/qgsmemoryprovider.h	2011-01-25 00:43:57 UTC (rev 15073)
+++ trunk/qgis/src/providers/memory/qgsmemoryprovider.h	2011-01-25 05:50:42 UTC (rev 15074)
@@ -34,6 +34,12 @@
     /**
      * Returns the permanent storage type for this layer as a friendly name.
      */
+
+    virtual QString dataSourceUri() const;
+
+    /**
+     * Returns the permanent storage type for this layer as a friendly name.
+     */
     virtual QString storageType() const;
 
     /** Select features based on a bounding rectangle. Features can be retrieved with calls to nextFeature.
@@ -185,6 +191,9 @@
     void updateExtent();
 
   private:
+    // Coordinate reference system
+    QgsCoordinateReferenceSystem mCrs;
+
     // fields
     QgsFieldMap mFields;
     QGis::WkbType mWkbType;



More information about the QGIS-commit mailing list