Skip to content
Permalink
Browse files

Fix reading saved color map file when an item's label contains

a comma character

Fixes #24112
  • Loading branch information
nyalldawson committed Sep 15, 2020
1 parent afd7698 commit 252149375c750d6a8f1ee281c1cc9d03de272170
@@ -19,6 +19,7 @@
#include "qgis.h"
#include <QFile>
#include <QTextStream>
#include <QRegularExpression>

bool QgsRasterRendererUtils::parseColorMapFile( const QString &path, QList<QgsColorRampShader::ColorRampItem> &items, QgsColorRampShader::Type &type, QStringList &errors )
{
@@ -32,22 +33,21 @@ bool QgsRasterRendererUtils::parseColorMapFile( const QString &path, QList<QgsCo
bool res = true;

QTextStream inputStream( &inputFile );
QString inputLine;
QStringList inputStringComponents;
int lineCounter = 0;
const QRegularExpression itemRegex( QStringLiteral( "^(.+?),(.+?),(.+?),(.+?),(.+?),(.+)$" ) );

//read through the input looking for valid data
while ( !inputStream.atEnd() )
{
lineCounter++;
inputLine = inputStream.readLine();
const QString inputLine = inputStream.readLine();
if ( !inputLine.isEmpty() )
{
if ( !inputLine.simplified().startsWith( '#' ) )
{
if ( inputLine.contains( QLatin1String( "INTERPOLATION" ), Qt::CaseInsensitive ) )
{
inputStringComponents = inputLine.split( ':' );
QStringList inputStringComponents = inputLine.split( ':' );
if ( inputStringComponents.size() == 2 )
{
if ( inputStringComponents[1].trimmed().toUpper().compare( QLatin1String( "INTERPOLATED" ), Qt::CaseInsensitive ) == 0 )
@@ -71,13 +71,12 @@ bool QgsRasterRendererUtils::parseColorMapFile( const QString &path, QList<QgsCo
}
else
{
inputStringComponents = inputLine.split( ',' );
if ( inputStringComponents.size() == 6 )
const QRegularExpressionMatch match = itemRegex.match( inputLine );
if ( match.hasMatch() )
{
QgsColorRampShader::ColorRampItem currentItem( QLocale().toDouble( inputStringComponents[0] ),
QColor::fromRgb( inputStringComponents[1].toInt(), inputStringComponents[2].toInt(),
inputStringComponents[3].toInt(), inputStringComponents[4].toInt() ),
inputStringComponents[5] );
QgsColorRampShader::ColorRampItem currentItem( match.captured( 1 ).toDouble(),
QColor::fromRgb( match.captured( 2 ).toInt(), match.captured( 3 ).toInt(), match.captured( 4 ).toInt(), match.captured( 5 ).toInt() ),
match.captured( 6 ) );
items.push_back( currentItem );
}
else
@@ -228,6 +228,7 @@ ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py)
ADD_PYTHON_TEST(PyQgsRasterLayerRenderer test_qgsrasterlayerrenderer.py)
ADD_PYTHON_TEST(PyQgsRasterColorRampShader test_qgsrastercolorrampshader.py)
ADD_PYTHON_TEST(PyQgsRasterRange test_qgsrasterrange.py)
ADD_PYTHON_TEST(PyQgsRasterRendererUtils test_qgsrasterrendererutils.py)
ADD_PYTHON_TEST(PyQgsRasterResampler test_qgsrasterresampler.py)
ADD_PYTHON_TEST(PyQgsRasterTransparencyWidget test_qgsrastertransparencywidget.py)
ADD_PYTHON_TEST(PyQgsRatioLockButton test_qgsratiolockbutton.py)
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsRasterRendererUtils.
.. note:: This program 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 2 of the License, or
(at your option) any later version.
"""
__author__ = '(C) 2020 by Nyall Dawson'
__date__ = '15/09/2020'
__copyright__ = 'Copyright 2020, The QGIS Project'

import qgis # NOQA

from qgis.PyQt.QtCore import QTemporaryDir
from qgis.PyQt.QtGui import (QColor)
from qgis.core import (QgsRasterRendererUtils,
QgsColorRampShader
)

from qgis.testing import start_app, unittest
from utilities import unitTestDataPath

start_app()
TEST_DATA_DIR = unitTestDataPath()


class TestQgsRasterRendererUtils(unittest.TestCase):

def testSaveRestoreColorMap(self):
items = [QgsColorRampShader.ColorRampItem(5.5, QColor(255, 100, 120, 60), 'my item'),
QgsColorRampShader.ColorRampItem(15.7, QColor(150, 90, 220)),
QgsColorRampShader.ColorRampItem(22, QColor(255, 0, 0, 100), 'my, & ^ "\' item'),
QgsColorRampShader.ColorRampItem(25.5, QColor(255, 200, 220, 10), 'my item 3')]

tmp_dir = QTemporaryDir()
tmp_file = "{}/ramp.txt".format(tmp_dir.path())

self.assertTrue(QgsRasterRendererUtils.saveColorMapFile(tmp_file, items, QgsColorRampShader.Interpolated))
res, read_items, type, errors = QgsRasterRendererUtils.parseColorMapFile('')
self.assertFalse(res)

res, read_items, type, errors = QgsRasterRendererUtils.parseColorMapFile(tmp_file)
self.assertTrue(res)
self.assertEqual(type, QgsColorRampShader.Interpolated)
self.assertFalse(errors)
self.assertEqual([i.value for i in read_items], [i.value for i in items])
self.assertEqual([i.color.name() for i in read_items], [i.color.name() for i in items])
self.assertEqual([i.label for i in read_items], ['my item', 'Color entry 2', 'my, & ^ "\' item', 'my item 3'])

self.assertTrue(QgsRasterRendererUtils.saveColorMapFile(tmp_file, items, QgsColorRampShader.Discrete))
res, read_items, type, errors = QgsRasterRendererUtils.parseColorMapFile(tmp_file)
self.assertTrue(res)
self.assertEqual(type, QgsColorRampShader.Discrete)
self.assertFalse(errors)

self.assertTrue(QgsRasterRendererUtils.saveColorMapFile(tmp_file, items, QgsColorRampShader.Exact))
res, read_items, type, errors = QgsRasterRendererUtils.parseColorMapFile(tmp_file)
self.assertTrue(res)
self.assertEqual(type, QgsColorRampShader.Exact)
self.assertFalse(errors)


if __name__ == '__main__':
unittest.main()

0 comments on commit 2521493

Please sign in to comment.
You can’t perform that action at this time.