diff --git a/test/style1.txt b/test/style1.txt new file mode 100644 index 0000000000000000000000000000000000000000..6182a760afdb50d3d4c7e5b15477ce5167364537 --- /dev/null +++ b/test/style1.txt @@ -0,0 +1,21 @@ +<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> +<qgis version="2.18.15" minimumScale="inf" maximumScale="1e+08" hasScaleBasedVisibilityFlag="0"> + <pipe> + <rasterrenderer opacity="1" alphaBand="-1" classificationMax="1493" classificationMinMaxOrigin="CumulativeCutFullExtentEstimated" band="1" classificationMin="160" type="singlebandpseudocolor"> + <rasterTransparency/> + <rastershader> + <colorrampshader colorRampType="INTERPOLATED" clip="0"> + <item alpha="255" value="160" label="160" color="#d7191c"/> + <item alpha="255" value="493.2" label="493.2" color="#fdae61"/> + <item alpha="255" value="826.5" label="826.5" color="#ffffbf"/> + <item alpha="255" value="1160" label="1160" color="#abdda4"/> + <item alpha="255" value="1493" label="1493" color="#2b83ba"/> + </colorrampshader> + </rastershader> + </rasterrenderer> + <brightnesscontrast brightness="0" contrast="0"/> + <huesaturation colorizeGreen="128" colorizeOn="0" colorizeRed="255" colorizeBlue="128" grayscaleMode="0" saturation="0" colorizeStrength="100"/> + <rasterresampler maxOversampling="2"/> + </pipe> + <blendMode>0</blendMode> +</qgis> diff --git a/test/style2.txt b/test/style2.txt new file mode 100644 index 0000000000000000000000000000000000000000..d6393bc86b100afad4ae578225b56407ef903739 --- /dev/null +++ b/test/style2.txt @@ -0,0 +1,17 @@ +<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> +<qgis version="2.18.15" minimumScale="0" maximumScale="1e+08" hasScaleBasedVisibilityFlag="0"> + <pipe> + <rasterrenderer opacity="1" alphaBand="-1" band="1" type="paletted"> + <rasterTransparency/> + <colorPalette> + <paletteEntry value="0" color="#000000" label="unclassified"/> + <paletteEntry value="1" color="#ff0000" label="class1"/> + <paletteEntry value="2" color="#00ff00" label="class2"/> + </colorPalette> + </rasterrenderer> + <brightnesscontrast brightness="0" contrast="0"/> + <huesaturation colorizeGreen="128" colorizeOn="0" colorizeRed="255" colorizeBlue="128" grayscaleMode="0" saturation="0" colorizeStrength="100"/> + <rasterresampler maxOversampling="2"/> + </pipe> + <blendMode>0</blendMode> +</qgis> diff --git a/test/style3.txt b/test/style3.txt new file mode 100644 index 0000000000000000000000000000000000000000..83bb054d04d9fc37a3d8a6b2f3f926e68b5a2ad3 --- /dev/null +++ b/test/style3.txt @@ -0,0 +1,93 @@ +<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> +<qgis simplifyDrawingTol="1" labelsEnabled="0" simplifyAlgorithm="0" maxScale="0" readOnly="0" version="3.0.2-Girona" minScale="1e+8" simplifyMaxScale="1" simplifyLocal="1" simplifyDrawingHints="1" hasScaleBasedVisibilityFlag="0"> + <renderer-v2 enableorderby="0" type="singleSymbol" symbollevels="0" forceraster="0"> + <symbols> + <symbol alpha="1" type="fill" clip_to_extent="1" name="0"> + <layer pass="0" enabled="1" locked="0" class="SimpleFill"> + <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/> + <prop v="168,123,178,255" k="color"/> + <prop v="bevel" k="joinstyle"/> + <prop v="0,0" k="offset"/> + <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> + <prop v="MM" k="offset_unit"/> + <prop v="35,35,35,255" k="outline_color"/> + <prop v="solid" k="outline_style"/> + <prop v="0.26" k="outline_width"/> + <prop v="MM" k="outline_width_unit"/> + <prop v="solid" k="style"/> + <data_defined_properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </data_defined_properties> + </layer> + </symbol> + </symbols> + <rotation/> + <sizescale/> + </renderer-v2> + <customproperties/> + <blendMode>0</blendMode> + <featureBlendMode>0</featureBlendMode> + <layerOpacity>1</layerOpacity> + <fieldConfiguration> + <field name="DN"> + <editWidget type=""> + <config> + <Option/> + </config> + </editWidget> + </field> + <field name="class_name"> + <editWidget type=""> + <config> + <Option/> + </config> + </editWidget> + </field> + </fieldConfiguration> + <aliases> + <alias field="DN" index="0" name=""/> + <alias field="class_name" index="1" name=""/> + </aliases> + <excludeAttributesWMS/> + <excludeAttributesWFS/> + <defaults> + <default expression="" field="DN" applyOnUpdate="0"/> + <default expression="" field="class_name" applyOnUpdate="0"/> + </defaults> + <constraints> + <constraint unique_strength="0" exp_strength="0" field="DN" notnull_strength="0" constraints="0"/> + <constraint unique_strength="0" exp_strength="0" field="class_name" notnull_strength="0" constraints="0"/> + </constraints> + <constraintExpressions> + <constraint field="DN" exp="" desc=""/> + <constraint field="class_name" exp="" desc=""/> + </constraintExpressions> + <attributeactions> + <defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/> + </attributeactions> + <attributetableconfig sortExpression="" sortOrder="0" actionWidgetStyle="dropDown"> + <columns/> + </attributetableconfig> + <editform></editform> + <editforminit/> + <editforminitcodesource>0</editforminitcodesource> + <editforminitfilepath></editforminitfilepath> + <editforminitcode><![CDATA[]]></editforminitcode> + <featformsuppress>0</featformsuppress> + <editorlayout>generatedlayout</editorlayout> + <editable/> + <labelOnTop/> + <widgets/> + <conditionalstyles> + <rowstyles/> + <fieldstyles/> + </conditionalstyles> + <expressionfields/> + <previewExpression></previewExpression> + <mapTip></mapTip> + <layerGeometryType>2</layerGeometryType> +</qgis> diff --git a/test/style4.txt b/test/style4.txt new file mode 100644 index 0000000000000000000000000000000000000000..d18e30ec2dbffb6e2af22412cd5805757a56178c --- /dev/null +++ b/test/style4.txt @@ -0,0 +1,257 @@ +<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> +<qgis simplifyDrawingTol="1" labelsEnabled="0" simplifyAlgorithm="0" maxScale="0" readOnly="0" version="3.0.2-Girona" minScale="1e+8" simplifyMaxScale="1" simplifyLocal="1" simplifyDrawingHints="1" hasScaleBasedVisibilityFlag="0"> + <renderer-v2 attr="class_name" enableorderby="0" type="categorizedSymbol" symbollevels="0" forceraster="0"> + <categories> + <category render="true" value="burnt and tilled pasture" label="burnt and tilled pasture" symbol="0"/> + <category render="true" value="burnt pasture" label="burnt pasture" symbol="1"/> + <category render="true" value="burnt secondary regrowth" label="burnt secondary regrowth" symbol="2"/> + <category render="true" value="tilled pasture" label="tilled pasture" symbol="3"/> + <category render="true" value="" label="" symbol="4"/> + </categories> + <symbols> + <symbol alpha="1" type="fill" clip_to_extent="1" name="0"> + <layer pass="0" enabled="1" locked="0" class="SimpleFill"> + <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/> + <prop v="228,86,159,255" k="color"/> + <prop v="bevel" k="joinstyle"/> + <prop v="0,0" k="offset"/> + <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> + <prop v="MM" k="offset_unit"/> + <prop v="35,35,35,255" k="outline_color"/> + <prop v="solid" k="outline_style"/> + <prop v="0.26" k="outline_width"/> + <prop v="MM" k="outline_width_unit"/> + <prop v="solid" k="style"/> + <data_defined_properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </data_defined_properties> + </layer> + </symbol> + <symbol alpha="1" type="fill" clip_to_extent="1" name="1"> + <layer pass="0" enabled="1" locked="0" class="SimpleFill"> + <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/> + <prop v="102,210,219,255" k="color"/> + <prop v="bevel" k="joinstyle"/> + <prop v="0,0" k="offset"/> + <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> + <prop v="MM" k="offset_unit"/> + <prop v="35,35,35,255" k="outline_color"/> + <prop v="solid" k="outline_style"/> + <prop v="0.26" k="outline_width"/> + <prop v="MM" k="outline_width_unit"/> + <prop v="solid" k="style"/> + <data_defined_properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </data_defined_properties> + </layer> + </symbol> + <symbol alpha="1" type="fill" clip_to_extent="1" name="2"> + <layer pass="0" enabled="1" locked="0" class="SimpleFill"> + <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/> + <prop v="102,53,225,255" k="color"/> + <prop v="bevel" k="joinstyle"/> + <prop v="0,0" k="offset"/> + <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> + <prop v="MM" k="offset_unit"/> + <prop v="35,35,35,255" k="outline_color"/> + <prop v="solid" k="outline_style"/> + <prop v="0.26" k="outline_width"/> + <prop v="MM" k="outline_width_unit"/> + <prop v="solid" k="style"/> + <data_defined_properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </data_defined_properties> + </layer> + </symbol> + <symbol alpha="1" type="fill" clip_to_extent="1" name="3"> + <layer pass="0" enabled="1" locked="0" class="SimpleFill"> + <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/> + <prop v="129,201,118,255" k="color"/> + <prop v="bevel" k="joinstyle"/> + <prop v="0,0" k="offset"/> + <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> + <prop v="MM" k="offset_unit"/> + <prop v="35,35,35,255" k="outline_color"/> + <prop v="solid" k="outline_style"/> + <prop v="0.26" k="outline_width"/> + <prop v="MM" k="outline_width_unit"/> + <prop v="solid" k="style"/> + <data_defined_properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </data_defined_properties> + </layer> + </symbol> + <symbol alpha="1" type="fill" clip_to_extent="1" name="4"> + <layer pass="0" enabled="1" locked="0" class="SimpleFill"> + <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/> + <prop v="232,165,31,255" k="color"/> + <prop v="bevel" k="joinstyle"/> + <prop v="0,0" k="offset"/> + <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> + <prop v="MM" k="offset_unit"/> + <prop v="35,35,35,255" k="outline_color"/> + <prop v="solid" k="outline_style"/> + <prop v="0.26" k="outline_width"/> + <prop v="MM" k="outline_width_unit"/> + <prop v="solid" k="style"/> + <data_defined_properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </data_defined_properties> + </layer> + </symbol> + </symbols> + <source-symbol> + <symbol alpha="1" type="fill" clip_to_extent="1" name="0"> + <layer pass="0" enabled="1" locked="0" class="SimpleFill"> + <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/> + <prop v="168,123,178,255" k="color"/> + <prop v="bevel" k="joinstyle"/> + <prop v="0,0" k="offset"/> + <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> + <prop v="MM" k="offset_unit"/> + <prop v="35,35,35,255" k="outline_color"/> + <prop v="solid" k="outline_style"/> + <prop v="0.26" k="outline_width"/> + <prop v="MM" k="outline_width_unit"/> + <prop v="solid" k="style"/> + <data_defined_properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </data_defined_properties> + </layer> + </symbol> + </source-symbol> + <colorramp type="randomcolors" name="[source]"/> + <rotation/> + <sizescale/> + </renderer-v2> + <customproperties> + <property key="embeddedWidgets/count" value="0"/> + <property key="variableNames"/> + <property key="variableValues"/> + </customproperties> + <blendMode>0</blendMode> + <featureBlendMode>0</featureBlendMode> + <layerOpacity>1</layerOpacity> + <SingleCategoryDiagramRenderer diagramType="Histogram" attributeLegend="1"> + <DiagramCategory barWidth="5" opacity="1" width="15" enabled="0" penColor="#000000" penAlpha="255" backgroundAlpha="255" backgroundColor="#ffffff" rotationOffset="270" scaleBasedVisibility="0" lineSizeScale="3x:0,0,0,0,0,0" height="15" minimumSize="0" maxScaleDenominator="1e+8" sizeScale="3x:0,0,0,0,0,0" penWidth="0" lineSizeType="MM" sizeType="MM" minScaleDenominator="0" labelPlacementMethod="XHeight" scaleDependency="Area" diagramOrientation="Up"> + <fontProperties style="" description="MS Shell Dlg 2,8.25,-1,5,50,0,0,0,0,0"/> + </DiagramCategory> + </SingleCategoryDiagramRenderer> + <DiagramLayerSettings linePlacementFlags="18" priority="0" placement="0" zIndex="0" obstacle="0" dist="0" showAll="1"> + <properties> + <Option type="Map"> + <Option value="" type="QString" name="name"/> + <Option name="properties"/> + <Option value="collection" type="QString" name="type"/> + </Option> + </properties> + </DiagramLayerSettings> + <fieldConfiguration> + <field name="DN"> + <editWidget type="TextEdit"> + <config> + <Option/> + </config> + </editWidget> + </field> + <field name="class_name"> + <editWidget type="TextEdit"> + <config> + <Option/> + </config> + </editWidget> + </field> + </fieldConfiguration> + <aliases> + <alias field="DN" index="0" name=""/> + <alias field="class_name" index="1" name=""/> + </aliases> + <excludeAttributesWMS/> + <excludeAttributesWFS/> + <defaults> + <default expression="" field="DN" applyOnUpdate="0"/> + <default expression="" field="class_name" applyOnUpdate="0"/> + </defaults> + <constraints> + <constraint unique_strength="0" exp_strength="0" field="DN" notnull_strength="0" constraints="0"/> + <constraint unique_strength="0" exp_strength="0" field="class_name" notnull_strength="0" constraints="0"/> + </constraints> + <constraintExpressions> + <constraint field="DN" exp="" desc=""/> + <constraint field="class_name" exp="" desc=""/> + </constraintExpressions> + <attributeactions> + <defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/> + </attributeactions> + <attributetableconfig sortExpression="" sortOrder="0" actionWidgetStyle="dropDown"> + <columns> + <column hidden="0" type="field" name="DN" width="-1"/> + <column hidden="0" type="field" name="class_name" width="-1"/> + <column hidden="1" type="actions" width="-1"/> + </columns> + </attributetableconfig> + <editform></editform> + <editforminit/> + <editforminitcodesource>0</editforminitcodesource> + <editforminitfilepath></editforminitfilepath> + <editforminitcode><![CDATA[# -*- coding: utf-8 -*- +""" +QGIS forms can have a Python function that is called when the form is +opened. + +Use this function to add extra logic to your forms. + +Enter the name of the function in the "Python Init function" +field. +An example follows: +""" +from qgis.PyQt.QtWidgets import QWidget + +def my_form_open(dialog, layer, feature): + geom = feature.geometry() + control = dialog.findChild(QWidget, "MyLineEdit") +]]></editforminitcode> + <featformsuppress>0</featformsuppress> + <editorlayout>generatedlayout</editorlayout> + <editable> + <field name="DN" editable="1"/> + <field name="class_name" editable="1"/> + </editable> + <labelOnTop> + <field labelOnTop="0" name="DN"/> + <field labelOnTop="0" name="class_name"/> + </labelOnTop> + <widgets/> + <conditionalstyles> + <rowstyles/> + <fieldstyles/> + </conditionalstyles> + <expressionfields/> + <previewExpression>class_name</previewExpression> + <mapTip></mapTip> + <layerGeometryType>2</layerGeometryType> +</qgis> diff --git a/test/test_mapvisualization.py b/test/test_mapvisualization.py index ba4c2cb176024fa07feb28269951d71bc9f74454..f31e4184af26f7e3ec09ef11572c7be56a03bb6a 100644 --- a/test/test_mapvisualization.py +++ b/test/test_mapvisualization.py @@ -22,10 +22,50 @@ from timeseriesviewer.utils import initQgisApplication from PyQt5.QtGui import * from PyQt5.QtCore import * import unittest +from timeseriesviewer.utils import * from timeseriesviewer.mapcanvas import * - +from timeseriesviewer.mapvisualization import * +from example.Images import Img_2014_05_07_LC82270652014127LGN00_BOA QGIS_APP = initQgisApplication() +def getChildElements(node): + assert isinstance(node, QDomNode) + childs = node.childNodes() + return [childs.at(i) for i in range(childs.count())] + +def compareXML(element1, element2 ): + + assert isinstance(element1, QDomNode) + assert isinstance(element2, QDomNode) + + tag1 = element1.nodeName() + tag2 = element2.nodeName() + if tag1 != tag2: + return False + + elts1 = getChildElements(element1); + elts2 = getChildElements(element2); + + if len(elts1) != len(elts2): + return False + + if len(elts1) == 0: + + + value1 = element1.nodeValue() + value2 = element2.nodeValue() + + if value1 != value2: + return False + else: + return True + else: + for e1, e2 in zip(elts1, elts2): + if not compareXML(e1, e2): + return False + + return True + class testclassDialogTest(unittest.TestCase): """Test rerources work.""" @@ -45,6 +85,128 @@ class testclassDialogTest(unittest.TestCase): m.show() + def test_renderer(self): + + styleFiles = file_search(os.path.dirname(__file__), 'style*.txt') + + + + + lyr = QgsRasterLayer(Img_2014_05_07_LC82270652014127LGN00_BOA) + + r0 = lyr.renderer() + xml0 = rendererToXml(r0) + r0b = rendererFromXml(xml0) + self.assertTrue(type(r0), type(r0b)) + + + + rasterRenderer = [QgsMultiBandColorRenderer(r0, 3,2,1, QgsContrastEnhancement(), QgsContrastEnhancement(), QgsContrastEnhancement()), + QgsPalettedRasterRenderer(r0,0, [ + QgsPalettedRasterRenderer.Class(0, QColor('black'), 'class1'), + QgsPalettedRasterRenderer.Class(1, QColor('green'), 'class2'), + ] ), + QgsHillshadeRenderer(r0, 0, 0.0, 100.0), + QgsSingleBandPseudoColorRenderer(r0, 0, QgsRasterShader(0.0, 255.0)), + QgsSingleBandColorDataRenderer(r0, 0), + QgsSingleBandGrayRenderer(r0, 0)] + + vectorRenderer = []#[QgsSingleSymbolRenderer(QgsLineSymbol()), QgsPointDistanceRenderer()] + + for r1 in rasterRenderer + vectorRenderer: + + xml1 = rendererToXml(r1) + self.assertIsInstance(xml1, QDomDocument) + + + r1b = rendererFromXml(xml1) + self.assertTrue(type(r1), type(r1b)) + + if isinstance(r1, QgsRasterRenderer): + self.assertIsInstance(r1b, QgsRasterRenderer) + elif isinstance(r1, QgsFeatureRenderer): + self.assertIsInstance(r1b, QgsFeatureRenderer) + + xml2 = rendererToXml(r1b) + self.assertIsInstance(xml2, QDomDocument) + self.assertTrue(xml1.toString() == xml2.toString()) + + + rClone = cloneRenderer(r1) + self.assertTrue(type(r1), type(rClone)) + xmlClone = rendererToXml(rClone) + self.assertIsInstance(xmlClone, QDomDocument) + + similar = compareXML(xml1.firstChild(), xml2.firstChild()) + self.assertTrue(similar) + + + + + + + for path in styleFiles: + f = open(path, encoding='utf8') + xml = ''.join(f.readlines()) + f.close() + + renderer = rendererFromXml(xml) + self.assertTrue(renderer != None) + #self.assertTrue(isinstance(renderer, QgsRasterRenderer) or isinstance(renderer, QgsFeatureRenderer), msg='Unable to read style from {}'.format(path)) + + + s = "" + + def test_maprendersettings(self): + from example.Images import Img_2014_01_15_LC82270652014015LGN00_BOA + + from timeseriesviewer.timeseries import TimeSeries + TS = TimeSeries() + TS.addFiles([Img_2014_01_15_LC82270652014015LGN00_BOA]) + sensor1 = TS.sensors()[0] + w = MapViewRenderSettingsV2(sensor1) + w.show() + + + lyr = QgsRasterLayer(Img_2014_01_15_LC82270652014015LGN00_BOA) + doc = QDomDocument() + err = '' + lyr.exportNamedStyle(doc, err) + xml0 = doc.toString() + self.assertEqual(err, '') + + xml = rendererToXml(lyr.renderer()) + self.assertIsInstance(xml, QDomDocument) + xml = xml.toString() + self.assertEqual(xml0, xml) + + + r0 = lyr.renderer() + r = w.rasterRenderer() + + self.assertIsInstance(r, QgsMultiBandColorRenderer) + + r2 = QgsSingleBandGrayRenderer(r, 2) + w.setRasterRenderer(r2) + self.assertIsInstance(w.currentRenderWidget(), QgsSingleBandGrayRendererWidget) + r2b = w.rasterRenderer() + self.assertIsInstance(r2b, QgsSingleBandGrayRenderer) + xml2, xml2b = rendererToXml(r2).toString(), rendererToXml(r2b).toString() + #self.assertEqual(xml2, xml2b) + + r3 = QgsSingleBandPseudoColorRenderer(r,0) + r3.setClassificationMin(0) + r3.setClassificationMax(100) + w.setRasterRenderer(r3) + self.assertIsInstance(w.currentRenderWidget(), QgsSingleBandPseudoColorRendererWidget) + r3b = w.rasterRenderer() + self.assertIsInstance(r3b, QgsSingleBandPseudoColorRenderer) + xml3, xml3b = rendererToXml(r3).toString(), rendererToXml(r3b).toString() + #self.assertEqual(xml3, xml3b) + s = "" + + +