00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "qgsfield.h"
00020 #include "qgsfeature.h"
00021 #include "qgsgeometry.h"
00022 #include "qgslogger.h"
00023 #include "qgsmessagelog.h"
00024 #include "qgscoordinatereferencesystem.h"
00025 #include "qgsvectorlayerimport.h"
00026 #include "qgsproviderregistry.h"
00027
00028 #define FEATURE_BUFFER_SIZE 200
00029
00030 typedef QgsVectorLayerImport::ImportError createEmptyLayer_t(
00031 const QString &uri,
00032 const QgsFieldMap &fields,
00033 QGis::WkbType geometryType,
00034 const QgsCoordinateReferenceSystem *destCRS,
00035 bool overwrite,
00036 QMap<int, int> *oldToNewAttrIdx,
00037 QString *errorMessage,
00038 const QMap<QString, QVariant> *options
00039 );
00040
00041
00042 QgsVectorLayerImport::QgsVectorLayerImport( const QString &uri,
00043 const QString &providerKey,
00044 const QgsFieldMap& fields,
00045 QGis::WkbType geometryType,
00046 const QgsCoordinateReferenceSystem* crs,
00047 bool overwrite,
00048 const QMap<QString, QVariant> *options )
00049 : mErrorCount( 0 )
00050 {
00051 mProvider = NULL;
00052
00053 QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
00054
00055 QLibrary *myLib = pReg->providerLibrary( providerKey );
00056 if ( !myLib )
00057 {
00058 mError = ErrInvalidProvider;
00059 mErrorMessage = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
00060 return;
00061 }
00062
00063 createEmptyLayer_t * pCreateEmpty = ( createEmptyLayer_t * ) cast_to_fptr( myLib->resolve( "createEmptyLayer" ) );
00064 if ( !pCreateEmpty )
00065 {
00066 delete myLib;
00067 mError = ErrProviderUnsupportedFeature;
00068 mErrorMessage = QObject::tr( "Provider %1 has no createEmptyLayer method" ).arg( providerKey );
00069 return;
00070 }
00071
00072 delete myLib;
00073
00074
00075 QString errMsg;
00076 mError = pCreateEmpty( uri, fields, geometryType, crs, overwrite, &mOldToNewAttrIdx, &errMsg, options );
00077 if ( hasError() )
00078 {
00079 mErrorMessage = errMsg;
00080 return;
00081 }
00082
00083 QgsDebugMsg( "Created empty layer" );
00084
00085 QgsVectorDataProvider *vectorProvider = ( QgsVectorDataProvider* ) pReg->provider( providerKey, uri );
00086 if ( !vectorProvider || !vectorProvider->isValid() )
00087 {
00088 mError = ErrInvalidLayer;
00089 mErrorMessage = QObject::tr( "Loading of layer failed" );
00090
00091 if ( vectorProvider )
00092 delete vectorProvider;
00093
00094 return;
00095 }
00096
00097 mProvider = vectorProvider;
00098 mError = NoError;
00099 }
00100
00101 QgsVectorLayerImport::~QgsVectorLayerImport()
00102 {
00103 flushBuffer();
00104
00105 if ( mProvider )
00106 delete mProvider;
00107 }
00108
00109 QgsVectorLayerImport::ImportError QgsVectorLayerImport::hasError()
00110 {
00111 return mError;
00112 }
00113
00114 QString QgsVectorLayerImport::errorMessage()
00115 {
00116 return mErrorMessage;
00117 }
00118
00119 bool QgsVectorLayerImport::addFeature( QgsFeature& feat )
00120 {
00121 const QgsAttributeMap &attrs = feat.attributeMap();
00122
00123 QgsAttributeMap newAttrs;
00124 for ( QgsAttributeMap::const_iterator it = attrs.begin(); it != attrs.end(); it++ )
00125 {
00126 if ( mOldToNewAttrIdx.contains( it.key() ) )
00127 {
00128 QgsDebugMsgLevel( QString( "moving field from pos %1 to %2" ).arg( it.key() ).arg( mOldToNewAttrIdx.value( it.key() ) ), 3 );
00129 newAttrs.insert( mOldToNewAttrIdx.value( it.key() ), *it );
00130 }
00131 else
00132 {
00133 QgsDebugMsgLevel( QString( "added attr pos %1" ).arg( it.key() ), 3 );
00134 newAttrs.insert( it.key(), *it );
00135 }
00136 }
00137 feat.setAttributeMap( newAttrs );
00138
00139 mFeatureBuffer.append( feat );
00140
00141 if ( mFeatureBuffer.count() >= FEATURE_BUFFER_SIZE )
00142 {
00143 return flushBuffer();
00144 }
00145
00146 return true;
00147 }
00148
00149 bool QgsVectorLayerImport::flushBuffer()
00150 {
00151 if ( mFeatureBuffer.count() <= 0 )
00152 return true;
00153
00154 if ( !mProvider->addFeatures( mFeatureBuffer ) )
00155 {
00156 QStringList errors = mProvider->errors();
00157 mProvider->clearErrors();
00158
00159 mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors was: \n%3" )
00160 .arg( mFeatureBuffer.first().id() )
00161 .arg( mFeatureBuffer.last().id() )
00162 .arg( errors.join( "\n" ) );
00163
00164 mError = ErrFeatureWriteFailed;
00165 mErrorCount += mFeatureBuffer.count();
00166
00167 mFeatureBuffer.clear();
00168 QgsDebugMsg( mErrorMessage );
00169 return false;
00170 }
00171
00172 mFeatureBuffer.clear();
00173 return true;
00174 }
00175
00176
00177 QgsVectorLayerImport::ImportError
00178 QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
00179 const QString& uri,
00180 const QString& providerKey,
00181 const QgsCoordinateReferenceSystem *destCRS,
00182 bool onlySelected,
00183 QString *errorMessage,
00184 bool skipAttributeCreation,
00185 QMap<QString, QVariant> *options )
00186 {
00187 const QgsCoordinateReferenceSystem* outputCRS;
00188 QgsCoordinateTransform* ct = 0;
00189 int shallTransform = false;
00190
00191 if ( layer == NULL )
00192 {
00193 return ErrInvalidLayer;
00194 }
00195
00196 if ( destCRS && destCRS->isValid() )
00197 {
00198
00199 outputCRS = destCRS;
00200 shallTransform = true;
00201 }
00202 else
00203 {
00204
00205 outputCRS = &layer->crs();
00206 }
00207
00208 QgsFieldMap fields = skipAttributeCreation ? QgsFieldMap() : layer->pendingFields();
00209 if ( layer->providerType() == "ogr" && layer->storageType() == "ESRI Shapefile" )
00210 {
00211
00212 for ( QgsFieldMap::iterator fldIt = fields.begin(); fldIt != fields.end(); ++fldIt )
00213 {
00214 fldIt.value().setName( fldIt.value().name().toLower() );
00215 }
00216 }
00217
00218 bool overwrite = false;
00219 if ( options )
00220 {
00221 overwrite = options->take( "overwrite" ).toBool();
00222 }
00223
00224 QgsVectorLayerImport * writer =
00225 new QgsVectorLayerImport( uri, providerKey, fields, layer->wkbType(), outputCRS, overwrite, options );
00226
00227
00228 ImportError err = writer->hasError();
00229 if ( err != NoError )
00230 {
00231 if ( errorMessage )
00232 *errorMessage = writer->errorMessage();
00233 delete writer;
00234 return err;
00235 }
00236
00237 if ( errorMessage )
00238 {
00239 errorMessage->clear();
00240 }
00241
00242 QgsAttributeList allAttr = skipAttributeCreation ? QgsAttributeList() : layer->pendingAllAttributesList();
00243 QgsFeature fet;
00244
00245 layer->select( allAttr, QgsRectangle(), layer->wkbType() != QGis::WKBNoGeometry );
00246
00247 const QgsFeatureIds& ids = layer->selectedFeaturesIds();
00248
00249
00250 if ( destCRS )
00251 {
00252 ct = new QgsCoordinateTransform( layer->crs(), *destCRS );
00253 }
00254
00255
00256 if ( ct == NULL )
00257 {
00258 shallTransform = false;
00259 }
00260
00261 int n = 0;
00262
00263 if ( errorMessage )
00264 {
00265 *errorMessage = QObject::tr( "Feature write errors:" );
00266 }
00267
00268
00269 while ( layer->nextFeature( fet ) )
00270 {
00271 if ( writer->errorCount() > 1000 )
00272 {
00273 if ( errorMessage )
00274 {
00275 *errorMessage += "\n" + QObject::tr( "Stopping after %1 errors" ).arg( writer->errorCount() );
00276 }
00277 break;
00278 }
00279
00280 if ( onlySelected && !ids.contains( fet.id() ) )
00281 continue;
00282
00283 if ( shallTransform )
00284 {
00285 try
00286 {
00287 if ( fet.geometry() )
00288 {
00289 fet.geometry()->transform( *ct );
00290 }
00291 }
00292 catch ( QgsCsException &e )
00293 {
00294 delete ct;
00295 delete writer;
00296
00297 QString msg = QObject::tr( "Failed to transform a point while drawing a feature of type '%1'. Writing stopped. (Exception: %2)" )
00298 .arg( fet.typeName() ).arg( e.what() );
00299 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
00300 if ( errorMessage )
00301 *errorMessage += "\n" + msg;
00302
00303 return ErrProjection;
00304 }
00305 }
00306 if ( skipAttributeCreation )
00307 {
00308 fet.clearAttributeMap();
00309 }
00310 if ( !writer->addFeature( fet ) )
00311 {
00312 if ( writer->hasError() && errorMessage )
00313 {
00314 *errorMessage += "\n" + writer->errorMessage();
00315 }
00316 }
00317 n++;
00318 }
00319
00320
00321 if ( !writer->flushBuffer() )
00322 {
00323 if ( writer->hasError() && errorMessage )
00324 {
00325 *errorMessage += "\n" + writer->errorMessage();
00326 }
00327 }
00328 int errors = writer->errorCount();
00329
00330 delete writer;
00331
00332 if ( shallTransform )
00333 {
00334 delete ct;
00335 }
00336
00337 if ( errorMessage )
00338 {
00339 if ( errors > 0 )
00340 {
00341 *errorMessage += "\n" + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
00342 }
00343 else
00344 {
00345 errorMessage->clear();
00346 }
00347 }
00348
00349 return errors == 0 ? NoError : ErrFeatureWriteFailed;
00350 }