def styleMap(self): categories = [] for cat in range(0, self.districts + 1): symbol = QgsSymbol.defaultSymbol(self.activeLayer.geometryType()) layer_style = {} layer_style['color'] = '%d, %d, %d' % (randrange( 0, 256), randrange(0, 256), randrange(0, 256)) layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object if cat == 0: category = QgsRendererCategory("", symbol, "") else: category = QgsRendererCategory(districtName[cat], symbol, str(districtName[cat])) # entry for the list of category items categories.append(category) renderer = QgsCategorizedSymbolRenderer(self.distfield, categories) # assign the created renderer to the layer if renderer is not None: self.activeLayer.setRenderer(renderer) self.activeLayer.triggerRepaint()
def set_style_mapzones(self): extras = f'"mapzones":""' body = self.create_body(extras=extras) # self.controller.log_info(f"SELECT gw_fct_getstylemapzones ({body})") json_return = self.controller.get_json('gw_fct_getstylemapzones', body) if not json_return: return False for mapzone in json_return['body']['data']['mapzones']: # self.controller.log_info(f"Mapzone: ({mapzone})") # Loop for each mapzone returned on json lyr = self.controller.get_layer_by_tablename(mapzone['layer']) categories = [] status = mapzone['status'] if status == 'Disable': pass if lyr: # Loop for each id returned on json for id in mapzone['values']: # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(lyr.geometryType()) symbol.setOpacity(float(mapzone['opacity'])) # Setting simp R = random.randint(0, 255) G = random.randint(0, 255) B = random.randint(0, 255) if status == 'Stylesheet': try: R = id['stylesheet']['color'][0] G = id['stylesheet']['color'][1] B = id['stylesheet']['color'][2] except TypeError: R = random.randint(0, 255) G = random.randint(0, 255) B = random.randint(0, 255) elif status == 'Random': R = random.randint(0, 255) G = random.randint(0, 255) B = random.randint(0, 255) # Setting sytle layer_style = {'color': '{}, {}, {}'.format(int(R), int(G), int(B))} symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) category = QgsRendererCategory(id['id'], symbol, str(id['id'])) categories.append(category) # apply symbol to layer renderer lyr.setRenderer(QgsCategorizedSymbolRenderer(mapzone['idname'], categories)) # repaint layer lyr.triggerRepaint()
def set_category_renderer(layer: QgsVectorLayer, column: str, start_color: Tuple[int, int, int], end_color: Tuple[int, int, int], unit: str = ''): ''' apply a category renderer to a layer. The categories will be the unique values of the given column with interpolated colors between given start and end color Parameters ---------- layer : QgsVectorLayer layer to apply the renderer to column : str name of the column containing the categories start_color : tuple rgb values of the first color in the color range end_color : tuple rgb values of the last color in the color range unit : str a unit to be added to the category label, defaults to no unit ''' idx = layer.fields().indexOf(column) unique_values = list(layer.uniqueValues(idx)) unique_values.sort() categories = [] geometry_type = layer.geometryType() for i, value in enumerate(unique_values): # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(geometry_type) # configure a symbol layer layer_style = {} rgb = [] for c in range(3): rgb.append(str(int(interpolate(start_color[c], end_color[c], i, len(unique_values))))) layer_style['color'] = ','.join(rgb) #layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(value, symbol, f'{value} {unit}') # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer(column, categories) layer.setRenderer(renderer)
def vector_apply_unique_value_renderer(vector_layer, column): """Apply colours to each unique value for a vector layer column. source: https://gis.stackexchange.com/a/175114 Args: vector_layer (QgsVectorLayer): A vector layer to apply unique symbology to. column (str): The column containing the unique values """ categories = [] uniq_vals = vector_layer.dataProvider().uniqueValues( vector_layer.fields().lookupField(column)) randcolors = random_colours(len(uniq_vals)) for i, ea_value in enumerate(sorted(uniq_vals)): # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(vector_layer.geometryType()) # configure a symbol layer layer_style = { 'color': '{}, {}, {}'.format(*randcolors[i]), 'outline': '#000000' } symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(ea_value, symbol, str(ea_value)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer(column, categories) # assign the created renderer to the layer if renderer is not None: vector_layer.setRenderer(renderer) # refresh vector_layer.triggerRepaint()
def categorize_layer(self, layer=None, attr='class', layer_name='Cyano_merged'): """ :param attr: :return: """ if not layer: layer = self.get_layer_by_name(layer_name) try: attr_idx = layer.fields().indexFromName(attr) except: attr_idx = 0 unique_values = layer.uniqueValues(attr_idx) categories = [] color_map = {0: '0, 0, 0', 1: '187, 187, 187', 2: '255, 255, 26', 3: '247, 126, 60', 4: '0, 0, 0'} color_map_hex = {0: '#000000', 1: '#bbbbbb', 2: '#ffff1a', 3: '#f77e3c', 4: '#000000'} for value in unique_values: symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # configure a symbol layer layer_style = {'color': color_map[value], 'outline': color_map_hex[value]} symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(value, symbol, str(value)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer(attr, categories) # assign the created renderer to the layer if renderer is not None: layer.setRenderer(renderer) layer.triggerRepaint()
def style_categorized(self, layer=None, style_by=None): if layer is None: layer = self.layer if style_by is None: style_by = self.default_field_name # get unique values fni = layer.fields().indexOf(style_by) unique_values = layer.dataProvider().uniqueValues(fni) # define categories categories = [] for unique_value in unique_values: # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # configure a symbol layer layer_style = {} layer_style['color'] = '%d, %d, %d' % (randrange( 0, 256), randrange(0, 256), randrange(0, 256)) layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(unique_value, symbol, str(unique_value)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer(style_by, categories) # assign the created renderer to the layer if renderer is not None: layer.setRenderer(renderer) layer.triggerRepaint() # NOTE QGIS3: probably not needed # self.iface.layerTreeView().refreshLayerSymbology(layer.id()) self.iface.mapCanvas().refresh()
categories = [] count = 0 iteration = 1 for unique_value in unique_values: count += 1 for unique_value in unique_values: symbol = QgsSymbol.defaultSymbol(layer.geometryType()) layer_style = {} increase = 256 / count layer_style['color'] = '%d, %d, %d' % (0, (256 - (iteration * (increase / 2))), 0) """layer_style['color'] = '%d, %d, %d' % (randrange(0,256), randrange(0,256), randrange(0,256))""" layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) category = QgsRendererCategory(unique_value, symbol, str(unique_value)) categories.append(category) iteration += 1 renderer = QgsCategorizedSymbolRenderer('ffh_typ_text', categories) if renderer is not None: valuableIntersected.setRenderer(renderer) valuableIntersected.triggerRepaint() """We do the same for the non-valuable habitats"""
def unionespacial(self, event): # Datos de viviendas de catastro bu = self.input_gml.filePath() # Datos de perímetros de núcleos de población EIEL nucleo = self.input_shp.filePath() # Unir aributos por localización: Viviendas y núcleos bu_output = 'C:/V_EIEL/viviendasclasificadas.shp' processing.run( "qgis:joinattributesbylocation", { 'INPUT': bu, 'JOIN': nucleo, 'PREDICATE': 0, 'JOIN_FIELDS': ['CODIGO', 'DENOMINACI'], 'METHOD': 0, 'PREFIX': 'NU_', 'OUTPUT': bu_output }) joinat = QgsVectorLayer(bu_output, "Viviendas clasificadas nucleo", "ogr") QgsProject.instance().addMapLayers([joinat]) # Selecciono registros sin clasificar de la capa de viviendas clasificadas utilizando la capa núcleos expresion = "NU_CODIGO is NULL" joinat.selectByExpression(expresion, QgsVectorLayer.SetSelection) #Genero el buffer de la capa núcleos nucleo = self.input_shp.filePath() file_output = 'C:/V_EIEL/buffernucleo.shp' processing.run( "native:buffer", { 'INPUT': nucleo, 'DISTANCE': 200, 'SEGMENTS': 10, 'DISSOLVE': False, 'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 1, 'OUTPUT': file_output }) lyrBuffer = QgsVectorLayer(file_output, "Buffer nucleo", "ogr") QgsProject.instance().addMapLayers([lyrBuffer]) # Unión espacial de los registros seleccionados de joinat con buffer bu_output_2 = 'C:/V_EIEL/viviendasclasificadas_2.shp' processing.run( "qgis:joinattributesbylocation", { 'INPUT': QgsProcessingFeatureSourceDefinition( 'Viviendas clasificadas nucleo', True), 'JOIN': lyrBuffer, 'PREDICATE': 0, 'JOIN_FIELDS': ['CODIGO', 'DENOMINACI'], 'METHOD': 0, 'PREFIX': 'NU_', 'OUTPUT': bu_output_2 }) joinat_2 = QgsVectorLayer(bu_output_2, "Viviendas clasificadas buffer", "ogr") QgsProject.instance().addMapLayers([joinat_2]) joinat.removeSelection() joinat.commitChanges() # El resto de viviendas no clasificadas mediante la union con capa buffer pasan a estar en diseminado joinat_2 = iface.activeLayer() expresion_2 = "NU_CODIGO_ is NULL" joinat_2.selectByExpression(expresion_2, QgsVectorLayer.SetSelection) joinat_2.startEditing() n = joinat_2.selectedFeatureCount() for i in range(0, n): diseminado = joinat_2.selectedFeatures() viv_diseminado = diseminado[i] viv_diseminado.setAttribute("NU_CODIGO_", "99") viv_diseminado["NU_CODIGO_"] = "99" joinat_2.updateFeature(viv_diseminado) viv_diseminado.setAttribute("NU_DENOM_1", "DISEMINADO") viv_diseminado["NU_DENOM_1"] = "DISEMINADO" joinat_2.updateFeature(viv_diseminado) joinat_2.commitChanges() joinat_2.removeSelection() joinat_2.startEditing() features = joinat_2.getFeatures() for feature in features: feature.setAttribute(feature.fieldNameIndex('NU_CODIGO'), feature['NU_CODIGO_']) feature.setAttribute(feature.fieldNameIndex('NU_DENOMIN'), feature['NU_DENOM_1']) joinat_2.updateFeature(feature) joinat_2.commitChanges() joinat_2.removeSelection() # Elimino los campos NU_CODIGO_ y NU_DENOM_1 para conservar la misma estructura en las dos capas joint attributes joinat_2.startEditing() joinat_2.deleteAttributes([27, 28]) joinat_2.updateFields() joinat_2.commitChanges() # Creo la capa union de Viviendas clasificadas nucleo(solo la selección) y viviendas clasificadas buffer # En primer lugar extraigo las viviendas clasificadas en la union con la capa nucleos expresion_3 = "NU_CODIGO is not NULL" joinat.selectByExpression(expresion_3, QgsVectorLayer.SetSelection) joinat.startEditing() seleccion = 'C:/V_EIEL/viviendasclasificadas_seleccion.shp' processing.run("native:saveselectedfeatures", { 'INPUT': joinat, 'OUTPUT': seleccion }) nucleo_seleccion = QgsVectorLayer( seleccion, "Viviendas clasificadas nucleo seleccion", "ogr") QgsProject.instance().addMapLayers([nucleo_seleccion]) joinat.removeSelection() resultado = 'C:/V_EIEL/viviendasclasificadas_resultado.shp' processing.run("native:mergevectorlayers", { 'LAYERS': [nucleo_seleccion, joinat_2], 'OUTPUT': resultado }) resultado_merge = QgsVectorLayer(resultado, "Viviendas clasificadas", "ogr") QgsProject.instance().addMapLayers([resultado_merge]) # Suprimo del proyecto todas las capas intermedias generadas en el proceso QgsProject.instance().removeMapLayer(nucleo_seleccion) QgsProject.instance().removeMapLayer(joinat_2) QgsProject.instance().removeMapLayer(joinat) QgsProject.instance().removeMapLayer(lyrBuffer) #Representación categorizada de la capa resultado #Valores únicos resultado_merge = iface.activeLayer() valoresnucleo = [] unico = resultado_merge.dataProvider() campos = unico.fields() id = campos.indexFromName('NU_DENOMIN') valoresnucleo = unico.uniqueValues(id) #Creación de categorías categorias = [] for valornucleo in valoresnucleo: # inicio el valor de símbolo por defecto para la geometría tipo symbol = QgsSymbol.defaultSymbol(resultado_merge.geometryType()) # configuración de capa de simbología layer_style = {} layer_style['color'] = '%d, %d, %d' % (random.randint( 0, 256), random.randint(0, 256), random.randint(0, 256)) layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # sustitución de simbología por defecto por simbología configurada if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # creación de objeto renderer categoria = QgsRendererCategory(valornucleo, symbol, str(valornucleo)) # generación de entrada para la lista de categorías categorias.append(categoria) renderer = QgsCategorizedSymbolRenderer('NU_DENOMIN', categorias) # asignación del renderer a la capa if renderer is not None: resultado_merge.setRenderer(renderer) resultado_merge.triggerRepaint() # Cálculo de estadísticas resultado = iface.activeLayer() estadisticas = 'C:/V_EIEL/estadisticas.csv' processing.run( "qgis:statisticsbycategories", { 'CATEGORIES_FIELD_NAME': ['NU_DENOMIN', 'NU_CODIGO'], 'INPUT': 'Viviendas clasificadas', 'OUTPUT': 'C:/V_EIEL/estadisticas.csv', 'VALUES_FIELD_NAME': 'numberOfDw', }) # Cargo datos calculados de estadísticas de distribución de viviendas en QTableWidget tbl_resultados with open(estadisticas, 'r') as leer_estadisticas: registros = leer_estadisticas.read().splitlines() contar = 0 #Descarto la primera linea del archivo por contener las cabeceras de los campos for registro in registros: r = 0 if contar > 0: campos = registro.split(',') #Puesto que el campo codigo se almacena con "" las elimino para que no aparezcan en la tabla sc = campos[1].lstrip('"').rstrip('"') #Cargo datos del csv en Qtable widget self.tbl_resultados.insertRow(r) self.tbl_resultados.setItem(r, 0, QTableWidgetItem(str(sc))) self.tbl_resultados.setItem( r, 1, QTableWidgetItem(str(campos[0]))) self.tbl_resultados.setItem( r, 2, QTableWidgetItem(str(campos[7]))) r = r + 1 contar = contar + 1 # Rastreo de registros duplicados en capa resultado por intersectar con dos buffer o dos núcleos features = resultado_merge.getFeatures() referencias = [] referencias_dup = [] for f in features: idr = f.fieldNameIndex('reference') referencia = f.attribute(idr) if referencia not in referencias: referencias.append(referencia) else: referencias_dup.append(referencia) self.lst_duplicados.addItems(referencias_dup) total_duplicados = self.lst_duplicados.count() self.text_duplicados.append(str(total_duplicados))
def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ # Retrieve the feature source and sink. The 'dest_id' variable is used # to uniquely identify the feature sink, and must be included in the # dictionary returned by the processAlgorithm function. source = self.parameterAsSource(parameters, self.INPUT_SHP, context) sourcecsv = self.parameterAsSource(parameters, self.INPUT_CSV, context) # If source was not found, throw an exception to indicate that the algorithm # encountered a fatal error. The exception text can be any string, but in this # case we use the pre-built invalidSourceError method to return a standard # helper text for when a source cannot be evaluated if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, source.fields(), source.wkbType(), source.sourceCrs()) # Send some information to the user # feedback.pushInfo('CRS is {}'.format(source.sourceCrs().authid())) # chosenFile = self.parameterDefinition('OUTPUT').valueAsPythonString(parameters['OUTPUT'], context) #outfilepath = os.path.dirname #feedback.pushInfo(outfilepath) chosenFile = self.parameterDefinition('OUTPUT').valueAsPythonString( parameters['OUTPUT'], context) filepath = os.path.dirname(chosenFile[1:]) + '/' feedback.pushInfo(filepath) joindict = { 'INPUT': parameters[self.INPUT_SHP], 'FIELD': 'ABSLGACODE', 'INPUT_2': parameters[self.INPUT_CSV], 'FIELD_2': 'LGAcode', 'METHOD': 0, 'DISCARD_NONMATCHING': True, 'PREFIX': 'JOINED', 'OUTPUT': 'memory' } join_layer = processing.run('qgis:joinattributestable', joindict) layers = self.QgsMapLayerRegistry.instance().mapLayers().values() allFeatures = [] for l in layers: for f in l.getFeatures(): allFeatures.append(f.geometry()) features = join_layer.getFeatures() for feature in features: new_feature = QgsFeature() # Set geometry to dissolved geometry new_feature.setGeometry(f.geometry()) # Set attributes from sum_unique_values dictionary that we had computed new_feature.setAttributes( [f[ABSLGACODE], sum_unique_values[f[ABSLGACODE]]]) sink.addFeature(new_feature, QgsFeatureSink.FastInsert) self.OUTPUT.dataProvider().addAttributes( [QgsField('65+', QVariant.String)]) self.OUTPUT.updateFields() self.OUTPUT.commitChanges() features = self.OUTPUT.getFeatures() for feature in features: lgastats.startEditing() elderly = feature['JOINED65+%'] old = feature['65+'] if float(elderly) > 35: old = 'VERY HIGH' elif float(elderly) > 25: old = 'HIGH' elif float(elderly) > 20: old = 'MEDIUM' elif float(elderly) > 15: old = 'LOW' else: old = 'VERY LOW' feature['65+'] = old self.OUTPUT.updateFeature(feature) self.OUTPUT.commitChanges() fni = self.OUTPUT.fields().indexFromName('65+') unique_ids = self.OUTPUT.dataProvider().uniqueValues(fni) QgsMessageLog.logMessage("sstyle for run layer..." + str(unique_ids)) categories = [] for unique_id in unique_ids: # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(lgastats.geometryType()) symbol.setOpacity(0.5) layer_style = {} layer_style['color'] = '%d, %d, %d' % (random.randrange( 0, 256), random.randrange(0, 256), random.randrange(0, 256)) layer_style['outline'] = '#000000' symbolLayer = QgsSimpleFillSymbolLayer.create(layer_style) if symbolLayer is not None: symbol.changeSymbolLayer(0, symbolLayer) category = QgsRendererCategory(unique_id, symbol, str(unique_id)) categories.append(category) renderer = QgsCategorizedSymbolRenderer('65+', categories) # assign the created renderer to the layer if renderer is not None: self.OUTPUT.setRenderer(renderer) self.OUTPUT.triggerRepaint() return {self.OUTPUT: dest_id}
def stylize_map(layer: QgsVectorLayer) -> [List[str], List[str]]: """Stylize the layer with unique colors per timezone Args: layer (QgsVectorLayer): The layer to stylize Returns: [List[str], List[str]]: A list with all timezone ids and one with the respective color """ print("Reading timezones from file") timezones = layer.uniqueValues(layer.fields().indexOf("tzid")) timezones = list(timezones) timezones.sort() categorized_renderer = QgsCategorizedSymbolRenderer() print("Stylizing map") timezone_ids = [] timezone_colors = [] features = layer.getFeatures() categories = [] currentColor = 0 for tz in timezones: # Modify the Etc timezones to match the Qt format qt_tz = tz # There are a few exceptions where the Qt timezone ids differ from the dataset ids: match = re.match(r"Etc/GMT([+-])(\d+)", tz) if match: qt_tz = f"UTC{match.group(1)}{match.group(2):0>2}:00" elif tz == "Etc/UTC": qt_tz = "UTC" elif tz == "Etc/GMT": qt_tz = "UTC+00:00" # Generate a consecutive color for each timezone currentColor += 25000 r = (currentColor >> 16) & 255 g = (currentColor >> 8 ) & 255 b = (currentColor ) & 255 # Add it to the mapping rh = hex(r)[2:] gh = hex(g)[2:] bh = hex(b)[2:] timezone_ids.append(qt_tz) timezone_colors.append(f"#{rh:0>2}{gh:0>2}{bh:0>2}") symbol = QgsSymbol.defaultSymbol(layer.geometryType()) symbol_layer = QgsSimpleFillSymbolLayer.create({"color": f"{r}, {g}, {b}"}) symbol_layer.setStrokeWidth(0.0) symbol_layer.setStrokeStyle(Qt.PenStyle.NoPen) symbol.changeSymbolLayer(0, symbol_layer) category = QgsRendererCategory(tz, symbol, tz) categories.append(category) renderer = QgsCategorizedSymbolRenderer("tzid", categories) layer.setRenderer(renderer) layer.triggerRepaint() return timezone_ids, timezone_colors