def test_style_with_symbols(self): style = QgsStyle() style.createMemoryDatabase() # style with only symbols symbol_a = createMarkerSymbol() symbol_a.setColor(QColor(255, 10, 10)) self.assertTrue(style.addSymbol('a', symbol_a, True)) style.tagSymbol(QgsStyle.SymbolEntity, 'a', ['tag 1', 'tag 2']) symbol_B = createMarkerSymbol() symbol_B.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('B ', symbol_B, True)) symbol_b = createFillSymbol() symbol_b.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('b', symbol_b, True)) symbol_C = createLineSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('C', symbol_C, True)) style.tagSymbol(QgsStyle.SymbolEntity, 'C', ['tag 3']) symbol_C = createMarkerSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol(' ----c/- ', symbol_C, True)) model = QgsStyleModel(style) self.assertEqual(model.rowCount(), 5) self.assertEqual(model.columnCount(), 2) self.assertEqual(model.headerData(0, Qt.Horizontal), 'Name') self.assertEqual(model.headerData(1, Qt.Horizontal), 'Tags') self.assertTrue(model.index(0, 0).isValid()) self.assertFalse(model.index(10, 0).isValid()) self.assertFalse(model.index(0, 10).isValid()) self.assertFalse(model.parent(model.index(0, 0)).isValid()) self.assertFalse(model.flags(model.index(-1, 0)) & Qt.ItemIsEditable) self.assertFalse(model.flags(model.index(5, 0)) & Qt.ItemIsEditable) self.assertFalse(model.flags(model.index(0, 1)) & Qt.ItemIsEditable) self.assertTrue(model.flags(model.index(0, 0)) & Qt.ItemIsEditable) for role in (Qt.DisplayRole, Qt.EditRole): self.assertIsNone(model.data(model.index(-1, 0), role)) self.assertIsNone(model.data(model.index(-1, 1), role)) self.assertEqual(model.data(model.index(0, 0), role), ' ----c/- ') self.assertFalse(model.data(model.index(0, 1), role)) self.assertIsNone(model.data(model.index(0, 2), role)) self.assertIsNone(model.data(model.index(0, -1), role)) self.assertEqual(model.data(model.index(1, 0), role), 'B ') self.assertFalse(model.data(model.index(1, 1), role)) self.assertEqual(model.data(model.index(2, 0), role), 'C') self.assertEqual(model.data(model.index(2, 1), role), 'tag 3') self.assertEqual(model.data(model.index(3, 0), role), 'a') self.assertEqual(model.data(model.index(3, 1), role), 'tag 1, tag 2') self.assertEqual(model.data(model.index(4, 0), role), 'b') self.assertFalse(model.data(model.index(4, 1), role)) self.assertIsNone(model.data(model.index(5, 0), role)) self.assertIsNone(model.data(model.index(5, 1), role)) # decorations self.assertIsNone(model.data(model.index(-1, 0), Qt.DecorationRole)) self.assertIsNone(model.data(model.index(0, 1), Qt.DecorationRole)) self.assertIsNone(model.data(model.index(5, 0), Qt.DecorationRole)) self.assertFalse( model.data(model.index(0, 0), Qt.DecorationRole).isNull()) self.assertEqual(model.data(model.index(0, 0), QgsStyleModel.TypeRole), QgsStyle.SymbolEntity) self.assertEqual(model.data(model.index(1, 0), QgsStyleModel.TypeRole), QgsStyle.SymbolEntity) self.assertEqual(model.data(model.index(4, 0), QgsStyleModel.TypeRole), QgsStyle.SymbolEntity)
def test_mixed_style(self): """ Test style with both symbols and ramps """ style = QgsStyle() style.createMemoryDatabase() # style with only symbols symbol_a = createMarkerSymbol() symbol_a.setColor(QColor(255, 10, 10)) self.assertTrue(style.addSymbol('a', symbol_a, True)) style.tagSymbol(QgsStyle.SymbolEntity, 'a', ['tag 1', 'tag 2']) symbol_B = createMarkerSymbol() symbol_B.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('B ', symbol_B, True)) symbol_b = createFillSymbol() symbol_b.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('b', symbol_b, True)) symbol_C = createLineSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('C', symbol_C, True)) style.tagSymbol(QgsStyle.SymbolEntity, 'C', ['tag 3']) symbol_C = createMarkerSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol(' ----c/- ', symbol_C, True)) ramp_a = QgsLimitedRandomColorRamp(5) self.assertTrue(style.addColorRamp('ramp a', ramp_a, True)) style.tagSymbol(QgsStyle.ColorrampEntity, 'ramp a', ['tag 1', 'tag 2']) symbol_B = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('ramp B ', symbol_B, True)) symbol_b = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('ramp c', symbol_b, True)) model = QgsStyleModel(style) self.assertEqual(model.rowCount(), 8) self.assertEqual(model.columnCount(), 2) self.assertTrue(model.index(0, 0).isValid()) self.assertFalse(model.index(10, 0).isValid()) self.assertFalse(model.index(0, 10).isValid()) self.assertFalse(model.parent(model.index(0, 0)).isValid()) for role in (Qt.DisplayRole, Qt.EditRole): self.assertIsNone(model.data(model.index(-1, 0), role)) self.assertIsNone(model.data(model.index(-1, 1), role)) self.assertEqual(model.data(model.index(0, 0), role), ' ----c/- ') self.assertFalse(model.data(model.index(0, 1), role)) self.assertIsNone(model.data(model.index(0, 2), role)) self.assertIsNone(model.data(model.index(0, -1), role)) self.assertEqual(model.data(model.index(1, 0), role), 'B ') self.assertFalse(model.data(model.index(1, 1), role)) self.assertEqual(model.data(model.index(2, 0), role), 'C') self.assertEqual(model.data(model.index(2, 1), role), 'tag 3') self.assertEqual(model.data(model.index(3, 0), role), 'a') self.assertEqual(model.data(model.index(3, 1), role), 'tag 1, tag 2') self.assertEqual(model.data(model.index(4, 0), role), 'b') self.assertFalse(model.data(model.index(4, 1), role)) self.assertEqual(model.data(model.index(5, 0), role), 'ramp B ') self.assertFalse(model.data(model.index(5, 1), role)) self.assertEqual(model.data(model.index(6, 0), role), 'ramp a') self.assertEqual(model.data(model.index(6, 1), role), 'tag 1, tag 2') self.assertEqual(model.data(model.index(7, 0), role), 'ramp c') self.assertFalse(model.data(model.index(7, 1), role)) self.assertIsNone(model.data(model.index(8, 0), role)) self.assertIsNone(model.data(model.index(8, 1), role)) # decorations self.assertIsNone(model.data(model.index(-1, 0), Qt.DecorationRole)) self.assertIsNone(model.data(model.index(0, 1), Qt.DecorationRole)) self.assertIsNone(model.data(model.index(8, 0), Qt.DecorationRole)) self.assertFalse( model.data(model.index(0, 0), Qt.DecorationRole).isNull()) self.assertFalse( model.data(model.index(5, 0), Qt.DecorationRole).isNull()) self.assertEqual(model.data(model.index(0, 0), QgsStyleModel.TypeRole), QgsStyle.SymbolEntity) self.assertEqual(model.data(model.index(1, 0), QgsStyleModel.TypeRole), QgsStyle.SymbolEntity) self.assertEqual(model.data(model.index(4, 0), QgsStyleModel.TypeRole), QgsStyle.SymbolEntity) self.assertEqual(model.data(model.index(5, 0), QgsStyleModel.TypeRole), QgsStyle.ColorrampEntity) self.assertEqual(model.data(model.index(6, 0), QgsStyleModel.TypeRole), QgsStyle.ColorrampEntity) self.assertEqual(model.data(model.index(7, 0), QgsStyleModel.TypeRole), QgsStyle.ColorrampEntity)
def test_renamed(self): style = QgsStyle() style.createMemoryDatabase() model = QgsStyleModel(style) symbol = createMarkerSymbol() self.assertTrue(style.addSymbol('a', symbol, True)) symbol = createMarkerSymbol() self.assertTrue(style.addSymbol('c', symbol, True)) ramp_a = QgsLimitedRandomColorRamp(5) self.assertTrue(style.addColorRamp('ramp a', ramp_a, True)) symbol_B = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('ramp c', symbol_B, True)) self.assertEqual(model.rowCount(), 4) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'a') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'c') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp a') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp c') self.assertTrue(style.renameSymbol('a', 'b')) self.assertEqual(model.rowCount(), 4) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'b') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'c') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp a') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp c') self.assertTrue(style.renameSymbol('b', 'd')) self.assertEqual(model.rowCount(), 4) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'c') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'd') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp a') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp c') self.assertTrue(style.renameSymbol('d', 'e')) self.assertEqual(model.rowCount(), 4) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'c') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'e') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp a') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp c') self.assertTrue(style.renameSymbol('c', 'f')) self.assertEqual(model.rowCount(), 4) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'e') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'f') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp a') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp c') self.assertTrue(style.renameColorRamp('ramp a', 'ramp b')) self.assertEqual(model.rowCount(), 4) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'e') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'f') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp b') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp c') self.assertTrue(style.renameColorRamp('ramp b', 'ramp d')) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'e') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'f') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp c') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp d') self.assertTrue(style.renameColorRamp('ramp d', 'ramp e')) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'e') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'f') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp c') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp e') self.assertTrue(style.renameColorRamp('ramp c', 'ramp f')) self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), 'e') self.assertEqual(model.data(model.index(1, 0), Qt.DisplayRole), 'f') self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), 'ramp e') self.assertEqual(model.data(model.index(3, 0), Qt.DisplayRole), 'ramp f')
def testMatchToSymbols(self): """ Test QgsCategorizedSymbolRender.matchToSymbols """ renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('x') symbol_a = createMarkerSymbol() symbol_a.setColor(QColor(255, 0, 0)) renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a')) symbol_b = createMarkerSymbol() symbol_b.setColor(QColor(0, 255, 0)) renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b')) symbol_c = createMarkerSymbol() symbol_c.setColor(QColor(0, 0, 255)) renderer.addCategory(QgsRendererCategory('c ', symbol_c, 'c')) matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols( None, QgsSymbol.Marker) self.assertEqual(matched, 0) style = QgsStyle() symbol_a = createMarkerSymbol() symbol_a.setColor(QColor(255, 10, 10)) self.assertTrue(style.addSymbol('a', symbol_a)) symbol_B = createMarkerSymbol() symbol_B.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('B ', symbol_B)) symbol_b = createFillSymbol() symbol_b.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('b', symbol_b)) symbol_C = createLineSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('C', symbol_C)) symbol_C = createMarkerSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol(' ----c/- ', symbol_C)) # non-matching symbol type matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols( style, QgsSymbol.Line) self.assertEqual(matched, 0) self.assertEqual(unmatched_cats, ['a', 'b', 'c ']) self.assertEqual(unmatched_symbols, [' ----c/- ', 'B ', 'C', 'a', 'b']) # exact match matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols( style, QgsSymbol.Marker) self.assertEqual(matched, 1) self.assertEqual(unmatched_cats, ['b', 'c ']) self.assertEqual(unmatched_symbols, [' ----c/- ', 'B ', 'C', 'b']) # make sure symbol was applied context = QgsRenderContext() renderer.startRender(context, QgsFields()) symbol, ok = renderer.symbolForValue2('a') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#ff0a0a') renderer.stopRender(context) # case insensitive match matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols( style, QgsSymbol.Marker, False) self.assertEqual(matched, 2) self.assertEqual(unmatched_cats, ['c ']) self.assertEqual(unmatched_symbols, [' ----c/- ', 'C', 'b']) # make sure symbols were applied context = QgsRenderContext() renderer.startRender(context, QgsFields()) symbol, ok = renderer.symbolForValue2('a') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#ff0a0a') symbol, ok = renderer.symbolForValue2('b') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#0aff0a') renderer.stopRender(context) # case insensitive match matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols( style, QgsSymbol.Marker, False) self.assertEqual(matched, 2) self.assertEqual(unmatched_cats, ['c ']) self.assertEqual(unmatched_symbols, [' ----c/- ', 'C', 'b']) # make sure symbols were applied context = QgsRenderContext() renderer.startRender(context, QgsFields()) symbol, ok = renderer.symbolForValue2('a') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#ff0a0a') symbol, ok = renderer.symbolForValue2('b') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#0aff0a') renderer.stopRender(context) # tolerant match matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols( style, QgsSymbol.Marker, True, True) self.assertEqual(matched, 2) self.assertEqual(unmatched_cats, ['b']) self.assertEqual(unmatched_symbols, ['B ', 'C', 'b']) # make sure symbols were applied context = QgsRenderContext() renderer.startRender(context, QgsFields()) symbol, ok = renderer.symbolForValue2('a') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#ff0a0a') symbol, ok = renderer.symbolForValue2('c ') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#0aff0a') renderer.stopRender(context) # tolerant match, case insensitive matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols( style, QgsSymbol.Marker, False, True) self.assertEqual(matched, 3) self.assertFalse(unmatched_cats) self.assertEqual(unmatched_symbols, ['C', 'b']) # make sure symbols were applied context = QgsRenderContext() renderer.startRender(context, QgsFields()) symbol, ok = renderer.symbolForValue2('a') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#ff0a0a') symbol, ok = renderer.symbolForValue2('b') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#0aff0a') symbol, ok = renderer.symbolForValue2('c ') self.assertTrue(ok) self.assertEqual(symbol.color().name(), '#0aff0a') renderer.stopRender(context)
def test_style_with_ramps(self): style = QgsStyle() style.createMemoryDatabase() # style with only ramps ramp_a = QgsLimitedRandomColorRamp(5) self.assertTrue(style.addColorRamp('a', ramp_a, True)) style.tagSymbol(QgsStyle.ColorrampEntity, 'a', ['tag 1', 'tag 2']) symbol_B = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('B ', symbol_B, True)) symbol_b = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('b', symbol_b, True)) symbol_C = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('C', symbol_C, True)) style.tagSymbol(QgsStyle.ColorrampEntity, 'C', ['tag 3']) symbol_C = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp(' ----c/- ', symbol_C, True)) model = QgsStyleModel(style) self.assertEqual(model.rowCount(), 5) self.assertEqual(model.columnCount(), 2) self.assertTrue(model.index(0, 0).isValid()) self.assertFalse(model.index(10, 0).isValid()) self.assertFalse(model.index(0, 10).isValid()) self.assertFalse(model.parent(model.index(0, 0)).isValid()) for role in (Qt.DisplayRole, Qt.EditRole): self.assertIsNone(model.data(model.index(-1, 0), role)) self.assertIsNone(model.data(model.index(-1, 1), role)) self.assertEqual(model.data(model.index(0, 0), role), ' ----c/- ') self.assertFalse(model.data(model.index(0, 1), role)) self.assertIsNone(model.data(model.index(0, 2), role)) self.assertIsNone(model.data(model.index(0, -1), role)) self.assertEqual(model.data(model.index(1, 0), role), 'B ') self.assertFalse(model.data(model.index(1, 1), role)) self.assertEqual(model.data(model.index(2, 0), role), 'C') self.assertEqual(model.data(model.index(2, 1), role), 'tag 3') self.assertEqual(model.data(model.index(3, 0), role), 'a') self.assertEqual(model.data(model.index(3, 1), role), 'tag 1, tag 2') self.assertEqual(model.data(model.index(4, 0), role), 'b') self.assertFalse(model.data(model.index(4, 1), role)) self.assertIsNone(model.data(model.index(5, 0), role)) self.assertIsNone(model.data(model.index(5, 1), role)) # decorations self.assertIsNone(model.data(model.index(-1, 0), Qt.DecorationRole)) self.assertIsNone(model.data(model.index(0, 1), Qt.DecorationRole)) self.assertIsNone(model.data(model.index(5, 0), Qt.DecorationRole)) self.assertFalse( model.data(model.index(0, 0), Qt.DecorationRole).isNull()) self.assertEqual(model.data(model.index(0, 0), QgsStyleModel.TypeRole), QgsStyle.ColorrampEntity) self.assertEqual(model.data(model.index(1, 0), QgsStyleModel.TypeRole), QgsStyle.ColorrampEntity) self.assertEqual(model.data(model.index(4, 0), QgsStyleModel.TypeRole), QgsStyle.ColorrampEntity)
def raster_apply_classified_renderer(raster_layer, rend_type, num_classes, color_ramp, invert=False, band_num=1, n_decimals=1): """ Applies quantile or equal intervals render to a raster layer. It also allows for the rounding of the values and legend labels. Args: raster_layer (QgsRasterLayer): The rasterlayer to apply classes to rend_type (str): The type of renderer to apply ('quantile' or 'equal interval') num_classes (int): The number of classes to create color_ramp (str): The colour ramp used to display the data band_num(int): The band number to use in the renderer invert (bool): invert the colour ramp n_decimals (int): the number of decimal places to round the values and labels Returns: """ # use an existing color ramp qgsStyles = QgsStyle().defaultStyle() # check to see if the colour ramp is installed if color_ramp != '' and color_ramp not in qgsStyles.colorRampNames(): raise ValueError( 'PAT symbology does not exist. See user manual for install instructions' ) ramp = qgsStyles.colorRamp(color_ramp) # get band statistics cbStats = raster_layer.dataProvider().bandStatistics( band_num, QgsRasterBandStats.All, raster_layer.extent(), 0) # create the renderer renderer = QgsSingleBandPseudoColorRenderer(raster_layer.dataProvider(), band_num) # set the max and min heights we found earlier renderer.setClassificationMin(cbStats.minimumValue) renderer.setClassificationMax(cbStats.maximumValue) if rend_type.lower() == 'quantile': renderer.createShader(ramp, QgsColorRampShader.Discrete, QgsColorRampShader.Quantile, num_classes) elif rend_type.lower() == 'equal interval': renderer.createShader(ramp, QgsColorRampShader.Discrete, QgsColorRampShader.EqualInterval, num_classes) # Round values off to the nearest decimal place and construct the label # get the newly created values and classes color_shader = renderer.shader().rasterShaderFunction() # iterate the values rounding and creating a range label. new_lst = [] for i, (value, color) in enumerate(color_shader.legendSymbologyItems(), start=1): value = float('{:.3g}'.format(float(value))) if i == 1: label = "<= {}".format(value) elif i == len(color_shader.legendSymbologyItems()): label = "> {}".format(last) else: label = "{} - {}".format(last, value) last = value new_lst.append(QgsColorRampShader.ColorRampItem(value, color, label)) # apply back to the shader then the layer color_shader.setColorRampItemList(new_lst) raster_layer.setRenderer(renderer) raster_layer.triggerRepaint()
def open_style(input_file): # pylint: disable=too-many-locals,too-many-branches,too-many-statements """ Opens a .style file """ if not Extractor.is_mdb_tools_binary_available(): bar = iface.messageBar() widget = bar.createMessage('SLYR', "MDB Tools utility not found") settings_button = QPushButton("Configure…", pressed=partial(open_settings, widget)) widget.layout().addWidget(settings_button) bar.pushWidget(widget, Qgis.Critical) return True style = QgsStyle() style.createMemoryDatabase() symbol_names = set() def make_name_unique(name): """ Ensures that the symbol name is unique (in a case insensitive way) """ counter = 0 candidate = 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): """ Handles feedback to progress dialog bridge """ progress_dialog.setValue(progress) iters = 0 while QCoreApplication.hasPendingEvents() and iters < 100: QCoreApplication.processEvents() iters += 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: 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(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(';') if symbol_type in ( Extractor.AREA_PATCHES, Extractor.LINE_PATCHES, Extractor.TEXT_SYMBOLS, Extractor.MAPLEX_LABELS, Extractor.LABELS): if symbol_type == Extractor.AREA_PATCHES: type_string = 'area patches' elif symbol_type == Extractor.LINE_PATCHES: type_string = 'line patches' elif symbol_type == Extractor.TEXT_SYMBOLS: type_string = 'text symbols' elif symbol_type == Extractor.MAPLEX_LABELS: type_string = 'maplex labels' elif symbol_type == Extractor.LABELS: type_string = 'labels' else: type_string = '' unreadable.append('<b>{}</b>: {} conversion requires a licensed version of the SLYR plugin'.format( html.escape(name), type_string)) continue 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), html.escape(msg))) elif level == Context.CRITICAL: errors.add('<b>{}</b>: {}'.format(html.escape(unique_name), html.escape(msg))) context.unsupported_object_callback = unsupported_object_callback # context.style_folder, _ = os.path.split(output_file) 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) 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) 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>' 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.exec_() return True
def __init__(self, parameters, is_new): QDialog.__init__(self, None) self.ui = Ui_MainDialog() self.ui.setupUi(self) self.ui.layer_list = LayerListWidget(self.ui.labelingGroup) self.ui.labelingLayout.addWidget(self.ui.layer_list) self.ui.bufferUnits.setValidator(QDoubleValidator()) self.ui.bufferSegments.setValidator(QIntValidator()) self.ui.simplifyTolerance.setValidator(QDoubleValidator()) self.parameters = parameters if self.parameters.file_format is None: self.parameters.file_format = "ESRI Shapefile" self.style = QgsStyle() # connect edit style self.ui.editStyleBtn.clicked.connect(self.on_style_edit) # connect file browser self.ui.browseBtn.clicked.connect(self.on_file_browse) # add a "tips" button self.ui.tipsBtn = QPushButton(self.tr("Tips"), self.ui.buttonBox) self.ui.buttonBox.addButton(self.ui.tipsBtn, QDialogButtonBox.ActionRole) self.ui.tipsBtn.clicked.connect(self.show_tips) # add a "save as defaults" button self.ui.saveDefaultsBtn = QPushButton( self.tr("Save as defaults"), self.ui.buttonBox ) self.ui.buttonBox.addButton( self.ui.saveDefaultsBtn, QDialogButtonBox.ActionRole ) self.ui.saveDefaultsBtn.clicked.connect(self.on_save_defaults) # add a "load defaults" button self.ui.loadDefaultsBtn = QPushButton( self.tr("Load defaults"), self.ui.buttonBox ) self.ui.buttonBox.addButton( self.ui.loadDefaultsBtn, QDialogButtonBox.ActionRole ) self.ui.loadDefaultsBtn.clicked.connect(self.load_defaults) # connect the "help" button self.ui.buttonBox.helpRequested.connect(self.on_help) self.ui.layer_list.ui.polygonOperatorCombo.currentIndexChanged[int].connect( self.on_polygon_operator_changed ) # connect the "apply" button for btn in self.ui.buttonBox.buttons(): if self.ui.buttonBox.buttonRole(btn) == QDialogButtonBox.ApplyRole: btn.clicked.connect(self.on_apply) break # save current style self.save_style_parameters = MaskParameters() self.update_parameters_from_style(self.save_style_parameters) self.update_parameters_from_style(self.parameters) self.is_new = is_new if self.is_new: self.setWindowTitle(self.tr("Create a mask")) else: self.setWindowTitle(self.tr("Update the current mask"))
def processAlgorithm( self, # pylint:disable=too-many-locals,too-many-statements,too-many-branches parameters, context, feedback): input_file = self.parameterAsString(parameters, self.INPUT, context) output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context) fields = QgsFields() fields.append(QgsField('name', QVariant.String, '', 60)) fields.append(QgsField('warning', QVariant.String, '', 250)) sink, dest = self.parameterAsSink(parameters, self.REPORT, context, fields) style = QgsStyle() style.createMemoryDatabase() results = {} 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 symbols_to_extract = [ Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS, Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS, Extractor.LINE_PATCHES, Extractor.AREA_PATCHES ] if Qgis.QGIS_VERSION_INT >= 30900: symbols_to_extract.extend( (Extractor.TEXT_SYMBOLS, Extractor.LABELS, Extractor.MAPLEX_LABELS)) type_percent = 100.0 / len(symbols_to_extract) results[self.LABEL_SETTINGS_COUNT] = 0 results[self.UNREADABLE_LABEL_SETTINGS] = 0 for type_index, symbol_type in enumerate(symbols_to_extract): feedback.pushInfo('Importing {} from {}'.format( symbol_type, input_file)) try: raw_symbols = Extractor.extract_styles(input_file, symbol_type) except MissingBinaryException: raise QgsProcessingException( # pylint: disable=raise-missing-from '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.' ) feedback.pushInfo('Found {} symbols of type "{}"\n\n'.format( len(raw_symbols), symbol_type)) if feedback.isCanceled(): break unreadable = 0 for index, raw_symbol in enumerate(raw_symbols): feedback.setProgress(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(';') feedback.pushInfo('{}/{}: {}'.format(index + 1, len(raw_symbols), name)) unique_name = make_name_unique(name) if name != unique_name: feedback.pushInfo( 'Corrected to unique name of {}'.format(unique_name)) handle = BytesIO(raw_symbol[Extractor.BLOB]) stream = Stream(handle) f = QgsFeature() try: symbol = stream.read_object() except UnreadableSymbolException as e: feedback.reportError( 'Error reading symbol {}: {}'.format(name, e), False) unreadable += 1 if sink: f.setAttributes( [name, 'Error reading symbol: {}'.format(e)]) sink.addFeature(f) continue except NotImplementedException as e: feedback.reportError( 'Parsing {} is not supported: {}'.format(name, e), False) unreadable += 1 if sink: f.setAttributes( [name, 'Parsing not supported: {}'.format(e)]) sink.addFeature(f) continue except UnsupportedVersionException as e: feedback.reportError( 'Cannot read {} version: {}'.format(name, e), False) unreadable += 1 if sink: f.setAttributes( [name, 'Version not supported: {}'.format(e)]) sink.addFeature(f) continue except UnknownClsidException as e: feedback.reportError(str(e), False) unreadable += 1 if sink: f.setAttributes([name, 'Unknown object: {}'.format(e)]) sink.addFeature(f) continue except UnreadablePictureException as e: feedback.reportError(str(e), False) unreadable += 1 if sink: f.setAttributes( [name, 'Unreadable picture: {}'.format(e)]) sink.addFeature(f) continue def unsupported_object_callback(msg, level=Context.WARNING): if level == Context.WARNING: feedback.reportError('Warning: {}'.format(msg), False) elif level == Context.CRITICAL: feedback.reportError(msg, False) if sink: feat = QgsFeature() feat.setAttributes([name, msg]) # pylint: disable=cell-var-from-loop sink.addFeature(feat) context = Context() context.symbol_name = unique_name context.style_folder, _ = os.path.split(output_file) context.unsupported_object_callback = unsupported_object_callback if symbol_type in (Extractor.AREA_PATCHES, Extractor.LINE_PATCHES): feedback.reportError( '{}: Legend patch conversion requires the licensed version of SLYR' .format(name), False) unreadable += 1 if sink: f.setAttributes( [name, 'Unreadable legend patch: {}'.format(name)]) sink.addFeature(f) continue try: qgis_symbol = SymbolConverter.Symbol_to_QgsSymbol( symbol, context) except NotImplementedException as e: feedback.reportError(str(e), False) unreadable += 1 if sink: f.setAttributes([name, str(e)]) sink.addFeature(f) continue except UnreadablePictureException as e: feedback.reportError(str(e), False) unreadable += 1 if sink: f.setAttributes( [name, 'Unreadable picture: {}'.format(e)]) sink.addFeature(f) continue if isinstance(qgis_symbol, QgsSymbol): 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) if symbol_type == Extractor.FILL_SYMBOLS: results[self.FILL_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_FILL_SYMBOLS] = unreadable elif symbol_type == Extractor.LINE_SYMBOLS: results[self.LINE_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_LINE_SYMBOLS] = unreadable elif symbol_type == Extractor.MARKER_SYMBOLS: results[self.MARKER_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_MARKER_SYMBOLS] = unreadable elif symbol_type == Extractor.COLOR_RAMPS: results[self.COLOR_RAMP_COUNT] = len(raw_symbols) results[self.UNREADABLE_COLOR_RAMPS] = unreadable elif symbol_type == Extractor.TEXT_SYMBOLS: results[self.TEXT_FORMAT_COUNT] = len(raw_symbols) results[self.UNREADABLE_TEXT_FORMATS] = unreadable elif symbol_type in (Extractor.MAPLEX_LABELS, Extractor.LABELS): results[self.LABEL_SETTINGS_COUNT] += len(raw_symbols) results[self.UNREADABLE_LABEL_SETTINGS] += unreadable elif symbol_type == Extractor.LINE_PATCHES: results[self.LINE_PATCH_COUNT] = len(raw_symbols) results[self.UNREADABLE_LINE_PATCHES] = unreadable elif symbol_type == Extractor.AREA_PATCHES: results[self.AREA_PATCH_COUNT] = len(raw_symbols) results[self.UNREADABLE_AREA_PATCHES] = unreadable style.exportXml(output_file) results[self.OUTPUT] = output_file results[self.REPORT] = dest return results
def editNetworkLayer(self, progressBar, layerName, scenariosExpression, networkExpression, variable, level, projectPath, group, networkLinkShapePath, method, layerId, expressionNetworkText, color): """ @summary: Get operators dictionary @param layerName: Layer name @type layerName: String @param scenariosExpression: Scenarios expression @type scenariosExpression: Stack object @param networkExpression: Network expression @type networkExpression: Stack object @param variable: Variable to evaluate @type variable: String @param level: Level to evaluate (Total, Routes, Operators) @type level: Level object @param projectPath: Project path @type projectPath: String @param group: Project group @type group: Layer group @param networkLinkShapePath: Network link shape path @type networkLinkShapePath: String @return: Result of the layer creation """ if scenariosExpression is None: QMessageBox.warning(None, "Network expression", "There is not scenarios information.") print("There is not scenarios information.") return False registry = QgsProject.instance() layersCount = len(registry.mapLayers()) result, resultData, minValue, maxValue = self.network_data_access.create_network_memory( layerName, scenariosExpression, networkExpression, variable, level, projectPath) progressBar.setValue(15) if result: # Source shape, name of the new shape, providerLib layer = QgsVectorLayer(networkLinkShapePath, layerName + "_network", 'ogr') epsg = layer.crs().postgisSrid() intMethod = 0 if method == "Color" else 1 rowCounter = len(resultData) if not layer.isValid(): return False feats = [feat for feat in layer.getFeatures()] # Create a vector layer with data on Memory memoryLayer = registry.mapLayer(layerId) memory_data = memoryLayer.dataProvider() joinedFieldName = "Result" shpField = "Id" attr = layer.dataProvider().fields().toList() attr += [QgsField(joinedFieldName, QVariant.Double)] progressBar.setValue(25) memory_data.addAttributes(attr) memory_data.addFeatures(feats) num = 30 progressBar.setValue(num) progressInterval = 70 / len(resultData) memoryLayer.startEditing() for rowItem in np.nditer(resultData): value = 0 num += progressInterval progressBar.setValue(num) it = memoryLayer.getFeatures("LINKID = '{0}'".format( str(rowItem['Id']).replace("b", "").replace("'", ""))) for id_feature in it: memoryLayer.changeAttributeValue( id_feature.id(), memory_data.fieldNameIndex(joinedFieldName), QVariant(round(float(rowItem['Result']), 2))) memoryLayer.commitChanges() myStyle = QgsStyle().defaultStyle() defaultColorRampNames = myStyle.colorRampNames() ramp = myStyle.colorRamp(defaultColorRampNames[0]) ranges = [] nCats = ramp.count() rng = maxValue - minValue nCats = 8 scale = QgsMapUnitScale(minValue, maxValue) if method == "Color": color1 = list( map(lambda x: int(x), color['color1'].split(",")[0:3])) color2 = list( map(lambda x: int(x), color['color2'].split(",")[0:3])) interpolatedColors = HP.linear_gradient(color1, color2, nCats) for i in range(0, nCats): v0 = minValue + rng / float(nCats) * i v1 = minValue + rng / float(nCats) * (i + 1) if method == "Color": line = QgsSimpleLineSymbolLayer( QColor(interpolatedColors['r'][i], interpolatedColors['g'][i], interpolatedColors['b'][i])) line.setOffsetUnit(2) line.setOffset(2) line.setWidth(0.8) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, line) myRange = QgsRendererRange(v0, v1, symbol, "") elif method == "Size": qcolor = QColor() qcolor.setRgb(color) line = QgsSimpleLineSymbolLayer(qcolor) line.setOffsetUnit(2) line.setOffset(0.7) # Symbol # symbolLine = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase.ArrowHead) # Mark line # markLine = QgsMarkerLineSymbolLayer() # markLine.setPlacement(4) symbolo = QgsLineSymbol() symbolo.changeSymbolLayer(0, line) # symbolo.appendSymbolLayer(line) myRange = QgsRendererRange(v0, v1, symbolo, "") ranges.append(myRange) # The first parameter refers to the name of the field that contains the calculated value (expression) modeRender = QgsGraduatedSymbolRenderer.Mode(2) renderer = QgsGraduatedSymbolRenderer(joinedFieldName, ranges) renderer.setMode(modeRender) renderer.setGraduatedMethod(intMethod) if method == "Size": renderer.setSymbolSizes(0.200000, 2.60000) renderer.setSourceColorRamp(ramp) memoryLayer.setRenderer(renderer) typeLayer = "network" fieldName = "LINKID" networkExpressionText = str(scenariosExpression) # Create XML File ".qtranus" with the parameters of the executions if FileMXML.if_exist_xml_layers(projectPath): if FileMXML.if_exist_layer(projectPath, memoryLayer.id()): FileMXML.update_xml_file(memoryLayer.name(), memoryLayer.id(), scenariosExpression, variable, networkExpression, projectPath, expressionNetworkText, method, level, color) else: FileMXML.add_layer_xml_file(memoryLayer.name(), memoryLayer.id(), scenariosExpression, variable, networkExpression, projectPath, expressionNetworkText, shpField, typeLayer, method, level, color) else: FileMXML.create_xml_file(memoryLayer.name(), memoryLayer.id(), scenariosExpression, variable, networkExpression, projectPath, expressionNetworkText, shpField, typeLayer, method, level, color) #group.insertLayer((layersCount+1), memoryLayer) progressBar.setValue(100) return True
def style_maps(layer, style_by, iface, output_type='damages-rlzs', perils=None, add_null_class=False, render_higher_on_top=False, repaint=True, use_sgc_style=False): symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # see properties at: # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073 symbol.setOpacity(1) if isinstance(symbol, QgsMarkerSymbol): # do it only for the layer with points symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen)) style = get_style(layer, iface.messageBar()) # this is the default, as specified in the user settings ramp = QgsGradientColorRamp(style['color_from'], style['color_to']) style_mode = style['style_mode'] # in most cases, we override the user-specified setting, and use # instead a setting that was required by scientists if output_type in OQ_TO_LAYER_TYPES: default_qgs_style = QgsStyle().defaultStyle() default_color_ramp_names = default_qgs_style.colorRampNames() if output_type in ( 'damages-rlzs', 'avg_losses-rlzs', 'avg_losses-stats', ): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.Jenks else: style_mode = 'Jenks' ramp_type_idx = default_color_ramp_names.index('Reds') symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top'])) inverted = False elif (output_type in ('gmf_data', 'ruptures') or (output_type == 'hmaps' and not use_sgc_style)): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if output_type == 'ruptures': if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.Pretty else: style_mode = 'PrettyBreaks' else: if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.EqualInterval else: style_mode = 'EqualInterval' ramp_type_idx = default_color_ramp_names.index('Spectral') inverted = True symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top'])) elif output_type == 'hmaps' and use_sgc_style: # FIXME: for SGC they were using size 10000 map units # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.Pretty else: style_mode = 'PrettyBreaks' try: ramp_type_idx = default_color_ramp_names.index( 'SGC_Green2Red_Hmap_Color_Ramp') except ValueError: raise ValueError( 'Color ramp SGC_Green2Red_Hmap_Color_Ramp was ' 'not found. Please import it from ' 'Settings -> Style Manager, loading ' 'svir/resources/sgc_green2red_hmap_color_ramp.xml') inverted = False registry = QgsApplication.symbolLayerRegistry() symbol_props = { 'name': 'square', 'color': '0,0,0', 'color_border': '0,0,0', 'offset': '0,0', 'size': '1.5', # FIXME 'angle': '0', } square = registry.symbolLayerMetadata( "SimpleMarker").createSymbolLayer(symbol_props) symbol = QgsSymbol.defaultSymbol(layer.geometryType()).clone() symbol.deleteSymbolLayer(0) symbol.appendSymbolLayer(square) symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen)) elif output_type in ['asset_risk', 'input']: # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.EqualInterval else: style_mode = 'EqualInterval' # exposure_strings = ['number', 'occupants', 'value'] # setting exposure colors by default colors = { 'single': RAMP_EXTREME_COLORS['Blues']['top'], 'ramp_name': 'Blues' } inverted = False if output_type == 'asset_risk': damage_strings = perils for damage_string in damage_strings: if damage_string in style_by: colors = { 'single': RAMP_EXTREME_COLORS['Spectral']['top'], 'ramp_name': 'Spectral' } inverted = True break else: # 'input' colors = { 'single': RAMP_EXTREME_COLORS['Greens']['top'], 'ramp_name': 'Greens' } symbol.symbolLayer(0).setShape( QgsSimpleMarkerSymbolLayerBase.Square) single_color = colors['single'] ramp_name = colors['ramp_name'] ramp_type_idx = default_color_ramp_names.index(ramp_name) symbol.setColor(QColor(single_color)) else: raise NotImplementedError( 'Undefined color ramp for output type %s' % output_type) ramp = default_qgs_style.colorRamp( default_color_ramp_names[ramp_type_idx]) if inverted: ramp.invert() # get unique values fni = layer.fields().indexOf(style_by) unique_values = layer.dataProvider().uniqueValues(fni) num_unique_values = len(unique_values - {NULL}) if num_unique_values > 2: if Qgis.QGIS_VERSION_INT < 31000: renderer = QgsGraduatedSymbolRenderer.createRenderer( layer, style_by, min(num_unique_values, style['classes']), style_mode, symbol.clone(), ramp) else: renderer = QgsGraduatedSymbolRenderer(style_by, []) # NOTE: the following returns an instance of one of the # subclasses of QgsClassificationMethod classification_method = \ QgsApplication.classificationMethodRegistry().method( style_mode) renderer.setClassificationMethod(classification_method) renderer.updateColorRamp(ramp) renderer.updateSymbols(symbol.clone()) renderer.updateClasses( layer, min(num_unique_values, style['classes'])) if not use_sgc_style: if Qgis.QGIS_VERSION_INT < 31000: label_format = renderer.labelFormat() # NOTE: the following line might be useful # label_format.setTrimTrailingZeroes(True) label_format.setPrecision(2) renderer.setLabelFormat(label_format, updateRanges=True) else: renderer.classificationMethod().setLabelPrecision(2) renderer.calculateLabelPrecision() elif num_unique_values == 2: categories = [] for unique_value in unique_values: symbol = symbol.clone() try: symbol.setColor( QColor(RAMP_EXTREME_COLORS[ramp_name] ['bottom' if unique_value == min(unique_values) else 'top'])) except Exception: symbol.setColor( QColor(style['color_from'] if unique_value == min(unique_values) else style['color_to'])) category = QgsRendererCategory(unique_value, symbol, str(unique_value)) # entry for the list of category items categories.append(category) renderer = QgsCategorizedSymbolRenderer(style_by, categories) else: renderer = QgsSingleSymbolRenderer(symbol.clone()) if add_null_class and NULL in unique_values: # add a class for NULL values rule_renderer = QgsRuleBasedRenderer(symbol.clone()) root_rule = rule_renderer.rootRule() not_null_rule = root_rule.children()[0].clone() # strip parentheses from stringified color HSL not_null_rule.setFilterExpression( '%s IS NOT NULL' % QgsExpression.quotedColumnRef(style_by)) not_null_rule.setLabel('%s:' % style_by) root_rule.appendChild(not_null_rule) null_rule = root_rule.children()[0].clone() null_rule.setSymbol( QgsFillSymbol.createSimple({ 'color': '160,160,160', 'style': 'diagonal_x' })) null_rule.setFilterExpression( '%s IS NULL' % QgsExpression.quotedColumnRef(style_by)) null_rule.setLabel(tr('No points')) root_rule.appendChild(null_rule) if isinstance(renderer, QgsGraduatedSymbolRenderer): # create value ranges rule_renderer.refineRuleRanges(not_null_rule, renderer) # remove default rule elif isinstance(renderer, QgsCategorizedSymbolRenderer): rule_renderer.refineRuleCategoris(not_null_rule, renderer) for rule in rule_renderer.rootRule().children()[1].children(): label = rule.label() # by default, labels are like: # ('"collapse-structural-ASH_DRY_sum" >= 0.0000 AND # "collapse-structural-ASH_DRY_sum" <= 2.3949') first, second = label.split(" AND ") bottom = first.rsplit(" ", 1)[1] top = second.rsplit(" ", 1)[1] simplified = "%s - %s" % (bottom, top) rule.setLabel(simplified) root_rule.removeChildAt(0) renderer = rule_renderer if render_higher_on_top: renderer.setUsingSymbolLevels(True) symbol_items = [item for item in renderer.legendSymbolItems()] for i in range(len(symbol_items)): sym = symbol_items[i].symbol().clone() key = symbol_items[i].ruleKey() for lay in range(sym.symbolLayerCount()): sym.symbolLayer(lay).setRenderingPass(i) renderer.setLegendSymbolItem(key, sym) layer.setRenderer(renderer) if not use_sgc_style: layer.setOpacity(0.7) if repaint: layer.triggerRepaint() iface.setActiveLayer(layer) iface.zoomToActiveLayer() # NOTE QGIS3: probably not needed # iface.layerTreeView().refreshLayerSymbology(layer.id()) iface.mapCanvas().refresh()
def processAlgorithm(self, # pylint:disable=missing-docstring,too-many-locals,too-many-statements,too-many-branches parameters, context, feedback): input_file = self.parameterAsString(parameters, self.INPUT, context) output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context) embed_pictures = self.parameterAsBool(parameters, self.EMBED_PICTURES, context) convert_fonts = self.parameterAsBool(parameters, self.CONVERT_FONTS, context) parameterize = self.parameterAsBool(parameters, self.PARAMETERIZE, context) units = self.parameterAsEnum(parameters, self.UNITS, context) force_svg = self.parameterAsBool(parameters, self.FORCE_SVG, context) relative_paths = self.parameterAsBool(parameters, self.RELATIVE_PATHS, context) picture_folder = self.parameterAsString(parameters, self.PICTURE_FOLDER, context) if not picture_folder: picture_folder, _ = os.path.split(output_file) mdbtools_folder = ProcessingConfig.getSetting('MDB_PATH') fields = QgsFields() fields.append(QgsField('name', QVariant.String, '', 60)) fields.append(QgsField('warning', QVariant.String, '', 250)) sink, dest = self.parameterAsSink(parameters, self.REPORT, context, fields) style = QgsStyle() style.createMemoryDatabase() results = {} symbol_names = set() def make_name_unique(name): """ Ensures that the symbol name is unique (in a case insensitive way) """ counter = 0 candidate = 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 for type_index, symbol_type in enumerate( (Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS, Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS)): feedback.pushInfo('Importing {} from {}'.format(symbol_type, input_file)) raw_symbols = Extractor.extract_styles(input_file, symbol_type, mdbtools_path=mdbtools_folder) feedback.pushInfo('Found {} symbols of type "{}"\n\n'.format(len(raw_symbols), symbol_type)) if feedback.isCanceled(): break unreadable = 0 for index, raw_symbol in enumerate(raw_symbols): feedback.setProgress(index / len(raw_symbols) * 33.3 + 33.3 * type_index) if feedback.isCanceled(): break name = raw_symbol[Extractor.NAME] tags = raw_symbol[Extractor.TAGS].split(';') feedback.pushInfo('{}/{}: {}'.format(index + 1, len(raw_symbols), name)) unique_name = make_name_unique(name) if name != unique_name: feedback.pushInfo('Corrected to unique name of {}'.format(unique_name)) handle = BytesIO(raw_symbol[Extractor.BLOB]) stream = Stream(handle) f = QgsFeature() try: symbol = stream.read_object() except UnreadableSymbolException as e: feedback.reportError('Error reading symbol {}: {}'.format(name, e)) unreadable += 1 if sink: f.setAttributes([name, 'Error reading symbol: {}'.format(e)]) sink.addFeature(f) continue except NotImplementedException as e: feedback.reportError('Parsing {} is not supported: {}'.format(name, e)) unreadable += 1 if sink: f.setAttributes([name, 'Parsing not supported: {}'.format(e)]) sink.addFeature(f) continue except UnsupportedVersionException as e: feedback.reportError('Cannot read {} version: {}'.format(name, e)) unreadable += 1 if sink: f.setAttributes([name, 'Version not supported: {}'.format(e)]) sink.addFeature(f) continue except UnknownGuidException as e: feedback.reportError(str(e)) unreadable += 1 if sink: f.setAttributes([name, 'Unknown object: {}'.format(e)]) sink.addFeature(f) continue except UnreadablePictureException as e: feedback.reportError(str(e)) unreadable += 1 if sink: f.setAttributes([name, 'Unreadable picture: {}'.format(e)]) sink.addFeature(f) continue self.check_for_unsupported_property(name, symbol, feedback, sink) context = Context() context.symbol_name = unique_name context.picture_folder = picture_folder context.embed_pictures = embed_pictures context.convert_fonts = convert_fonts context.parameterise_svg = parameterize context.force_svg_instead_of_raster = force_svg context.relative_paths = relative_paths context.style_folder, _ = os.path.split(output_file) context.units = QgsUnitTypes.RenderPoints if units == 0 else QgsUnitTypes.RenderMillimeters try: qgis_symbol = Symbol_to_QgsSymbol(symbol, context) except NotImplementedException as e: feedback.reportError(str(e)) unreadable += 1 if sink: f.setAttributes([name, str(e)]) sink.addFeature(f) 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) 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) if symbol_type == Extractor.FILL_SYMBOLS: results[self.FILL_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_FILL_SYMBOLS] = unreadable elif symbol_type == Extractor.LINE_SYMBOLS: results[self.LINE_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_LINE_SYMBOLS] = unreadable elif symbol_type == Extractor.MARKER_SYMBOLS: results[self.MARKER_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_MARKER_SYMBOLS] = unreadable elif symbol_type == Extractor.COLOR_RAMPS: results[self.COLOR_RAMP_COUNT] = len(raw_symbols) results[self.UNREADABLE_COLOR_RAMPS] = unreadable style.exportXml(output_file) results[self.OUTPUT] = output_file results[self.REPORT] = dest return results
def run(self): """ Start the library generation """ patched_xml = ['S_01_081_0017', 'S_01_081_0018', 'S_14_145_0015', 'S_05_019_0001', 'L_19_006_0008', 'L_25_116_0001', 'S_11_042_0013', 'L_21_105_0002', 'L_21_107_0010', 'L_22_092_0003', 'L_22_092_0008', 'L_22_092_0009', 'L_22_092_0010', 'L_22_092_0011', 'L_22_092_0012', 'P_31_159_0002', 'S_01_081_0010', 'S_01_089_0016', 'S_05_017_0008', 'S_10_041_0004', 'S_13_046_0012', 'S_13_046_0018', 'S_14_048_0008', 'S_18_071_0001', 'P_28_157_0001', 'P_32_160_0001', 'P_33_161_0001'] # Symbols for which it exists a manually modified svg patched_svg = ['P_26_120_0015', 'P_33_172_0001', 'P_26_122_0007', 'P_26_124_0004_1', 'L_20_099_0006', 'L_20_099_0007', 'L_20_099_0009', 'L_20_099_0011', 'P_28_157_0001', 'P_32_160_0001', 'P_33_161_0001'] blobs = [] style = QgsStyle() context = Context() context.units = QgsUnitTypes.RenderMillimeters context.relative_paths = True context.picture_folder = os.path.join( self.output_directory, 'svg') context.convert_fonts = True context.force_svg_instead_of_raster = True context.parameterise_svg = False context.embed_pictures = False a = QApplication([]) for fn in os.listdir(self.bin_directory): file = os.path.join(self.bin_directory, fn) if os.path.isfile(file): blobs.append(file) symbol_name = os.path.splitext(fn)[0] with open(file, 'rb') as f: context.symbol_name = symbol_name symbol = read_symbol(f, debug=False) qgis_symbol = Symbol_to_QgsSymbol(symbol, context) if symbol_name in patched_xml: xml_file = os.path.join( self.patched_xml_directory, symbol_name + '.xml') style.importXml(xml_file) print("Patch symbol {} with {}".format( symbol_name, xml_file)) continue style.addSymbol(symbol_name, qgis_symbol) style.exportXml( os.path.join(self.output_directory, 'libreria.xml')) for svg in patched_svg: svg_src = os.path.join(self.patched_svg_directory, svg + '.svg') svg_dest = os.path.join( self.output_directory, 'svg', svg + '.svg') copyfile(svg_src, svg_dest) print("Patch svg {} with {}".format(svg_dest, svg_src))
def processAlgorithm(self, parameters, context, feedback): # pylint: disable=missing-docstring,too-many-locals,too-many-statements,too-many-branches input_file = self.parameterAsString(parameters, self.INPUT, context) output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context) mdbtools_folder = ProcessingConfig.getSetting('MDB_PATH') style = QgsStyle() style.createMemoryDatabase() results = {} symbol_names = set() def make_name_unique(name): """ Ensures that the symbol name is unique (in a case insensitive way) """ counter = 0 candidate = 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 for type_index, symbol_type in enumerate( (Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS, Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS)): feedback.pushInfo('Importing {} from {}'.format( symbol_type, input_file)) raw_symbols = Extractor.extract_styles( input_file, symbol_type, mdbtools_path=mdbtools_folder) feedback.pushInfo('Found {} symbols of type "{}"\n\n'.format( len(raw_symbols), symbol_type)) if feedback.isCanceled(): break unreadable = 0 for index, raw_symbol in enumerate(raw_symbols): feedback.setProgress(index / len(raw_symbols) * 33.3 + 33.3 * type_index) if feedback.isCanceled(): break name = raw_symbol[Extractor.NAME] tags = raw_symbol[Extractor.TAGS].split(';') feedback.pushInfo('{}/{}: {}'.format(index + 1, len(raw_symbols), name)) unique_name = make_name_unique(name) if name != unique_name: feedback.pushInfo( 'Corrected to unique name of {}'.format(unique_name)) handle = BytesIO(raw_symbol[Extractor.BLOB]) stream = Stream(handle) try: symbol = stream.read_object() except UnreadableSymbolException as e: feedback.reportError('Error reading symbol {}: {}'.format( name, e)) unreadable += 1 continue except NotImplementedException as e: feedback.reportError( 'Parsing {} is not supported: {}'.format(name, e)) unreadable += 1 continue except UnsupportedVersionException as e: feedback.reportError('Cannot read {} version: {}'.format( name, e)) unreadable += 1 continue except UnknownGuidException as e: feedback.reportError(str(e)) unreadable += 1 continue self.check_for_unsupported_property(symbol, feedback) try: qgis_symbol = Symbol_to_QgsSymbol(symbol) except NotImplementedException as e: feedback.reportError(str(e)) unreadable += 1 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) 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) if symbol_type == Extractor.FILL_SYMBOLS: results[self.FILL_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_FILL_SYMBOLS] = unreadable elif symbol_type == Extractor.LINE_SYMBOLS: results[self.LINE_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_LINE_SYMBOLS] = unreadable elif symbol_type == Extractor.MARKER_SYMBOLS: results[self.MARKER_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_MARKER_SYMBOLS] = unreadable elif symbol_type == Extractor.COLOR_RAMPS: results[self.COLOR_RAMP_COUNT] = len(raw_symbols) results[self.UNREADABLE_COLOR_RAMPS] = unreadable style.exportXml(output_file) results[self.OUTPUT] = output_file return results
def test_tags_changed(self): style = QgsStyle() style.createMemoryDatabase() model = QgsStyleModel(style) symbol = createMarkerSymbol() self.assertTrue(style.addSymbol('a', symbol, True)) symbol = createMarkerSymbol() self.assertTrue(style.addSymbol('c', symbol, True)) ramp_a = QgsLimitedRandomColorRamp(5) self.assertTrue(style.addColorRamp('ramp a', ramp_a, True)) symbol_B = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('ramp c', symbol_B, True)) self.assertFalse(model.data(model.index(0, 1), Qt.DisplayRole)) self.assertFalse(model.data(model.index(1, 1), Qt.DisplayRole)) self.assertFalse(model.data(model.index(2, 1), Qt.DisplayRole)) self.assertFalse(model.data(model.index(3, 1), Qt.DisplayRole)) style.tagSymbol(QgsStyle.SymbolEntity, 'a', ['t1', 't2']) self.assertEqual(model.data(model.index(0, 1), Qt.DisplayRole), 't1, t2') self.assertFalse(model.data(model.index(1, 1), Qt.DisplayRole)) self.assertFalse(model.data(model.index(2, 1), Qt.DisplayRole)) self.assertFalse(model.data(model.index(3, 1), Qt.DisplayRole)) style.tagSymbol(QgsStyle.SymbolEntity, 'a', ['t3']) self.assertEqual(model.data(model.index(0, 1), Qt.DisplayRole), 't1, t2, t3') self.assertFalse(model.data(model.index(1, 1), Qt.DisplayRole)) self.assertFalse(model.data(model.index(2, 1), Qt.DisplayRole)) self.assertFalse(model.data(model.index(3, 1), Qt.DisplayRole)) style.tagSymbol(QgsStyle.ColorrampEntity, 'ramp a', ['t1', 't2']) self.assertEqual(model.data(model.index(0, 1), Qt.DisplayRole), 't1, t2, t3') self.assertFalse(model.data(model.index(1, 1), Qt.DisplayRole)) self.assertEqual(model.data(model.index(2, 1), Qt.DisplayRole), 't1, t2') self.assertFalse(model.data(model.index(3, 1), Qt.DisplayRole)) style.tagSymbol(QgsStyle.ColorrampEntity, 'ramp c', ['t3']) self.assertEqual(model.data(model.index(0, 1), Qt.DisplayRole), 't1, t2, t3') self.assertFalse(model.data(model.index(1, 1), Qt.DisplayRole)) self.assertEqual(model.data(model.index(2, 1), Qt.DisplayRole), 't1, t2') self.assertEqual(model.data(model.index(3, 1), Qt.DisplayRole), 't3') style.tagSymbol(QgsStyle.SymbolEntity, 'c', ['t4']) self.assertEqual(model.data(model.index(0, 1), Qt.DisplayRole), 't1, t2, t3') self.assertEqual(model.data(model.index(1, 1), Qt.DisplayRole), 't4') self.assertEqual(model.data(model.index(2, 1), Qt.DisplayRole), 't1, t2') self.assertEqual(model.data(model.index(3, 1), Qt.DisplayRole), 't3') style.detagSymbol(QgsStyle.SymbolEntity, 'c', ['t4']) self.assertEqual(model.data(model.index(0, 1), Qt.DisplayRole), 't1, t2, t3') self.assertFalse(model.data(model.index(1, 1), Qt.DisplayRole)) self.assertEqual(model.data(model.index(2, 1), Qt.DisplayRole), 't1, t2') self.assertEqual(model.data(model.index(3, 1), Qt.DisplayRole), 't3') style.detagSymbol(QgsStyle.ColorrampEntity, 'ramp a', ['t1']) self.assertEqual(model.data(model.index(0, 1), Qt.DisplayRole), 't1, t2, t3') self.assertFalse(model.data(model.index(1, 1), Qt.DisplayRole)) self.assertEqual(model.data(model.index(2, 1), Qt.DisplayRole), 't2') self.assertEqual(model.data(model.index(3, 1), Qt.DisplayRole), 't3')
parser = argparse.ArgumentParser() parser.add_argument("file", help="style file to extract", nargs='?') parser.add_argument("destination", help="QGIS symbol XML file destination", nargs='?') args = parser.parse_args() if not args.file: args.file = '/home/nyall/Styles/GEO_Surface___Solid_Shades.style' if not args.destination: args.destination = '/home/nyall/Styles/GEO_Surface___Solid_Shades.xml' styles = [(args.file, Extractor.FILL_SYMBOLS)] style = QgsStyle() for (fill_style_db, symbol_type) in styles: print('{}:{}'.format(fill_style_db, symbol_type)) raw_symbols = Extractor.extract_styles(fill_style_db, symbol_type) print('Found {} symbols of type "{}"\n\n'.format(len(raw_symbols), symbol_type)) for index, raw_symbol in enumerate(raw_symbols): name = raw_symbol[Extractor.NAME] # print('{}/{}: {}'.format(index + 1, len(raw_symbols),name)) handle = BytesIO(raw_symbol[Extractor.BLOB]) try: symbol = read_symbol(file_handle=handle)
def test_filter_proxy(self): style = QgsStyle() style.createMemoryDatabase() symbol_a = createMarkerSymbol() symbol_a.setColor(QColor(255, 10, 10)) self.assertTrue(style.addSymbol('a', symbol_a, True)) style.tagSymbol(QgsStyle.SymbolEntity, 'a', ['tag 1', 'tag 2']) symbol_B = createMarkerSymbol() symbol_B.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('BB', symbol_B, True)) symbol_b = createFillSymbol() symbol_b.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('b', symbol_b, True)) symbol_C = createLineSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('C', symbol_C, True)) style.tagSymbol(QgsStyle.SymbolEntity, 'C', ['tag 3']) symbol_C = createMarkerSymbol() symbol_C.setColor(QColor(10, 255, 10)) self.assertTrue(style.addSymbol('another', symbol_C, True)) ramp_a = QgsLimitedRandomColorRamp(5) self.assertTrue(style.addColorRamp('ramp a', ramp_a, True)) style.tagSymbol(QgsStyle.ColorrampEntity, 'ramp a', ['tag 1', 'tag 2']) symbol_B = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('ramp BB', symbol_B, True)) symbol_b = QgsLimitedRandomColorRamp() self.assertTrue(style.addColorRamp('ramp c', symbol_b, True)) model = QgsStyleProxyModel(style) self.assertEqual(model.rowCount(), 8) # filter string model.setFilterString('xx') self.assertEqual(model.filterString(), 'xx') self.assertEqual(model.rowCount(), 0) model.setFilterString('b') self.assertEqual(model.rowCount(), 3) self.assertEqual(model.data(model.index(0, 0)), 'b') self.assertEqual(model.data(model.index(1, 0)), 'BB') self.assertEqual(model.data(model.index(2, 0)), 'ramp BB') model.setFilterString('bb') self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'BB') self.assertEqual(model.data(model.index(1, 0)), 'ramp BB') model.setFilterString('tag 1') self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'ramp a') model.setFilterString('TAG 1') self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'ramp a') model.setFilterString('ram b') self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'ramp BB') model.setFilterString('ta ram') # match ta -> "tag 1", ram -> "ramp a" self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'ramp a') model.setFilterString('') self.assertEqual(model.rowCount(), 8) # entity type model.setEntityFilter(QgsStyle.SymbolEntity) self.assertEqual(model.rowCount(), 8) model.setEntityFilter(QgsStyle.ColorrampEntity) self.assertEqual(model.rowCount(), 8) model.setEntityFilterEnabled(True) self.assertEqual(model.rowCount(), 3) self.assertEqual(model.data(model.index(0, 0)), 'ramp a') self.assertEqual(model.data(model.index(1, 0)), 'ramp BB') self.assertEqual(model.data(model.index(2, 0)), 'ramp c') model.setFilterString('BB') self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'ramp BB') model.setFilterString('') model.setEntityFilter(QgsStyle.SymbolEntity) self.assertEqual(model.rowCount(), 5) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'another') self.assertEqual(model.data(model.index(2, 0)), 'b') self.assertEqual(model.data(model.index(3, 0)), 'BB') self.assertEqual(model.data(model.index(4, 0)), 'C') model.setFilterString('ot') self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'another') model.setFilterString('') model.setEntityFilterEnabled(False) self.assertEqual(model.rowCount(), 8) # symbol type filter model.setSymbolType(QgsSymbol.Line) self.assertEqual(model.rowCount(), 8) model.setSymbolType(QgsSymbol.Marker) self.assertEqual(model.rowCount(), 8) model.setSymbolTypeFilterEnabled(True) self.assertEqual(model.rowCount(), 6) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'another') self.assertEqual(model.data(model.index(2, 0)), 'BB') self.assertEqual(model.data(model.index(3, 0)), 'ramp a') self.assertEqual(model.data(model.index(4, 0)), 'ramp BB') model.setEntityFilterEnabled(True) self.assertEqual(model.rowCount(), 3) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'another') self.assertEqual(model.data(model.index(2, 0)), 'BB') model.setFilterString('oth') self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'another') model.setEntityFilterEnabled(False) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'another') model.setEntityFilterEnabled(True) model.setFilterString('') model.setSymbolType(QgsSymbol.Line) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'C') model.setSymbolType(QgsSymbol.Fill) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'b') model.setSymbolTypeFilterEnabled(False) model.setEntityFilterEnabled(False) self.assertEqual(model.rowCount(), 8) # tag filter self.assertEqual(model.tagId(), -1) tag_1_id = style.tagId('tag 1') tag_3_id = style.tagId('tag 3') model.setTagId(tag_1_id) self.assertEqual(model.tagId(), tag_1_id) self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'ramp a') model.setEntityFilterEnabled(True) model.setEntityFilter(QgsStyle.ColorrampEntity) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'ramp a') model.setEntityFilterEnabled(False) model.setFilterString('ra') self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'ramp a') model.setEntityFilterEnabled(False) model.setFilterString('') model.setTagId(-1) self.assertEqual(model.rowCount(), 8) model.setTagId(tag_3_id) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'C') style.tagSymbol(QgsStyle.ColorrampEntity, 'ramp c', ['tag 3']) self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'C') self.assertEqual(model.data(model.index(1, 0)), 'ramp c') style.detagSymbol(QgsStyle.ColorrampEntity, 'ramp c') self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'C') model.setTagId(-1) self.assertEqual(model.rowCount(), 8) # favorite filter style.addFavorite(QgsStyle.ColorrampEntity, 'ramp c') style.addFavorite(QgsStyle.SymbolEntity, 'another') self.assertEqual(model.favoritesOnly(), False) model.setFavoritesOnly(True) self.assertEqual(model.favoritesOnly(), True) self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'another') self.assertEqual(model.data(model.index(1, 0)), 'ramp c') model.setEntityFilterEnabled(True) model.setEntityFilter(QgsStyle.ColorrampEntity) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'ramp c') model.setEntityFilterEnabled(False) model.setFilterString('er') self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'another') model.setEntityFilterEnabled(False) model.setFilterString('') self.assertEqual(model.rowCount(), 2) style.addFavorite(QgsStyle.ColorrampEntity, 'ramp a') self.assertEqual(model.rowCount(), 3) self.assertEqual(model.data(model.index(0, 0)), 'another') self.assertEqual(model.data(model.index(1, 0)), 'ramp a') self.assertEqual(model.data(model.index(2, 0)), 'ramp c') style.removeFavorite(QgsStyle.ColorrampEntity, 'ramp a') self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'another') self.assertEqual(model.data(model.index(1, 0)), 'ramp c') style.addFavorite(QgsStyle.SymbolEntity, 'BB') self.assertEqual(model.rowCount(), 3) self.assertEqual(model.data(model.index(0, 0)), 'another') self.assertEqual(model.data(model.index(1, 0)), 'BB') self.assertEqual(model.data(model.index(2, 0)), 'ramp c') style.removeFavorite(QgsStyle.SymbolEntity, 'another') self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'BB') self.assertEqual(model.data(model.index(1, 0)), 'ramp c') model.setFavoritesOnly(False) self.assertEqual(model.rowCount(), 8) # smart group filter style.addSmartgroup('smart', 'AND', ['tag 3'], [], ['c'], []) self.assertEqual(model.smartGroupId(), -1) model.setSmartGroupId(1) self.assertEqual(model.smartGroupId(), 1) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.data(model.index(0, 0)), 'C') style.addSmartgroup('smart', 'OR', ['tag 3'], [], ['c'], []) model.setSmartGroupId(2) self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'C') self.assertEqual(model.data(model.index(1, 0)), 'ramp c') style.tagSymbol(QgsStyle.SymbolEntity, 'a', ['tag 3']) self.assertEqual(model.rowCount(), 3) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'C') self.assertEqual(model.data(model.index(2, 0)), 'ramp c') style.renameColorRamp('ramp c', 'x') self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), 'a') self.assertEqual(model.data(model.index(1, 0)), 'C') model.setSmartGroupId(-1) self.assertEqual(model.rowCount(), 8)
def processAlgorithm(self, parameters, context, feedback): project = QgsProject() project.setFileName( os.path.join(parameters[self.FOLDER], "all-outputs-qgis.qgs")) project.setCrs(QgsCoordinateReferenceSystem('EPSG:27700')) def getMaxValue(layer, fieldname): maxfound = float("-inf") for f in layer.getFeatures(): attr = f.attribute(fieldname) assert attr >= 0 if attr > maxfound: maxfound = attr return maxfound with open( os.path.join(parameters[self.FOLDER], "all-town-metadata.json")) as f: metadata = json.load(f) classmethods = { 'quantile': QgsClassificationQuantile, 'jenks': QgsClassificationJenks, 'equal': QgsClassificationEqualInterval } html = "" output = [] views_sorted_by_mode = sorted(metadata["views"], key=lambda v: v["mode"]) for view in views_sorted_by_mode: keysymbol = u'🔑' viewname = view["label"] keysign = "" if viewname.find(keysymbol) != -1: viewname = viewname.replace(keysymbol, '', 1) keysign = "*** " viewname = keysign + view["mode"] + " " + viewname html += f""" <h2>{viewname}</h2> {view["description"]} <ul> """ for layer in view["layers"]: layername = viewname + " - " + layer["scalar_field_units"] layerpath = os.path.join(parameters[self.FOLDER], layer["file"]) vlayer = QgsVectorLayer(layerpath, layername, "ogr") if not vlayer.isValid(): feedback.pushInfo("Layer failed to load: " + layerpath) else: context.temporaryLayerStore().addMapLayer(vlayer) html += f"""<li><b>file:</b> {layer["file"]}""" if "symbol_field" in layer: html += f"""<ul> <li><b>symbol field:</b> {layer["symbol_field"]} </ul> """ categories = [] scalar_fieldname = layer["scalar_field"] maxvalue = getMaxValue(vlayer, scalar_fieldname) feedback.pushInfo("Max value for %s is %f" % (scalar_fieldname, maxvalue)) for formality in ["I", "F"]: for severity, colour in [(3, 'red'), (2, 'yellow'), (1, 'green')]: colour = { ("I", "red"): "#FF0000", ("I", "yellow"): "#FFFF00", ("I", "green"): "#00FF00", ("F", "red"): "#FF9999", ("F", "yellow"): "#FFFF66", ("F", "green"): "#99FF99", }[(formality, colour)] symbol_code = "%s%d" % (formality, severity) if formality == "F": symbol = QgsMarkerSymbol.createSimple({ 'color': colour, 'size': '3', 'outline_color': '#888888' }) else: assert (formality == "I") symbol = QgsMarkerSymbol.createSimple({ 'color': colour, 'size': '3', 'outline_color': '#000000', 'name': 'star' }) objTransf = QgsSizeScaleTransformer( QgsSizeScaleTransformer.Flannery, 0, #minvalue maxvalue, #maxvalue 3, #minsize 10, #maxsize 0, #nullsize 1) #exponent objProp = QgsProperty() objProp.setField(scalar_fieldname) objProp.setTransformer(objTransf) symbol.setDataDefinedSize(objProp) label = { "F": "Formal", "I": "Informal" }[formality] + " " + { 3: "Major", 2: "Secondary", 1: "Tertiary" }[severity] cat = QgsRendererCategory( symbol_code, symbol, label, True) categories.append(cat) renderer = QgsCategorizedSymbolRenderer( "Crossings", categories) renderer.setClassAttribute(layer["symbol_field"]) vlayer.setRenderer(renderer) else: html += f"""<ul> <li><b>field:</b> {layer["scalar_field"]} <li><b>units:</b> {layer["scalar_field_units"]} <li><b>recommended classification:</b> {layer["classes"]} </ul> """ default_style = QgsStyle().defaultStyle() color_ramp = default_style.colorRamp('bt') renderer = QgsGraduatedSymbolRenderer() renderer.setClassAttribute(layer["scalar_field"]) classmethod = classmethods[layer["classes"]]() renderer.setClassificationMethod(classmethod) renderer.updateClasses(vlayer, 5) renderer.updateColorRamp(color_ramp) vlayer.setRenderer(renderer) project.addMapLayer(vlayer) feedback.pushInfo("Loaded " + layerpath) html += "</ul>" project.write() town = views_sorted_by_mode[0]["town"] with open(os.path.join(parameters[self.FOLDER], "metadata.html"), "w") as htmlfile: htmlfile.write( f"<html><head><title>{town} metadata</title></head><body><h1>{town}</h1>{html}</body></html>" ) return {self.OUTPUT: output}