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)
def testLoadPalettedClassDataFromFile(self): # bad file classes = QgsPalettedRasterRenderer.classDataFromFile('ajdhjashjkdh kjahjkdhk') self.assertEqual(len(classes), 0) # good file! path = os.path.join(unitTestDataPath('raster'), 'test.clr') classes = QgsPalettedRasterRenderer.classDataFromFile(path) self.assertEqual(len(classes), 10) self.assertEqual(classes[0].value, 1) self.assertEqual(classes[0].color.name(), '#000000') self.assertEqual(classes[0].color.alpha(), 255) self.assertEqual(classes[1].value, 2) self.assertEqual(classes[1].color.name(), '#c8c8c8') self.assertEqual(classes[2].value, 3) self.assertEqual(classes[2].color.name(), '#006e00') self.assertEqual(classes[3].value, 4) self.assertEqual(classes[3].color.name(), '#6e4100') self.assertEqual(classes[4].value, 5) self.assertEqual(classes[4].color.name(), '#0000ff') self.assertEqual(classes[4].color.alpha(), 255) self.assertEqual(classes[5].value, 6) self.assertEqual(classes[5].color.name(), '#0059ff') self.assertEqual(classes[6].value, 7) self.assertEqual(classes[6].color.name(), '#00aeff') self.assertEqual(classes[7].value, 8) self.assertEqual(classes[7].color.name(), '#00fff6') self.assertEqual(classes[8].value, 9) self.assertEqual(classes[8].color.name(), '#eeff00') self.assertEqual(classes[9].value, 10) self.assertEqual(classes[9].color.name(), '#ffb600')
def testPalettedClassDataToString(self): classes = [QgsPalettedRasterRenderer.Class(1, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')] self.assertEqual(QgsPalettedRasterRenderer.classDataToString(classes), '1 0 255 0 255 class 2\n3 255 0 0 255 class 1') # must be sorted by value to work OK in ArcMap classes = [QgsPalettedRasterRenderer.Class(4, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')] self.assertEqual(QgsPalettedRasterRenderer.classDataToString(classes), '3 255 0 0 255 class 1\n4 0 255 0 255 class 2')
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])
def testPalettedRasterRenderer(self): # create 10 color classes #classesString = '122 0 0 0 255 122\n123 1 1 1 255 123\n124 2 2 2 255 124\n125 3 3 3 255 125\n126 4 4 4 255 126\n127 5 5 5 255 127\n128 6 6 6 255 128\n129 7 7 7 255 129\n130 8 8 8 255 130' classesString = '' for index in range(10): classesString += '{0} {0} {0} {0} 255 {0}\n'.format(index) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'values') self.assertFalse(colorMap.hasAttribute('extendend')) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries classesString = '' values = range(255) for index in range(255): classesString += '{0} {1} {1} {1} 255 {0}\n'.format(index, random.choice(values)) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertTrue(colorMap.hasAttribute('extended')) self.assertEqual(colorMap.attribute('extended'), 'true')
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)
def testLoadPalettedColorDataFromString(self): """ Test interpreting a bunch of color data format strings """ esri_clr_format = '1 255 255 0\n2 64 0 128\n3 255 32 32\n4 0 255 0\n5 0 0 255' esri_clr_format_win = '1 255 255 0\r\n2 64 0 128\r\n3 255 32 32\r\n4 0 255 0\r\n5 0 0 255' esri_clr_format_tab = '1\t255\t255\t0\n2\t64\t0\t128\n3\t255\t32\t32\n4\t0\t255\t0\n5\t0\t0\t255' esri_clr_spaces = '1 255 255 0\n2 64 0 128\n3 255 32 32\n4 0 255 0\n5 0 0 255' gdal_clr_comma = '1,255,255,0\n2,64,0,128\n3,255,32,32\n4,0,255,0\n5,0,0,255' gdal_clr_colon = '1:255:255:0\n2:64:0:128\n3:255:32:32\n4:0:255:0\n5:0:0:255' for f in [esri_clr_format, esri_clr_format_win, esri_clr_format_tab, esri_clr_spaces, gdal_clr_comma, gdal_clr_colon]: classes = QgsPalettedRasterRenderer.classDataFromString(f) self.assertEqual(len(classes), 5) self.assertEqual(classes[0].value, 1) self.assertEqual(classes[0].color.name(), '#ffff00') self.assertEqual(classes[1].value, 2) self.assertEqual(classes[1].color.name(), '#400080') self.assertEqual(classes[2].value, 3) self.assertEqual(classes[2].color.name(), '#ff2020') self.assertEqual(classes[3].value, 4) self.assertEqual(classes[3].color.name(), '#00ff00') self.assertEqual(classes[4].value, 5) self.assertEqual(classes[4].color.name(), '#0000ff') grass_named_colors = '0 white\n1 yellow\n3 black\n6 blue\n9 magenta\n11 aqua\n13 grey\n14 gray\n15 orange\n19 brown\n21 purple\n22 violet\n24 indigo\n90 green\n180 cyan\n270 red\n' classes = QgsPalettedRasterRenderer.classDataFromString(grass_named_colors) self.assertEqual(len(classes), 16) self.assertEqual(classes[0].value, 0) self.assertEqual(classes[0].color.name(), '#ffffff') self.assertEqual(classes[1].value, 1) self.assertEqual(classes[1].color.name(), '#ffff00') self.assertEqual(classes[2].value, 3) self.assertEqual(classes[2].color.name(), '#000000') self.assertEqual(classes[3].value, 6) self.assertEqual(classes[3].color.name(), '#0000ff') self.assertEqual(classes[4].value, 9) self.assertEqual(classes[4].color.name(), '#ff00ff') self.assertEqual(classes[5].value, 11) self.assertEqual(classes[5].color.name(), '#00ffff') self.assertEqual(classes[6].value, 13) self.assertEqual(classes[6].color.name(), '#808080') self.assertEqual(classes[7].value, 14) self.assertEqual(classes[7].color.name(), '#808080') self.assertEqual(classes[8].value, 15) self.assertEqual(classes[8].color.name(), '#ffa500') self.assertEqual(classes[9].value, 19) self.assertEqual(classes[9].color.name(), '#a52a2a') self.assertEqual(classes[10].value, 21) self.assertEqual(classes[10].color.name(), '#800080') self.assertEqual(classes[11].value, 22) self.assertEqual(classes[11].color.name(), '#ee82ee') self.assertEqual(classes[12].value, 24) self.assertEqual(classes[12].color.name(), '#4b0082') self.assertEqual(classes[13].value, 90) self.assertEqual(classes[13].color.name(), '#008000') self.assertEqual(classes[14].value, 180) self.assertEqual(classes[14].color.name(), '#00ffff') self.assertEqual(classes[15].value, 270) self.assertEqual(classes[15].color.name(), '#ff0000') gdal_alpha = '1:255:255:0:0\n2:64:0:128:50\n3:255:32:32:122\n4:0:255:0:200\n5:0:0:255:255' classes = QgsPalettedRasterRenderer.classDataFromString(gdal_alpha) self.assertEqual(len(classes), 5) self.assertEqual(classes[0].value, 1) self.assertEqual(classes[0].color.name(), '#ffff00') self.assertEqual(classes[0].color.alpha(), 0) self.assertEqual(classes[1].value, 2) self.assertEqual(classes[1].color.name(), '#400080') self.assertEqual(classes[1].color.alpha(), 50) self.assertEqual(classes[2].value, 3) self.assertEqual(classes[2].color.name(), '#ff2020') self.assertEqual(classes[2].color.alpha(), 122) self.assertEqual(classes[3].value, 4) self.assertEqual(classes[3].color.name(), '#00ff00') self.assertEqual(classes[3].color.alpha(), 200) self.assertEqual(classes[4].value, 5) self.assertEqual(classes[4].color.name(), '#0000ff') self.assertEqual(classes[4].color.alpha(), 255) # qgis style, with labels qgis = '3 255 0 0 255 class 1\n4 0 255 0 200 class 2' classes = QgsPalettedRasterRenderer.classDataFromString(qgis) self.assertEqual(len(classes), 2) self.assertEqual(classes[0].value, 3) self.assertEqual(classes[0].color.name(), '#ff0000') self.assertEqual(classes[0].color.alpha(), 255) self.assertEqual(classes[0].label, 'class 1') self.assertEqual(classes[1].value, 4) self.assertEqual(classes[1].color.name(), '#00ff00') self.assertEqual(classes[1].color.alpha(), 200) self.assertEqual(classes[1].label, 'class 2') # some bad inputs bad = '' classes = QgsPalettedRasterRenderer.classDataFromString(bad) self.assertEqual(len(classes), 0) bad = '\n\n\n' classes = QgsPalettedRasterRenderer.classDataFromString(bad) self.assertEqual(len(classes), 0) bad = 'x x x x' classes = QgsPalettedRasterRenderer.classDataFromString(bad) self.assertEqual(len(classes), 0) bad = '1 255 0 0\n2 255 255\n3 255 0 255' classes = QgsPalettedRasterRenderer.classDataFromString(bad) self.assertEqual(len(classes), 2) bad = '1 255 a 0' classes = QgsPalettedRasterRenderer.classDataFromString(bad) self.assertEqual(len(classes), 1)
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")
def test_homogenize_colors(self): """Test color homogenize""" tmp_dir = QTemporaryDir() shutil.copy( os.path.join(os.path.dirname(__file__), 'data', 'ExistingVegetationTypes_sample.img'), tmp_dir.path()) shutil.copy( os.path.join(os.path.dirname(__file__), 'data', 'ExistingVegetationTypes_sample.img.vat.dbf'), tmp_dir.path()) raster_layer = QgsRasterLayer( os.path.join(tmp_dir.path(), 'ExistingVegetationTypes_sample.img'), 'rat_test', 'gdal') rat = get_rat(raster_layer, 1) self.assertTrue(rat.isValid()) unique_labels = rat_classify(raster_layer, 1, rat, 'EVT_NAME') if Qgis.QGIS_VERSION_INT >= 31800: self.assertEqual(unique_labels, list(range(1, 60))) else: self.assertEqual(unique_labels, list(range(0, 59))) # Get color map color_map = {} for klass in raster_layer.renderer().classes(): color_map[klass.value] = klass.color.name() # Two different colors for EVT_NAME self.assertEqual(color_map[11.0], '#0000ff') self.assertEqual(color_map[12.0], '#9fa1f0') # Reclass unique_labels = rat_classify(raster_layer, 1, rat, 'NVCSCLASS') if Qgis.QGIS_VERSION_INT >= 31800: self.assertEqual(unique_labels, [1, 3, 5, 6, 7, 22, 31, 41, 44]) else: self.assertEqual(unique_labels, [0, 2, 4, 5, 6, 21, 30, 40, 43]) color_map = {} for klass in raster_layer.renderer().classes(): color_map[klass.value] = klass.color.name() # Same colors for NVCSCLASS self.assertEqual(color_map[11.0], '#0000ff') self.assertEqual(color_map[12.0], '#0000ff') # Manually change one color classes = raster_layer.renderer().classes() classes[0].color = QColor(10, 20, 30) renderer = QgsPalettedRasterRenderer(raster_layer.dataProvider(), 1, classes) raster_layer.setRenderer(renderer) color_map = {} for klass in raster_layer.renderer().classes(): color_map[klass.value] = klass.color.name() # Manually changed colors for NVCSCLASS self.assertEqual(color_map[11.0], '#0a141e') self.assertEqual(color_map[12.0], '#0000ff') self.assertTrue(homogenize_colors(raster_layer)) color_map = {} for klass in raster_layer.renderer().classes(): color_map[klass.value] = klass.color.name() # Same colors for NVCSCLASS self.assertEqual(color_map[11.0], '#0a141e') self.assertEqual(color_map[12.0], '#0a141e')
def _test(is_dbf): QgsProject.instance().removeAllMapLayers() tmp_dir = QTemporaryDir() shutil.copy( os.path.join(os.path.dirname(__file__), 'data', 'raster-palette.tif'), tmp_dir.path()) rat_path = os.path.join( tmp_dir.path(), 'raster-palette.tif' + ('.vat.dbf' if is_dbf else '.aux.xml')) self.assertFalse(os.path.exists(rat_path)) raster_layer = QgsRasterLayer( os.path.join(tmp_dir.path(), 'raster-palette.tif'), 'rat_test', 'gdal') QgsProject.instance().addMapLayer(raster_layer) self.assertTrue(raster_layer.isValid()) self.assertFalse(can_create_rat(raster_layer)) self.assertFalse(has_rat(raster_layer)) band = 1 # Set renderer ramp = QgsRandomColorRamp() renderer = QgsPalettedRasterRenderer( raster_layer.dataProvider(), 1, QgsPalettedRasterRenderer.classDataFromRaster( raster_layer.dataProvider(), band, ramp)) raster_layer.setRenderer(renderer) self.assertTrue(can_create_rat(raster_layer)) rat = create_rat_from_raster(raster_layer, is_dbf, rat_path) self.assertTrue(rat.isValid()) self.assertEqual(rat.data['Count'], [78, 176, 52]) self.assertEqual( rat.data['Value'], [2.257495271713565, 7.037407804695962, 270.4551067154352]) self.assertEqual(rat.data['A'], [255, 255, 255]) self.assertNotEqual(rat.data['R'], [0, 0, 0]) self.assertTrue(rat.save(band)) self.assertTrue(os.path.exists(rat_path)) QgsProject.instance().removeMapLayers([raster_layer.id()]) del (raster_layer) self.assertTrue(os.path.exists(rat_path)) QgsApplication.processEvents() # Reload and check raster_layer = QgsRasterLayer( os.path.join(tmp_dir.path(), 'raster-palette.tif'), 'rat_test', 'gdal') self.assertTrue(raster_layer.isValid()) self.assertFalse(can_create_rat(raster_layer)) self.assertTrue(has_rat(raster_layer), rat_path) os.unlink(rat_path)
result_dataset = None fileInfo = QFileInfo(result_path) baseName = fileInfo.baseName() layer = QgsRasterLayer(result_path, baseName) pcolor = [] pcolor.append(QgsColorRampShader.ColorRampItem(1, QColor("#d2ca97"))) pcolor.append(QgsColorRampShader.ColorRampItem(2, QColor("#f7f7f7"))) pcolor.append(QgsColorRampShader.ColorRampItem(3, QColor("#a1d99b"))) pcolor.append(QgsColorRampShader.ColorRampItem(4, QColor("#41ab5d"))) pcolor.append(QgsColorRampShader.ColorRampItem(5, QColor("#006d2c"))) pcolor.append(QgsColorRampShader.ColorRampItem(6, QColor("#00441b"))) renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1, QgsPalettedRasterRenderer.colorTableToClassData(pcolor)) layer.setRenderer(renderer) extent = layer.extent() width, height = layer.width(), layer.height() renderer = layer.renderer() provider = layer.dataProvider() crs = layer.crs().toWkt() pipe = QgsRasterPipe() pipe.set(provider.clone()) pipe.set(renderer.clone()) file_writer = QgsRasterFileWriter("C:/temp/naip/classified_res.tif") file_writer.writeRaster(pipe, width, height, extent,
def rat_classify(raster_layer, band, rat, criteria, ramp=None, feedback=QgsRasterBlockFeedback()) -> list: """Classify a raster. Note: cannot use a custom shader function QgsColorRampShader subclass because it's lost in the clone stage of the renderer. :param raster_layer: the raster layer to classify :type raster_layer: QgsRasterLayer :param band: band number (1-based) :type band: int :param rat: the RAT data :type rat: dict :param criteria: key of the RAT to be used for labels :type criteria: str :param ramp: optional color ramp, defaults to QgsRandomColorRamp() :type ramp: QgsColorRamp, optional :param feedback: QGIS feedback object, defaults to QgsRasterBlockFeedback() :type feedback: QgsRasterBlockFeedback, optional :return: unique row indexes for legend items (1-based) :rtype: list """ has_color = rat.has_color labels = rat.data[criteria] label_colors = {} unique_indexes = [] # QGIS >= 3.18 for first element label if Qgis.QGIS_VERSION_INT >= 31800: base_legend_row_index = 1 else: base_legend_row_index = 0 if rat.thematic_type == gdal.GRTT_THEMATIC: # Use paletted rat_log('Using paletted renderer') value_column_name = rat.field_name(gdal.GFU_MinMax) values = rat.data[value_column_name] is_integer = isinstance(values[0], int) if ramp is None: ramp = QgsRandomColorRamp() classes = QgsPalettedRasterRenderer.classDataFromRaster( raster_layer.dataProvider(), band, ramp, feedback) row_index = base_legend_row_index for klass in classes: value = int(klass.value) if is_integer else klass.value try: index = values.index(value) except ValueError: # NODATA rat_log( f'Value {value} not found in RAT, assuming NODATA', Qgis.Warning) data_provider = raster_layer.dataProvider() if not data_provider.userNoDataValuesContains(band, value): nodata = data_provider.userNoDataValues(band) nodata_value = QgsRasterRange(value, value) nodata.append(nodata_value) data_provider.setUserNoDataValue(band, nodata) continue klass.label = str(labels[index]) if klass.label not in label_colors: unique_indexes.append(row_index) if has_color: label_colors[klass.label] = rat.data[RAT_COLOR_HEADER_NAME][index] else: label_colors[klass.label] = klass.color klass.color = label_colors[klass.label] row_index += 1 renderer = QgsPalettedRasterRenderer( raster_layer.dataProvider(), band, classes) else: # ranges rat_log('Using singleband pseudocolor renderer') min_value_column = rat.field_name(gdal.GFU_Min) max_value_column = rat.field_name(gdal.GFU_Max) # Collect unique values and colors from criteria row_index = base_legend_row_index unique_labels = [] for index in range(len(labels)): label = labels[index] if label not in unique_labels: unique_labels.append(label) unique_indexes.append(row_index) # Collect color if has_color: label_colors[label] = rat.data[RAT_COLOR_HEADER_NAME][index] row_index += 1 # Assign colors from random ramp if not has_color: ramp = QgsRandomColorRamp() ramp.setTotalColorCount(len(unique_labels)) i = 0 for index in unique_indexes: label_colors[labels[index]] = ramp.color(ramp.value(i)) i += 1 # Create values for the ramp # Collect colors for all classes colors = [] for label in labels: colors.append(label_colors[label]) ramp = QgsPresetSchemeColorRamp(colors) minValue = min(rat.data[min_value_column]) maxValue = max(rat.data[max_value_column]) assert minValue < maxValue, "Min Value must be lower than Max Value" shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader( minValue, maxValue, ramp) colorRampShaderFcn.setClip(True) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Discrete) items = [] row = 0 for label in labels: items.append(QgsColorRampShader.ColorRampItem( rat.data[max_value_column][row], label_colors[label], label)) row += 1 colorRampShaderFcn.setColorRampItemList(items) try: # for older QGIS colorRampShaderFcn.legendSettings().setUseContinuousLegend(False) except AttributeError: rat_log( 'QgsColorRampShader.legendSettings().setUseContinuousLegend() is not supported on ths QGIS version.', Qgis.Warning) shader.setRasterShaderFunction(colorRampShaderFcn) renderer = QgsSingleBandPseudoColorRenderer( raster_layer.dataProvider(), band, shader) raster_layer.setRenderer(renderer) raster_layer.triggerRepaint() return unique_indexes
def on_cannyPushButton_clicked(self): raster_layer_name = self.rasterLayerComboBox.currentText() raster_layer = QgsProject.instance().mapLayersByName( raster_layer_name)[0] provider = raster_layer.dataProvider() extent = provider.extent() rows = raster_layer.height() cols = raster_layer.width() # 读取栅格值 block = provider.block(1, extent, cols, rows) img = np.zeros([rows, cols, 3], np.uint8) band_num = 3 for band_index in range(band_num): block = provider.block(band_index + 1, extent, cols, rows) # for row_index in range(rows): # for col_index in range(cols): # img[row_index][col_index][band_index] = block.value( # row_index, col_index) img[:, :, band_index] = np.array(block.data()).reshape([rows, cols]) print(img) print(img.shape) edges = cv2.Canny(img, 200, 400, 15) plt.subplot(121) plt.imshow(img) plt.title('Original Image') plt.xticks([]) plt.yticks([]) plt.subplot(122) plt.imshow(edges, cmap='gray') plt.title('Edge Image') plt.xticks([]) plt.yticks([]) plt.show() cv2.imwrite(r'edge_result.jpg', edges) # 写入Tiff driver = gdal.GetDriverByName('GTiff') # 创建图像 print(f'cols {cols}, rows {rows}') ds = driver.Create('edge_result.tif', xsize=cols, ysize=rows, bands=1, eType=gdal.GDT_Byte) # 设置参考坐标系 crs_wkt = raster_layer.crs().toWkt() ds.SetProjection(crs_wkt) print(crs_wkt) # srs = osr.SpatialReference() # srs.SetUTM(12, 1) # srs.SetWellKnownGeogCS('WGS84') # ds.SetProjection(srs.ExportToWkt()) # 设置Tiff的图像转换参数 transformParam = [ extent.xMinimum(), (extent.width() / cols), 0, extent.yMaximum(), 0, -(extent.height() / rows) ] ds.SetGeoTransform(transformParam) print(transformParam) # 写入数据 ds.GetRasterBand(1).WriteArray(edges[:, :]) # 关闭文件 ds = None # 添加至图层并设置样式 rlayer = QgsRasterLayer('edge_result.tif', "result tif layer") QgsProject.instance().addMapLayer(rlayer) palette_raster_render = QgsPalettedRasterRenderer( rlayer.dataProvider(), 1, [ QgsPalettedRasterRenderer.Class(0, QtGui.QColor(0, 0, 0, 0)), QgsPalettedRasterRenderer.Class(255, QtGui.QColor(255, 0, 0, 255)) ]) rlayer.setRenderer(palette_raster_render)