From d0a870bb38fb46783639e649af6eb4b6a5afe942 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Tue, 18 Jun 2024 14:25:14 +0200 Subject: [PATCH] #11514 OSDU: parse and add datum elevation to well paths. --- .../OsduImportCommands/RiaOsduConnector.cpp | 26 ++++++++++++++++++- .../OsduImportCommands/RiaOsduConnector.h | 1 + .../RicWellPathsImportOsduFeature.cpp | 3 ++- .../RiuWellImportWizard.cpp | 3 ++- .../OsduImportCommands/RiuWellImportWizard.h | 1 + .../FileInterface/RifOsduWellPathReader.cpp | 8 +++--- .../FileInterface/RifOsduWellPathReader.h | 2 +- .../WellPath/RimOsduWellPath.cpp | 21 +++++++++++++++ .../WellPath/RimOsduWellPath.h | 4 +++ .../WellPath/RimWellPathCollection.cpp | 10 ++++--- .../WellPath/RimWellPathCollection.h | 3 ++- 11 files changed, 70 insertions(+), 12 deletions(-) diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp index a4c2d4c89d..8c1dcfc92a 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.cpp @@ -19,6 +19,8 @@ #include #include +#include + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -457,7 +459,29 @@ void RiaOsduConnector::parseWellbores( QNetworkReply* reply, const QString& well QString id = resultObj["id"].toString(); QString kind = resultObj["kind"].toString(); QString name = resultObj["data"].toObject()["FacilityName"].toString(); - m_wellbores[wellId].push_back( OsduWellbore{ id, kind, name, wellId } ); + + // Extract datum elevation. The DefaultVerticalMeasurementID is probably the datum elevation needed. + // Default to 0.0 if nothing is found, but finding nothing is suspicious. + double datumElevation = std::numeric_limits::infinity(); + QString defaultVerticalMeasurementId = resultObj["data"].toObject()["DefaultVerticalMeasurementID"].toString(); + QJsonArray verticalMeasurementsArray = resultObj["data"].toObject()["VerticalMeasurements"].toArray(); + for ( const QJsonValue& vma : verticalMeasurementsArray ) + { + QString verticalMeasurementId = vma["VerticalMeasurementID"].toString(); + if ( verticalMeasurementId == defaultVerticalMeasurementId ) + { + double verticalMeasurement = vma["VerticalMeasurement"].toDouble( 0.0 ); + datumElevation = verticalMeasurement; + } + } + + if ( std::isinf( datumElevation ) ) + { + RiaLogging::warning( QString( "Missing datum elevation for well bore '%1'. Id: %2" ).arg( name ).arg( id ) ); + datumElevation = 0.0; + } + + m_wellbores[wellId].push_back( OsduWellbore{ id, kind, name, wellId, datumElevation } ); } } diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h index 98a19de628..b474416f2e 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiaOsduConnector.h @@ -27,6 +27,7 @@ struct OsduWellbore QString kind; QString name; QString wellId; + double datumElevation; }; struct OsduWellboreTrajectory diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp b/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp index 88bec7c83a..d0209b9b26 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp +++ b/ApplicationLibCode/Commands/OsduImportCommands/RicWellPathsImportOsduFeature.cpp @@ -90,7 +90,7 @@ void RicWellPathsImportOsduFeature::onActionTriggered( bool isChecked ) auto task = progress.task( QString( "Importing well: %1" ).arg( w.name ) ); auto [wellPathGeometry, errorMessage] = - RimWellPathCollection::loadWellPathGeometryFromOsdu( osduConnector, w.wellboreTrajectoryId ); + RimWellPathCollection::loadWellPathGeometryFromOsdu( osduConnector, w.wellboreTrajectoryId, w.datumElevation ); if ( wellPathGeometry.notNull() ) { auto wellPath = new RimOsduWellPath; @@ -98,6 +98,7 @@ void RicWellPathsImportOsduFeature::onActionTriggered( bool isChecked ) wellPath->setWellId( w.wellId ); wellPath->setWellboreId( w.wellboreId ); wellPath->setWellboreTrajectoryId( w.wellboreTrajectoryId ); + wellPath->setDatumElevationFromOsdu( w.datumElevation ); oilField->wellPathCollection->addWellPath( wellPath ); diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp index 14604fb167..d34f5c245b 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.cpp @@ -579,7 +579,8 @@ void WellSummaryPage::wellboreTrajectoryFinished( const QString& wellboreId, int wiz->addWellInfo( { .name = wellbore.value().name, .wellId = well.value().id, .wellboreId = w.wellboreId, - .wellboreTrajectoryId = wellboreTrajectoryId } ); + .wellboreTrajectoryId = wellboreTrajectoryId, + .datumElevation = wellbore.value().datumElevation } ); } } diff --git a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h index 449bd5e840..4e27c87723 100644 --- a/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h +++ b/ApplicationLibCode/Commands/OsduImportCommands/RiuWellImportWizard.h @@ -370,6 +370,7 @@ public: QString wellId; QString wellboreId; QString wellboreTrajectoryId; + double datumElevation; }; RiuWellImportWizard( const QString& downloadFolder, diff --git a/ApplicationLibCode/FileInterface/RifOsduWellPathReader.cpp b/ApplicationLibCode/FileInterface/RifOsduWellPathReader.cpp index d1000e246c..04838836eb 100644 --- a/ApplicationLibCode/FileInterface/RifOsduWellPathReader.cpp +++ b/ApplicationLibCode/FileInterface/RifOsduWellPathReader.cpp @@ -106,7 +106,7 @@ std::pair, QString> RifOsduWellPathReader::parseCsv( const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::pair, QString> RifOsduWellPathReader::readWellPathData( const QByteArray& content ) +std::pair, QString> RifOsduWellPathReader::readWellPathData( const QByteArray& content, double datumElevation ) { arrow::MemoryPool* pool = arrow::default_memory_pool(); @@ -155,14 +155,16 @@ std::pair, QString> RifOsduWellPathReader::readWellPathDat for ( size_t i = 0; i < firstSize; i++ ) { - cvf::Vec3d point( readValues[X][i], readValues[Y][i], -readValues[TVD][i] ); + cvf::Vec3d point( readValues[X][i], readValues[Y][i], -readValues[TVD][i] + datumElevation ); double md = readValues[MD][i]; wellPathPoints.push_back( point ); measuredDepths.push_back( md ); } - return { cvf::make_ref( wellPathPoints, measuredDepths ), "" }; + auto wellPath = cvf::make_ref( wellPathPoints, measuredDepths ); + wellPath->setDatumElevation( datumElevation ); + return { wellPath, "" }; } return { nullptr, "" }; diff --git a/ApplicationLibCode/FileInterface/RifOsduWellPathReader.h b/ApplicationLibCode/FileInterface/RifOsduWellPathReader.h index ffb52f83e0..768cfa4876 100644 --- a/ApplicationLibCode/FileInterface/RifOsduWellPathReader.h +++ b/ApplicationLibCode/FileInterface/RifOsduWellPathReader.h @@ -32,5 +32,5 @@ class RifOsduWellPathReader { public: static std::pair, QString> parseCsv( const QString& content ); - static std::pair, QString> readWellPathData( const QByteArray& content ); + static std::pair, QString> readWellPathData( const QByteArray& content, double datumElevation ); }; diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.cpp b/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.cpp index cb16b7c949..2543a18a92 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.cpp @@ -1,5 +1,6 @@ #include "RimOsduWellPath.h" +#include "cafPdmObject.h" #include "cafPdmObjectScriptingCapability.h" CAF_PDM_SOURCE_INIT( RimOsduWellPath, "OsduWellPath" ); @@ -20,6 +21,9 @@ RimOsduWellPath::RimOsduWellPath() CAF_PDM_InitFieldNoDefault( &m_wellboreTrajectoryId, "WellboreTrajectoryId", "Wellbore Trajectory Id" ); m_wellboreTrajectoryId.uiCapability()->setUiReadOnly( true ); + CAF_PDM_InitField( &m_datumElevationFromOsdu, "DatumElevationFromOsdu", 0.0, "Datum Elevation From OSDU" ); + m_datumElevationFromOsdu.uiCapability()->setUiReadOnly( true ); + // Required, as these settings are set in RimWellPath() m_name.uiCapability()->setUiReadOnly( false ); m_name.uiCapability()->setUiHidden( false ); @@ -82,6 +86,22 @@ QString RimOsduWellPath::wellboreTrajectoryId() const return m_wellboreTrajectoryId; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimOsduWellPath::setDatumElevationFromOsdu( double datumElevation ) +{ + m_datumElevationFromOsdu = datumElevation; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimOsduWellPath::datumElevationFromOsdu() const +{ + return m_datumElevationFromOsdu; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -91,6 +111,7 @@ void RimOsduWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering osduGroup->add( &m_wellId ); osduGroup->add( &m_wellboreId ); osduGroup->add( &m_wellboreTrajectoryId ); + osduGroup->add( &m_datumElevationFromOsdu ); RimWellPath::defineUiOrdering( uiConfigName, uiOrdering ); } diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.h index 362ab3bcb5..72d1628803 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimOsduWellPath.h @@ -36,6 +36,9 @@ public: void setWellboreTrajectoryId( const QString& wellboreTrajectoryId ); QString wellboreTrajectoryId() const; + void setDatumElevationFromOsdu( double datumElevationFromOsdu ); + double datumElevationFromOsdu() const; + protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; @@ -43,4 +46,5 @@ private: caf::PdmField m_wellId; caf::PdmField m_wellboreId; caf::PdmField m_wellboreTrajectoryId; + caf::PdmField m_datumElevationFromOsdu; }; diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp index 84d6f8497b..9d52f24cda 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp @@ -178,8 +178,9 @@ void RimWellPathCollection::loadDataAndUpdate() } else if ( oWPath ) { - RiaOsduConnector* osduConnector = app->makeOsduConnector(); - auto [wellPathGeometry, errorMessage] = loadWellPathGeometryFromOsdu( osduConnector, oWPath->wellboreTrajectoryId() ); + RiaOsduConnector* osduConnector = app->makeOsduConnector(); + auto [wellPathGeometry, errorMessage] = + loadWellPathGeometryFromOsdu( osduConnector, oWPath->wellboreTrajectoryId(), oWPath->datumElevationFromOsdu() ); if ( wellPathGeometry.notNull() ) { oWPath->setWellPathGeometry( wellPathGeometry.p() ); @@ -1052,7 +1053,8 @@ void RimWellPathCollection::onChildAdded( caf::PdmFieldHandle* containerForNewOb /// //-------------------------------------------------------------------------------------------------- std::pair, QString> RimWellPathCollection::loadWellPathGeometryFromOsdu( RiaOsduConnector* osduConnector, - const QString& wellboreTrajectoryId ) + const QString& wellboreTrajectoryId, + double datumElevation ) { auto [fileContents, errorMessage] = osduConnector->requestWellboreTrajectoryParquetDataById( wellboreTrajectoryId ); if ( !errorMessage.isEmpty() ) @@ -1060,7 +1062,7 @@ std::pair, QString> RimWellPathCollection::loadWellPathGeo return { nullptr, errorMessage }; } - return RifOsduWellPathReader::readWellPathData( fileContents ); + return RifOsduWellPathReader::readWellPathData( fileContents, datumElevation ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h index d4ca69fe4b..966725626d 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h @@ -135,7 +135,8 @@ public: void onChildAdded( caf::PdmFieldHandle* containerForNewObject ) override; - static std::pair, QString> loadWellPathGeometryFromOsdu( RiaOsduConnector* osduConnector, const QString& fileId ); + static std::pair, QString> + loadWellPathGeometryFromOsdu( RiaOsduConnector* osduConnector, const QString& wellTrajectoryId, double datumElevation ); static std::pair, QString> loadWellLogFromOsdu( RiaOsduConnector* osduConnector, const QString& wellLogId );