Gruppo Custom↵
Abstract
Questo gruppo contiene funzioni Python create dall'utente.
Le funzioni vanno salvate in file *.py nella cartella espression
presente nel profilo utente QGIS (C:\Users\nomeUtente\AppData\Roaming\QGIS\QGIS3\profiles\default\python\expressions)
Un ringraziamento particolare a Giulio Fattori, autore di molte di queste funzioni personalizzate
fattoriale↵
Calcola il fattoriale di un numero definito come il prodotto di tutti i numeri tra 1 e n. Per convenzione il fattoriale di 0 = 1 la notazione matematica per fattoriale è n! La funzione è compresa nel modulo math NB: valore massimo memorizzabile in un campo numerico è 20! (2432902008176640000)
Sintassi:
- fact(numero)
Argomenti:
- numero un numero intero
Esempio:
Codice Python:
from qgis.core import *
from qgis.gui import *
import math
@qgsfunction(args='auto', group='Custom')
def fact(n, feature, parent):
"""
Calcola il fattoriale di un numero
definito come il prodotto di tutti
i numeri tra 1 e n.<ul> </ul>
Per convenzione il fattoriale di 0 = 1
la notazione matematica per fattoriale è n!
La funzione è compresa nel modulo math
NB: valore massimo memorizzabile 20!
<ul> </ul>
<h2>Example usage:</h2>
<ul>
<li>Fattoriale(5) -> 120</li>
<li>in simboli 5! = 120</li>
</ul>
"""
return math.factorial(n)
Lo script Python è stato realizzato da Giulio Fattori
my_sum↵
Calcola la somma dei due parametri valore1 e valore2.
Sintassi:
- my_sum(numero1, numero2)
Argomenti:
- numero1_ un valore numerico o un campo
- numero2 un valore numerico o un campo Esempio:
Codice Python:
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom')
def my_sum(value1, value2, feature, parent):
"""
Calcola la somma dei due parametri valore1 e valore2.
<h2>Esempio di utilizzo:</h2>
<ul>
<li>my_sum(5, 8) -> 13</li>
<li>my_sum("fiel1", "field2") -> 42</li>
</ul>
"""
return value1 + value2
perimetro_km↵
Questa funzione ritorna il valore del perimetro della geometria in km
Sintassi:
- perimetro_km()
Argomenti:
- senza argomenti
Esempio:
Codice Python:
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom')
def perimetro_km( feature, parent):
"""
Questa funzione ritorna il valore del perimetro della geometria in km
<ul>
<li>perimetro_km() - > 25</li>
</ul>
"""
geom_perimetro_km = feature.geometry().length()/1000
return geom_perimetro_km
reverse_string↵
Questa funzione ritorna il valore rovesciato di un testo
Sintassi:
- reverse_string(stringa)
Argomenti:
- stringa una stringa di testo Esempio:
Codice Python:
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom')
def reverse_string(string_to_reverse, feature, parent):
"""
Questa funzione ritorna il valore rovesciato di un testo
<ul>
<li>reverse_string('Pigrecoinfinito) - > 'otinifniocergiP'</li>
</ul>
"""
return string_to_reverse[::-1]
get_parcel_info↵
WMS Catasto Agenzia delle Entrate CC BY 4.0:
La funzione, tramite una richiesta GetFeatureInfo, restituisce le informazioni utili sulla particella che ricade sotto il pixel di mio interesse:
Sintassi:
- get_parcel_info(x,y)
Argomenti:
- x coordinata x di un punto
- y coordinata x di un punto
Esempio:
codice Python:
# -*- coding: utf-8 -*-
"""
/***************************************************************************
WMS Catasto Agenzia delle Entrate CC BY 4.0
-------------------
copyright : (C) 2020 by Giulio Fattori
email : xxxxxxxxxxxxx
***************************************************************************/
"""
from qgis.core import *
from qgis.gui import *
import requests
@qgsfunction(args='auto', group='Custom')
def get_parcel_info(xx, yy, feature, parent):
"""
<h1>WMS Catasto Agenzia delle Entrate CC BY 4.0:</h1><br>
La funzione, tramite una richiesta GetFeatureInfo, restituisce le informazioni utili sulla particella che ricade sotto il pixel di mio interesse:
<h2>Esempio:</h2>
<ul>
<li>get_parcel_info(355461.5,4222490.7) -> 'IT.AGE.PLA.G273_0033A0.673'</li>
<li>get_parcel_info("fieldX", "fieldY") -> 'IT.AGE.PLA.G273_0033A0.673'</li>
</ul>
<h2>NB: le coordinate X e Y devono essere in EPSG 3045</h2>
"""
req = "https://wms.cartografia.agenziaentrate.gov.it/inspire/wms/ows01.php?REQUEST=GetFeatureInfo&SERVICE=WMS&SRS=EPSG:3045&STYLES=&VERSION=1.1&FORMAT=image/png&BBOX="+str(xx-1)+","+str(yy-1)+","+str(xx+1)+","+str(yy+1)+"&HEIGHT=9&WIDTH=9&LAYERS=CP.CadastralParcel&QUERY_LAYERS=CP.CadastralParcel&INFO_FORMAT=text/html&X=5&Y=5"
r = requests.get(req, auth=('user', 'pass'))
a = r.text.partition("InspireId localId</th><td>")[2]
b = a.partition("</td>")[0]
return b
Lo script Python è stato realizzato da Giulio Fattori
get_catastal_info↵
Catasto Agenzia delle Entrate CC BY 4.0:
La funzione, tramite una richiesta ajax.php, restituisce le informazioni disponibili su quel che ricade sotto il punto selezionato.
Sintassi:
- get_catastal_info(longitudine, latitudine, chiave)
Argomenti:
- longitudine coordinata x del punto
- latitudine coordinata y del punto
-
chiave per le Particelle:
- SIGLA_PROV
- COD_COMUNE
- DENOM
- SEZIONE
- FOGLIO
- ALLEGATO
- SVILUPPO
- NUM_PART
- TIPOLOGIA
Per Acque e Strade: - TIPOLOGIA
- COMUNI
Esempio:
codice Python:
# -*- coding: utf-8 -*-
"""
/***************************************************************************
WMS Catasto Agenzia delle Entrate CC BY 4.0
-------------------
copyright : (C) 2020 by Giulio Fattori
email : xxxxxxxxxxxxx
***************************************************************************/
"""
from qgis.core import *
from qgis.gui import *
import requests, json
@qgsfunction(args='auto', group='Custom')
def get_catastal_info(xx, yy, chiave, feature, parent):
"""
<h1>Catasto Agenzia delle Entrate CC BY 4.0:</h1>
La funzione, tramite una richiesta ajax.php, restituisce le informazioni disponibili su quel che ricade sotto il punto selezionato.
<p style="color:Olive"><b>Sintassi</b></p>
<p style="color:blue"><b>get_catastal_info</b><mark style="color:black">(</mark>
<mark style="color:red">x</mark>
<mark style="color:black">,</mark>
<mark style="color:red">y</mark>
<mark style="color:black">,</mark>
<mark style="color:red">chiave</mark>
<mark style="color:black">)</mark><br>
<br><mark style="color:black"><b>Le possibili chiavi sono:
<ul>
Per le particelle:
<li>SIGLA_PROV</li>
<li>COD_COMUNE</li>
<li>DENOM</li>
<li>SEZIONE</li>
<li>FOGLIO</li>
<li>ALLEGATO</li>
<li>SVILUPPO</li>
<li>NUM_PART</li>
<li>TIPOLOGIA</li>
</ul>
<ul>Per Acque e Strade:
<li>TIPOLOGIA</li>
<li>COMUNI</li>
</ul></b>
<h2>Esempio:</h2>
<ul>
<li>get_catastal_info(12.567315,37.914197, 'TIPOLOGIA') -> 'ACQUA'</li>
</ul>
<h2><b>Le coordinate X e Y devono essere espresse nel sistema WGS84 (EPSG:4326)</h2>
<h2><b>Il campo risultante deve essere di tipo string di adeguata lunghezza</h2>
<h2><b>Se la chiave non è presente risulterà ND</h2>
"""
req = "https://wms.cartografia.agenziaentrate.gov.it/inspire/ajax/ajax.php?op=getDatiOggetto&lon=" + str(xx) + "&lat=" + str(yy)
r = requests.get(req, auth=('user', 'pass'))
res = json.loads(r.text)
try:
b = str(res[chiave])
except:
b = 'ND'
return b
Lo script Python è stato realizzato da Giulio Fattori
fill-down↵
Restituisce un valore dal campo specificato, dove il valore del campo della riga precedente viene propagato ai campi con valori NULL
successivi. Opera in base all'id dei record.
Sintassi:
- fill_down(attibuto) -> popola le celle sottostanti
Argomenti:
- attributo un campo
Esempio:
from qgis.core import *
from qgis.gui import *
mem = 'NULL'
@qgsfunction(args='auto', group='Custom', handlesnull=True)
def fill_down(value1, feature, parent):
"""
Restituisce un valore dal campo specificato,
dove il valore del campo della riga precedente
viene propagato ai campi con valori Null successivi
<p>
Returns a value from the specified field,
where the value of the field of the previous row
it is propagated to subsequent null fields
<h2>Example usage:</h2>
<ul>
<li>fill_down("Dato") -> Fill_Data</li>
<table>
<thead>
<tr>
<th>Dato</th>
<th>Fill_Data</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:right">a</td>
<td style="text-align:right">a</td>
</tr>
<tr>
<td> </td>
<td style="text-align:right">a</td>
</tr>
<tr>
<td> </td>
<td style="text-align:right">a</td>
</tr>
<tr>
<td style="text-align:right">b</td>
<td style="text-align:right">b</td>
</tr>
<tr>
<td></td>
<td style="text-align:right">b</td>
</tr>
</tbody>
</table>
</ul>
Opera in base all'id dei record
<p>
Operate based on the ID of the records
"""
global mem
res = str(value1)
if res in ('NULL',''):
res = mem
else:
mem = str(value1)
return res
Lo script Python è stato realizzato da Giulio Fattori
random_points_in_polygon↵
Genera 'n' di punti all'interno della geometria del poligono corrente.
Sintassi:
- random_points_in_polygon(numero)
Argomenti:
- numero numero di punti da tracciare
from qgis.core import *
from qgis.gui import *
import random # Needed for generating pseudo random numbers
@qgsfunction(args='auto', group='Custom')
def random_points_in_polygon(number_of_points, feature, parent):
"""
<i>random_points_in_polygon( n )</i><br><br>
Generates 'n' number of points inside the current polygon geometry.<br><br>
<b>Requires</b><br>
<i>n</i> (Integer)<br><br>
<b>Example</b><br>
<i>random_points_in_polygon( 25 )</i><br>
<br>
<geometry: MultiPoint> with 25 points
"""
points = list() # Create an empty list for the points
# Until there's the required points in the list, loop (not the best way probably)
while len(points) < number_of_points:
# Create random x and y coordinates inside feature geometry bounding box
rnd_x = random.uniform(feature.geometry().boundingBox().xMinimum(), feature.geometry().boundingBox().xMaximum())
rnd_y = random.uniform(feature.geometry().boundingBox().yMinimum(), feature.geometry().boundingBox().yMaximum())
# Use the coordinates to create a point
rnd_point = QgsPointXY(rnd_x, rnd_y)
# Test if the point is inside the feature geometry
if QgsGeometry.fromPointXY(rnd_point).within(feature.geometry()):
# If it is inside, add it to the list (increasing the length of the list)
points.append(rnd_point)
# Return a multipoint geometry
return QgsGeometry.fromMultiPointXY(points)
Lo script Python è stato realizzato da
randomize↵
Calcola un valore random intero univoco compreso tra start e stop.
ATTENZIONE A NON IMPOSTARE L'INTERVALLO MINORE DEL NUMERO DI FEATURE
Sintassi:
- randomize(start, stop)
Argomenti:
- start un numero intero
- stop un numero intero
Esempi:
Osservazione:
La funzione è particolarmente utile se si volessero generare, tra start e stop, enne valori casuali univoci (senza ripetizioni)
from qgis.core import *
from qgis.gui import *
import random
random_list = []
@qgsfunction(args='auto', group='Custom')
def randomize(start, stop, feature, parent):
"""
Calcola un valore random intero univoco
compreso tra start e stop
<ul>ATTENZIONE A NON IMPOSTARE L'INTERVALLO MINORE DEL NUMERO DI FEATURE
</ul>
<h2>Example usage:</h2>
<ul>
<li>randomize( 0, 1000 ) -> 13</li>
</ul>
"""
a = random.randint(start, stop)
while a in random_list:
a = random.randint(start, stop)
random_list.append(a)
return a
Lo script Python è stato realizzato da Giulio Fattori
get_catg_color↵
Restituisce il colore RGBA (stringa [r,g,b,a] come intero 0-255) dell'elemento categorizzato: il campo in input è quello utilizzato per la categorizzazione. Per i campi della categorizzazione numerici formattatarli opportunamente e utilizzare la stessa espressione per catturarne il colore.
Sintassi:
- get_catg_color(nomeCampoCategoria)
Argomenti:
- nomeCampoCategoria nome del campo con cui si è effettuata la categorizzazione
Esempi:
get_catg_color("nomeCampoCategoria") → '228,52,199,255'
get_catg_color(to_string(format_number("nomeCampoCategoria",2))) → '228,52,199,255'
from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
@qgsfunction(args='auto', group='Custom')
def get_catg_color(value, feature, parent):
"""
Restituisce il colore RGBA (stringa [r,g,b,a] come intero 0-255) dell'elemento categorizzato:
il campo in input è quello utilizzato per la categorizzazione
Per i campi della categorizzazione numerici formattatarli opportunamente e
utilizzare la stessa espressione per catturarne il colore
<h2>Example usage:</h2>
<ul>
<li>get_color("nomeCampoCategoria") -> '228,52,199,255'</li>
<li>get_color(to_string(format_number("nomeCampoCategoria",2))) -> '228,52,199,255'</li>
</ul>
"""
layer = iface.activeLayer()
renderer = layer.renderer()
if layer.renderer().type() == "categorizedSymbol":
campo = renderer.legendClassificationAttribute()
for cat in renderer.categories():
if str(value) == cat.value():
colorato = cat.symbol().symbolLayer(0).properties()['color']
break
return colorato
Osservazioni:
La funzione è utile nel Plugin DataPlotly per associare i colori ai grafici.
Lo script Python è stato realizzato da Giulio Fattori
svg_pie↵
Genera un grafico a torta inseribile in una cornice HTML nel compositore di stampe.
Sintassi:
- svg_pie( array(values), donut, array(colors), array(descriptions), legenda)
Argomenti:
- array(val) - array percentuali
- donut - raggio del vuoto al centro [0-1]
- array(colors) - array colori
- array(descriptions) - array descrizioni
- legenda - legenda [-1] - percentuali interne[0] - legenda [1]
Esempi:
La somma delle percentuali deve essere pari a 1 o inferiore Se la somma delle percentuali e' inferiore al 100% ci sara' un settore vuoto. Elenco dei colori desiderati, se vuoto o in numero insufficiente saranno utilizzati quelli di default. Elenco delle descrizioni, se vuoto o in numero insufficiente sara' utilizzato il carattere spazio.
Colori di default in ordine di utilizzo Red, Aquamarine, Orange, Cyan, Yellow, Green, Grey, Beige, Gold, DarkKhaki, Royalblue, Fucsia è comunque possibile utilizzare qualsiasi colore CSS inserendone il nome.
#Korto19 2021
from qgis.core import *
from qgis.gui import *
import math
@qgsfunction(args='auto', group='Custom')
def svg_pie(value, donut, pcol, flipper, legenda, feature, parent):
"""
Genera un grafico a torta inseribile in una cornice HTML nel compositore di stampe
<p style="color:Olive"><b>Sintassi</b></p>
<p style="color:blue"><b>svg_pie</b><mark style="color:black">(</mark>
<mark style="color:red">array(values)</mark><mark style="color:black">,</mark>
<mark style="color:red">donut</mark><mark style="color:black">,</mark>
<mark style="color:red">array(colors)</mark><mark style="color:black">,</mark>
<mark style="color:red">array(descriptions)</mark><mark style="color:black">,</mark>
<mark style="color:red">legenda</mark><mark style="color:black">)</mark>
<p style="color:Olive"><b>Argomenti</b></p>
<p style="color:red"><b>array(val)</b><mark style="color:black"> - array percentuali </mark><br>
<mark style="color:red"><b>donut </b><mark style="color:black"> - raggio del vuoto al centro [0-1]</mark><br>
<mark style="color:red"><b>array(colors) </b><mark style="color:black"> - array colori</mark><br>
<mark style="color:red"><b>array(descriptions) </b><mark style="color:black"> - array descrizioni</mark><br>
<mark style="color:red"><b>legenda</b><mark style="color:black"> - legenda [-1] - percentuali interne[0] - legenda [1]</mark></p>
<h2><strong>Example usage:</strong></h2>
<ul>
<li>svg_Pie(array(.5,.1,.3),.8,array('red','cyan','gray'),array('uno','due','tre'),0)<li>
</ul>
<br>
<strong> La somma delle percentuali deve essere pari a 1 o inferiore</strong><br>
<strong> Se la somma delle percentuali e' inferiore al 100% ci sara' un settore vuoto</strong><br>
<strong> Elenco dei colori desiderati, se vuoto o in numero insufficiente saranno utilizzati quelli di default</strong><br>
<strong> Elenco delle descrizioni, se vuoto o in numero insufficiente sara' utilizzato il carattere spazio</strong><br><br>
Colori di default in ordine di utilizzo<br>
Red, Aquamarine, Orange, Cyan, Yellow, Green, Grey, Beige, Gold, DarkKhaki, Royalblue, Fucsia<br>
e' comunque possibile utilizzare qualsiasi colore CSS inserendone il nome
"""
dcol = ['red', 'Aquamarine', 'orange', 'cyan', 'yellow', 'green', 'grey', 'beige', 'Gold', 'DarkKhaki', 'royalblue', 'fucsia']
#aggiunge colori mancanti
if len(pcol) < len(value):
for j in range (0, len(value)-len(pcol)+1):
if dcol[j] not in pcol:
pcol.append(dcol[j])
#aggiunge vuoti se non ci son testi
if len(flipper) < len(value):
for j in range (0, len(value)-len(flipper)+1):
flipper.append('')
vc = 0.85
vt = -0.81
xi = '1'
yi = '0'
if legenda:
riq = '''viewBox="-1.2 -1.2 4 4"'''
else:
riq = '''viewBox="-1.1 -1.1 2.2 2.2"'''
svg_text = '''<svg width="100%" heigth="100%"'''+riq+'''" >
<style>
#legend{
text-anchor: middle;
font-weight: bold;
font-size: .008em;
fill: purple;
}
text{
font-weight: light;
font-size: .006em;
font-family: Arial;
transform: rotate(90deg);
}
#perc{
fill: black;
font-weight: bold;
font-size: .006em;
font-family: Arial;
text-anchor: middle;
}
path{
stroke: white;
stroke-width: 0.01;
}
</style>
<g transform="translate(0,0) rotate(-90)">'''
if sum(value[0:])>1:
svg_text = 'Somma valori maggiore del 100%'
else:
for i in range (0, len(value)):
pr = sum(value[0:i+1])
vx = str(math.cos(2*3.14*pr))
vy = str(math.sin(2*3.14*pr))
if value[i] > 0.5:
larc = '1'
else:
larc = '0'
svg_text = svg_text + '''<path d= "M '''+ xi + ''' ''' + yi +''' A 1 1 0 ''' + larc + ''' 1 '''+ vx + ''' ''' + vy +''' L 0 0" fill="''' + pcol[i] + '''"/>'''
xi = vx
yi = vy
if legenda == -1:
svg_text = svg_text + '''<circle r="0.06" cx="'''+ str(vc) +'''" cy="1.4" fill="''' + pcol[i] + '''"/>
<text x="1.5" y="'''+ str(vt) +'''" >'''+ "{:.2%}".format(value[i]) + " " + flipper[i] + '''</text>'''
vc = vc - .2
vt = vt + .2
if legenda == 1:
svg_text = svg_text + '''<circle r="0.06" cx="'''+ str(vc) +'''" cy="1.4" fill="''' + pcol[i] + '''"/>
<text x="1.5" y="'''+ str(vt) +'''" >'''+ " " + flipper[i] + '''</text>'''
vc = vc - .2
vt = vt + .2
if pr > 0.5:
larc = '0'
else:
larc = '1'
if donut:
svg_text = svg_text + '''<circle r="''' + str(donut) + '''" cx="0" cy="0" fill="white" />'''
if legenda:
svg_text = svg_text + '''<text id="legend" x="1.9" y="-1">Legenda</text>'''
#scrive percentuali entro torta
if legenda >= 0:
pr = 0
for i in range (0, len(value)):
pr = sum(value[0:i+1]) - value[i]/2
vx = 0.8*math.cos(2*3.14*(pr-.25))
vy = 0.8*math.sin(2*3.14*(pr-.25))
svg_text = svg_text + '''<text id="perc" x="''' + str(vx) + '''" y="''' + str(vy) + '''">'''+"{:.2%}".format(value[i]) +'''</text>'''
svg_text = svg_text + '''</g></svg>'''
return svg_text
Lo script Python è stato realizzato da Giulio Fattori
MinMaxValueFieldName↵
Restituisce il nome/valore della colonna col minimo o massimo valore nella riga.
Sintassi:
- MinMaxValueFieldName (attrmap, esclusion, minmax, vresult)
Argomenti:
- attrmap deve essere la funzione attributes() che restituisce tutti i nomi dei campi
- array() contiene l'elenco dei campi da escludere delimitati da apici
- minmax per considerare il minimo vmin o massimo vmax
- vresult per ottenere il nome fname o valore fval del campo
Avvertenze:
La funzione va in errore se non esclusi tutti i campi testo.
Esempi:
MinMaxValueFieldName( attributes(),array('fid','PRO_COM','COMUNE'),'vmax','fname') -> '2012'
MinMaxValueFieldName( attributes(),array( fid','PRO_COM','COMUNE'),'vmax','fval') -> '19250'
#Korto19 2021
from qgis.core import *
from qgis.gui import *
import json
@qgsfunction(args='auto', group='Custom')
def MinMaxValueFieldName(attrmap, esclusion, minmax, vresult, feature, parent):
"""
Restituisce il nome della colonna col minimo o massimo valore nella riga<p>
La funzione <b>MinMaxValueFieldName(attrmap, esclusion, minmax, vresult)</b> richiede quattro parametri:
<ul>
<li> <b>attrmap</b> deve essere la funzione <b>attributes()</b> che restituisce tutti i nomi dei campi</li>
<li> <b>array()</b> contiene l'elenco dei campi da escludere delimitati da apici</li>
<li> <b>minmax</b> per considerare il minimo <b>vmin</b> o massimo <b>vmax</b></li>
<li> <b>vresult</b> per ottenere il nome <b>fname</b> o valore <b>fval</b> del campo</li>
</ul>
<h2>Esempi d'uso:</h2>
<ul>
<li>MinMaxValueFieldName( attributes(),array( 'fid' , 'PRO_COM' , 'COMUNE' ), 'vmax', 'fname') -> '2012'</li>
<li>MinMaxValueFieldName( attributes(),array( 'fid' , 'PRO_COM' , 'COMUNE' ), 'vmax', 'fval') -> '19250'</li>
</ul>
<b><h2>AVVERTENZE:</h2>
<ul>
<li>La funzione va in errore se non esclusi tutti i campi testo</li>
</ul></b>
"""
#Trasformo in array l'elenco dei campi
esclusion = json.dumps(esclusion)
#Recupero i valori numerici della riga
_attrmap = {key: attrmap[key] for key in attrmap.keys() if key not in esclusion and attrmap[key] is not None} # exclude not needed fields
#Discrimino per vmin o vmax
if vresult == 'fname':
if minmax == 'vmax':
result = [k for k,v in _attrmap.items() if v==max(_attrmap.values())][0]
elif minmax == 'vmin':
result = [k for k,v in _attrmap.items() if v==min(_attrmap.values())][0]
elif vresult == 'fval':
if minmax == 'vmax':
result = [v for k,v in _attrmap.items() if v==max(_attrmap.values())][0]
elif minmax == 'vmin':
result = [v for k,v in _attrmap.items() if v==min(_attrmap.values())][0]
return result
Lo script è stato riscritto da Giulio Fattori, la fonte è qui, grazie Taras
Ordina array alfanumerico in modo numerico↵
# -*- coding: utf-8 -*-
"""
/***************************************************************************
Ordina array alfanumerico in modo numerico
-------------------
copyright : (C) 2021 by Giulio Fattori
email : xxxxxxxxxxxxx
***************************************************************************/
"""
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def array_sort_special(value1, feature, parent):
"""
Ordina un array alfanumerico numericamente
<h2>Esempio:</h2>
<ul>
<li>array_sort_special('5/A-5-4-8-3-6-9-7-1-10-7/B-2-7/A') -> ['1','2','3','4','5','5/A','6','7','7/A','7/B','8','9','10']</li>
</ul>
"""
data = value1.split('-')
r = sorted(data, key=lambda item: (int(item.partition('/')[0])
if item[0].isdigit() else float('inf'), item))
#return (','.join(r))
return r
Lo script è stato riscritto da Giulio Fattori
Natural sorting↵
from qgis.core import *
from qgis.gui import *
import re
def natural_sort_key(s):
ns = re.compile('([0-9]+)')
return [int(t) if t.isdigit() else t.lower() for t in re.split(ns, s)]
@qgsfunction(args='auto', group='Custom', usesgeometry=False)
def sort_my_list(field, feature, parent):
"""
Ordina un array secondo la Natural sorting
<h2>Esempio:</h2>
<ul>
<li>sort_my_list('field') -> 'elementi ordinati'</li>
</ul>
Nota: il nome del parametro del campo (field) per sort_my_addresses
deve essere compreso tra virgolette singole ('), non virgolette doppie (").
Ad esempio 'field', non "field"
<ul>
by Kadir Şahbaz
</ul>
Commentare decomentare le ulti due righe per avere una array o una stringa
"""
_list = feature[field].split("-")
_list.sort(key=natural_sort_key)
return _list
#return ','.join(_list)
Lo script è stato riscritto da Kadir Şahbaz
Dimensioni immagini↵
Estrae le dimensioni delle immagini in pixel nei casi di immagine con link assoluto o memorizzate come BLOB:
# -*- coding: utf-8 -*-
"""
/***************************************************************************
Dimensioni immagini
-------------------
copyright : (C) 2022 by Giulio Fattori
email : xxxxxxxxxxxxx
***************************************************************************/
"""
from qgis.core import *
from qgis.gui import *
from PyQt5.QtGui import QImage, QImageReader
@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def get_blob_sizes(img_blob, feature, parent):
"""
Calculate blob image dimension (W x H)
<h2>Example usage:</h2>
<ul>
<li>get_blob_sizes("img_blob") -> '1024 x 512 px'</li>
</ul>
"""
image = QImage().fromData(img_blob)
sizeOfImage = image.size()
img_height = sizeOfImage.height()
img_width = sizeOfImage.width()
dim_blob = str(img_width)+ ' x ' + str(img_height) + ' px '
return dim_blob
@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def get_image_sizes(img_shape, feature, parent):
"""
Calculate blob image size
<h2>Example usage:</h2>
<ul>
<li>get_image_sizes(img_shape) -> '1024 x 512 px'</li>
</ul>
NEED ABSOLUTE IMAGE LINK
"""
reader = QImageReader(img_shape)
sizeOfImage = reader.size()
img_height = sizeOfImage.height()
img_width = sizeOfImage.width()
dim_image = str(img_width)+ ' x ' + str(img_height) + ' px '
return dim_image
Lo script è stato realizzato da Giulio Fattori
Ordina i punti lungo una linea orientata↵
Restituisce l'ordinamento di elementi puntuali rispetto ad una linea orientata
# -*- coding: utf-8 -*-
"""
/***************************************************************************
Ordina i punti lungo una linea orientata
-------------------
copyright : (C) 2022 by Giulio Fattori
email : xxxxxxxxxxxxx
***************************************************************************/
"""
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom', usesgeometry=True)
def order_point_along_line(r_layer, v_reverse, feature, parent, context):
"""
Restituisce l'ordinamento di elementi puntuali rispetto ad una linea orientata
<p style="color:Red">Va eseguita su di un layer puntuale aggiungendo un campo numerico</p>
<p style="color:Red">Il parametro v_layer è il nome del vettore lineare</p>
<p style="color:Red">Il parametro v_reverse è un booleano 0/1 permette l'inversione della linea</p>
<p>
<h2>Example usage:</h2>
<ul>
<li>order_point_along_line('r_layer', v_reverse)</li>
<li>da come risultato il numero d'ordine progressivo del punto</li>
</ul>
<p>Tratto da:</p>
<p style="color:blue">https://pigrecoinfinito.com/2022/03/14/ordinare-i-punti-lungo-una-linea</p>
"""
if v_reverse == 0:
expression = QgsExpression("with_variable ('nearest',\
overlay_nearest(\'" + r_layer + "\',$geometry)[0],\
array_find(\
array_sort(\
array_foreach(\
array_agg($geometry, group_by:=@nearest),\
line_locate_point(@nearest,@element))),\
line_locate_point(@nearest,$geometry))+1\
)"
)
else:
expression = QgsExpression("with_variable ('nearest',\
overlay_nearest(\'" + r_layer + "\',reverse($geometry))[0],\
array_find(\
array_sort(\
array_foreach(\
array_agg($geometry, group_by:=@nearest),\
line_locate_point(@nearest,@element))),\
line_locate_point(@nearest,$geometry))+1\
)"
)
n_point = expression.evaluate(context)
return n_point
Lo script è stato realizzato da Giulio Fattori
Estrarre testo da legenda categorizzata↵
Estrarre il testo decodifica dalla legenda
# -*- coding: utf-8 -*-
"""
/***************************************************************************
Ordina i punti lungo una linea orientata
-------------------
copyright : (C) 2022 by Giulio Fattori
email : xxxxxxxxxxxxx
***************************************************************************/
"""
from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
@qgsfunction(args='auto', group='Custom')
def get_catg_label(value_in, feature, parent):
"""
Restituisce il testo della legenda dell'elemento categorizzato:
<br>
<p><b>il campo in input e' quello utilizzato per la categorizzazione</b>
<br>
<h2>Example usage:</h2>
<ul>
<li>get_catg_label("Area") -> 'Parcheggio'</li>
</ul>
"""
layer = iface.activeLayer()
renderer = layer.renderer()
if layer.renderer().type() == "categorizedSymbol":
for cat in renderer.categories():
#print('val ', type(cat.value()), type(value_in))
if str(value_in) == str(cat.value()):
#print('res ',cat.value(), value_in)
cat_label_out = cat.label()
break
else:
cat_label_out = ''
return cat_label_out
Lo script è stato realizzato da Giulio Fattori
Recupera l'alias di un attributo specificato nel layer corrente↵
# -*- coding: utf-8 -*-
"""
/***************************************************************************
ALIAS NAME CC BY 4.0
-------------------
copyright : (C) 2024 by Federico Gianoli
***************************************************************************/
"""
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom')
def get_field_alias(field_name, feature, parent):
"""
Retrieves the alias of a field specified in the current layer.
<ul> </ul>
<h2>Example usage:</h2>
<ul>
<li>get_field_alias('Field_Name') -> 'FieldAlias'</li>
</ul>
"""
layer = feature.fields()
field_index = layer.indexOf(field_name)
if field_index != -1:
alias = layer[field_index].alias()
return alias
else:
return f"Field '{field_name}' not found."