src/core/qgsvectordataprovider.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsvectordataprovider.cpp - DataProvider Interface for vector layers
00003      --------------------------------------
00004     Date                 : 26-Oct-2004
00005     Copyright            : (C) 2004 by Marco Hugentobler
00006     email                : marco.hugentobler@autoform.ch
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 /* $Id: qgsvectordataprovider.cpp 9605 2008-11-09 00:14:12Z timlinux $ */
00016 
00017 #include <QTextCodec>
00018 
00019 #include <cfloat> // for DBL_MAX
00020 #include <climits>
00021 
00022 #include "qgsvectordataprovider.h"
00023 #include "qgsfeature.h"
00024 #include "qgsfield.h"
00025 #include "qgslogger.h"
00026 
00027 QgsVectorDataProvider::QgsVectorDataProvider( QString uri )
00028     : QgsDataProvider( uri ),
00029     mCacheMinMaxDirty( TRUE ),
00030     mEncoding( QTextCodec::codecForLocale() ),
00031     mFetchFeaturesWithoutGeom( FALSE )
00032 {
00033 }
00034 
00035 
00036 QgsVectorDataProvider::~QgsVectorDataProvider()
00037 {
00038 }
00039 
00040 QString QgsVectorDataProvider::storageType() const
00041 {
00042   return "Generic vector file";
00043 }
00044 
00045 long QgsVectorDataProvider::updateFeatureCount()
00046 {
00047   return -1;
00048 }
00049 
00050 bool QgsVectorDataProvider::featureAtId( int featureId,
00051     QgsFeature& feature,
00052     bool fetchGeometry,
00053     QgsAttributeList fetchAttributes )
00054 {
00055   select( fetchAttributes, QgsRectangle(), fetchGeometry );
00056 
00057   while ( nextFeature( feature ) )
00058   {
00059     if ( feature.id() == featureId )
00060       return TRUE;
00061   }
00062 
00063   return FALSE;
00064 }
00065 
00066 QString QgsVectorDataProvider::dataComment() const
00067 {
00068   return QString();
00069 }
00070 
00071 bool QgsVectorDataProvider::addFeatures( QgsFeatureList &flist )
00072 {
00073   return false;
00074 }
00075 
00076 bool QgsVectorDataProvider::deleteFeatures( const QgsFeatureIds & id )
00077 {
00078   return false;
00079 }
00080 
00081 bool QgsVectorDataProvider::addAttributes( const QgsNewAttributesMap & attributes )
00082 {
00083   return false;
00084 }
00085 
00086 bool QgsVectorDataProvider::deleteAttributes( const QgsAttributeIds& attributes )
00087 {
00088   return false;
00089 }
00090 
00091 bool QgsVectorDataProvider::changeAttributeValues( const QgsChangedAttributesMap & attr_map )
00092 {
00093   return false;
00094 }
00095 
00096 QVariant QgsVectorDataProvider::defaultValue( int fieldId )
00097 {
00098   return QVariant();
00099 }
00100 
00101 bool QgsVectorDataProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
00102 {
00103   return false;
00104 }
00105 
00106 bool QgsVectorDataProvider::createSpatialIndex()
00107 {
00108   return false;
00109 }
00110 
00111 int QgsVectorDataProvider::capabilities() const
00112 {
00113   return QgsVectorDataProvider::NoCapabilities;
00114 }
00115 
00116 
00117 void QgsVectorDataProvider::setEncoding( const QString& e )
00118 {
00119   QTextCodec* ncodec = QTextCodec::codecForName( e.toLocal8Bit().data() );
00120   if ( ncodec )
00121   {
00122     mEncoding = ncodec;
00123   }
00124   else
00125   {
00126     QgsDebugMsg( "error finding QTextCodec for " + e );
00127   }
00128 }
00129 
00130 QString QgsVectorDataProvider::encoding() const
00131 {
00132   if ( mEncoding )
00133   {
00134     return mEncoding->name();
00135   }
00136 
00137   return "";
00138 }
00139 
00140 QString QgsVectorDataProvider::capabilitiesString() const
00141 {
00142   QStringList abilitiesList;
00143 
00144   int abilities = capabilities();
00145 
00146   if ( abilities & QgsVectorDataProvider::AddFeatures )
00147   {
00148     abilitiesList += "Add Features";
00149     QgsDebugMsg( "Capability: Add Features" );
00150   }
00151 
00152   if ( abilities & QgsVectorDataProvider::DeleteFeatures )
00153   {
00154     abilitiesList += "Delete Features";
00155     QgsDebugMsg( "Capability: Delete Features" );
00156   }
00157 
00158   if ( abilities & QgsVectorDataProvider::ChangeAttributeValues )
00159   {
00160     abilitiesList += "Change Attribute Values";
00161     QgsDebugMsg( "Capability: Change Attribute Values" );
00162   }
00163 
00164   if ( abilities & QgsVectorDataProvider::AddAttributes )
00165   {
00166     abilitiesList += "Add Attributes";
00167     QgsDebugMsg( "Capability: Add Attributes" );
00168   }
00169 
00170   if ( abilities & QgsVectorDataProvider::DeleteAttributes )
00171   {
00172     abilitiesList += "Delete Attributes";
00173     QgsDebugMsg( "Capability: Delete Attributes" );
00174   }
00175 
00176   if ( abilities & QgsVectorDataProvider::CreateSpatialIndex )
00177   {
00178     // TODO: Tighten up this test.  See QgsOgrProvider for details.
00179     abilitiesList += "Create Spatial Index";
00180     QgsDebugMsg( "Capability: Create Spatial Index" );
00181   }
00182 
00183   if ( abilities & QgsVectorDataProvider::SelectAtId )
00184   {
00185     // Not really meaningful to the user.
00186     // abilitiesList += "Select at ID";
00187     QgsDebugMsg( "Capability: Select at ID" );
00188   }
00189 
00190   if ( abilities & QgsVectorDataProvider::ChangeGeometries )
00191   {
00192     abilitiesList += "Change Geometries";
00193     QgsDebugMsg( "Capability: Change Geometries" );
00194   }
00195 
00196   if ( abilities & QgsVectorDataProvider::SelectGeometryAtId )
00197   {
00198 
00199     if ( abilities & QgsVectorDataProvider::RandomSelectGeometryAtId )
00200     {
00201       abilitiesList += "Select Geometries by ID (random access)";
00202       QgsDebugMsg( "Capability: Select Geometries by ID (random access)" );
00203     }
00204     else if ( abilities & QgsVectorDataProvider::SequentialSelectGeometryAtId )
00205     {
00206       abilitiesList += "Select Geometries by ID (sequential access)";
00207       QgsDebugMsg( "Capability: Select Geometries by ID (sequential access)" );
00208     }
00209     else
00210     {
00211       abilitiesList += "Select Geometries by ID (unknown access method)";
00212       QgsDebugMsg( "Capability: Select Geometries by ID (unknown access method)" );
00213     }
00214   }
00215 
00216   return abilitiesList.join( ", " );
00217 
00218 }
00219 
00220 
00221 int QgsVectorDataProvider::fieldNameIndex( const QString& fieldName ) const
00222 {
00223   const QgsFieldMap &theFields = fields();
00224 
00225   for ( QgsFieldMap::const_iterator it = theFields.begin(); it != theFields.end(); ++it )
00226   {
00227     if ( it->name() == fieldName )
00228     {
00229       return it.key();
00230     }
00231   }
00232   return -1;
00233 }
00234 
00235 QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const
00236 {
00237   QMap<QString, int> resultMap;
00238 
00239   const QgsFieldMap& theFields = fields();
00240   QgsFieldMap::const_iterator field_it = theFields.constBegin();
00241   for ( ; field_it != theFields.constEnd(); ++field_it )
00242   {
00243     resultMap.insert( field_it.value().name(), field_it.key() );
00244   }
00245 
00246   return resultMap;
00247 }
00248 
00249 QgsAttributeList QgsVectorDataProvider::attributeIndexes()
00250 {
00251   uint count = fieldCount();
00252   QgsAttributeList list;
00253 
00254   for ( uint i = 0; i < count; i++ )
00255     list.append( i );
00256 
00257   return list;
00258 }
00259 
00260 void QgsVectorDataProvider::enableGeometrylessFeatures( bool fetch )
00261 {
00262   mFetchFeaturesWithoutGeom = fetch;
00263 }
00264 
00265 const QgsNativeTypeMap &QgsVectorDataProvider::supportedNativeTypes() const
00266 {
00267   return mSupportedNativeTypes;
00268 }
00269 
00270 
00271 QVariant QgsVectorDataProvider::minimumValue( int index )
00272 {
00273   if ( !fields().contains( index ) )
00274   {
00275     QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
00276     return QVariant();
00277   }
00278 
00279   if ( mCacheMinMaxDirty )
00280   {
00281     fillMinMaxCache();
00282   }
00283 
00284   if ( !mCacheMinValues.contains( index ) )
00285     return QVariant();
00286 
00287   return mCacheMinValues[index];
00288 }
00289 
00290 QVariant QgsVectorDataProvider::maximumValue( int index )
00291 {
00292   if ( !fields().contains( index ) )
00293   {
00294     QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
00295     return QVariant();
00296   }
00297 
00298   if ( mCacheMinMaxDirty )
00299   {
00300     fillMinMaxCache();
00301   }
00302 
00303   if ( !mCacheMaxValues.contains( index ) )
00304     return QVariant();
00305 
00306   return mCacheMaxValues[index];
00307 }
00308 
00309 void QgsVectorDataProvider::uniqueValues( int index, QList<QVariant> &values )
00310 {
00311   QgsFeature f;
00312   QgsAttributeList keys;
00313   keys.append( index );
00314   select( keys, QgsRectangle(), false );
00315 
00316   QSet<QString> set;
00317   values.clear();
00318 
00319   while ( nextFeature( f ) )
00320   {
00321     if ( !set.contains( f.attributeMap()[index].toString() ) )
00322     {
00323       values.append( f.attributeMap()[index] );
00324       set.insert( f.attributeMap()[index].toString() );
00325     }
00326   }
00327 }
00328 
00329 void QgsVectorDataProvider::fillMinMaxCache()
00330 {
00331   const QgsFieldMap& flds = fields();
00332   for ( QgsFieldMap::const_iterator it = flds.begin(); it != flds.end(); ++it )
00333   {
00334     if ( it->type() == QVariant::Int )
00335     {
00336       mCacheMinValues[it.key()] = QVariant( INT_MAX );
00337       mCacheMaxValues[it.key()] = QVariant( INT_MIN );
00338     }
00339     else if ( it->type() == QVariant::Double )
00340     {
00341       mCacheMinValues[it.key()] = QVariant( DBL_MAX );
00342       mCacheMaxValues[it.key()] = QVariant( -DBL_MAX );
00343     }
00344   }
00345 
00346   QgsFeature f;
00347   QgsAttributeList keys = mCacheMinValues.keys();
00348   select( keys, QgsRectangle(), false );
00349 
00350   while ( nextFeature( f ) )
00351   {
00352     QgsAttributeMap attrMap = f.attributeMap();
00353     for ( QgsAttributeList::const_iterator it = keys.begin(); it != keys.end(); ++it )
00354     {
00355       const QVariant& varValue = attrMap[*it];
00356 
00357       if ( flds[*it].type() == QVariant::Int )
00358       {
00359         int value = varValue.toInt();
00360         if ( value < mCacheMinValues[*it].toInt() )
00361           mCacheMinValues[*it] = value;
00362         if ( value > mCacheMaxValues[*it].toInt() )
00363           mCacheMaxValues[*it] = value;
00364       }
00365       else if ( flds[*it].type() == QVariant::Double )
00366       {
00367         double value = varValue.toDouble();
00368         if ( value < mCacheMinValues[*it].toDouble() )
00369           mCacheMinValues[*it] = value;
00370         if ( value > mCacheMaxValues[*it].toDouble() )
00371           mCacheMaxValues[*it] = value;
00372       }
00373     }
00374   }
00375 
00376   mCacheMinMaxDirty = FALSE;
00377 }
00378 
00379 QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, QString value )
00380 {
00381   QVariant v( value );
00382 
00383   if ( !v.convert( type ) )
00384     v = QVariant( QString::null );
00385 
00386   return v;
00387 }

Generated on Fri Jan 9 16:51:12 2009 for Quantum GIS API Documentation by  doxygen 1.5.1