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