00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <QSettings>
00018 #include <QTextCodec>
00019
00020 #include <cfloat>
00021 #include <climits>
00022
00023 #include "qgsvectordataprovider.h"
00024 #include "qgsfeature.h"
00025 #include "qgsfield.h"
00026 #include "qgslogger.h"
00027
00028 QgsVectorDataProvider::QgsVectorDataProvider( QString uri )
00029 : QgsDataProvider( uri )
00030 , mCacheMinMaxDirty( true )
00031 , mFetchFeaturesWithoutGeom( true )
00032 {
00033 QSettings settings;
00034 setEncoding( settings.value( "/UI/encoding", QString( "System" ) ).toString() );
00035 }
00036
00037
00038 QgsVectorDataProvider::~QgsVectorDataProvider()
00039 {
00040 }
00041
00042 QString QgsVectorDataProvider::storageType() const
00043 {
00044 return "Generic vector file";
00045 }
00046
00047 long QgsVectorDataProvider::updateFeatureCount()
00048 {
00049 return -1;
00050 }
00051
00052 bool QgsVectorDataProvider::featureAtId( int featureId,
00053 QgsFeature& feature,
00054 bool fetchGeometry,
00055 QgsAttributeList fetchAttributes )
00056 {
00057 select( fetchAttributes, QgsRectangle(), fetchGeometry );
00058
00059 while ( nextFeature( feature ) )
00060 {
00061 if ( feature.id() == featureId )
00062 return true;
00063 }
00064
00065 return false;
00066 }
00067
00068 QString QgsVectorDataProvider::dataComment() const
00069 {
00070 return QString();
00071 }
00072
00073 bool QgsVectorDataProvider::addFeatures( QgsFeatureList &flist )
00074 {
00075 return false;
00076 }
00077
00078 bool QgsVectorDataProvider::deleteFeatures( const QgsFeatureIds & id )
00079 {
00080 return false;
00081 }
00082
00083 bool QgsVectorDataProvider::addAttributes( const QList<QgsField> & attributes )
00084 {
00085 return false;
00086 }
00087
00088 bool QgsVectorDataProvider::addAttributes( const QMap<QString, QString> &attributes )
00089 {
00090 const QMap<QString, QVariant::Type> &map = supportedNativeTypes();
00091 QList< QgsField > list;
00092
00093 for ( QMap<QString, QString>::const_iterator it = attributes.constBegin(); it != attributes.constEnd(); it++ )
00094 {
00095 if ( !map.contains( it.value() ) )
00096 return false;
00097
00098 list << QgsField( it.key(), map[ it.value()], it.value() );
00099 }
00100
00101 return addAttributes( list );
00102 }
00103
00104 bool QgsVectorDataProvider::deleteAttributes( const QgsAttributeIds& attributes )
00105 {
00106 return false;
00107 }
00108
00109 bool QgsVectorDataProvider::changeAttributeValues( const QgsChangedAttributesMap & attr_map )
00110 {
00111 return false;
00112 }
00113
00114 QVariant QgsVectorDataProvider::defaultValue( int fieldId )
00115 {
00116 return QVariant();
00117 }
00118
00119 bool QgsVectorDataProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
00120 {
00121 return false;
00122 }
00123
00124 bool QgsVectorDataProvider::createSpatialIndex()
00125 {
00126 return false;
00127 }
00128
00129 int QgsVectorDataProvider::capabilities() const
00130 {
00131 return QgsVectorDataProvider::NoCapabilities;
00132 }
00133
00134
00135 void QgsVectorDataProvider::setEncoding( const QString& e )
00136 {
00137 QTextCodec* ncodec = QTextCodec::codecForName( e.toLocal8Bit().data() );
00138 if ( ncodec )
00139 {
00140 mEncoding = ncodec;
00141 }
00142 else
00143 {
00144 QgsDebugMsg( "error finding QTextCodec for " + e );
00145 }
00146 }
00147
00148 QString QgsVectorDataProvider::encoding() const
00149 {
00150 if ( mEncoding )
00151 {
00152 return mEncoding->name();
00153 }
00154
00155 return "";
00156 }
00157
00158 QString QgsVectorDataProvider::capabilitiesString() const
00159 {
00160 QStringList abilitiesList;
00161
00162 int abilities = capabilities();
00163
00164 if ( abilities & QgsVectorDataProvider::AddFeatures )
00165 {
00166 abilitiesList += tr( "Add Features" );
00167 QgsDebugMsg( "Capability: Add Features" );
00168 }
00169
00170 if ( abilities & QgsVectorDataProvider::DeleteFeatures )
00171 {
00172 abilitiesList += tr( "Delete Features" );
00173 QgsDebugMsg( "Capability: Delete Features" );
00174 }
00175
00176 if ( abilities & QgsVectorDataProvider::ChangeAttributeValues )
00177 {
00178 abilitiesList += tr( "Change Attribute Values" );
00179 QgsDebugMsg( "Capability: Change Attribute Values" );
00180 }
00181
00182 if ( abilities & QgsVectorDataProvider::AddAttributes )
00183 {
00184 abilitiesList += tr( "Add Attributes" );
00185 QgsDebugMsg( "Capability: Add Attributes" );
00186 }
00187
00188 if ( abilities & QgsVectorDataProvider::DeleteAttributes )
00189 {
00190 abilitiesList += tr( "Delete Attributes" );
00191 QgsDebugMsg( "Capability: Delete Attributes" );
00192 }
00193
00194 if ( abilities & QgsVectorDataProvider::CreateSpatialIndex )
00195 {
00196
00197 abilitiesList += tr( "Create Spatial Index" );
00198 QgsDebugMsg( "Capability: Create Spatial Index" );
00199 }
00200
00201 if ( abilities & QgsVectorDataProvider::SelectAtId )
00202 {
00203 abilitiesList += tr( "Fast Access to Features at ID" );
00204 QgsDebugMsg( "Capability: Select at ID" );
00205 }
00206
00207 if ( abilities & QgsVectorDataProvider::ChangeGeometries )
00208 {
00209 abilitiesList += tr( "Change Geometries" );
00210 QgsDebugMsg( "Capability: Change Geometries" );
00211 }
00212
00213 return abilitiesList.join( ", " );
00214
00215 }
00216
00217
00218 int QgsVectorDataProvider::fieldNameIndex( const QString& fieldName ) const
00219 {
00220 const QgsFieldMap &theFields = fields();
00221
00222 for ( QgsFieldMap::const_iterator it = theFields.constBegin(); it != theFields.constEnd(); ++it )
00223 {
00224 if ( it->name() == fieldName )
00225 {
00226 return it.key();
00227 }
00228 }
00229 return -1;
00230 }
00231
00232 QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const
00233 {
00234 QMap<QString, int> resultMap;
00235
00236 const QgsFieldMap& theFields = fields();
00237 QgsFieldMap::const_iterator field_it = theFields.constBegin();
00238 for ( ; field_it != theFields.constEnd(); ++field_it )
00239 {
00240 resultMap.insert( field_it.value().name(), field_it.key() );
00241 }
00242
00243 return resultMap;
00244 }
00245
00246 QgsAttributeList QgsVectorDataProvider::attributeIndexes()
00247 {
00248 uint count = fieldCount();
00249 QgsAttributeList list;
00250
00251 for ( uint i = 0; i < count; i++ )
00252 list.append( i );
00253
00254 return list;
00255 }
00256
00257 void QgsVectorDataProvider::enableGeometrylessFeatures( bool fetch )
00258 {
00259 mFetchFeaturesWithoutGeom = fetch;
00260 }
00261
00262 const QList< QgsVectorDataProvider::NativeType > &QgsVectorDataProvider::nativeTypes() const
00263 {
00264 return mNativeTypes;
00265 }
00266
00267 const QMap<QString, QVariant::Type> &QgsVectorDataProvider::supportedNativeTypes() const
00268 {
00269 if ( mOldTypeList.size() > 0 )
00270 return mOldTypeList;
00271
00272 QgsVectorDataProvider *p = ( QgsVectorDataProvider * )this;
00273
00274 const QList< QgsVectorDataProvider::NativeType > &types = nativeTypes();
00275
00276 for ( QList< QgsVectorDataProvider::NativeType >::const_iterator it = types.constBegin(); it != types.constEnd(); it++ )
00277 {
00278 p->mOldTypeList.insert( it->mTypeName, it->mType );
00279 }
00280
00281 return p->mOldTypeList;
00282 }
00283
00284 bool QgsVectorDataProvider::supportedType( const QgsField &field ) const
00285 {
00286 int i;
00287 for ( i = 0; i < mNativeTypes.size(); i++ )
00288 {
00289 if ( field.type() == mNativeTypes[i].mType &&
00290 field.length() >= mNativeTypes[i].mMinLen && field.length() <= mNativeTypes[i].mMaxLen &&
00291 field.precision() >= mNativeTypes[i].mMinPrec && field.precision() <= mNativeTypes[i].mMaxPrec )
00292 {
00293 break;
00294 }
00295 }
00296
00297 return i < mNativeTypes.size();
00298 }
00299
00300 QVariant QgsVectorDataProvider::minimumValue( int index )
00301 {
00302 if ( !fields().contains( index ) )
00303 {
00304 QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
00305 return QVariant();
00306 }
00307
00308 fillMinMaxCache();
00309
00310 if ( !mCacheMinValues.contains( index ) )
00311 return QVariant();
00312
00313 return mCacheMinValues[index];
00314 }
00315
00316 QVariant QgsVectorDataProvider::maximumValue( int index )
00317 {
00318 if ( !fields().contains( index ) )
00319 {
00320 QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
00321 return QVariant();
00322 }
00323
00324 fillMinMaxCache();
00325
00326 if ( !mCacheMaxValues.contains( index ) )
00327 return QVariant();
00328
00329 return mCacheMaxValues[index];
00330 }
00331
00332 void QgsVectorDataProvider::uniqueValues( int index, QList<QVariant> &values, int limit )
00333 {
00334 QgsFeature f;
00335 QgsAttributeList keys;
00336 keys.append( index );
00337 select( keys, QgsRectangle(), false );
00338
00339 QSet<QString> set;
00340 values.clear();
00341
00342 while ( nextFeature( f ) )
00343 {
00344 if ( !set.contains( f.attributeMap()[index].toString() ) )
00345 {
00346 values.append( f.attributeMap()[index] );
00347 set.insert( f.attributeMap()[index].toString() );
00348 }
00349
00350 if ( limit >= 0 && values.size() >= limit )
00351 break;
00352 }
00353 }
00354
00355 void QgsVectorDataProvider::clearMinMaxCache()
00356 {
00357 mCacheMinMaxDirty = true;
00358 }
00359
00360 void QgsVectorDataProvider::fillMinMaxCache()
00361 {
00362 if ( !mCacheMinMaxDirty )
00363 return;
00364
00365 const QgsFieldMap& flds = fields();
00366 for ( QgsFieldMap::const_iterator it = flds.begin(); it != flds.end(); ++it )
00367 {
00368 if ( it->type() == QVariant::Int )
00369 {
00370 mCacheMinValues[it.key()] = QVariant( INT_MAX );
00371 mCacheMaxValues[it.key()] = QVariant( INT_MIN );
00372 }
00373 else if ( it->type() == QVariant::Double )
00374 {
00375 mCacheMinValues[it.key()] = QVariant( DBL_MAX );
00376 mCacheMaxValues[it.key()] = QVariant( -DBL_MAX );
00377 }
00378 else
00379 {
00380 mCacheMinValues[it.key()] = QVariant();
00381 mCacheMaxValues[it.key()] = QVariant();
00382 }
00383 }
00384
00385 QgsFeature f;
00386 QgsAttributeList keys = mCacheMinValues.keys();
00387 select( keys, QgsRectangle(), false );
00388
00389 while ( nextFeature( f ) )
00390 {
00391 QgsAttributeMap attrMap = f.attributeMap();
00392 for ( QgsAttributeList::const_iterator it = keys.begin(); it != keys.end(); ++it )
00393 {
00394 const QVariant& varValue = attrMap[*it];
00395
00396 if ( flds[*it].type() == QVariant::Int )
00397 {
00398 int value = varValue.toInt();
00399 if ( value < mCacheMinValues[*it].toInt() )
00400 mCacheMinValues[*it] = value;
00401 if ( value > mCacheMaxValues[*it].toInt() )
00402 mCacheMaxValues[*it] = value;
00403 }
00404 else if ( flds[*it].type() == QVariant::Double )
00405 {
00406 double value = varValue.toDouble();
00407 if ( value < mCacheMinValues[*it].toDouble() )
00408 mCacheMinValues[*it] = value;
00409 if ( value > mCacheMaxValues[*it].toDouble() )
00410 mCacheMaxValues[*it] = value;
00411 }
00412 else
00413 {
00414 QString value = varValue.toString();
00415 if ( mCacheMinValues[*it].isNull() || value < mCacheMinValues[*it].toString() )
00416 {
00417 mCacheMinValues[*it] = value;
00418 }
00419 if ( mCacheMaxValues[*it].isNull() || value > mCacheMaxValues[*it].toString() )
00420 {
00421 mCacheMaxValues[*it] = value;
00422 }
00423 }
00424 }
00425 }
00426
00427 mCacheMinMaxDirty = false;
00428 }
00429
00430 QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, QString value )
00431 {
00432 QVariant v( value );
00433
00434 if ( !v.convert( type ) )
00435 v = QVariant( QString::null );
00436
00437 return v;
00438 }
00439
00440 const QStringList &QgsVectorDataProvider::availableEncodings()
00441 {
00442 if ( smEncodings.isEmpty() )
00443 {
00444 smEncodings << "BIG5";
00445 smEncodings << "BIG5-HKSCS";
00446 smEncodings << "EUCJP";
00447 smEncodings << "EUCKR";
00448 smEncodings << "GB2312";
00449 smEncodings << "GBK";
00450 smEncodings << "GB18030";
00451 smEncodings << "JIS7";
00452 smEncodings << "SHIFT-JIS";
00453 smEncodings << "TSCII";
00454 smEncodings << "UTF-8";
00455 smEncodings << "UTF-16";
00456 smEncodings << "KOI8-R";
00457 smEncodings << "KOI8-U";
00458 smEncodings << "ISO8859-1";
00459 smEncodings << "ISO8859-2";
00460 smEncodings << "ISO8859-3";
00461 smEncodings << "ISO8859-4";
00462 smEncodings << "ISO8859-5";
00463 smEncodings << "ISO8859-6";
00464 smEncodings << "ISO8859-7";
00465 smEncodings << "ISO8859-8";
00466 smEncodings << "ISO8859-8-I";
00467 smEncodings << "ISO8859-9";
00468 smEncodings << "ISO8859-10";
00469 smEncodings << "ISO8859-11";
00470 smEncodings << "ISO8859-12";
00471 smEncodings << "ISO8859-13";
00472 smEncodings << "ISO8859-14";
00473 smEncodings << "ISO8859-15";
00474 smEncodings << "IBM 850";
00475 smEncodings << "IBM 866";
00476 smEncodings << "CP874";
00477 smEncodings << "CP1250";
00478 smEncodings << "CP1251";
00479 smEncodings << "CP1252";
00480 smEncodings << "CP1253";
00481 smEncodings << "CP1254";
00482 smEncodings << "CP1255";
00483 smEncodings << "CP1256";
00484 smEncodings << "CP1257";
00485 smEncodings << "CP1258";
00486 smEncodings << "Apple Roman";
00487 smEncodings << "TIS-620";
00488 smEncodings << "System";
00489 }
00490
00491 return smEncodings;
00492 }
00493
00494 QStringList QgsVectorDataProvider::smEncodings;