[QGIS Commit] r8233 - in trunk/qgis: python/core src/app src/core
src/providers/grass src/providers/ogr src/providers/postgres
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sun Mar 16 12:52:11 EDT 2008
Author: jef
Date: 2008-03-16 12:52:11 -0400 (Sun, 16 Mar 2008)
New Revision: 8233
Modified:
trunk/qgis/python/core/qgsvectordataprovider.sip
trunk/qgis/src/app/qgsuniquevaluedialog.cpp
trunk/qgis/src/core/qgsvectordataprovider.cpp
trunk/qgis/src/core/qgsvectordataprovider.h
trunk/qgis/src/providers/grass/qgsgrassprovider.h
trunk/qgis/src/providers/ogr/qgsogrprovider.cpp
trunk/qgis/src/providers/ogr/qgsogrprovider.h
trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
trunk/qgis/src/providers/postgres/qgspostgresprovider.h
Log:
- add getUniqueValues method to QgsVectorDataProvider
- implement getUniqueValues in QgsPostgresProvider (fixes #399)
- implement getUniqueValues, minValue and maxValue in OgsOgrProvider
- use getUniqueValues in QgsUniqueValueDialog
- update QgsPostgresProvider::storageType interface (fixes #995)
(applied patch from Steven Mizuno, thanks again)
Modified: trunk/qgis/python/core/qgsvectordataprovider.sip
===================================================================
--- trunk/qgis/python/core/qgsvectordataprovider.sip 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/python/core/qgsvectordataprovider.sip 2008-03-16 16:52:11 UTC (rev 8233)
@@ -135,6 +135,15 @@
*/
virtual QVariant maxValue(int index);
+ /**
+ * Return unique values of an attribute
+ * @param index the index of the attribute
+ * @param values reference to the list to fill
+ *
+ * Default implementation simply iterates the features
+ */
+ virtual void getUniqueValues(int index, QStringList &uniqueValues);
+
/**
* Adds a list of features
* @return true in case of success and false in case of failure
Modified: trunk/qgis/src/app/qgsuniquevaluedialog.cpp
===================================================================
--- trunk/qgis/src/app/qgsuniquevaluedialog.cpp 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/app/qgsuniquevaluedialog.cpp 2008-03-16 16:52:11 UTC (rev 8233)
@@ -157,33 +157,26 @@
QgsVectorDataProvider *provider = dynamic_cast<QgsVectorDataProvider *>(mVectorLayer->getDataProvider());
if (provider)
{
- QString value;
- QgsAttributeList attlist;
-
QgsSymbol* symbol;
int nr = provider->indexFromFieldName(attributeName);
if(nr == -1)
{
return;
}
- attlist.append(nr);
- provider->select(attlist, QgsRect(), false);
- QgsFeature feat;
-
//go through all the features and insert their value into the map and into mClassListWidget
mClassListWidget->clear();
- while(provider->getNextFeature(feat))
- {
- const QgsAttributeMap& attrs = feat.attributeMap();
- value = attrs[nr].toString();
- if(mValues.find(value)==mValues.end())
+ QStringList keys;
+ provider->getUniqueValues(nr, keys);
+
+ QStringListIterator it(keys);
+ while( it.hasNext() )
{
+ QString value = it.next();
symbol=new QgsSymbol(mVectorLayer->vectorType(), value);
mValues.insert(std::make_pair(value,symbol));
}
- }
//set symbology for all QgsSiSyDialogs
QColor thecolor;
Modified: trunk/qgis/src/core/qgsvectordataprovider.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectordataprovider.cpp 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/core/qgsvectordataprovider.cpp 2008-03-16 16:52:11 UTC (rev 8233)
@@ -291,6 +291,21 @@
return mCacheMaxValues[index];
}
+void QgsVectorDataProvider::getUniqueValues(int index, QStringList &values)
+{
+ QgsFeature f;
+ QgsAttributeList keys;
+ keys.append(index);
+ select(keys, QgsRect(), false);
+
+ QMap<QString,int> map;
+
+ while( getNextFeature(f) )
+ map.insert( f.attributeMap()[index].toString(), 1);
+
+ values = map.keys();
+}
+
void QgsVectorDataProvider::fillMinMaxCache()
{
const QgsFieldMap& flds = fields();
Modified: trunk/qgis/src/core/qgsvectordataprovider.h
===================================================================
--- trunk/qgis/src/core/qgsvectordataprovider.h 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/core/qgsvectordataprovider.h 2008-03-16 16:52:11 UTC (rev 8233)
@@ -153,7 +153,7 @@
* @param index the index of the attribute
*
* Default implementation walks all numeric attributes and caches minimal
- * and maximal values. If provider has facilities to retreive minimal
+ * and maximal values. If provider has facilities to retrieve minimal
* value directly, override this function.
*/
virtual QVariant minValue(int index);
@@ -163,12 +163,21 @@
* @param index the index of the attribute
*
* Default implementation walks all numeric attributes and caches minimal
- * and maximal values. If provider has facilities to retreive maximal
+ * and maximal values. If provider has facilities to retrieve maximal
* value directly, override this function.
*/
virtual QVariant maxValue(int index);
/**
+ * Return unique values of an attribute
+ * @param index the index of the attribute
+ * @param values reference to the list to fill
+ *
+ * Default implementation simply iterates the features
+ */
+ virtual void getUniqueValues(int index, QStringList &uniqueValues);
+
+ /**
* Adds a list of features
* @return true in case of success and false in case of failure
*/
Modified: trunk/qgis/src/providers/grass/qgsgrassprovider.h
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrassprovider.h 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/providers/grass/qgsgrassprovider.h 2008-03-16 16:52:11 UTC (rev 8233)
@@ -119,7 +119,7 @@
/**
* Returns the permanent storage type for this layer as a friendly name.
*/
- QString storageType() const;
+ virtual QString storageType() const;
/** Select features based on a bounding rectangle. Features can be retrieved with calls to getNextFeature.
Modified: trunk/qgis/src/providers/ogr/qgsogrprovider.cpp
===================================================================
--- trunk/qgis/src/providers/ogr/qgsogrprovider.cpp 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/providers/ogr/qgsogrprovider.cpp 2008-03-16 16:52:11 UTC (rev 8233)
@@ -30,6 +30,7 @@
#include <QtDebug>
#include <QFile>
+#include <QDir>
#include <QFileInfo>
#include <QMap>
#include <QString>
@@ -483,7 +484,6 @@
OGRFeatureH feature= OGR_F_Create(fdef);
QGis::WKBTYPE ftype = f.geometry()->wkbType();
unsigned char* wkb = f.geometry()->wkbBuffer();
- OGRErr err;
if( f.geometry()->wkbSize() > 0 )
{
@@ -901,8 +901,6 @@
-
-
QGISEXTERN QString fileVectorFilters()
{
static QString myFileFilters;
@@ -1217,7 +1215,6 @@
return true;
}
-
QgsSpatialRefSys QgsOgrProvider::getSRS()
{
QgsDebugMsg("QgsOgrProvider::getSRS()");
@@ -1246,3 +1243,109 @@
return srs;
}
+
+void QgsOgrProvider::getUniqueValues(int index, QStringList &uniqueValues)
+{
+ QgsField fld = mAttributeFields[index];
+ QFileInfo fi( dataSourceUri() );
+ if( !fi.exists() )
+ return;
+
+ QString sql = QString("SELECT DISTINCT %1 FROM %2 ORDER BY %1").arg( fld.name() ).arg( fi.baseName() );
+
+ uniqueValues.clear();
+
+ OGRLayerH l = OGR_DS_ExecuteSQL(ogrDataSource, sql.ascii(), NULL, "SQL");
+ if(l==0)
+ return;
+
+ OGRFeatureH f;
+ while( f=OGR_L_GetNextFeature(l) )
+ {
+ uniqueValues.append( mEncoding->toUnicode(OGR_F_GetFieldAsString(f, 0)) );
+ OGR_F_Destroy(f);
+ }
+
+ OGR_DS_ReleaseResultSet(l, ogrDataSource);
+}
+
+
+
+QVariant QgsOgrProvider::minValue(int index)
+{
+ QgsField fld = mAttributeFields[index];
+ QFileInfo fi( dataSourceUri() );
+ if( !fi.exists() )
+ return QVariant();
+
+ QString sql = QString("SELECT MIN(%1) FROM %2").arg( fld.name() ).arg( fi.baseName() );
+
+ OGRLayerH l = OGR_DS_ExecuteSQL(ogrDataSource, sql.ascii(), NULL, "SQL");
+
+ if(l==0)
+ return QVariant();
+
+ OGRFeatureH f = OGR_L_GetNextFeature(l);
+ if(f==0)
+ {
+ OGR_DS_ReleaseResultSet(l, ogrDataSource);
+ return QVariant();
+ }
+
+ QString str = mEncoding->toUnicode( mEncoding->toUnicode( OGR_F_GetFieldAsString(f,0) ) );
+ OGR_F_Destroy(f);
+
+ QVariant value;
+
+ switch (fld.type())
+ {
+ case QVariant::String: value = QVariant(str); break;
+ case QVariant::Int: value = QVariant(str.toInt()); break;
+ case QVariant::Double: value = QVariant(str.toDouble()); break;
+ //case QVariant::DateTime: value = QVariant(QDateTime::fromString(str)); break;
+ default: assert(NULL && "unsupported field type");
+ }
+
+ OGR_DS_ReleaseResultSet(l, ogrDataSource);
+
+ return value;
+}
+
+QVariant QgsOgrProvider::maxValue(int index)
+{
+ QgsField fld = mAttributeFields[index];
+ QFileInfo fi( dataSourceUri() );
+ if( !fi.exists() )
+ return QVariant();
+
+ QString sql = QString("SELECT MAX(%1) FROM %2").arg( fld.name() ).arg( fi.baseName() );
+
+ OGRLayerH l = OGR_DS_ExecuteSQL(ogrDataSource, sql.ascii(), NULL, "SQL");
+ if(l==0)
+ return QVariant();
+
+ OGRFeatureH f = OGR_L_GetNextFeature(l);
+ if(f==0)
+ {
+ OGR_DS_ReleaseResultSet(l, ogrDataSource);
+ return QVariant();
+ }
+
+ QString str = mEncoding->toUnicode( mEncoding->toUnicode( OGR_F_GetFieldAsString(f,0) ) );
+ OGR_F_Destroy(f);
+
+ QVariant value;
+
+ switch (fld.type())
+ {
+ case QVariant::String: value = QVariant(str); break;
+ case QVariant::Int: value = QVariant(str.toInt()); break;
+ case QVariant::Double: value = QVariant(str.toDouble()); break;
+ //case QVariant::DateTime: value = QVariant(QDateTime::fromString(str)); break;
+ default: assert(NULL && "unsupported field type");
+ }
+
+ OGR_DS_ReleaseResultSet(l, ogrDataSource);
+
+ return value;
+}
Modified: trunk/qgis/src/providers/ogr/qgsogrprovider.h
===================================================================
--- trunk/qgis/src/providers/ogr/qgsogrprovider.h 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/providers/ogr/qgsogrprovider.h 2008-03-16 16:52:11 UTC (rev 8233)
@@ -182,7 +182,19 @@
*/
bool isValid();
+ /** Returns the minimum value of an attribute
+ * @param index the index of the attribute */
+ QVariant minValue(int index);
+ /** Returns the maximum value of an attribute
+ * @param index the index of the attribute */
+ QVariant maxValue(int index);
+
+ /** Return the unique values of an attribute
+ * @param index the index of the attribute
+ * @param values reference to the list of unique values */
+ virtual void getUniqueValues(int index, QStringList &uniqueValues);
+
protected:
/** loads fields from input file to member attributeFields */
void loadFields();
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2008-03-16 16:52:11 UTC (rev 8233)
@@ -334,7 +334,7 @@
connection = 0;
}
-QString QgsPostgresProvider::storageType()
+QString QgsPostgresProvider::storageType() const
{
return "PostgreSQL database with PostGIS extension";
}
@@ -1272,10 +1272,8 @@
PGresult* unique = PQexec(connection, sql.toUtf8());
- if (PQntuples(unique) == 1)
-// if (strncmp(PQgetvalue(unique, 0, 0),"t", 1) == 0)
- if (QString::fromUtf8(PQgetvalue(unique, 0, 0)).compare("t") == 0) //really should compare just first character as original did
- isUnique = true;
+ if (PQntuples(unique)==1 && QString::fromUtf8(PQgetvalue(unique, 0, 0)).startsWith("t") == 0)
+ isUnique = true;
PQclear(unique);
@@ -1634,6 +1632,37 @@
return minValue.toDouble();
}
+// Returns the list of unique values of an attribute
+void QgsPostgresProvider::getUniqueValues(int index, QStringList &uniqueValues)
+{
+ // get the field name
+ QgsField fld = attributeFields[index];
+ QString sql;
+ if(sqlWhereClause.isEmpty())
+ {
+ sql = QString("select distinct %1 from %2 order by %1")
+ .arg(quotedIdentifier(fld.name()))
+ .arg(mSchemaTableName);
+ }
+ else
+ {
+ sql = QString("select distinct %1 from %2 where %3 order by %1")
+ .arg(quotedIdentifier(fld.name()))
+ .arg(mSchemaTableName)
+ .arg(sqlWhereClause);
+ }
+
+ uniqueValues.clear();
+
+ PGresult *res= PQexec(connection, sql.toUtf8());
+ if (PQresultStatus(res) == PGRES_TUPLES_OK)
+ {
+ for(int i=0; i<PQntuples(res); i++)
+ uniqueValues.append( QString::fromUtf8(PQgetvalue(res,i,0)) );
+ }
+ PQclear(res);
+}
+
// Returns the maximum value of an attribute
QVariant QgsPostgresProvider::maxValue(int index)
@@ -1700,7 +1729,7 @@
if (PQntuples(result)==1 && !PQgetisnull(result, 0, 0) )
defaultValue = QString::fromUtf8(PQgetvalue(result, 0, 0));
- QgsDebugMsg( QString("defaultValue for %1 is NULL: %2").arg(fieldId).arg( defaultValue.isNull() ) );
+ // QgsDebugMsg( QString("defaultValue for %1 is NULL: %2").arg(fieldId).arg( defaultValue.isNull() ) );
PQclear(result);
@@ -2391,7 +2420,7 @@
// version 7.4, binary cursors return data in XDR whereas previous versions
// return data in the endian of the server
- QString firstOid = "select regclass('" + mSchemaTableName + "')::oid";
+ QString firstOid = "select regclass(" + quotedValue(mSchemaTableName) + ")::oid";
PGresult * oidResult = PQexec(connection, firstOid.toUtf8());
// get the int value from a "normal" select
QString oidValue = QString::fromUtf8(PQgetvalue(oidResult,0,0));
@@ -2577,13 +2606,13 @@
return result;
}
-QString QgsPostgresProvider::quotedIdentifier( QString ident )
+QString QgsPostgresProvider::quotedIdentifier( QString ident ) const
{
ident.replace('"', "\"\"");
return ident.prepend("\"").append("\"");
}
-QString QgsPostgresProvider::quotedValue( QString value )
+QString QgsPostgresProvider::quotedValue( QString value ) const
{
if( value.isNull() )
return "NULL";
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.h
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.h 2008-03-16 16:35:51 UTC (rev 8232)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.h 2008-03-16 16:52:11 UTC (rev 8233)
@@ -69,7 +69,7 @@
/**
* Returns the permanent storage type for this layer as a friendly name.
*/
- QString storageType();
+ virtual QString storageType() const;
/*! Get the QgsSpatialRefSys for this layer
* @note Must be reimplemented by each provider.
@@ -131,8 +131,6 @@
*/
size_t layerCount() const;
-
-
/**
* Get the number of features in the layer
*/
@@ -184,14 +182,19 @@
*/
void reset();
- /** Returns the minimum value of an attributs
+ /** Returns the minimum value of an attribute
* @param index the index of the attribute */
QVariant minValue(int index);
- /** Returns the maximum value of an attributs
+ /** Returns the maximum value of an attribute
* @param index the index of the attribute */
QVariant maxValue(int index);
+ /** Return the unique values of an attribute
+ * @param index the index of the attribute
+ * @param values reference to the list of unique values */
+ virtual void getUniqueValues(int index, QStringList &uniqueValues);
+
/**Returns true if layer is valid
*/
bool isValid();
@@ -330,11 +333,11 @@
/** Double quote a PostgreSQL identifier for placement in a SQL string.
*/
- QString quotedIdentifier( QString ident );
+ QString quotedIdentifier( QString ident ) const;
/** Quote a value for placement in a SQL string.
*/
- QString quotedValue( QString value );
+ QString quotedValue( QString value ) const;
/** Load the field list
*/
More information about the QGIS-commit
mailing list