diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp index 9030451a4a..a4c2d4c89d 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp @@ -103,6 +103,20 @@ RiaOsduConnector::~RiaOsduConnector() { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaOsduConnector::clearCachedData() +{ + QMutexLocker lock( &m_mutex ); + m_fields.clear(); + m_wells.clear(); + m_wellbores.clear(); + m_wellboreTrajectories.clear(); + m_wellLogs.clear(); + m_parquetData.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -374,7 +388,7 @@ void RiaOsduConnector::parseFields( QNetworkReply* reply ) QMutexLocker lock( &m_mutex ); m_fields.clear(); - foreach ( const QJsonValue& value, resultsArray ) + for ( const QJsonValue& value : resultsArray ) { QJsonObject resultObj = value.toObject(); @@ -406,7 +420,7 @@ void RiaOsduConnector::parseWells( QNetworkReply* reply ) { QMutexLocker lock( &m_mutex ); m_wells.clear(); - foreach ( const QJsonValue& value, resultsArray ) + for ( const QJsonValue& value : resultsArray ) { QJsonObject resultObj = value.toObject(); QString id = resultObj["id"].toString(); @@ -437,7 +451,7 @@ void RiaOsduConnector::parseWellbores( QNetworkReply* reply, const QString& well { QMutexLocker lock( &m_mutex ); m_wellbores[wellId].clear(); - foreach ( const QJsonValue& value, resultsArray ) + for ( const QJsonValue& value : resultsArray ) { QJsonObject resultObj = value.toObject(); QString id = resultObj["id"].toString(); @@ -449,6 +463,10 @@ void RiaOsduConnector::parseWellbores( QNetworkReply* reply, const QString& well emit wellboresFinished( wellId ); } + else + { + RiaLogging::error( "Failed to download well with id " + wellId + ": " + reply->errorString() ); + } } //-------------------------------------------------------------------------------------------------- @@ -467,8 +485,8 @@ void RiaOsduConnector::parseWellTrajectory( QNetworkReply* reply, const QString& { QMutexLocker lock( &m_mutex ); - m_wellboreTrajectories.clear(); - foreach ( const QJsonValue& value, resultsArray ) + m_wellboreTrajectories[wellboreId].clear(); + for ( const QJsonValue& value : resultsArray ) { QJsonObject resultObj = value.toObject(); QString id = resultObj["id"].toString(); @@ -478,7 +496,11 @@ void RiaOsduConnector::parseWellTrajectory( QNetworkReply* reply, const QString& } } - emit wellboreTrajectoryFinished( wellboreId ); + emit wellboreTrajectoryFinished( wellboreId, resultsArray.size(), "" ); + } + else + { + emit wellboreTrajectoryFinished( wellboreId, 0, "Failed to download: " + reply->errorString() ); } } @@ -498,8 +520,8 @@ void RiaOsduConnector::parseWellLogs( QNetworkReply* reply, const QString& wellb { QMutexLocker lock( &m_mutex ); - m_wellLogs.clear(); - foreach ( const QJsonValue& value, resultsArray ) + m_wellLogs[wellboreId].clear(); + for ( const QJsonValue& value : resultsArray ) { QJsonObject resultObj = value.toObject(); QString id = resultObj["id"].toString(); diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h index 1846160ffe..98a19de628 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h @@ -58,7 +58,6 @@ public: const QString& clientId ); ~RiaOsduConnector() override; - void requestFieldsByName( const QString& token, const QString& fieldName ); void requestFieldsByName( const QString& fieldName ); void requestWellsByFieldId( const QString& fieldId ); void requestWellboresByWellId( const QString& wellId ); @@ -71,6 +70,8 @@ public: QString wellIdForWellboreId( const QString& wellboreId ) const; + void clearCachedData(); + QString server() const; QString dataPartition() const; @@ -96,7 +97,7 @@ signals: void fieldsFinished(); void wellsFinished(); void wellboresFinished( const QString& wellId ); - void wellboreTrajectoryFinished( const QString& wellboreId ); + void wellboreTrajectoryFinished( const QString& wellboreId, int numTrajectories, const QString& errorMessage ); void wellLogsFinished( const QString& wellboreId ); void tokenReady( const QString& token ); @@ -112,6 +113,7 @@ private: QNetworkReply* makeDownloadRequest( const QString& url, const QString& dataPartitionId, const QString& token, const QString& contentType ); + void requestFieldsByName( const QString& token, const QString& fieldName ); void requestFieldsByName( const QString& server, const QString& dataPartitionId, const QString& token, const QString& fieldName ); void requestWellsByFieldId( const QString& server, const QString& dataPartitionId, const QString& token, const QString& fieldId ); void requestWellboresByWellId( const QString& server, const QString& dataPartitionId, const QString& token, const QString& wellId ); diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp b/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp index 8b4cbbf1ce..88bec7c83a 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp +++ b/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp @@ -38,6 +38,8 @@ #include "RiuMainWindow.h" #include "RiuWellImportWizard.h" +#include "cafProgressInfo.h" + #include "cvfObject.h" #include @@ -81,8 +83,12 @@ void RicWellPathsImportOsduFeature::onActionTriggered( bool isChecked ) if ( QDialog::Accepted == wellImportwizard.exec() ) { std::vector importedWells = wellImportwizard.importedWells(); + + caf::ProgressInfo progress( importedWells.size(), "Importing wells from OSDU" ); for ( auto w : importedWells ) { + auto task = progress.task( QString( "Importing well: %1" ).arg( w.name ) ); + auto [wellPathGeometry, errorMessage] = RimWellPathCollection::loadWellPathGeometryFromOsdu( osduConnector, w.wellboreTrajectoryId ); if ( wellPathGeometry.notNull() ) diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp index e30f28ff33..794900b3ef 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp @@ -106,6 +106,7 @@ void RiuWellImportWizard::slotAuthenticationRequired( QNetworkReply* networkRepl //-------------------------------------------------------------------------------------------------- void RiuWellImportWizard::downloadWells( const QString& fieldId ) { + m_osduConnector->clearCachedData(); m_osduConnector->requestWellsByFieldId( fieldId ); } @@ -145,17 +146,17 @@ QString RiuWellImportWizard::selectedFieldId() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuWellImportWizard::setSelectedWellboreId( const QString& wellboreId ) +void RiuWellImportWizard::setSelectedWellboreIds( const std::vector& wellboreIds ) { - m_selectedWellboreId = wellboreId; + m_selectedWellboreIds = wellboreIds; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiuWellImportWizard::selectedWellboreId() const +std::vector RiuWellImportWizard::selectedWellboreIds() const { - return m_selectedWellboreId; + return m_selectedWellboreIds; } //-------------------------------------------------------------------------------------------------- @@ -355,6 +356,7 @@ WellSelectionPage::WellSelectionPage( RimWellPathImport* wellPathImport, RiaOsdu m_tableView = new QTableView( this ); m_tableView->setSelectionBehavior( QAbstractItemView::SelectRows ); + m_tableView->setSelectionMode( QAbstractItemView::MultiSelection ); QHeaderView* header = m_tableView->horizontalHeader(); header->setSectionResizeMode( QHeaderView::Interactive ); header->setStretchLastSection( true ); @@ -427,7 +429,7 @@ void WellSelectionPage::wellboresFinished( const QString& wellId ) bool WellSelectionPage::isComplete() const { QItemSelectionModel* select = m_tableView->selectionModel(); - return select->selectedRows().size() == 1; + return !select->selectedRows().empty(); } //-------------------------------------------------------------------------------------------------- @@ -437,11 +439,21 @@ void WellSelectionPage::selectWellbore( const QItemSelection& newSelection, cons { if ( !newSelection.indexes().empty() ) { - QModelIndex index = newSelection.indexes()[0]; - int column = 0; - QString wellboreId = m_osduWellboresModel->data( index.siblingAtColumn( column ) ).toString(); - RiuWellImportWizard* wiz = dynamic_cast( wizard() ); - wiz->setSelectedWellboreId( wellboreId ); + std::vector wellboreIds; + QModelIndexList selection = m_tableView->selectionModel()->selectedRows(); + for ( QModelIndex index : selection ) + { + int idColumn = 0; + + if ( index.column() == idColumn ) + { + QString wellboreId = m_osduWellboresModel->data( index.siblingAtColumn( idColumn ) ).toString(); + wellboreIds.push_back( wellboreId ); + } + } + + RiuWellImportWizard* wiz = dynamic_cast( wizard() ); + wiz->setSelectedWellboreIds( wellboreIds ); } } @@ -464,7 +476,9 @@ WellSummaryPage::WellSummaryPage( RimWellPathImport* wellPathImport, RiaOsduConn setButtonText( QWizard::FinishButton, "Import" ); - connect( m_osduConnector, SIGNAL( wellboreTrajectoryFinished( const QString& ) ), SLOT( wellboreTrajectoryFinished( const QString& ) ) ); + connect( m_osduConnector, + SIGNAL( wellboreTrajectoryFinished( const QString&, int, const QString& ) ), + SLOT( wellboreTrajectoryFinished( const QString&, int, const QString& ) ) ); } //-------------------------------------------------------------------------------------------------- @@ -474,18 +488,36 @@ void WellSummaryPage::initializePage() { RiuWellImportWizard* wiz = dynamic_cast( wizard() ); - QString wellboreId = wiz->selectedWellboreId(); - wiz->downloadWellPaths( wellboreId ); + QMutexLocker lock( &m_mutex ); + m_pendingWellboreIds.clear(); + for ( const QString& wellboreId : wiz->selectedWellboreIds() ) + { + m_pendingWellboreIds.insert( wellboreId ); + } + + for ( const QString& wellboreId : wiz->selectedWellboreIds() ) + { + wiz->downloadWellPaths( wellboreId ); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void WellSummaryPage::wellboreTrajectoryFinished( const QString& wellboreId ) +void WellSummaryPage::wellboreTrajectoryFinished( const QString& wellboreId, int numTrajectories, const QString& errorMessage ) { std::vector wellboreTrajectories = m_osduConnector->wellboreTrajectories( wellboreId ); std::vector wells = m_osduConnector->wells(); + auto findWellboreById = []( const std::vector& wellbores, const QString& wellboreId ) -> std::optional + { + auto it = std::find_if( wellbores.begin(), wellbores.end(), [wellboreId]( const OsduWellbore& w ) { return w.id == wellboreId; } ); + if ( it != wellbores.end() ) + return std::optional( *it ); + else + return {}; + }; + auto findWellForWellId = []( const std::vector& wells, const QString& wellId ) -> std::optional { auto it = std::find_if( wells.begin(), wells.end(), [wellId]( const OsduWell& w ) { return w.id == wellId; } ); @@ -497,18 +529,47 @@ void WellSummaryPage::wellboreTrajectoryFinished( const QString& wellboreId ) RiuWellImportWizard* wiz = dynamic_cast( wizard() ); - for ( auto w : wellboreTrajectories ) { - QString wellId = m_osduConnector->wellIdForWellboreId( w.wellboreId ); + QMutexLocker lock( &m_mutex ); + + QString wellId = m_osduConnector->wellIdForWellboreId( wellboreId ); std::optional well = findWellForWellId( wells, wellId ); - if ( well.has_value() ) + std::vector wellbores = m_osduConnector->wellbores( wellId ); + std::optional wellbore = findWellboreById( wellbores, wellboreId ); + + if ( well.has_value() && wellbore.has_value() ) { - QString wellboreTrajectoryId = w.id; - wiz->addWellInfo( { .name = well.value().name, - .wellId = well.value().id, - .wellboreId = w.wellboreId, - .wellboreTrajectoryId = wellboreTrajectoryId } ); + if ( !errorMessage.isEmpty() ) + { + m_textEdit->append( QString( "Wellbore '%1' download failed: %2." ).arg( wellbore.value().name ).arg( errorMessage ) ); + } + else if ( numTrajectories == 0 ) + { + m_textEdit->append( QString( "Wellbore '%1': No trajectory found." ).arg( wellbore.value().name ) ); + } + + for ( auto w : wellboreTrajectories ) + { + QString wellboreTrajectoryId = w.id; + wiz->addWellInfo( { .name = wellbore.value().name, + .wellId = well.value().id, + .wellboreId = w.wellboreId, + .wellboreTrajectoryId = wellboreTrajectoryId } ); + } } + + m_pendingWellboreIds.erase( wellboreId ); } + + emit( completeChanged() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool WellSummaryPage::isComplete() const +{ + QMutexLocker lock( &m_mutex ); + return m_pendingWellboreIds.empty(); } diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h index b465ae7f01..c3adeae7cb 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h @@ -28,6 +28,8 @@ #include "RiaOsduConnector.h" +#include + class QFile; class QLabel; class QTextEdit; @@ -296,14 +298,17 @@ public: WellSummaryPage( RimWellPathImport* wellPathImport, RiaOsduConnector* osduConnector, QWidget* parent = nullptr ); void initializePage() override; + bool isComplete() const override; private slots: - void wellboreTrajectoryFinished( const QString& wellId ); + void wellboreTrajectoryFinished( const QString& wellboreId, int numTrajectories, const QString& errorMessage ); private: RimWellPathImport* m_wellPathImportObject; RiaOsduConnector* m_osduConnector; QTextEdit* m_textEdit; + std::set m_pendingWellboreIds; + mutable QMutex m_mutex; }; //-------------------------------------------------------------------------------------------------- @@ -331,10 +336,10 @@ public: // Methods used from the wizard pages void resetAuthenticationCount(); - void setSelectedFieldId( const QString& fieldId ); - QString selectedFieldId() const; - void setSelectedWellboreId( const QString& wellboreId ); - QString selectedWellboreId() const; + void setSelectedFieldId( const QString& fieldId ); + QString selectedFieldId() const; + void setSelectedWellboreIds( const std::vector& wellboreIds ); + std::vector selectedWellboreIds() const; void addWellInfo( RiuWellImportWizard::WellInfo wellInfo ); std::vector importedWells() const; @@ -347,9 +352,9 @@ public slots: void slotAuthenticationRequired( QNetworkReply* networkReply, QAuthenticator* authenticator ); private: - RiaOsduConnector* m_osduConnector; - QString m_selectedFieldId; - QString m_selectedWellboreId; + RiaOsduConnector* m_osduConnector; + QString m_selectedFieldId; + std::vector m_selectedWellboreIds; QString m_destinationFolder;