예제 #1
0
    def testSetDataSource(self):
        """Test change data source"""

        temp_dir = QTemporaryDir()
        options = QgsDataProvider.ProviderOptions()
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        layer = QgsRasterLayer(myPath, myBaseName)
        renderer = QgsSingleBandGrayRenderer(layer.dataProvider(), 2)

        image = layer.previewAsImage(QSize(400, 400))
        self.assertFalse(image.isNull())
        self.assertTrue(image.save(os.path.join(temp_dir.path(), 'expected.png'), "PNG"))

        layer.setDataSource(myPath.replace('4326.tif', '4326-BAD_SOURCE.tif'), 'bad_layer', 'gdal', options)
        self.assertFalse(layer.isValid())
        image = layer.previewAsImage(QSize(400, 400))
        self.assertTrue(image.isNull())

        layer.setDataSource(myPath.replace('4326-BAD_SOURCE.tif', '4326.tif'), 'bad_layer', 'gdal', options)
        self.assertTrue(layer.isValid())
        image = layer.previewAsImage(QSize(400, 400))
        self.assertFalse(image.isNull())
        self.assertTrue(image.save(os.path.join(temp_dir.path(), 'actual.png'), "PNG"))

        self.assertTrue(filecmp.cmp(os.path.join(temp_dir.path(), 'actual.png'), os.path.join(temp_dir.path(), 'expected.png')), False)
예제 #2
0
파일: folder.py 프로젝트: inasafe/inasafe
    def _add_tabular_layer(self, tabular_layer, layer_name, save_style=False):
        """Add a tabular layer to the folder.

        :param tabular_layer: The layer to add.
        :type tabular_layer: QgsVectorLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :param save_style: If we have to save a QML too. Default to False.
        :type save_style: bool

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """
        output = QFileInfo(
            self.uri.filePath(layer_name + '.csv'))

        QgsVectorFileWriter.writeAsVectorFormat(
            tabular_layer,
            output.absoluteFilePath(),
            'utf-8',
            QgsCoordinateTransform(),
            'CSV')

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            tabular_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
예제 #3
0
    def testPalettedColorTableToClassData(self):
        entries = [QgsColorRampShader.ColorRampItem(5, QColor(255, 0, 0), 'item1'),
                   QgsColorRampShader.ColorRampItem(3, QColor(0, 255, 0), 'item2'),
                   QgsColorRampShader.ColorRampItem(6, QColor(0, 0, 255), 'item3'),
                   ]
        classes = QgsPalettedRasterRenderer.colorTableToClassData(entries)
        self.assertEqual(classes[0].value, 5)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[2].value, 6)
        self.assertEqual(classes[0].label, 'item1')
        self.assertEqual(classes[1].label, 'item2')
        self.assertEqual(classes[2].label, 'item3')
        self.assertEqual(classes[0].color.name(), '#ff0000')
        self.assertEqual(classes[1].color.name(), '#00ff00')
        self.assertEqual(classes[2].color.name(), '#0000ff')

        # test #13263
        path = os.path.join(unitTestDataPath('raster'),
                            'hub13263.vrt')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))
        classes = QgsPalettedRasterRenderer.colorTableToClassData(layer.dataProvider().colorTable(1))
        self.assertEqual(len(classes), 4)
        classes = QgsPalettedRasterRenderer.colorTableToClassData(layer.dataProvider().colorTable(15))
        self.assertEqual(len(classes), 256)
예제 #4
0
    def testIdentify(self):
        myPath = os.path.join(unitTestDataPath(), 'landsat.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage
        myPoint = QgsPointXY(786690, 3345803)
        # print 'Extents: %s' % myRasterLayer.extent().toString()
        #myResult, myRasterValues = myRasterLayer.identify(myPoint)
        #assert myResult
        myRasterValues = myRasterLayer.dataProvider().identify(myPoint, QgsRaster.IdentifyFormatValue).results()

        assert len(myRasterValues) > 0

        # Get the name of the first band
        myBand = list(myRasterValues.keys())[0]
        # myExpectedName = 'Band 1
        myExpectedBand = 1
        myMessage = 'Expected "%s" got "%s" for first raster band name' % (
                    myExpectedBand, myBand)
        assert myExpectedBand == myBand, myMessage

        # Convert each band value to a list of ints then to a string

        myValues = list(myRasterValues.values())
        myIntValues = []
        for myValue in myValues:
            myIntValues.append(int(myValue))
        myValues = str(myIntValues)
        myExpectedValues = '[127, 141, 112, 72, 86, 126, 156, 211, 170]'
        myMessage = 'Expected: %s\nGot: %s' % (myValues, myExpectedValues)
        self.assertEqual(myValues, myExpectedValues, myMessage)
예제 #5
0
    def testOneBandRaster(self):
        path = os.path.join(unitTestDataPath('raster'),
                            'band1_float32_noct_epsg4326.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer)

        combo = QgsRasterBandComboBox()
        combo.setLayer(layer)
        self.assertEqual(combo.layer(), layer)
        self.assertEqual(combo.currentBand(), 1)
        self.assertEqual(combo.count(), 1)

        combo.setShowNotSetOption(True)
        self.assertEqual(combo.currentBand(), 1)
        self.assertEqual(combo.count(), 2)
        combo.setBand(-1)
        self.assertEqual(combo.currentBand(), -1)
        combo.setBand(1)
        self.assertEqual(combo.currentBand(), 1)

        combo.setShowNotSetOption(False)
        self.assertEqual(combo.currentBand(), 1)
        self.assertEqual(combo.count(), 1)
 def run_clicked(self):
     self.setEnabled(False)
     input = self.inputbox.currentLayer().source()
     if str(self.output.text()) == '':
         try:
             output = os.environ['temp']+'out'+str(int(clock()*10000))+'.tif'
         except:
             if os.access('/tmp/kuw_filter', os.F_OK)==False:
                 os.mkdir('/tmp/kuw_filter')
             output = '/tmp/kuw_filter/out'+str(int(clock()*10000))+'.tif'
     else:
        output = str(self.output.text())
     self.setCursor(QCursor(Qt.WaitCursor))
     start = dt.datetime.now()
     if doFilter(self, input, output):
         elapsed = dt.datetime.now() - start
         elapsed = str(dt.timedelta(seconds=round(elapsed.total_seconds())))
         self.msgbox(QApplication.translate('kuw_filterdialog','Time elapsed:\n ')+elapsed)
         if self.addout.isChecked():
             fileName = str(output)
             fileInfo = QFileInfo(fileName)
             baseName = fileInfo.baseName()
             iface.addRasterLayer(fileName, baseName)
     self.setCursor(QCursor(Qt.ArrowCursor))
     self.setEnabled(True)
     self.close()
예제 #7
0
파일: folder.py 프로젝트: inasafe/inasafe
    def _add_raster_layer(self, raster_layer, layer_name, save_style=False):
        """Add a raster layer to the folder.

        :param raster_layer: The layer to add.
        :type raster_layer: QgsRasterLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :param save_style: If we have to save a QML too. Default to False.
        :type save_style: bool

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """
        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(self.uri.filePath(layer_name + '.tif'))

        source = QFileInfo(raster_layer.source())
        if source.exists() and source.suffix() in ['tiff', 'tif']:
            # If it's tiff file based.
            QFile.copy(source.absoluteFilePath(), output.absoluteFilePath())

        else:
            # If it's not file based.
            renderer = raster_layer.renderer()
            provider = raster_layer.dataProvider()
            crs = raster_layer.crs()

            pipe = QgsRasterPipe()
            pipe.set(provider.clone())
            pipe.set(renderer.clone())

            file_writer = QgsRasterFileWriter(output.absoluteFilePath())
            file_writer.Mode(1)

            file_writer.writeRaster(
                pipe,
                provider.xSize(),
                provider.ySize(),
                provider.extent(),
                crs)

            del file_writer

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            raster_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
예제 #8
0
 def testIssue7023(self):
     """Check if converting a raster from 1.8 to 2 works."""
     myPath = os.path.join(unitTestDataPath("raster"), "raster-pallette-crash2.tif")
     myFileInfo = QFileInfo(myPath)
     myBaseName = myFileInfo.baseName()
     myRasterLayer = QgsRasterLayer(myPath, myBaseName)
     myMessage = "Raster not loaded: %s" % myPath
     assert myRasterLayer.isValid(), myMessage
     # crash on next line
     QgsProject.instance().addMapLayers([myRasterLayer])
예제 #9
0
    def testShaderCrash(self):
        """Check if we assign a shader and then reassign it no crash occurs."""
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        myRasterShader = QgsRasterShader()
        myColorRampShader = QgsColorRampShader()
        myColorRampShader.setColorRampType(QgsColorRampShader.Interpolated)
        myItems = []
        myItem = QgsColorRampShader.ColorRampItem(
            10, QColor('#ffff00'), 'foo')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(
            100, QColor('#ff00ff'), 'bar')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(
            1000, QColor('#00ff00'), 'kazam')
        myItems.append(myItem)
        myColorRampShader.setColorRampItemList(myItems)
        myRasterShader.setRasterShaderFunction(myColorRampShader)
        myPseudoRenderer = QgsSingleBandPseudoColorRenderer(
            myRasterLayer.dataProvider(), 1, myRasterShader)
        myRasterLayer.setRenderer(myPseudoRenderer)

        return
        # ####### works first time #############

        myRasterShader = QgsRasterShader()
        myColorRampShader = QgsColorRampShader()
        myColorRampShader.setColorRampType(QgsColorRampShader.Interpolated)
        myItems = []
        myItem = QgsColorRampShader.ColorRampItem(10,
                                                  QColor('#ffff00'), 'foo')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(100,
                                                  QColor('#ff00ff'), 'bar')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(1000,
                                                  QColor('#00ff00'), 'kazam')
        myItems.append(myItem)
        myColorRampShader.setColorRampItemList(myItems)
        myRasterShader.setRasterShaderFunction(myColorRampShader)
        # ####### crash on next line (fixed now)##################
        myPseudoRenderer = QgsSingleBandPseudoColorRenderer(
            myRasterLayer.dataProvider(), 1, myRasterShader)
        myRasterLayer.setRenderer(myPseudoRenderer)
예제 #10
0
    def test_setRenderer(self):
        myPath = os.path.join(unitTestDataPath("raster"), "band1_float32_noct_epsg4326.tif")
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        layer = QgsRasterLayer(myPath, myBaseName)

        self.rendererChanged = False
        layer.rendererChanged.connect(self.onRendererChanged)

        rShader = QgsRasterShader()
        r = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, rShader)

        layer.setRenderer(r)
        assert self.rendererChanged
        assert layer.renderer() == r
예제 #11
0
    def testPalettedRendererWithNegativeColorValue(self):
        """ test paletted raster renderer with negative values in color table"""

        path = os.path.join(unitTestDataPath('raster'),
                            'hub13263.vrt')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1,
                                             [QgsPalettedRasterRenderer.Class(-1, QColor(0, 255, 0), 'class 2'),
                                              QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')])

        self.assertEqual(renderer.nColors(), 2)
        self.assertEqual(renderer.usesBands(), [1])
예제 #12
0
파일: folder.py 프로젝트: inasafe/inasafe
    def _add_vector_layer(self, vector_layer, layer_name, save_style=False):
        """Add a vector layer to the folder.

        :param vector_layer: The layer to add.
        :type vector_layer: QgsVectorLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :param save_style: If we have to save a QML too. Default to False.
        :type save_style: bool

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """

        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(
            self.uri.filePath(layer_name + '.' + self._default_vector_format))

        driver_mapping = {
            'shp': 'ESRI Shapefile',
            'kml': 'KML',
            'geojson': 'GeoJSON',
        }

        QgsVectorFileWriter.writeAsVectorFormat(
            vector_layer,
            output.absoluteFilePath(),
            'utf-8',
            QgsCoordinateTransform(),  # No tranformation
            driver_mapping[self._default_vector_format])

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            vector_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
예제 #13
0
    def testSignals(self):
        path = os.path.join(unitTestDataPath('raster'),
                            'band3_float32_noct_epsg4326.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer)

        combo = QgsRasterBandComboBox()
        combo.setLayer(layer)

        signal_spy = QSignalSpy(combo.bandChanged)
        combo.setBand(2)
        self.assertEqual(len(signal_spy), 1)
        self.assertEqual(signal_spy[0][0], 2)
        combo.setBand(3)
        self.assertEqual(len(signal_spy), 2)
        self.assertEqual(signal_spy[1][0], 3)
예제 #14
0
파일: folder.py 프로젝트: inasafe/inasafe
    def layer_uri(self, layer_name):
        """Get layer URI.

        :param layer_name: The name of the layer to fetch.
        :type layer_name: str

        :return: The URI to the layer.
        :rtype: str

        .. versionadded:: 4.0
        """
        layers = self.layers()
        for layer, extension in product(layers, EXTENSIONS):
            one_file = QFileInfo(
                self.uri.filePath(layer + '.' + extension))
            if one_file.exists():
                if one_file.baseName() == layer_name:
                    return one_file.absoluteFilePath()
        else:
            return None
예제 #15
0
    def testPalettedBand(self):
        """ test paletted raster render band"""
        path = os.path.join(unitTestDataPath(),
                            'landsat_4326.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 2,
                                             [QgsPalettedRasterRenderer.Class(137, QColor(0, 255, 0), 'class 2'),
                                              QgsPalettedRasterRenderer.Class(138, QColor(255, 0, 0), 'class 1'),
                                              QgsPalettedRasterRenderer.Class(139, QColor(0, 0, 255), 'class 1')])

        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer_band2")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer_band2"), "Paletted rendering test failed")

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 3,
                                             [QgsPalettedRasterRenderer.Class(120, QColor(0, 255, 0), 'class 2'),
                                              QgsPalettedRasterRenderer.Class(123, QColor(255, 0, 0), 'class 1'),
                                              QgsPalettedRasterRenderer.Class(124, QColor(0, 0, 255), 'class 1')])

        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer_band3")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer_band3"), "Paletted rendering test failed")
예제 #16
0
    def testClone(self):
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        layer = QgsRasterLayer(myPath, myBaseName)

        renderer = layer.renderer().clone()
        renderer.setOpacity(33.3)
        layer.setRenderer(renderer)

        # clone layer
        clone = layer.clone()

        # generate xml from layer
        layer_doc = QDomDocument("doc")
        layer_elem = layer_doc.createElement("maplayer")
        layer.writeLayerXml(layer_elem, layer_doc, QgsReadWriteContext())

        # generate xml from clone
        clone_doc = QDomDocument("doc")
        clone_elem = clone_doc.createElement("maplayer")
        clone.writeLayerXml(clone_elem, clone_doc, QgsReadWriteContext())

        # replace id within xml of clone
        clone_id_elem = clone_elem.firstChildElement("id")
        clone_id_elem_patch = clone_doc.createElement("id")
        clone_id_elem_patch_value = clone_doc.createTextNode(layer.id())
        clone_id_elem_patch.appendChild(clone_id_elem_patch_value)
        clone_elem.replaceChild(clone_id_elem_patch, clone_id_elem)

        # update doc
        clone_doc.appendChild(clone_elem)
        layer_doc.appendChild(layer_elem)

        # compare xml documents
        self.assertEqual(layer_doc.toString(), clone_doc.toString())
 def workerFinished(self, ok, ret):
     """Handles the output from the worker and cleans up after the
        worker has finished."""
     # clean up the worker and thread
     self.showInfo("Handling the result")
     self.worker.deleteLater()
     self.thread.quit()
     self.thread.wait()
     self.thread.deleteLater()
     # remove widget from message bar (pop)
     self.iface.messageBar().popWidget(self.messageBar)
     if ok and ret is not None:
         #self.showInfo("Ret: "+str(ret[10,]))
         # Transformation:
         self.minx = self.thinninglayer.extent().xMinimum()
         self.maxx = self.thinninglayer.extent().xMaximum()
         self.miny = self.thinninglayer.extent().yMinimum()
         self.maxy = self.thinninglayer.extent().yMaximum()
         self.rows = self.thinninglayer.height()
         self.cols = self.thinninglayer.width()
         self.xres = (self.maxx - self.minx) / float(self.cols)
         self.yres = (self.maxy - self.miny) / float(self.rows)
         geotransform = (self.minx, self.xres, 0, self.maxy, 0, -self.yres)
         try:
             format = self.DEFAULTPROVIDER
             driver = gdal.GetDriverByName(format)
             NOVALUE = 0
             metadata = driver.GetMetadata()
             fileName = self.outputRaster.text()
             if self.outputRaster.text() == "":
                 self.showInfo("No output file specified, " +
                                      "creating a temporary file")
                 # Get a temporary file
                 fileName = mktemp(prefix='greyskel',
                        suffix=self.DEFAULTEXTENSION)
             fileInfo = QFileInfo(fileName)
             filepath = fileInfo.absolutePath()
             baseName = fileInfo.baseName()
             suffix = fileInfo.suffix()
             thisfilename = filepath + baseName + '.' + suffix
             thisfilename = fileName
             self.showInfo("File name: " + thisfilename)
             gdaldatatype = gdal.GDT_Byte
             skelmatrix = None
             if self.levelValuesCheckBox.isChecked():
                 # Transform the pixel values back to the original
                 # level values
                 my_dict = {}
                 # Add zero to handle the "empty" pixels
                 my_dict[0] = 0
                 for i in range(len(self.levels)):
                     my_dict[i + 1] = self.levels[i]
                 skelmatrix = np.vectorize(my_dict.__getitem__,
                                           otypes=[np.float])(ret)
                 gdaldatatype = gdal.GDT_Int32
                 if not self.intband:
                     gdaldatatype = gdal.GDT_Float32
             else:
                 skelmatrix = ret
             outDataset = driver.Create(thisfilename, self.cols,
                                        self.rows, 1, gdaldatatype)
             if self.thinninglayer.dataProvider().crs() is not None:
                 srs = self.thinninglayer.dataProvider().crs()
                 outDataset.SetProjection(srs.toWkt().encode('ascii',
                                                            'ignore'))
             skeletonband = outDataset.GetRasterBand(1)
             skeletonband.WriteArray(skelmatrix)
             skeletonband.SetNoDataValue(NOVALUE)
             #stats = skeletonband.GetStatistics(False, True)
             #skeletonband.SetStatistics(stats[0], stats[1],
             #                                 stats[2], stats[3])
             outDataset.SetGeoTransform(geotransform)
             outDataset = None  # To close the file
             # report the result
             rlayer = QgsRasterLayer(thisfilename, baseName)
             self.layerlistchanging = True
             #QgsMapLayerRegistry.instance().addMapLayer(rlayer)
             QgsProject.instance().addMapLayer(rlayer)
             self.layerlistchanging = False
         except:
             import traceback
             self.showError("Can't write the skeleton file:  %s" %
                                self.outputRaster.text() + ' - ' +
                                traceback.format_exc())
             okb = self.button_box.button(QDialogButtonBox.Ok)
             okb.setEnabled(True)
             closb = self.button_box.button(QDialogButtonBox.Close)
             closb.setEnabled(True)
             cancb = self.button_box.button(QDialogButtonBox.Cancel)
             cancb.setEnabled(False)
             return
         QgsMessageLog.logMessage(self.tr('ThinGreyscale finished'),
                             self.THINGREYSCALE, Qgis.Info)
     else:
         # notify the user that something went wrong
         if not ok:
             self.showError(self.tr('Aborted') + '!')
         else:
             self.showError(self.tr('No skeleton created') + '!')
     self.progressBar.setValue(0.0)
     #self.aprogressBar.setValue(0.0)
     self.iterProgressBar.setValue(0.0)
     self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
     self.button_box.button(QDialogButtonBox.Close).setEnabled(True)
     self.button_box.button(QDialogButtonBox.Cancel).setEnabled(False)
예제 #18
0
    def testPaletted(self):
        """ test paletted raster renderer with raster with color table"""
        path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1, [
            QgsPalettedRasterRenderer.Class(1, QColor(0, 255, 0), 'class 2'),
            QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')
        ])

        self.assertEqual(renderer.nColors(), 2)
        self.assertEqual(renderer.usesBands(), [1])

        # test labels
        self.assertEqual(renderer.label(1), 'class 2')
        self.assertEqual(renderer.label(3), 'class 1')
        self.assertFalse(renderer.label(101))

        # test legend symbology - should be sorted by value
        legend = renderer.legendSymbologyItems()
        self.assertEqual(legend[0][0], 'class 2')
        self.assertEqual(legend[1][0], 'class 1')
        self.assertEqual(legend[0][1].name(), '#00ff00')
        self.assertEqual(legend[1][1].name(), '#ff0000')

        # test retrieving classes
        classes = renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'class 1')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')

        # test set label
        # bad index
        renderer.setLabel(1212, 'bad')
        renderer.setLabel(3, 'new class')
        self.assertEqual(renderer.label(3), 'new class')

        # color ramp
        r = QgsLimitedRandomColorRamp(5)
        renderer.setSourceColorRamp(r)
        self.assertEqual(renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(renderer.sourceColorRamp().count(), 5)

        # clone
        new_renderer = renderer.clone()
        classes = new_renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(new_renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(new_renderer.sourceColorRamp().count(), 5)

        # write to xml and read
        doc = QDomDocument('testdoc')
        elem = doc.createElement('qgis')
        renderer.writeXml(doc, elem)
        restored = QgsPalettedRasterRenderer.create(
            elem.firstChild().toElement(), layer.dataProvider())
        self.assertTrue(restored)
        self.assertEqual(restored.usesBands(), [1])
        classes = restored.classes()
        self.assertTrue(classes)
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(restored.sourceColorRamp().type(), 'random')
        self.assertEqual(restored.sourceColorRamp().count(), 5)

        # render test
        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer"),
                        "Paletted rendering test failed")
예제 #19
0
    def testWriteSld(self):
        """Test SLD generation for the XMLS fields geneerated at RasterLayer level and not to the deeper renderer level."""

        myPath = os.path.join(unitTestDataPath(), 'landsat.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        # do generic export with default layer values
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = root.elementsByTagName('sld:LayerFeatureConstraints')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = element.elementsByTagName('sld:FeatureTypeConstraint')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = root.elementsByTagName('sld:UserStyle')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        name = element.firstChildElement('sld:Name')
        self.assertFalse(name.isNull())
        self.assertEqual(name.text(), 'landsat')

        abstract = element.firstChildElement('sld:Abstract')
        self.assertTrue(abstract.isNull())

        title = element.firstChildElement('sld:Title')
        self.assertTrue(title.isNull())

        featureTypeStyle = element.firstChildElement('sld:FeatureTypeStyle')
        self.assertFalse(featureTypeStyle.isNull())

        rule = featureTypeStyle.firstChildElement('sld:Rule')
        self.assertFalse(rule.isNull())

        temp = rule.firstChildElement('sld:MinScaleDenominator')
        self.assertTrue(temp.isNull())

        temp = rule.firstChildElement('sld:MaxScaleDenominator')
        self.assertTrue(temp.isNull())

        rasterSymbolizer = rule.firstChildElement('sld:RasterSymbolizer')
        self.assertFalse(rule.isNull())

        vendorOptions = rasterSymbolizer.elementsByTagName('sld:VendorOption')
        self.assertTrue(vendorOptions.size() == 0)

        # set no default values and check exported sld
        myRasterLayer.setName('')
        myRasterLayer.setAbstract('fake')
        myRasterLayer.setTitle('fake')
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = root.elementsByTagName('sld:LayerFeatureConstraints')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = element.elementsByTagName('sld:FeatureTypeConstraint')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = root.elementsByTagName('sld:UserStyle')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        # no generated if empty
        name = element.firstChildElement('sld:Name')
        self.assertTrue(name.isNull())

        # generated if not empty
        abstract = element.firstChildElement('sld:Abstract')
        self.assertFalse(abstract.isNull())
        self.assertEqual(abstract.text(), 'fake')

        title = element.firstChildElement('sld:Title')
        self.assertFalse(title.isNull())
        self.assertEqual(title.text(), 'fake')

        # if setScaleBasedVisibility is true print scales
        myRasterLayer.setScaleBasedVisibility(True)
        myRasterLayer.setMaximumScale(0.0001)
        myRasterLayer.setMinimumScale(0.01)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:Rule')
        self.assertEqual(len(elements), 1)
        rule = elements.at(0).toElement()
        self.assertFalse(rule.isNull())

        temp = rule.firstChildElement('sld:MinScaleDenominator')
        self.assertFalse(temp.isNull())
        self.assertEqual(temp.text(), '0.0001')

        temp = rule.firstChildElement('sld:MaxScaleDenominator')
        self.assertFalse(temp.isNull())
        self.assertEqual(temp.text(), '0.01')

        # check non default hueSaturationFilter values
        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleLightness)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'lightness')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleLuminosity)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'luminosity')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleAverage)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'average')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleOff)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', None)

        # manage colorize vendorOption tags
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(True)
        hue.setColorizeStrength(50)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', '1')
        self.assertVendorOption(element, 'colorizeRed', '255')
        self.assertVendorOption(element, 'colorizeGreen', '128')
        self.assertVendorOption(element, 'colorizeBlue', '128')
        self.assertVendorOption(element, 'colorizeStrength', '0.5')
        self.assertVendorOption(element, 'saturation', '0.498039')

        # other hue non default values, no colorize and saturation = 0
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(False)
        hue.setSaturation(0)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', None)
        self.assertVendorOption(element, 'colorizeRed', None)
        self.assertVendorOption(element, 'colorizeGreen', None)
        self.assertVendorOption(element, 'colorizeBlue', None)
        self.assertVendorOption(element, 'colorizeStrength', None)
        self.assertVendorOption(element, 'saturation', None)
        self.assertVendorOption(element, 'brightness', None)
        self.assertVendorOption(element, 'contrast', None)

        # other hue non default values, no colorize and saturation = 100
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(False)
        hue.setSaturation(100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', None)
        self.assertVendorOption(element, 'colorizeRed', None)
        self.assertVendorOption(element, 'colorizeGreen', None)
        self.assertVendorOption(element, 'colorizeBlue', None)
        self.assertVendorOption(element, 'colorizeStrength', None)
        self.assertVendorOption(element, 'saturation', '1')
        hue.setSaturation(-100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        self.assertVendorOption(root, 'saturation', '0')

        # brightness filter default values
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertTrue(myRasterLayer.brightnessFilter().brightness() == 0)
        self.assertTrue(myRasterLayer.brightnessFilter().contrast() == 0)
        self.assertVendorOption(element, 'brightness', None)
        self.assertVendorOption(element, 'contrast', None)

        # brightness filter no default values
        bf = myRasterLayer.brightnessFilter()
        bf.setBrightness(-255)
        bf.setContrast(-100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'brightness', '0')
        self.assertVendorOption(element, 'contrast', '0')

        bf.setBrightness(255)
        bf.setContrast(100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'brightness', '1')
        self.assertVendorOption(element, 'contrast', '1')
예제 #20
0
    def testPalettedClassDataFromLayer(self):
        # no layer
        classes = QgsPalettedRasterRenderer.classDataFromRaster(None, 1)
        self.assertFalse(classes)

        # 10 class layer
        path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer10 = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer10.dataProvider(), 1)
        self.assertEqual(len(classes), 10)
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[0].label, '1')
        self.assertEqual(classes[1].value, 2)
        self.assertEqual(classes[1].label, '2')
        self.assertEqual(classes[2].value, 3)
        self.assertEqual(classes[2].label, '3')
        self.assertEqual(classes[3].value, 4)
        self.assertEqual(classes[3].label, '4')
        self.assertEqual(classes[4].value, 5)
        self.assertEqual(classes[4].label, '5')
        self.assertEqual(classes[5].value, 6)
        self.assertEqual(classes[5].label, '6')
        self.assertEqual(classes[6].value, 7)
        self.assertEqual(classes[6].label, '7')
        self.assertEqual(classes[7].value, 8)
        self.assertEqual(classes[7].label, '8')
        self.assertEqual(classes[8].value, 9)
        self.assertEqual(classes[8].label, '9')
        self.assertEqual(classes[9].value, 10)
        self.assertEqual(classes[9].label, '10')

        # bad band
        self.assertFalse(
            QgsPalettedRasterRenderer.classDataFromRaster(
                layer10.dataProvider(), 10101010))

        # with ramp
        r = QgsGradientColorRamp(QColor(200, 0, 0, 100),
                                 QColor(0, 200, 0, 200))
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer10.dataProvider(), 1, r)
        self.assertEqual(len(classes), 10)
        self.assertEqual(classes[0].color.name(), '#c80000')
        self.assertEqual(classes[1].color.name(), '#b21600')
        self.assertEqual(classes[2].color.name(), '#9c2c00')
        self.assertEqual(classes[3].color.name(), '#854200')
        self.assertEqual(classes[4].color.name(), '#6f5900')
        self.assertEqual(classes[5].color.name(), '#596f00')
        self.assertEqual(classes[6].color.name(), '#428500')
        self.assertEqual(classes[7].color.name(), '#2c9c00')
        self.assertEqual(classes[8].color.name(), '#16b200')
        self.assertEqual(classes[9].color.name(), '#00c800')

        # 30 class layer
        path = os.path.join(unitTestDataPath('raster'), 'unique_1.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer10 = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer10.dataProvider(), 1)
        self.assertEqual(len(classes), 30)
        expected = [
            11, 21, 22, 24, 31, 82, 2002, 2004, 2014, 2019, 2027, 2029, 2030,
            2080, 2081, 2082, 2088, 2092, 2097, 2098, 2099, 2105, 2108, 2110,
            2114, 2118, 2126, 2152, 2184, 2220
        ]
        self.assertEqual([c.value for c in classes], expected)

        # bad layer
        path = os.path.join(unitTestDataPath('raster'), 'hub13263.vrt')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer.dataProvider(), 1)
        self.assertFalse(classes)
예제 #21
0
    def testPalettedClassDataFromLayer(self):
        # no layer
        classes = QgsPalettedRasterRenderer.classDataFromRaster(None, 1)
        self.assertFalse(classes)

        # 10 class layer
        path = os.path.join(unitTestDataPath('raster'),
                            'with_color_table.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer10 = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(layer10.dataProvider(), 1)
        self.assertEqual(len(classes), 10)
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[0].label, '1')
        self.assertEqual(classes[1].value, 2)
        self.assertEqual(classes[1].label, '2')
        self.assertEqual(classes[2].value, 3)
        self.assertEqual(classes[2].label, '3')
        self.assertEqual(classes[3].value, 4)
        self.assertEqual(classes[3].label, '4')
        self.assertEqual(classes[4].value, 5)
        self.assertEqual(classes[4].label, '5')
        self.assertEqual(classes[5].value, 6)
        self.assertEqual(classes[5].label, '6')
        self.assertEqual(classes[6].value, 7)
        self.assertEqual(classes[6].label, '7')
        self.assertEqual(classes[7].value, 8)
        self.assertEqual(classes[7].label, '8')
        self.assertEqual(classes[8].value, 9)
        self.assertEqual(classes[8].label, '9')
        self.assertEqual(classes[9].value, 10)
        self.assertEqual(classes[9].label, '10')

        # bad band
        self.assertFalse(QgsPalettedRasterRenderer.classDataFromRaster(layer10.dataProvider(), 10101010))

        # with ramp
        r = QgsGradientColorRamp(QColor(200, 0, 0, 100), QColor(0, 200, 0, 200))
        classes = QgsPalettedRasterRenderer.classDataFromRaster(layer10.dataProvider(), 1, r)
        self.assertEqual(len(classes), 10)
        self.assertEqual(classes[0].color.name(), '#c80000')
        self.assertEqual(classes[1].color.name(), '#b21600')
        self.assertEqual(classes[2].color.name(), '#9c2c00')
        self.assertEqual(classes[3].color.name(), '#854200')
        self.assertEqual(classes[4].color.name(), '#6f5900')
        self.assertEqual(classes[5].color.name(), '#596f00')
        self.assertEqual(classes[6].color.name(), '#428500')
        self.assertEqual(classes[7].color.name(), '#2c9c00')
        self.assertEqual(classes[8].color.name(), '#16b200')
        self.assertEqual(classes[9].color.name(), '#00c800')

        # 30 class layer
        path = os.path.join(unitTestDataPath('raster'),
                            'unique_1.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer10 = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(layer10.dataProvider(), 1)
        self.assertEqual(len(classes), 30)
        expected = [11, 21, 22, 24, 31, 82, 2002, 2004, 2014, 2019, 2027, 2029, 2030, 2080, 2081, 2082, 2088, 2092, 2097, 2098, 2099, 2105, 2108, 2110, 2114, 2118, 2126, 2152, 2184, 2220]
        self.assertEqual([c.value for c in classes], expected)

        # bad layer
        path = os.path.join(unitTestDataPath('raster'),
                            'hub13263.vrt')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(layer.dataProvider(), 1)
        self.assertFalse(classes)
예제 #22
0
    def testTransparency(self):
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1)
        myRasterLayer.setRenderer(renderer)
        myRasterLayer.setContrastEnhancement(
            QgsContrastEnhancement.StretchToMinimumMaximum,
            QgsRasterMinMaxOrigin.MinMax)

        myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement()
        # print ("myContrastEnhancement.minimumValue = %.17g" %
        #       myContrastEnhancement.minimumValue())
        # print ("myContrastEnhancement.maximumValue = %.17g" %
        #        myContrastEnhancement.maximumValue())

        # Unfortunately the minimum/maximum values calculated in C++ and Python
        # are slightly different (e.g. 3.3999999521443642e+38 x
        # 3.3999999521444001e+38)
        # It is not clear where the precision is lost.
        # We set the same values as C++.
        myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38)
        myContrastEnhancement.setMaximumValue(3.3999999521443642e+38)
        #myType = myRasterLayer.dataProvider().dataType(1);
        #myEnhancement = QgsContrastEnhancement(myType);

        myTransparentSingleValuePixelList = []
        rasterTransparency = QgsRasterTransparency()

        myTransparentPixel1 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel1.min = -2.5840000772112106e+38
        myTransparentPixel1.max = -1.0879999684602689e+38
        myTransparentPixel1.percentTransparent = 50
        myTransparentSingleValuePixelList.append(myTransparentPixel1)

        myTransparentPixel2 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel2.min = 1.359999960575336e+37
        myTransparentPixel2.max = 9.520000231087593e+37
        myTransparentPixel2.percentTransparent = 70
        myTransparentSingleValuePixelList.append(myTransparentPixel2)

        rasterTransparency.setTransparentSingleValuePixelList(
            myTransparentSingleValuePixelList)

        rasterRenderer = myRasterLayer.renderer()
        assert rasterRenderer

        rasterRenderer.setRasterTransparency(rasterTransparency)

        QgsProject.instance().addMapLayers([
            myRasterLayer,
        ])

        myMapSettings = QgsMapSettings()
        myMapSettings.setLayers([myRasterLayer])
        myMapSettings.setExtent(myRasterLayer.extent())

        myChecker = QgsRenderChecker()
        myChecker.setControlName("expected_raster_transparency")
        myChecker.setMapSettings(myMapSettings)

        myResultFlag = myChecker.runTest("raster_transparency_python")
        assert myResultFlag, "Raster transparency rendering test failed"
예제 #23
0
    def testPaletted(self):
        """ test paletted raster renderer with raster with color table"""
        path = os.path.join(unitTestDataPath('raster'),
                            'with_color_table.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1,
                                             [QgsPalettedRasterRenderer.Class(1, QColor(0, 255, 0), 'class 2'),
                                              QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')])

        self.assertEqual(renderer.nColors(), 2)
        self.assertEqual(renderer.usesBands(), [1])

        # test labels
        self.assertEqual(renderer.label(1), 'class 2')
        self.assertEqual(renderer.label(3), 'class 1')
        self.assertFalse(renderer.label(101))

        # test legend symbology - should be sorted by value
        legend = renderer.legendSymbologyItems()
        self.assertEqual(legend[0][0], 'class 2')
        self.assertEqual(legend[1][0], 'class 1')
        self.assertEqual(legend[0][1].name(), '#00ff00')
        self.assertEqual(legend[1][1].name(), '#ff0000')

        # test retrieving classes
        classes = renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'class 1')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')

        # test set label
        # bad index
        renderer.setLabel(1212, 'bad')
        renderer.setLabel(3, 'new class')
        self.assertEqual(renderer.label(3), 'new class')

        # color ramp
        r = QgsLimitedRandomColorRamp(5)
        renderer.setSourceColorRamp(r)
        self.assertEqual(renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(renderer.sourceColorRamp().count(), 5)

        # clone
        new_renderer = renderer.clone()
        classes = new_renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(new_renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(new_renderer.sourceColorRamp().count(), 5)

        # write to xml and read
        doc = QDomDocument('testdoc')
        elem = doc.createElement('qgis')
        renderer.writeXml(doc, elem)
        restored = QgsPalettedRasterRenderer.create(elem.firstChild().toElement(), layer.dataProvider())
        self.assertTrue(restored)
        self.assertEqual(restored.usesBands(), [1])
        classes = restored.classes()
        self.assertTrue(classes)
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(restored.sourceColorRamp().type(), 'random')
        self.assertEqual(restored.sourceColorRamp().count(), 5)

        # render test
        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer"), "Paletted rendering test failed")
예제 #24
0
    def accept(self):
        """Handler for when OK is clicked."""
        input_path = self.input_path.text()
        input_title = self.line_edit_title.text()
        input_source = self.line_edit_source.text()
        output_path = self.output_path.text()
        if not output_path.endswith('.tif'):
            # noinspection PyArgumentList,PyCallByClass,PyTypeChecker
            QMessageBox.warning(
                self,
                tr('InaSAFE'),
                tr('Output file name must be tif file'))
        if not os.path.exists(input_path):
            # noinspection PyArgumentList,PyCallByClass,PyTypeChecker
            QMessageBox.warning(
                self,
                tr('InaSAFE'),
                tr('Input file does not exist'))
            return

        algorithm = 'nearest'
        if self.nearest_mode.isChecked():
            algorithm = 'nearest'
        elif self.inverse_distance_mode.isChecked():
            algorithm = 'invdist'
        elif self.use_ascii_mode.isChecked():
            algorithm = 'use_ascii'

        # Smoothing
        smoothing_method = NONE_SMOOTHING
        if self.numpy_smoothing.isChecked():
            smoothing_method = NUMPY_SMOOTHING
        if self.scipy_smoothing.isChecked():
            smoothing_method = SCIPY_SMOOTHING

        # noinspection PyUnresolvedReferences
        QgsApplication.instance().setOverrideCursor(
            QtGui.QCursor(QtCore.Qt.WaitCursor)
        )

        extra_keywords = {}
        if self.check_box_custom_shakemap_id.isChecked():
            event_id = self.line_edit_shakemap_id.text()
            extra_keywords[extra_keyword_earthquake_event_id['key']] = event_id

        current_index = self.combo_box_source_type.currentIndex()
        source_type = self.combo_box_source_type.itemData(current_index)
        if source_type:
            extra_keywords[
                extra_keyword_earthquake_source['key']] = source_type

        file_name = convert_mmi_data(
            input_path,
            input_title,
            input_source,
            output_path,
            algorithm=algorithm,
            algorithm_filename_flag=True,
            smoothing_method=smoothing_method,
            extra_keywords=extra_keywords
        )

        file_info = QFileInfo(file_name)
        base_name = file_info.baseName()
        self.output_layer = QgsRasterLayer(file_name, base_name)

        # noinspection PyUnresolvedReferences
        QgsApplication.instance().restoreOverrideCursor()

        if self.load_result.isChecked():
            # noinspection PyTypeChecker
            mmi_ramp_roman(self.output_layer)
            self.output_layer.saveDefaultStyle()
            if not self.output_layer.isValid():
                LOGGER.debug("Failed to load")
            else:
                # noinspection PyArgumentList
                QgsProject.instance().addMapLayer(self.output_layer)
                iface.zoomToActiveLayer()

        if (self.keyword_wizard_checkbox.isChecked()
                and self.keyword_wizard_checkbox.isEnabled()):
            self.launch_keyword_wizard()

        self.done(self.Accepted)
예제 #25
0
    def testTransparency(self):
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1)
        myRasterLayer.setRenderer(renderer)
        myRasterLayer.setContrastEnhancement(
            QgsContrastEnhancement.StretchToMinimumMaximum,
            QgsRasterMinMaxOrigin.MinMax)

        myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement()
        # print ("myContrastEnhancement.minimumValue = %.17g" %
        #       myContrastEnhancement.minimumValue())
        # print ("myContrastEnhancement.maximumValue = %.17g" %
        #        myContrastEnhancement.maximumValue())

        # Unfortunately the minimum/maximum values calculated in C++ and Python
        # are slightly different (e.g. 3.3999999521443642e+38 x
        # 3.3999999521444001e+38)
        # It is not clear where the precision is lost.
        # We set the same values as C++.
        myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38)
        myContrastEnhancement.setMaximumValue(3.3999999521443642e+38)
        #myType = myRasterLayer.dataProvider().dataType(1);
        #myEnhancement = QgsContrastEnhancement(myType);

        myTransparentSingleValuePixelList = []
        rasterTransparency = QgsRasterTransparency()

        myTransparentPixel1 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel1.min = -2.5840000772112106e+38
        myTransparentPixel1.max = -1.0879999684602689e+38
        myTransparentPixel1.percentTransparent = 50
        myTransparentSingleValuePixelList.append(myTransparentPixel1)

        myTransparentPixel2 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel2.min = 1.359999960575336e+37
        myTransparentPixel2.max = 9.520000231087593e+37
        myTransparentPixel2.percentTransparent = 70
        myTransparentSingleValuePixelList.append(myTransparentPixel2)

        rasterTransparency.setTransparentSingleValuePixelList(
            myTransparentSingleValuePixelList)

        rasterRenderer = myRasterLayer.renderer()
        assert rasterRenderer

        rasterRenderer.setRasterTransparency(rasterTransparency)

        QgsProject.instance().addMapLayers([myRasterLayer, ])

        myMapSettings = QgsMapSettings()
        myMapSettings.setLayers([myRasterLayer])
        myMapSettings.setExtent(myRasterLayer.extent())

        myChecker = QgsRenderChecker()
        myChecker.setControlName("expected_raster_transparency")
        myChecker.setMapSettings(myMapSettings)

        myResultFlag = myChecker.runTest("raster_transparency_python")
        assert myResultFlag, "Raster transparency rendering test failed"
예제 #26
0
def get_rat(raster_layer, band, colors=('R', 'G', 'B', 'A')):
    """Extracts RAT from raster layer and given band

    :param raster_layer: the raster layer to classify
    :type raster_layer: QgsRasterLayer
    :param band: band number (1-based)
    :type band: int
    :param colors: default name of the RGB(A) columns for sidecar DBF files, defaults to ('R', 'G', 'B', 'A'), these are searched first
    :type red_column_name: tuple, optional
    :return: RAT
    :rtype: RAT
    """

    headers = []
    values = {}
    fields = {}
    # For sidecar files
    path = None

    COLOR_ROLES = (gdal.GFU_Red, gdal.GFU_Green, gdal.GFU_Blue, gdal.GFU_Alpha)

    is_dbf = False

    ds = gdal.OpenEx(raster_layer.source())
    if ds:
        band = ds.GetRasterBand(band)
        if band:
            rat = band.GetDefaultRAT()
            if rat is not None:
                for i in range(0, rat.GetColumnCount()):
                    column = rat.GetNameOfCol(i)
                    headers.append(column)
                    values[column] = []
                    fields[column] = RATField(column, rat.GetUsageOfCol(i),
                                              rat.GetTypeOfCol(i))

                for r in range(0, rat.GetRowCount()):
                    for c in range(0, rat.GetColumnCount()):
                        column = headers[c]
                        if fields[column].type == gdal.GFT_Integer:
                            values[headers[c]].append(rat.GetValueAsInt(r, c))
                        elif fields[column].type == gdal.GFT_Real:
                            values[headers[c]].append(
                                rat.GetValueAsDouble(r, c))
                        else:
                            values[headers[c]].append(
                                html.unescape(rat.GetValueAsString(r, c)))

                # Try to identify fields in case of RAT with wrong usages
                usages = [f.usage for f in fields.values()]
                if gdal.GFU_MinMax not in usages and not {
                        gdal.GFU_Min, gdal.GFU_Max
                }.issubset(usages):
                    try:
                        field_name = [
                            f.name for f in fields.values()
                            if f.name.upper() == 'VALUE'
                        ][0]
                        fields[field_name].usage = gdal.GFU_MinMax
                    except IndexError:
                        pass

                    try:
                        field_name = [
                            f.name for f in fields.values()
                            if f.name.upper() in ('VALUE MIN', 'MIN',
                                                  'MIN VALUE', 'VALUE_MIN',
                                                  'MIN_VALUE')
                        ][0]
                        fields[field_name].usage = gdal.GFU_Min
                    except IndexError:
                        pass

                    try:
                        field_name = [
                            f.name for f in fields.values()
                            if f.name.upper() in ('VALUE MAX', 'MAX',
                                                  'MAX VALUE', 'VALUE_MAX',
                                                  'MAX_VALUE')
                        ][0]
                        fields[field_name].usage = gdal.GFU_Max
                    except IndexError:
                        pass

                if gdal.GFU_PixelCount not in usages:
                    try:
                        field_name = [
                            f.name for f in fields.values()
                            if f.name.upper() == 'COUNT'
                        ][0]
                        fields[field_name].usage = gdal.GFU_PixelCount
                    except IndexError:
                        pass

                path = raster_layer.source() + '.aux.xml'

    # Search for sidecar DBF files, `band` is ignored!
    if not values:

        info = QFileInfo(raster_layer.publicSource())
        directory = info.dir().path()
        basename = info.baseName()
        filename = info.fileName()
        candidates = (basename + '.dbf', basename + '.vat.dbf',
                      filename + '.dbf', filename + '.vat.dbf')

        for candidate in candidates:

            if os.path.exists(os.path.join(directory, candidate)):
                rat_layer = QgsVectorLayer(os.path.join(directory, candidate),
                                           'rat', 'ogr')

                if rat_layer.isValid():
                    path = os.path.join(directory, candidate)

                    # Get fields
                    # Check if color fields are there, fall-back to RED GREEN BLUE ALPHA if not
                    field_upper_names = [
                        f.name().upper() for f in rat_layer.fields()
                    ]
                    upper_colors = [c.upper() for c in colors]

                    def _search_color():
                        color_found = True
                        for color_field_name in upper_colors[:3]:
                            if color_field_name not in field_upper_names:
                                color_found = False
                        return color_found

                    if not _search_color() and colors == ('R', 'G', 'B', 'A'):
                        upper_colors = ('RED', 'GREEN', 'BLUE', 'ALPHA')

                    # Create fields
                    for f in rat_layer.fields():

                        headers.append(f.name())
                        field_name_upper = f.name().upper()
                        if field_name_upper in upper_colors:
                            fields[f.name()] = RATField(
                                f.name(), COLOR_ROLES[upper_colors.index(
                                    field_name_upper)],
                                gdal.GFT_Integer if f.type()
                                in (QVariant.Int,
                                    QVariant.LongLong) else gdal.GFT_Real)
                        elif field_name_upper == 'COUNT':
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_PixelCount,
                                gdal.GFT_Integer)
                        elif field_name_upper == 'VALUE':
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_MinMax,
                                gdal.GFT_Integer if f.type()
                                in (QVariant.Int,
                                    QVariant.LongLong) else gdal.GFT_Real)
                        elif field_name_upper in ('VALUE MIN', 'VALUE_MIN',
                                                  'MIN VALUE', 'MIN_VALUE'):
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_Min,
                                gdal.GFT_Integer if f.type()
                                in (QVariant.Int,
                                    QVariant.LongLong) else gdal.GFT_Real)
                        elif field_name_upper in ('VALUE MAX', 'VALUE_MAX',
                                                  'MAX VALUE', 'MAX_VALUE'):
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_Max,
                                gdal.GFT_Integer if f.type()
                                in (QVariant.Int,
                                    QVariant.LongLong) else gdal.GFT_Real)
                        else:
                            if f.type() in (QVariant.Int, QVariant.LongLong):
                                type = gdal.GFT_Integer
                            elif f.type() == QVariant.Double:
                                type = gdal.GFT_Real
                            else:
                                type = gdal.GFT_String

                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_Generic, type)

                    for header in headers:
                        values[header] = []
                    for f in rat_layer.getFeatures():
                        for header in headers:
                            values[header].append(f.attribute(header))
                    is_dbf = True
                    break

    # Colors
    if headers:
        red = None
        green = None
        blue = None
        alpha = None
        is_integer = False

        for name, f in fields.items():
            if f.usage == gdal.GFU_Red:
                red = name
                is_integer = f.type == gdal.GFT_Integer
                continue
            if f.usage == gdal.GFU_Green:
                green = name
                continue
            if f.usage == gdal.GFU_Blue:
                blue = name
                continue
            if f.usage == gdal.GFU_Alpha:
                alpha = name
                continue

        if red and green and blue:
            headers.append(RAT_COLOR_HEADER_NAME)
            values[RAT_COLOR_HEADER_NAME] = []
            for i in range(len(values[red])):
                func = 'fromRgb' if is_integer else 'fromRgbF'
                if alpha:
                    values[RAT_COLOR_HEADER_NAME].append(
                        getattr(QColor,
                                func)(values[red][i], values[green][i],
                                      values[blue][i], values[alpha][i]))
                else:
                    values[RAT_COLOR_HEADER_NAME].append(
                        getattr(QColor, func)(values[red][i], values[green][i],
                                              values[blue][i]))

    return RAT(values, is_dbf, fields, path)
예제 #27
0
    def testWriteSld(self):
        """Test SLD generation for the XMLS fields geneerated at RasterLayer level and not to the deeper renderer level."""

        myPath = os.path.join(unitTestDataPath(), 'landsat.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        # do generic export with default layer values
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = root.elementsByTagName('sld:LayerFeatureConstraints')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = element.elementsByTagName('sld:FeatureTypeConstraint')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = root.elementsByTagName('sld:UserStyle')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        name = element.firstChildElement('sld:Name')
        self.assertFalse(name.isNull())
        self.assertEqual(name.text(), 'landsat')

        abstract = element.firstChildElement('sld:Abstract')
        self.assertTrue(abstract.isNull())

        title = element.firstChildElement('sld:Title')
        self.assertTrue(title.isNull())

        featureTypeStyle = element.firstChildElement('sld:FeatureTypeStyle')
        self.assertFalse(featureTypeStyle.isNull())

        rule = featureTypeStyle.firstChildElement('sld:Rule')
        self.assertFalse(rule.isNull())

        temp = rule.firstChildElement('sld:MinScaleDenominator')
        self.assertTrue(temp.isNull())

        temp = rule.firstChildElement('sld:MaxScaleDenominator')
        self.assertTrue(temp.isNull())

        rasterSymbolizer = rule.firstChildElement('sld:RasterSymbolizer')
        self.assertFalse(rule.isNull())

        vendorOptions = rasterSymbolizer.elementsByTagName('sld:VendorOption')
        self.assertTrue(vendorOptions.size() == 0)

        # set no default values and check exported sld
        myRasterLayer.setName('')
        myRasterLayer.setAbstract('fake')
        myRasterLayer.setTitle('fake')
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = root.elementsByTagName('sld:LayerFeatureConstraints')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = element.elementsByTagName('sld:FeatureTypeConstraint')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = root.elementsByTagName('sld:UserStyle')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        # no generated if empty
        name = element.firstChildElement('sld:Name')
        self.assertTrue(name.isNull())

        # generated if not empty
        abstract = element.firstChildElement('sld:Abstract')
        self.assertFalse(abstract.isNull())
        self.assertEqual(abstract.text(), 'fake')

        title = element.firstChildElement('sld:Title')
        self.assertFalse(title.isNull())
        self.assertEqual(title.text(), 'fake')

        # if setScaleBasedVisibility is true print scales
        myRasterLayer.setScaleBasedVisibility(True)
        myRasterLayer.setMaximumScale(0.0001)
        myRasterLayer.setMinimumScale(0.01)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:Rule')
        self.assertEqual(len(elements), 1)
        rule = elements.at(0).toElement()
        self.assertFalse(rule.isNull())

        temp = rule.firstChildElement('sld:MinScaleDenominator')
        self.assertFalse(temp.isNull())
        self.assertEqual(temp.text(), '0.0001')

        temp = rule.firstChildElement('sld:MaxScaleDenominator')
        self.assertFalse(temp.isNull())
        self.assertEqual(temp.text(), '0.01')

        # check non default hueSaturationFilter values
        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleLightness)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'lightness')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleLuminosity)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'luminosity')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleAverage)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'average')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleOff)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', None)

        # manage colorize vendorOption tags
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(True)
        hue.setColorizeStrength(50)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', '1')
        self.assertVendorOption(element, 'colorizeRed', '255')
        self.assertVendorOption(element, 'colorizeGreen', '128')
        self.assertVendorOption(element, 'colorizeBlue', '128')
        self.assertVendorOption(element, 'colorizeStrength', '0.5')
        self.assertVendorOption(element, 'saturation', '0.498039')

        # other hue non default values, no colorize and saturation = 0
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(False)
        hue.setSaturation(0)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', None)
        self.assertVendorOption(element, 'colorizeRed', None)
        self.assertVendorOption(element, 'colorizeGreen', None)
        self.assertVendorOption(element, 'colorizeBlue', None)
        self.assertVendorOption(element, 'colorizeStrength', None)
        self.assertVendorOption(element, 'saturation', None)
        self.assertVendorOption(element, 'brightness', None)
        self.assertVendorOption(element, 'contrast', None)

        # other hue non default values, no colorize and saturation = 100
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(False)
        hue.setSaturation(100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', None)
        self.assertVendorOption(element, 'colorizeRed', None)
        self.assertVendorOption(element, 'colorizeGreen', None)
        self.assertVendorOption(element, 'colorizeBlue', None)
        self.assertVendorOption(element, 'colorizeStrength', None)
        self.assertVendorOption(element, 'saturation', '1')
        hue.setSaturation(-100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        self.assertVendorOption(root, 'saturation', '0')

        # brightness filter default values
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertTrue(myRasterLayer.brightnessFilter().brightness() == 0)
        self.assertTrue(myRasterLayer.brightnessFilter().contrast() == 0)
        self.assertVendorOption(element, 'brightness', None)
        self.assertVendorOption(element, 'contrast', None)

        # brightness filter no default values
        bf = myRasterLayer.brightnessFilter()
        bf.setBrightness(-255)
        bf.setContrast(-100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'brightness', '0')
        self.assertVendorOption(element, 'contrast', '0')

        bf.setBrightness(255)
        bf.setContrast(100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'brightness', '1')
        self.assertVendorOption(element, 'contrast', '1')
예제 #28
0
    def open_style(input_file):  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
        """
        Opens a .style file
        """
        if input_file.lower().endswith(
                '.style') and not Extractor.is_mdb_tools_binary_available():
            message_bar = iface.messageBar()
            widget = message_bar.createMessage('SLYR',
                                               "MDB Tools utility not found")
            settings_button = QPushButton("Configure…",
                                          pressed=partial(
                                              BrowserUtils.open_settings,
                                              widget))
            widget.layout().addWidget(settings_button)
            message_bar.pushWidget(widget, Qgis.Critical)
            return True

        style = QgsStyle()
        style.createMemoryDatabase()

        symbol_names = set()

        def make_name_unique(original_name):
            """
            Ensures that the symbol name is unique (in a case-insensitive way)
            """
            counter = 0
            candidate = original_name
            while candidate.lower() in symbol_names:
                # make name unique
                if counter == 0:
                    candidate += '_1'
                else:
                    candidate = candidate[:candidate.rfind('_') +
                                          1] + str(counter)
                counter += 1
            symbol_names.add(candidate.lower())
            return candidate

        feedback = QgsFeedback()

        progress_dialog = QProgressDialog("Loading style database…", "Abort",
                                          0, 100, None)
        progress_dialog.setWindowTitle("Loading Style")

        def progress_changed(progress: float):
            """
            Handles feedback to progress dialog bridge
            """
            progress_dialog.setValue(int(progress))
            iterations = 0
            while QCoreApplication.hasPendingEvents() and iterations < 100:
                QCoreApplication.processEvents()
                iterations += 1

        feedback.progressChanged.connect(progress_changed)

        def cancel():
            """
            Slot to cancel the import
            """
            feedback.cancel()

        progress_dialog.canceled.connect(cancel)
        unreadable = []
        warnings = set()
        errors = set()

        types_to_extract = [
            Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS,
            Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS,
            Extractor.TEXT_SYMBOLS, Extractor.LABELS, Extractor.MAPLEX_LABELS,
            Extractor.AREA_PATCHES, Extractor.LINE_PATCHES
        ]

        type_percent = 100 / len(types_to_extract)

        for type_index, symbol_type in enumerate(types_to_extract):

            try:
                raw_symbols = Extractor.extract_styles(input_file, symbol_type)
            except MissingBinaryException:
                BrowserUtils.show_warning(
                    'MDB Tools utility not found',
                    'Convert style',
                    'The MDB tools "mdb-export" utility is required to convert .style databases. Please setup a path to the MDB tools utility in the SLYR options panel.',
                    level=Qgis.Critical)
                progress_dialog.deleteLater()
                return True

            if feedback.isCanceled():
                break

            for index, raw_symbol in enumerate(raw_symbols):
                feedback.setProgress(
                    int(index / len(raw_symbols) * type_percent +
                        type_percent * type_index))
                if feedback.isCanceled():
                    break
                name = raw_symbol[Extractor.NAME]
                tags = raw_symbol[Extractor.TAGS].split(';')

                unique_name = make_name_unique(name)

                handle = BytesIO(raw_symbol[Extractor.BLOB])
                stream = Stream(handle)
                stream.allow_shortcuts = False

                try:
                    symbol = stream.read_object()
                except UnreadableSymbolException as e:
                    e = 'Unreadable object: {}'.format(e)
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except NotImplementedException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnsupportedVersionException as e:
                    e = 'Unsupported version: {}'.format(e)
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnknownClsidException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnreadablePictureException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue

                context = Context()
                context.symbol_name = unique_name

                def unsupported_object_callback(msg, level=Context.WARNING):
                    if level == Context.WARNING:
                        warnings.add('<b>{}</b>: {}'.format(
                            html.escape(unique_name),  # pylint: disable=cell-var-from-loop
                            html.escape(msg)))
                    elif level == Context.CRITICAL:
                        errors.add('<b>{}</b>: {}'.format(
                            html.escape(unique_name),  # pylint: disable=cell-var-from-loop
                            html.escape(msg)))

                context.unsupported_object_callback = unsupported_object_callback
                # context.style_folder, _ = os.path.split(output_file)

                if symbol_type in (Extractor.AREA_PATCHES,
                                   Extractor.LINE_PATCHES):
                    unreadable.append(
                        '<b>{}</b>: Legend patch conversion requires the licensed version of SLYR'
                        .format(html.escape(name)))
                    continue

                try:
                    qgis_symbol = SymbolConverter.Symbol_to_QgsSymbol(
                        symbol, context)
                except NotImplementedException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnreadablePictureException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue

                if isinstance(qgis_symbol, QgsSymbol):
                    # self.check_for_missing_fonts(qgis_symbol, feedback)
                    style.addSymbol(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsColorRamp):
                    style.addColorRamp(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsTextFormat):
                    if Qgis.QGIS_VERSION_INT >= 30900:
                        style.addTextFormat(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsPalLayerSettings):
                    if Qgis.QGIS_VERSION_INT >= 30900:
                        style.addLabelSettings(unique_name, qgis_symbol, True)
                elif Qgis.QGIS_VERSION_INT >= 31300:
                    if isinstance(qgis_symbol, QgsLegendPatchShape):
                        style.addLegendPatchShape(unique_name, qgis_symbol,
                                                  True)

                if tags:
                    if isinstance(qgis_symbol, QgsSymbol):
                        assert style.tagSymbol(QgsStyle.SymbolEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol, QgsColorRamp):
                        assert style.tagSymbol(QgsStyle.ColorrampEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol, QgsTextFormat) and hasattr(
                            QgsStyle, 'TextFormatEntity'):
                        assert style.tagSymbol(QgsStyle.TextFormatEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol,
                                    QgsPalLayerSettings) and hasattr(
                                        QgsStyle, 'LabelSettingsEntity'):
                        assert style.tagSymbol(QgsStyle.LabelSettingsEntity,
                                               unique_name, tags)
                    elif Qgis.QGIS_VERSION_INT >= 31300:
                        if isinstance(qgis_symbol, QgsLegendPatchShape):
                            assert style.tagSymbol(
                                QgsStyle.LegendPatchShapeEntity, unique_name,
                                tags)
        progress_dialog.deleteLater()
        if feedback.isCanceled():
            return True

        if errors or unreadable or warnings:
            message = ''
            if unreadable:
                message = '<p>The following symbols could not be converted:</p>'
                message += '<ul>'
                for w in unreadable:
                    message += '<li>{}</li>'.format(w.replace('\n', '<br>'))
                message += '</ul>'

            if errors:
                message += '<p>The following errors were generated while converting symbols:</p>'
                message += '<ul>'
                for w in errors:
                    message += '<li>{}</li>'.format(w.replace('\n', '<br>'))
                message += '</ul>'

            if warnings:
                message += '<p>The following warnings were generated while converting symbols:</p>'
                message += '<ul>'
                for w in warnings:
                    message += '<li>{}</li>'.format(w.replace('\n', '<br>'))
                message += '</ul>'

            BrowserUtils.show_warning(
                'style could not be completely converted',
                'Convert style',
                message,
                level=Qgis.Critical if
                (unreadable or errors) else Qgis.Warning)

        if Qgis.QGIS_VERSION_INT >= 30800:
            dlg = QgsStyleManagerDialog(style, readOnly=True)
            dlg.setFavoritesGroupVisible(False)
            dlg.setSmartGroupsVisible(False)
            fi = QFileInfo(input_file)
            dlg.setBaseStyleName(fi.baseName())
        else:
            dlg = QgsStyleManagerDialog(style)
        dlg.setWindowTitle(fi.baseName())
        dlg.exec_()
        return True