Quantum GIS API Documentation
1.8
|
00001 /*************************************************************************** 00002 qgsvectordataprovider.cpp - DataProvider Interface for vector layers 00003 -------------------------------------- 00004 Date : 26-Oct-2004 00005 Copyright : (C) 2004 by Marco Hugentobler 00006 email : [email protected] 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 00016 #include <QSettings> 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 #include "qgsmessagelog.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", "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( QgsFeatureId 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 Q_UNUSED( flist ); 00076 return false; 00077 } 00078 00079 bool QgsVectorDataProvider::deleteFeatures( const QgsFeatureIds &ids ) 00080 { 00081 Q_UNUSED( ids ); 00082 return false; 00083 } 00084 00085 bool QgsVectorDataProvider::addAttributes( const QList<QgsField> &attributes ) 00086 { 00087 Q_UNUSED( attributes ); 00088 return false; 00089 } 00090 00091 bool QgsVectorDataProvider::addAttributes( const QMap<QString, QString> &attributes ) 00092 { 00093 const QList< NativeType > &types = nativeTypes(); 00094 QList< QgsField > list; 00095 00096 for ( QMap<QString, QString>::const_iterator it = attributes.constBegin(); it != attributes.constEnd(); it++ ) 00097 { 00098 int i; 00099 for ( i = 0; i < types.size() && types[i].mTypeName != it.value(); i++ ) 00100 ; 00101 00102 if ( i == types.size() ) 00103 return false; 00104 00105 list << QgsField( it.key(), types[i].mType, it.value() ); 00106 } 00107 00108 return addAttributes( list ); 00109 } 00110 00111 bool QgsVectorDataProvider::deleteAttributes( const QgsAttributeIds &attributes ) 00112 { 00113 Q_UNUSED( attributes ); 00114 return false; 00115 } 00116 00117 bool QgsVectorDataProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map ) 00118 { 00119 Q_UNUSED( attr_map ); 00120 return false; 00121 } 00122 00123 QVariant QgsVectorDataProvider::defaultValue( int fieldId ) 00124 { 00125 Q_UNUSED( fieldId ); 00126 return QVariant(); 00127 } 00128 00129 bool QgsVectorDataProvider::changeGeometryValues( QgsGeometryMap &geometry_map ) 00130 { 00131 Q_UNUSED( geometry_map ); 00132 return false; 00133 } 00134 00135 bool QgsVectorDataProvider::createSpatialIndex() 00136 { 00137 return false; 00138 } 00139 00140 bool QgsVectorDataProvider::createAttributeIndex( int field ) 00141 { 00142 Q_UNUSED( field ); 00143 return true; 00144 } 00145 00146 int QgsVectorDataProvider::capabilities() const 00147 { 00148 return QgsVectorDataProvider::NoCapabilities; 00149 } 00150 00151 00152 void QgsVectorDataProvider::setEncoding( const QString& e ) 00153 { 00154 QTextCodec* ncodec = QTextCodec::codecForName( e.toLocal8Bit().constData() ); 00155 if ( ncodec ) 00156 { 00157 mEncoding = ncodec; 00158 } 00159 else 00160 { 00161 QgsMessageLog::logMessage( tr( "Codec %1 not found. Falling back to system locale" ).arg( e ) ); 00162 mEncoding = QTextCodec::codecForName( "System" ); 00163 00164 if ( !mEncoding ) 00165 mEncoding = QTextCodec::codecForLocale(); 00166 00167 Q_ASSERT( mEncoding ); 00168 } 00169 } 00170 00171 QString QgsVectorDataProvider::encoding() const 00172 { 00173 if ( mEncoding ) 00174 { 00175 return mEncoding->name(); 00176 } 00177 00178 return ""; 00179 } 00180 00181 QString QgsVectorDataProvider::capabilitiesString() const 00182 { 00183 QStringList abilitiesList; 00184 00185 int abilities = capabilities(); 00186 00187 if ( abilities & QgsVectorDataProvider::AddFeatures ) 00188 { 00189 abilitiesList += tr( "Add Features" ); 00190 QgsDebugMsg( "Capability: Add Features" ); 00191 } 00192 00193 if ( abilities & QgsVectorDataProvider::DeleteFeatures ) 00194 { 00195 abilitiesList += tr( "Delete Features" ); 00196 QgsDebugMsg( "Capability: Delete Features" ); 00197 } 00198 00199 if ( abilities & QgsVectorDataProvider::ChangeAttributeValues ) 00200 { 00201 abilitiesList += tr( "Change Attribute Values" ); 00202 QgsDebugMsg( "Capability: Change Attribute Values" ); 00203 } 00204 00205 if ( abilities & QgsVectorDataProvider::AddAttributes ) 00206 { 00207 abilitiesList += tr( "Add Attributes" ); 00208 QgsDebugMsg( "Capability: Add Attributes" ); 00209 } 00210 00211 if ( abilities & QgsVectorDataProvider::DeleteAttributes ) 00212 { 00213 abilitiesList += tr( "Delete Attributes" ); 00214 QgsDebugMsg( "Capability: Delete Attributes" ); 00215 } 00216 00217 if ( abilities & QgsVectorDataProvider::CreateSpatialIndex ) 00218 { 00219 // TODO: Tighten up this test. See QgsOgrProvider for details. 00220 abilitiesList += tr( "Create Spatial Index" ); 00221 QgsDebugMsg( "Capability: Create Spatial Index" ); 00222 } 00223 00224 if ( abilities & QgsVectorDataProvider::SelectAtId ) 00225 { 00226 abilitiesList += tr( "Fast Access to Features at ID" ); 00227 QgsDebugMsg( "Capability: Select at ID" ); 00228 } 00229 00230 if ( abilities & QgsVectorDataProvider::ChangeGeometries ) 00231 { 00232 abilitiesList += tr( "Change Geometries" ); 00233 QgsDebugMsg( "Capability: Change Geometries" ); 00234 } 00235 00236 return abilitiesList.join( ", " ); 00237 00238 } 00239 00240 00241 int QgsVectorDataProvider::fieldNameIndex( const QString& fieldName ) const 00242 { 00243 const QgsFieldMap &theFields = fields(); 00244 00245 for ( QgsFieldMap::const_iterator it = theFields.constBegin(); it != theFields.constEnd(); ++it ) 00246 { 00247 if ( QString::compare( it->name(), fieldName, Qt::CaseInsensitive ) == 0 ) 00248 { 00249 return it.key(); 00250 } 00251 } 00252 return -1; 00253 } 00254 00255 QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const 00256 { 00257 QMap<QString, int> resultMap; 00258 00259 const QgsFieldMap& theFields = fields(); 00260 QgsFieldMap::const_iterator field_it = theFields.constBegin(); 00261 for ( ; field_it != theFields.constEnd(); ++field_it ) 00262 { 00263 resultMap.insert( field_it.value().name(), field_it.key() ); 00264 } 00265 00266 return resultMap; 00267 } 00268 00269 QgsAttributeList QgsVectorDataProvider::attributeIndexes() 00270 { 00271 uint count = fieldCount(); 00272 QgsAttributeList list; 00273 00274 for ( uint i = 0; i < count; i++ ) 00275 list.append( i ); 00276 00277 return list; 00278 } 00279 00280 void QgsVectorDataProvider::enableGeometrylessFeatures( bool fetch ) 00281 { 00282 mFetchFeaturesWithoutGeom = fetch; 00283 } 00284 00285 const QList< QgsVectorDataProvider::NativeType > &QgsVectorDataProvider::nativeTypes() const 00286 { 00287 return mNativeTypes; 00288 } 00289 00290 const QMap<QString, QVariant::Type> &QgsVectorDataProvider::supportedNativeTypes() const 00291 { 00292 if ( mOldTypeList.size() > 0 ) 00293 return mOldTypeList; 00294 00295 QgsVectorDataProvider *p = ( QgsVectorDataProvider * )this; 00296 00297 const QList< QgsVectorDataProvider::NativeType > &types = nativeTypes(); 00298 00299 for ( QList< QgsVectorDataProvider::NativeType >::const_iterator it = types.constBegin(); it != types.constEnd(); it++ ) 00300 { 00301 p->mOldTypeList.insert( it->mTypeName, it->mType ); 00302 } 00303 00304 return p->mOldTypeList; 00305 } 00306 00307 bool QgsVectorDataProvider::supportedType( const QgsField &field ) const 00308 { 00309 int i; 00310 for ( i = 0; i < mNativeTypes.size(); i++ ) 00311 { 00312 if ( field.type() == mNativeTypes[i].mType && 00313 field.length() >= mNativeTypes[i].mMinLen && field.length() <= mNativeTypes[i].mMaxLen && 00314 field.precision() >= mNativeTypes[i].mMinPrec && field.precision() <= mNativeTypes[i].mMaxPrec ) 00315 { 00316 break; 00317 } 00318 } 00319 00320 return i < mNativeTypes.size(); 00321 } 00322 00323 QVariant QgsVectorDataProvider::minimumValue( int index ) 00324 { 00325 if ( !fields().contains( index ) ) 00326 { 00327 QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) ); 00328 return QVariant(); 00329 } 00330 00331 fillMinMaxCache(); 00332 00333 if ( !mCacheMinValues.contains( index ) ) 00334 return QVariant(); 00335 00336 return mCacheMinValues[index]; 00337 } 00338 00339 QVariant QgsVectorDataProvider::maximumValue( int index ) 00340 { 00341 if ( !fields().contains( index ) ) 00342 { 00343 QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) ); 00344 return QVariant(); 00345 } 00346 00347 fillMinMaxCache(); 00348 00349 if ( !mCacheMaxValues.contains( index ) ) 00350 return QVariant(); 00351 00352 return mCacheMaxValues[index]; 00353 } 00354 00355 void QgsVectorDataProvider::uniqueValues( int index, QList<QVariant> &values, int limit ) 00356 { 00357 QgsFeature f; 00358 QgsAttributeList keys; 00359 keys.append( index ); 00360 select( keys, QgsRectangle(), false ); 00361 00362 QSet<QString> set; 00363 values.clear(); 00364 00365 while ( nextFeature( f ) ) 00366 { 00367 if ( !set.contains( f.attributeMap()[index].toString() ) ) 00368 { 00369 values.append( f.attributeMap()[index] ); 00370 set.insert( f.attributeMap()[index].toString() ); 00371 } 00372 00373 if ( limit >= 0 && values.size() >= limit ) 00374 break; 00375 } 00376 } 00377 00378 void QgsVectorDataProvider::clearMinMaxCache() 00379 { 00380 mCacheMinMaxDirty = true; 00381 } 00382 00383 void QgsVectorDataProvider::fillMinMaxCache() 00384 { 00385 if ( !mCacheMinMaxDirty ) 00386 return; 00387 00388 const QgsFieldMap& flds = fields(); 00389 for ( QgsFieldMap::const_iterator it = flds.begin(); it != flds.end(); ++it ) 00390 { 00391 if ( it->type() == QVariant::Int ) 00392 { 00393 mCacheMinValues[it.key()] = QVariant( INT_MAX ); 00394 mCacheMaxValues[it.key()] = QVariant( INT_MIN ); 00395 } 00396 else if ( it->type() == QVariant::Double ) 00397 { 00398 mCacheMinValues[it.key()] = QVariant( DBL_MAX ); 00399 mCacheMaxValues[it.key()] = QVariant( -DBL_MAX ); 00400 } 00401 else 00402 { 00403 mCacheMinValues[it.key()] = QVariant(); 00404 mCacheMaxValues[it.key()] = QVariant(); 00405 } 00406 } 00407 00408 QgsFeature f; 00409 QgsAttributeList keys = mCacheMinValues.keys(); 00410 select( keys, QgsRectangle(), false ); 00411 00412 while ( nextFeature( f ) ) 00413 { 00414 QgsAttributeMap attrMap = f.attributeMap(); 00415 for ( QgsAttributeList::const_iterator it = keys.begin(); it != keys.end(); ++it ) 00416 { 00417 const QVariant& varValue = attrMap[*it]; 00418 00419 if ( flds[*it].type() == QVariant::Int ) 00420 { 00421 int value = varValue.toInt(); 00422 if ( value < mCacheMinValues[*it].toInt() ) 00423 mCacheMinValues[*it] = value; 00424 if ( value > mCacheMaxValues[*it].toInt() ) 00425 mCacheMaxValues[*it] = value; 00426 } 00427 else if ( flds[*it].type() == QVariant::Double ) 00428 { 00429 double value = varValue.toDouble(); 00430 if ( value < mCacheMinValues[*it].toDouble() ) 00431 mCacheMinValues[*it] = value; 00432 if ( value > mCacheMaxValues[*it].toDouble() ) 00433 mCacheMaxValues[*it] = value; 00434 } 00435 else 00436 { 00437 QString value = varValue.toString(); 00438 if ( mCacheMinValues[*it].isNull() || value < mCacheMinValues[*it].toString() ) 00439 { 00440 mCacheMinValues[*it] = value; 00441 } 00442 if ( mCacheMaxValues[*it].isNull() || value > mCacheMaxValues[*it].toString() ) 00443 { 00444 mCacheMaxValues[*it] = value; 00445 } 00446 } 00447 } 00448 } 00449 00450 mCacheMinMaxDirty = false; 00451 } 00452 00453 QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, QString value ) 00454 { 00455 QVariant v( value ); 00456 00457 if ( !v.convert( type ) ) 00458 v = QVariant( QString::null ); 00459 00460 return v; 00461 } 00462 00463 const QStringList &QgsVectorDataProvider::availableEncodings() 00464 { 00465 if ( smEncodings.isEmpty() ) 00466 { 00467 foreach( QString codec, QTextCodec::availableCodecs() ) 00468 { 00469 smEncodings << codec; 00470 } 00471 qSort( smEncodings ); 00472 #if 0 00473 smEncodings << "BIG5"; 00474 smEncodings << "BIG5-HKSCS"; 00475 smEncodings << "EUCJP"; 00476 smEncodings << "EUCKR"; 00477 smEncodings << "GB2312"; 00478 smEncodings << "GBK"; 00479 smEncodings << "GB18030"; 00480 smEncodings << "JIS7"; 00481 smEncodings << "SHIFT-JIS"; 00482 smEncodings << "TSCII"; 00483 smEncodings << "UTF-8"; 00484 smEncodings << "UTF-16"; 00485 smEncodings << "KOI8-R"; 00486 smEncodings << "KOI8-U"; 00487 smEncodings << "ISO8859-1"; 00488 smEncodings << "ISO8859-2"; 00489 smEncodings << "ISO8859-3"; 00490 smEncodings << "ISO8859-4"; 00491 smEncodings << "ISO8859-5"; 00492 smEncodings << "ISO8859-6"; 00493 smEncodings << "ISO8859-7"; 00494 smEncodings << "ISO8859-8"; 00495 smEncodings << "ISO8859-8-I"; 00496 smEncodings << "ISO8859-9"; 00497 smEncodings << "ISO8859-10"; 00498 smEncodings << "ISO8859-11"; 00499 smEncodings << "ISO8859-12"; 00500 smEncodings << "ISO8859-13"; 00501 smEncodings << "ISO8859-14"; 00502 smEncodings << "ISO8859-15"; 00503 smEncodings << "IBM 850"; 00504 smEncodings << "IBM 866"; 00505 smEncodings << "CP874"; 00506 smEncodings << "CP1250"; 00507 smEncodings << "CP1251"; 00508 smEncodings << "CP1252"; 00509 smEncodings << "CP1253"; 00510 smEncodings << "CP1254"; 00511 smEncodings << "CP1255"; 00512 smEncodings << "CP1256"; 00513 smEncodings << "CP1257"; 00514 smEncodings << "CP1258"; 00515 smEncodings << "Apple Roman"; 00516 smEncodings << "TIS-620"; 00517 smEncodings << "System"; 00518 #endif 00519 } 00520 00521 return smEncodings; 00522 } 00523 00524 void QgsVectorDataProvider::clearErrors() 00525 { 00526 mErrors.clear(); 00527 } 00528 00529 bool QgsVectorDataProvider::hasErrors() 00530 { 00531 return !mErrors.isEmpty(); 00532 } 00533 00534 QStringList QgsVectorDataProvider::errors() 00535 { 00536 return mErrors; 00537 } 00538 00539 void QgsVectorDataProvider::pushError( QString msg ) 00540 { 00541 mErrors << msg; 00542 } 00543 00544 QStringList QgsVectorDataProvider::smEncodings;