def test_update_color_from_raster_athematic(self): rat = get_rat(self.raster_layer_athematic, 1) self.assertTrue(rat.has_color) rat_classify(self.raster_layer_athematic, 1, rat, 'Class') shader = self.raster_layer_athematic.renderer().shader() colorRampShaderFcn = shader.rasterShaderFunction() classes = classes = colorRampShaderFcn.colorRampItemList() color_map = {klass.value: klass.color for klass in classes} # Remove color self.assertTrue(rat.remove_color_fields()) self.assertFalse(rat.has_color) # Add color result, error_message = rat.insert_color_fields(len(rat.keys) - 1) self.assertTrue(result, error_message) self.assertTrue(rat.has_color) for color in rat.data[RAT_COLOR_HEADER_NAME]: self.assertEqual(color, QColor(Qt.black)) # Update color from raster self.assertTrue( rat.update_colors_from_raster(self.raster_layer_athematic)) value_column = rat.value_columns[1] self.assertEqual(value_column, rat.field_name(gdal.GFU_Max)) for row_index in range(len(rat.data[RAT_COLOR_HEADER_NAME])): self.assertEqual(rat.data[RAT_COLOR_HEADER_NAME][row_index], color_map[rat.data[value_column][row_index]])
def test_update_color_from_raster(self): rat = get_rat(self.raster_layer_dbf, 1) self.assertTrue(rat.has_color) rat_classify(self.raster_layer_dbf, 1, rat, 'EVT_NAME') color_map = { klass.value: klass.color for klass in self.raster_layer_dbf.renderer().classes() } # Remove color self.assertTrue(rat.remove_color_fields()) self.assertFalse(rat.has_color) # Add color result, error_message = rat.insert_color_fields(len(rat.keys) - 1) self.assertTrue(result, error_message) self.assertTrue(rat.has_color) for color in rat.data[RAT_COLOR_HEADER_NAME]: self.assertEqual(color, QColor(Qt.black)) # Update color from raster self.assertTrue(rat.update_colors_from_raster(self.raster_layer_dbf)) value_column = rat.value_columns[0] self.assertEqual(value_column, rat.field_name(gdal.GFU_MinMax)) for row_index in range(len(rat.data[RAT_COLOR_HEADER_NAME])): self.assertEqual(rat.data[RAT_COLOR_HEADER_NAME][row_index], color_map[rat.data[value_column][row_index]])
def test_dialog(self): raster_layer = QgsRasterLayer( os.path.join(os.path.dirname(__file__), 'data', 'ExistingVegetationTypes_sample.img'), 'rat_test', 'gdal') self.assertTrue(raster_layer.isValid()) rat = get_rat(raster_layer, 1) rat_classify(raster_layer, 1, rat, 'EVT_NAME') dialog = RasterAttributeTableDialog(raster_layer) model = dialog.mRATView.model() self.assertEqual(model.rowCount(QModelIndex()), 59) self.assertEqual(model.columnCount(QModelIndex()), 17) header_model = dialog.mRATView.horizontalHeader().model() self.assertEqual(header_model.headerData(0, Qt.Horizontal), RAT_COLOR_HEADER_NAME) model = dialog.mRATView.model() color = model.data(model.index(0, 0), Qt.ItemDataRole.BackgroundColorRole) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 255) self.assertEqual(header_model.headerData(0, Qt.Horizontal), RAT_COLOR_HEADER_NAME) self.assertEqual(header_model.headerData(1, Qt.Horizontal), 'VALUE') if not os.environ.get('CI', False): dialog.exec_()
def test_athematic_rat(self): """Test RAT from single band with range values""" tmp_dir = QTemporaryDir() shutil.copy(os.path.join(os.path.dirname( __file__), 'data', '2x2_1_BAND_FLOAT.tif'), tmp_dir.path()) shutil.copy(os.path.join(os.path.dirname( __file__), 'data', '2x2_1_BAND_FLOAT.tif.aux.xml'), tmp_dir.path()) raster_layer = QgsRasterLayer(os.path.join( tmp_dir.path(), '2x2_1_BAND_FLOAT.tif'), 'rat_test', 'gdal') band = 1 rat = get_rat(raster_layer, band) self.assertTrue(rat.isValid()) self.assertEqual(rat.thematic_type, gdal.GRTT_ATHEMATIC) self.assertEqual(rat.value_columns, ['Value Min', 'Value Max']) self.assertEqual(rat.field_usages, { gdal.GFU_Generic, gdal.GFU_Name, gdal.GFU_Min, gdal.GFU_Max, gdal.GFU_Red, gdal.GFU_Green, gdal.GFU_Blue}) self.assertEqual(rat.data[rat.value_columns[0]], [-1e+25, 3000000000000.0, 1e+20]) self.assertEqual(rat.data[rat.value_columns[1]], [ 3000000000000.0, 1e+20, 5e+25]) # Round trip tests unique_indexes = rat_classify(raster_layer, band, rat, 'Class', ramp=None) self.assertEqual(unique_indexes, [1, 2, 3]) rat2 = create_rat_from_raster(raster_layer, True, os.path.join( tmp_dir.path(), '2x2_1_BAND_FLOAT.tif.vat.dbf')) self.assertTrue(rat2.isValid()) # Generic (Class3) is gone self.assertEqual(rat2.field_usages, { gdal.GFU_Name, gdal.GFU_Min, gdal.GFU_Max, gdal.GFU_Red, gdal.GFU_Green, gdal.GFU_Blue, gdal.GFU_Alpha}) self.assertEqual( rat2.data['Value Min'], [-3.40282e+38, 3000000000000.0, 1e+20]) self.assertEqual( rat2.data['Value Max'], [3000000000000.0, 1e+20, 5e+25]) # Reclass on class 2 unique_indexes = rat_classify(raster_layer, band, rat, 'Class2', ramp=None) self.assertEqual(unique_indexes, [1, 2]) rat2 = create_rat_from_raster(raster_layer, True, os.path.join( tmp_dir.path(), '2x2_1_BAND_FLOAT.tif.vat.dbf')) self.assertTrue(rat2.isValid()) # Generic (Class3) is gone self.assertEqual(rat2.field_usages, { gdal.GFU_Name, gdal.GFU_Min, gdal.GFU_Max, gdal.GFU_Red, gdal.GFU_Green, gdal.GFU_Blue, gdal.GFU_Alpha}) self.assertEqual( rat2.data['Value Min'], [-3.40282e+38, 3000000000000.0, 1e+20]) self.assertEqual( rat2.data['Value Max'], [3000000000000.0, 1e+20, 5e+25])
def classify(self): """Create classification on the selected criteria""" if QMessageBox.question( None, QCoreApplication.translate('RAT', "Overwrite classification"), QCoreApplication.translate( 'RAT', "The existing classification will be overwritten, do you want to continue?" )) == QMessageBox.Yes: band = self.mRasterBandsComboBox.currentIndex() + 1 criteria = self.mClassifyComboBox.currentText() # TODO: ramp & feedback unique_class_row_indexes = rat_classify(self.raster_layer, band, self.rat, criteria) unique_class_row_indexes.insert(0, 0) if self.iface is not None: deduplicate_legend_entries(self.iface, self.raster_layer, criteria, unique_class_row_indexes, expand=True) # Adopt the layer self.raster_layer.setCustomProperty( RAT_CUSTOM_PROPERTY_CLASSIFICATION_CRITERIA, criteria)
def test_rat_xml_no_data_thematic(self): """Test we can open an XML rat with a missing value (band 1, value 4)""" tmp_dir = QTemporaryDir() shutil.copy( os.path.join(os.path.dirname(__file__), 'data', '2x2_2_BANDS_INT16_NODATA.tif'), tmp_dir.path()) shutil.copy( os.path.join(os.path.dirname(__file__), 'data', '2x2_2_BANDS_INT16_NODATA.tif.aux.xml'), tmp_dir.path()) raster_layer = QgsRasterLayer( os.path.join(tmp_dir.path(), '2x2_2_BANDS_INT16_NODATA.tif'), 'rat_test', 'gdal') rat = get_rat(raster_layer, 1) self.assertTrue(rat.isValid()) self.assertEqual(rat.thematic_type, gdal.GRTT_THEMATIC) self.assertIn(gdal.GFU_PixelCount, rat.field_usages) unique_row_indexes = rat_classify(raster_layer, 1, rat, 'Class') if Qgis.QGIS_VERSION_INT >= 31800: self.assertEqual(unique_row_indexes, [1, 2]) else: self.assertEqual(unique_row_indexes, [0, 1])
def test_classify_athematic(self): """Test issue with athematic RAT classification dedup""" tmp_dir = QTemporaryDir() shutil.copy(os.path.join(os.path.dirname( __file__), 'data', 'band1_float32_noct_epsg4326.tif'), tmp_dir.path()) shutil.copy(os.path.join(os.path.dirname( __file__), 'data', 'band1_float32_noct_epsg4326.tif.aux.xml'), tmp_dir.path()) raster_layer = QgsRasterLayer(os.path.join( tmp_dir.path(), 'band1_float32_noct_epsg4326.tif'), 'rat_test', 'gdal') rat = get_rat(raster_layer, 1) self.assertTrue(rat.isValid()) unique_indexes = rat_classify(raster_layer, 1, rat, 'class2') self.assertEqual(unique_indexes, [1, 2, 3])
def _test_classify(self, raster_layer, criteria): self.assertTrue(raster_layer.isValid()) rat = get_rat(raster_layer, 1) unique_values_count = len(set(rat.data[criteria])) unique_row_indexes = rat_classify(raster_layer, 1, rat, criteria) self.assertEqual(len(unique_row_indexes), unique_values_count) renderer = raster_layer.renderer() classes = renderer.classes() colors = {} for idx in unique_row_indexes: klass = classes[idx - 1] colors[klass.label] = klass.color.name() for klass in classes: self.assertEqual(klass.color.name(), colors[klass.label])
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')