#include "RimFileWellPath.h" #include "RicfCommandObject.h" #include "RifWellPathImporter.h" #include "RimProject.h" #include "RimTools.h" #include "cafUtils.h" #include CAF_PDM_SOURCE_INIT( RimFileWellPath, "WellPath" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimFileWellPath::RimFileWellPath() { CAF_PDM_InitScriptableObjectWithNameAndComment( "File Well Path", ":/Well.svg", "", "", "FileWellPath", "Well Paths Loaded From File" ); CAF_PDM_InitFieldNoDefault( &id, "WellPathId", "Id" ); id.uiCapability()->setUiReadOnly( true ); id.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &sourceSystem, "SourceSystem", "Source System" ); sourceSystem.uiCapability()->setUiReadOnly( true ); sourceSystem.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &utmZone, "UTMZone", "UTM Zone" ); utmZone.uiCapability()->setUiReadOnly( true ); utmZone.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &updateDate, "WellPathUpdateDate", "Update Date" ); updateDate.uiCapability()->setUiReadOnly( true ); updateDate.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &updateUser, "WellPathUpdateUser", "Update User" ); updateUser.uiCapability()->setUiReadOnly( true ); updateUser.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &m_surveyType, "WellPathSurveyType", "Survey Type" ); m_surveyType.uiCapability()->setUiReadOnly( true ); m_surveyType.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &m_filePath, "WellPathFilepath", "File Path" ); m_filePath.uiCapability()->setUiReadOnly( true ); // Read-only legacy field used to migrate SSIHUB-cached well paths saved before commit // bdb46d9df407878f0016ea2c150f44cc07fef698 removed the cache mechanism. See initAfterRead. CAF_PDM_InitFieldNoDefault( &m_filePathInCache_OBSOLETE, "WellPathFilePathInCache", "File Name" ); m_filePathInCache_OBSOLETE.uiCapability()->setUiHidden( true ); m_filePathInCache_OBSOLETE.xmlCapability()->setIOWritable( false ); CAF_PDM_InitField( &m_wellPathIndexInFile, "WellPathNumberInFile", -1, "Well Number in File" ); m_wellPathIndexInFile.uiCapability()->setUiReadOnly( true ); CAF_PDM_InitField( &m_useAutoGeneratedPointAtSeaLevel, "UseAutoGeneratedPointAtSeaLevel", false, "Generate Point at Sea Level" ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimFileWellPath::~RimFileWellPath() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimFileWellPath::filePath() const { return m_filePath().path(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFileWellPath::setFilepath( const QString& path ) { m_filePath = path; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- int RimFileWellPath::wellPathIndexInFile() const { return m_wellPathIndexInFile(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFileWellPath::setWellPathIndexInFile( int index ) { m_wellPathIndexInFile = index; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFileWellPath::setSurveyType( QString surveyType ) { m_surveyType = surveyType; if ( m_surveyType() == "PLAN" ) setWellPathColor( cvf::Color3f( 0.999f, 0.333f, 0.0f ) ); else if ( m_surveyType() == "PROTOTYPE" ) setWellPathColor( cvf::Color3f( 0.0f, 0.333f, 0.999f ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFileWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { RimWellPath::defineUiOrdering( uiConfigName, uiOrdering ); uiOrdering.add( &m_useAutoGeneratedPointAtSeaLevel ); caf::PdmUiGroup* fileInfoGroup = uiOrdering.createGroupBeforeGroup( "Simulation Well", "File" ); fileInfoGroup->add( &m_filePath ); fileInfoGroup->add( &m_wellPathIndexInFile ); if ( !id().isEmpty() ) uiOrdering.insertBeforeItem( m_datumElevation.uiCapability(), &id ); if ( !sourceSystem().isEmpty() ) uiOrdering.insertBeforeItem( m_datumElevation.uiCapability(), &sourceSystem ); if ( !utmZone().isEmpty() ) uiOrdering.insertBeforeItem( m_datumElevation.uiCapability(), &utmZone ); if ( !updateDate().isEmpty() ) uiOrdering.insertBeforeItem( m_datumElevation.uiCapability(), &updateDate ); if ( !updateUser().isEmpty() ) uiOrdering.insertBeforeItem( m_datumElevation.uiCapability(), &updateUser ); if ( !m_surveyType().isEmpty() ) uiOrdering.insertBeforeItem( m_datumElevation.uiCapability(), &m_surveyType ); } //-------------------------------------------------------------------------------------------------- /// Read JSON or ascii file containing well path data //-------------------------------------------------------------------------------------------------- bool RimFileWellPath::readWellPathFile( QString* errorMessage, RifWellPathImporter* wellPathImporter, bool initializeWellNamesFromFile ) { if ( caf::Utils::fileExists( filePath() ) ) { RifWellPathImporter::WellData wellData = wellPathImporter->readWellData( filePath(), m_wellPathIndexInFile() ); RifWellPathImporter::WellMetaData wellMetaData = RifWellPathImporter::readWellMetaData( filePath(), m_wellPathIndexInFile() ); // General well info if ( initializeWellNamesFromFile || name().isEmpty() ) { // Initialize the well path and export names from the source file during first import, or if no name // has been assigned yet (e.g. projects saved before the well path name was persisted). Subsequent data // reloads of a named well path preserve the name stored in the project while continuing to refresh // geometry and metadata. setName( wellData.m_name ); } id = wellMetaData.m_id; sourceSystem = wellMetaData.m_sourceSystem; utmZone = wellMetaData.m_utmZone; updateUser = wellMetaData.m_updateUser; setSurveyType( wellMetaData.m_surveyType ); updateDate = wellMetaData.m_updateDate.toString( "d MMMM yyyy" ); if ( m_useAutoGeneratedPointAtSeaLevel ) { ensureWellPathStartAtSeaLevel( wellData.m_wellPathGeometry.p() ); } setWellPathGeometry( wellData.m_wellPathGeometry.p() ); return true; } else { if ( errorMessage ) ( *errorMessage ) = "Could not find the well path file: " + filePath(); return false; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFileWellPath::ensureWellPathStartAtSeaLevel( RigWellPath* wellPath ) { std::vector wellPathPoints = wellPath->wellPathPoints(); std::vector measuredDepths = wellPath->measuredDepths(); if ( wellPathPoints.empty() || measuredDepths.empty() || wellPathPoints.size() != measuredDepths.size() ) return; cvf::Vec3d firstPoint = wellPathPoints[0]; const double epsilon = 1e-3; bool firstPointAtSeaLevel = std::abs( firstPoint.z() ) < epsilon; if ( !firstPointAtSeaLevel ) { // Insert a new point on sea level straight above the // first point in the read well path. std::vector newPoints = { cvf::Vec3d( firstPoint.x(), firstPoint.y(), 0.0 ) }; newPoints.insert( newPoints.end(), wellPathPoints.begin(), wellPathPoints.end() ); // Use rkbDiff as MD for the point at sea level double mdAtSeaLevel = 0.0; if ( wellPath->datumElevation() > 0.0 ) { mdAtSeaLevel = wellPath->datumElevation(); } else if ( airGap() != std::numeric_limits::infinity() && airGap() > 0.0 ) { mdAtSeaLevel = airGap(); } std::vector newMeasuredDepths = { mdAtSeaLevel }; newMeasuredDepths.insert( newMeasuredDepths.end(), measuredDepths.begin(), measuredDepths.end() ); wellPath->setWellPathPoints( newPoints, newMeasuredDepths ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFileWellPath::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) { RimWellPath::fieldChangedByUi( changedField, oldValue, newValue ); if ( changedField == &m_useAutoGeneratedPointAtSeaLevel ) { RifWellPathImporter wellPathImporter; QString errorMessage; if ( readWellPathFile( &errorMessage, &wellPathImporter, false ) ) { RimProject::current()->scheduleCreateDisplayModelAndRedrawAllViews(); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFileWellPath::initAfterRead() { RimWellPath::initAfterRead(); QString cachedPath = m_filePathInCache_OBSOLETE().path(); if ( cachedPath.isEmpty() ) return; QString newCacheFileName = RimTools::getCacheRootDirectoryPathFromProject() + "_wellpaths/" + QFileInfo( cachedPath ).fileName(); if ( caf::Utils::fileExists( newCacheFileName ) ) { m_filePath = newCacheFileName; } }