ResInsight/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp
2017-05-23 10:28:42 +02:00

407 lines
15 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimWellPathCollection.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiaColorTables.h"
#include "RigWellPath.h"
#include "RimProject.h"
#include "RimWellLogFile.h"
#include "RimWellPath.h"
#include "RiuMainWindow.h"
#include "RivWellPathCollectionPartMgr.h"
#include "RifWellPathImporter.h"
#include "cafPdmUiEditorHandle.h"
#include "cafProgressInfo.h"
#include <QFile>
#include <QFileInfo>
#include <QMessageBox>
#include <fstream>
#include <cmath>
namespace caf
{
template<>
void RimWellPathCollection::WellVisibilityEnum::setUp()
{
addItem(RimWellPathCollection::FORCE_ALL_OFF, "FORCE_ALL_OFF", "Off");
addItem(RimWellPathCollection::ALL_ON, "ALL_ON", "Individual");
addItem(RimWellPathCollection::FORCE_ALL_ON, "FORCE_ALL_ON", "On");
}
}
CAF_PDM_SOURCE_INIT(RimWellPathCollection, "WellPaths");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPathCollection::RimWellPathCollection()
{
CAF_PDM_InitObject("Wells", ":/WellCollection.png", "", "");
CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", "");
isActive.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&showWellPathLabel, "ShowWellPathLabel", true, "Show well path labels", "", "", "");
cvf::Color3f defWellLabelColor = RiaApplication::instance()->preferences()->defaultWellLabelColor();
CAF_PDM_InitField(&wellPathLabelColor, "WellPathLabelColor", defWellLabelColor, "Well label color", "", "", "");
CAF_PDM_InitField(&wellPathVisibility, "GlobalWellPathVisibility", WellVisibilityEnum(ALL_ON), "Global well path visibility", "", "", "");
CAF_PDM_InitField(&wellPathRadiusScaleFactor, "WellPathRadiusScale", 0.1, "Well Path radius scale", "", "", "");
CAF_PDM_InitField(&wellPathCrossSectionVertexCount, "WellPathVertexCount", 12, "Well Path vertex count", "", "", "");
wellPathCrossSectionVertexCount.xmlCapability()->setIOWritable(false);
wellPathCrossSectionVertexCount.xmlCapability()->setIOReadable(false);
wellPathCrossSectionVertexCount.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&wellPathClip, "WellPathClip", true, "Clip Well Paths", "", "", "");
CAF_PDM_InitField(&wellPathClipZDistance, "WellPathClipZDistance", 100, "Well path clipping depth distance", "", "", "");
CAF_PDM_InitFieldNoDefault(&wellPaths, "WellPaths", "Well Paths", "", "", "");
wellPaths.uiCapability()->setUiHidden(true);
m_wellPathCollectionPartManager = new RivWellPathCollectionPartMgr(this);
m_wellPathImporter = new RifWellPathImporter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPathCollection::~RimWellPathCollection()
{
wellPaths.deleteAllChildObjects();
delete m_wellPathImporter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
scheduleGeometryRegenAndRedrawViews();
}
//--------------------------------------------------------------------------------------------------
/// Read JSON files containing well path data
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::readWellPathFiles()
{
caf::ProgressInfo progress(wellPaths.size(), "Reading well paths from file");
for (size_t wpIdx = 0; wpIdx < wellPaths.size(); wpIdx++)
{
if (!wellPaths[wpIdx]->filepath().isEmpty())
{
QString errorMessage;
if (!wellPaths[wpIdx]->readWellPathFile(&errorMessage, m_wellPathImporter))
{
QMessageBox::warning(RiuMainWindow::instance(),
"File open error",
errorMessage);
}
}
RimWellLogFile* wellLogFile = wellPaths[wpIdx]->m_wellLogFile;
if (wellLogFile)
{
QString errorMessage;
if (!wellLogFile->readFile(&errorMessage))
{
QString displayMessage = "Could not open the well log file: \n" + wellLogFile->fileName();
if (!errorMessage.isEmpty())
{
displayMessage += "\n\n";
displayMessage += errorMessage;
}
QMessageBox::warning(RiuMainWindow::instance(),
"File open error",
displayMessage);
}
}
progress.setProgressDescription(QString("Reading file %1").arg(wellPaths[wpIdx]->name));
progress.incrementProgress();
}
this->sortWellsByName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::addWellPaths( QStringList filePaths )
{
std::vector<RimWellPath*> wellPathArray;
foreach (QString filePath, filePaths)
{
// Check if this file is already open
bool alreadyOpen = false;
for (size_t wpIdx = 0; wpIdx < wellPaths.size(); wpIdx++)
{
QFile f1;
f1.setFileName(filePath);
QString s1 = f1.fileName();
QFile f2;
f2.setFileName(wellPaths[wpIdx]->filepath());
QString s2 = f2.fileName();
if (s1 == s2)
{
//printf("Attempting to open well path JSON file that is already open:\n %s\n", (const char*) filePath.toLocal8Bit());
alreadyOpen = true;
break;
}
}
if (!alreadyOpen)
{
QFileInfo fi(filePath);
if (fi.suffix().compare("json") == 0)
{
RimWellPath* wellPath = new RimWellPath();
wellPath->filepath = filePath;
wellPathArray.push_back(wellPath);
}
else
{
// Create Well path objects for all the paths in the assumed ascii file
size_t wellPathCount = m_wellPathImporter->wellDataCount(filePath);
for (size_t i = 0; i < wellPathCount; ++i)
{
RimWellPath* wellPath = new RimWellPath();
wellPath->filepath = filePath;
wellPath->wellPathIndexInFile = static_cast<int>(i);
wellPathArray.push_back(wellPath);
}
}
}
}
readAndAddWellPaths(wellPathArray);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::readAndAddWellPaths(std::vector<RimWellPath*>& wellPathArray)
{
caf::ProgressInfo progress(wellPathArray.size(), "Reading well paths from file");
const caf::ColorTable& colorTable = RiaColorTables::wellLogPlotPaletteColors();
cvf::Color3ubArray wellColors = colorTable.color3ubArray();
cvf::Color3ubArray interpolatedWellColors = wellColors;
if (wellPathArray.size() > 1)
{
interpolatedWellColors = caf::ColorTable::interpolateColorArray(wellColors, wellPathArray.size());
}
for (size_t wpIdx = 0; wpIdx < wellPathArray.size(); wpIdx++)
{
RimWellPath* wellPath = wellPathArray[wpIdx];
wellPath->readWellPathFile(NULL, m_wellPathImporter);
progress.setProgressDescription(QString("Reading file %1").arg(wellPath->name));
// If a well path with this name exists already, make it read the well path file
RimWellPath* existingWellPath = wellPathByName(wellPath->name);
if (existingWellPath)
{
existingWellPath->filepath = wellPath->filepath;
existingWellPath->wellPathIndexInFile = wellPath->wellPathIndexInFile;
existingWellPath->readWellPathFile(NULL, m_wellPathImporter);
delete wellPath;
}
else
{
wellPath->wellPathColor = cvf::Color3f(interpolatedWellColors[wpIdx]);
wellPaths.push_back(wellPath);
}
progress.incrementProgress();
}
this->sortWellsByName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::addWellLogs(const QStringList& filePaths)
{
foreach (QString filePath, filePaths)
{
RimWellLogFile* logFileInfo = RimWellLogFile::readWellLogFile(filePath);
if (logFileInfo)
{
RimWellPath* wellPath = wellPathByName(logFileInfo->wellName());
if (!wellPath)
{
wellPath = new RimWellPath();
wellPaths.push_back(wellPath);
}
wellPath->setLogFileInfo(logFileInfo);
}
}
this->sortWellsByName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiGroup* wellHeadGroup = uiOrdering.addNewGroup("Well labels");
wellHeadGroup->add(&showWellPathLabel);
wellHeadGroup->add(&wellPathLabelColor);
caf::PdmUiGroup* wellPipe = uiOrdering.addNewGroup("Well pipe");
wellPipe->add(&wellPathVisibility);
wellPipe->add(&wellPathRadiusScaleFactor);
caf::PdmUiGroup* advancedGroup = uiOrdering.addNewGroup("Clipping");
advancedGroup->add(&wellPathClip);
advancedGroup->add(&wellPathClipZDistance);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimWellPathCollection::objectToggleField()
{
return &isActive;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::scheduleGeometryRegenAndRedrawViews()
{
m_wellPathCollectionPartManager->scheduleGeometryRegen();
RimProject* proj;
this->firstAncestorOrThisOfType(proj);
if (proj) proj->createDisplayModelAndRedrawAllViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath)
{
for (size_t wellPathIdx = 0; wellPathIdx < wellPaths.size(); wellPathIdx++)
{
wellPaths[wellPathIdx]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellPathCollection::wellPathByName(const QString& wellPathName) const
{
for (size_t wellPathIdx = 0; wellPathIdx < wellPaths.size(); wellPathIdx++)
{
if (wellPaths[wellPathIdx]->name() == wellPathName)
{
return wellPaths[wellPathIdx];
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::deleteAllWellPaths()
{
wellPaths.deleteAllChildObjects();
m_wellPathImporter->clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::removeWellPath(RimWellPath* wellPath)
{
wellPaths.removeChildObject(wellPath);
bool isFilePathUsed = false;
for (size_t i = 0; i < wellPaths.size(); i++)
{
if (wellPaths[i]->filepath == wellPath->filepath)
{
isFilePathUsed = true;
break;
}
}
if (!isFilePathUsed)
{
// One file can have multiple well paths
// If no other well paths are referencing the filepath, remove cached data from the file reader
m_wellPathImporter->removeFilePath(wellPath->filepath);
}
}
bool lessWellPath(const caf::PdmPointer<RimWellPath>& w1, const caf::PdmPointer<RimWellPath>& w2)
{
if (w1.notNull() && w2.notNull())
return (w1->name() < w2->name());
else if (w1.notNull())
return true;
else
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::sortWellsByName()
{
std::sort(wellPaths.begin(), wellPaths.end(), lessWellPath);
}