///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) Equinor ASA // // 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RifColorLegendData.h" #include "RiaTextStringTools.h" #include "RigFormationNames.h" #include "cafAssert.h" #include "cafPdmUiFilePathEditor.h" #include #include #include "cvfColor3.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RifColorLegendData::readFormationNamesFile( const QString& fileName, QString* errorMessage ) { QFileInfo fileInfo( fileName ); if ( fileInfo.fileName() == "layer_zone_table.txt" ) { return RifColorLegendData::readFmuFormationNameFile( fileName, errorMessage ); } else { return RifColorLegendData::readLyrFormationNameFile( fileName, errorMessage ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RifColorLegendData::readLyrFormationNameFile( const QString& fileName, QString* errorMessage ) { cvf::ref formationNames = new RigFormationNames; QFile dataFile( fileName ); if ( !dataFile.open( QFile::ReadOnly ) ) { if ( errorMessage ) ( *errorMessage ) += "Could not open file: " + fileName + "\n"; return formationNames; } QTextStream stream( &dataFile ); int lineNumber = 1; while ( !stream.atEnd() ) { QString line = stream.readLine(); QStringList lineSegs = line.split( "'" ); if ( lineSegs.size() == 0 ) continue; // Empty line if ( lineSegs.size() == 1 ) continue; // No name present. Comment line ? if ( lineSegs.size() == 2 ) { if ( errorMessage ) ( *errorMessage ) += "Missing quote on line : " + QString::number( lineNumber ) + "\n"; continue; // One quote present } if ( lineSegs.size() == 3 ) // Normal case { if ( lineSegs[0].contains( "--" ) ) continue; // Comment line QString formationName = lineSegs[1]; int commentMarkPos = lineSegs[2].indexOf( "--" ); QString numberString = lineSegs[2]; if ( commentMarkPos >= 0 ) numberString.truncate( commentMarkPos ); // extract last word which may contain formation color QString colorWord = RiaTextStringTools::splitSkipEmptyParts( numberString ).last(); if ( QColor::isValidColor( colorWord ) ) numberString.remove( colorWord ); // remove color if present as last word on line // extract words containing formation number(s) QStringList numberWords = RiaTextStringTools::splitSkipEmptyParts( numberString, QRegExp( "-" ) ); if ( numberWords.size() == 2 ) // formation range with or without color at end of line { bool isNumber1 = false; bool isNumber2 = false; int startK = numberWords[0].toInt( &isNumber1 ); int endK = numberWords[1].toInt( &isNumber2 ); if ( !( isNumber2 && isNumber1 ) ) { if ( errorMessage ) ( *errorMessage ) += "Format error on line: " + QString::number( lineNumber ) + "\n"; continue; } int tmp = startK; startK = tmp < endK ? tmp : endK; endK = tmp > endK ? tmp : endK; if ( QColor::isValidColor( colorWord ) ) // formation color present at end of line { cvf::Color3f formationColor; convertStringToColor( colorWord, &formationColor ); formationNames->appendFormationRange( formationName, formationColor, startK - 1, endK - 1 ); } else // no color present { formationNames->appendFormationRange( formationName, startK - 1, endK - 1 ); } } else if ( numberWords.size() == 1 ) { bool isNumber1 = false; int kLayerCount = numberWords[0].toInt( &isNumber1 ); if ( !isNumber1 ) { if ( errorMessage ) ( *errorMessage ) += "Format error on line: " + QString::number( lineNumber ) + "\n"; continue; } if ( QColor::isValidColor( colorWord ) ) // formation color present at end of line { cvf::Color3f formationColor; convertStringToColor( colorWord, &formationColor ); formationNames->appendFormationRangeHeight( formationName, formationColor, kLayerCount ); } else // no color present { formationNames->appendFormationRangeHeight( formationName, kLayerCount ); } } else { if ( errorMessage ) ( *errorMessage ) += "Format error on line: " + QString::number( lineNumber ) + "\n"; } } ++lineNumber; } return formationNames; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RifColorLegendData::readFmuFormationNameFile( const QString& fileName, QString* errorMessage ) { cvf::ref formationNames = new RigFormationNames; QFile dataFile( fileName ); if ( !dataFile.open( QFile::ReadOnly ) ) { if ( errorMessage ) ( *errorMessage ) += "Could not open file: " + fileName + "\n"; return formationNames; } QTextStream stream( &dataFile ); int lineNumber = 1; QString currentFormationName; int startK = -1; int endK = -1; while ( !stream.atEnd() ) { QString line = stream.readLine(); if ( line.isNull() ) { // Make sure we append the last formation if ( !currentFormationName.isEmpty() ) { formationNames->appendFormationRange( currentFormationName, startK - 1, endK - 1 ); } break; } else { QTextStream lineStream( &line ); double kLayer; QString formationName; lineStream >> kLayer >> formationName; if ( lineStream.status() != QTextStream::Ok ) { *errorMessage = QString( "Failed to parse line %1 of '%2'" ).arg( lineNumber ).arg( fileName ); return formationNames; } if ( formationName != currentFormationName ) { // Append previous formation if ( !currentFormationName.isEmpty() ) { formationNames->appendFormationRange( currentFormationName, startK - 1, endK - 1 ); } // Start new formation currentFormationName = formationName; startK = kLayer; endK = kLayer; } else { endK = kLayer; } } } // Append previous formation at the end of the stream if ( !currentFormationName.isEmpty() ) { formationNames->appendFormationRange( currentFormationName, startK - 1, endK - 1 ); } return formationNames; } //-------------------------------------------------------------------------------------------------- /// Conversion of a color specification from string representation to Color3f. /// String can be in various formats according to QColor capabilities, notably /// SVG color keyword names, c.f. https://www.w3.org/TR/SVG11/types.html#ColorKeywords, /// or #RRGGBB used on a LYR formation data file. //-------------------------------------------------------------------------------------------------- bool RifColorLegendData::convertStringToColor( const QString& word, cvf::Color3f* color ) { if ( word.isEmpty() ) return false; QColor colorQ( word ); if ( colorQ.isValid() ) { *color = cvf::Color3f::fromByteColor( colorQ.red(), colorQ.green(), colorQ.blue() ); return true; } return false; }