QGIS sta facendo passi da gigante nello sviluppo del codice e sta sempre più avvicinandosi al mondo 3D con nuove funzionalità come per esempio la definizione di shapefile 3D, info 3D ecc… ma ancora molte funzioni (come calcolo area $area, $perimetro, $lunghezza ecc…) sono sempre in 2D anche se lo shapefile è 3D.
In questo articolo utilizzerò Python per calcolare superfici e lunghezze di shapefile 3D partendo dai vertici (punti x,y,z) delle features (per esempio un file CSV di punti (x,y,z)).

unisco questi punti per formare tanti triangoli utilizzando lo SNAP di QGIS che si aggancia anche alla Z, cosi da realizzare triangoli nello spazio 3D:

esporto lo shapefile ‘tring_3D’ utilizzando il plugin ‘wkt export‘ ottenendo un file cosi strutturato:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 954254.42000000004190952 4152822.06000000005587935 755, 957341.85999999998603016 4173449.14999999990686774 458, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 959935.60999999998603016 4147696.77000000001862645 669, 954254.42000000004190952 4152822.06000000005587935 755, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 973804.56999999994877726 4151234.29999999981373549 883, 959935.60999999998603016 4147696.77000000001862645 669, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 976720.17000000004190952 4165318.29999999981373549 657, 973804.56999999994877726 4151234.29999999981373549 883, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 981652.81999999994877726 4173070.77000000001862645 466, 976720.17000000004190952 4165318.29999999981373549 657, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 973609.97999999998137355 4180161.54999999981373549 739, 981652.81999999994877726 4173070.77000000001862645 466, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 963006.18000000005122274 4178101.87999999988824129 333, 973609.97999999998137355 4180161.54999999981373549 739, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((967569.83999999996740371 4165799.08000000007450581 829, 957341.85999999998603016 4173449.14999999990686774 458, 963006.18000000005122274 4178101.87999999988824129 333, 967569.83999999996740371 4165799.08000000007450581 829)) | |
PolygonZ ((976720.17000000004190952 4165318.29999999981373549 657, 986701.2099999999627471 4155965.89000000013038516 900, 973804.56999999994877726 4151234.29999999981373549 883, 976720.17000000004190952 4165318.29999999981373549 657)) | |
PolygonZ ((976720.17000000004190952 4165318.29999999981373549 657, 981652.81999999994877726 4173070.77000000001862645 466, 986701.2099999999627471 4155965.89000000013038516 900, 976720.17000000004190952 4165318.29999999981373549 657)) | |
PolygonZ ((986701.2099999999627471 4155965.89000000013038516 900, 989900.02000000001862645 4176380.87999999988824129 459, 1003161.91000000003259629 4173698.75999999977648258 382, 986701.2099999999627471 4155965.89000000013038516 900)) | |
PolygonZ ((986701.2099999999627471 4155965.89000000013038516 0, 981652.81999999994877726 4173070.77000000001862645 466, 989900.02000000001862645 4176380.87999999988824129 459, 986701.2099999999627471 4155965.89000000013038516 0)) | |
PolygonZ ((1003161.91000000003259629 4173698.75999999977648258 382, 997619.93000000005122274 4182769.43999999994412065 377, 1008400.43999999994412065 4177627.31000000005587935 874, 1003161.91000000003259629 4173698.75999999977648258 382)) | |
PolygonZ ((997619.93000000005122274 4182769.43999999994412065 377, 1003161.91000000003259629 4173698.75999999977648258 382, 989900.02000000001862645 4176380.87999999988824129 459, 997619.93000000005122274 4182769.43999999994412065 377)) | |
PolygonZ ((980723.56000000005587935 4186202.18999999994412065 629, 989900.02000000001862645 4176380.87999999988824129 459, 981652.81999999994877726 4173070.77000000001862645 466, 980723.56000000005587935 4186202.18999999994412065 629)) | |
PolygonZ ((980723.56000000005587935 4186202.18999999994412065 629, 988030.52000000001862645 4189083.22000000020489097 837, 989900.02000000001862645 4176380.87999999988824129 459, 980723.56000000005587935 4186202.18999999994412065 629)) | |
PolygonZ ((988030.52000000001862645 4189083.22000000020489097 837, 997619.93000000005122274 4182769.43999999994412065 377, 989900.02000000001862645 4176380.87999999988824129 459, 988030.52000000001862645 4189083.22000000020489097 837)) | |
PolygonZ ((988030.52000000001862645 4189083.22000000020489097 837, 997075.91000000003259629 4194992.03000000026077032 640, 997619.93000000005122274 4182769.43999999994412065 377, 988030.52000000001862645 4189083.22000000020489097 837)) | |
PolygonZ ((997075.91000000003259629 4194992.03000000026077032 640, 1008400.43999999994412065 4177627.31000000005587935 874, 997619.93000000005122274 4182769.43999999994412065 377, 997075.91000000003259629 4194992.03000000026077032 640)) | |
PolygonZ ((973609.97999999998137355 4180161.54999999981373549 739, 980723.56000000005587935 4186202.18999999994412065 629, 981652.81999999994877726 4173070.77000000001862645 466, 973609.97999999998137355 4180161.54999999981373549 739)) | |
PolygonZ ((963006.18000000005122274 4178101.87999999988824129 333, 968416.25 4192046.33999999985098839 646, 973609.97999999998137355 4180161.54999999981373549 739, 963006.18000000005122274 4178101.87999999988824129 333)) | |
PolygonZ ((968416.25 4192046.33999999985098839 646, 973036.16000000003259629 4192947.14000000013038516 873, 973609.97999999998137355 4180161.54999999981373549 739, 968416.25 4192046.33999999985098839 646)) | |
PolygonZ ((973036.16000000003259629 4192947.14000000013038516 873, 980723.56000000005587935 4186202.18999999994412065 629, 973609.97999999998137355 4180161.54999999981373549 739, 973036.16000000003259629 4192947.14000000013038516 873)) | |
PolygonZ ((973036.16000000003259629 4192947.14000000013038516 873, 983555.25 4200077.79999999981373549 623, 980723.56000000005587935 4186202.18999999994412065 629, 973036.16000000003259629 4192947.14000000013038516 873)) | |
PolygonZ ((980723.56000000005587935 4186202.18999999994412065 629, 983555.25 4200077.79999999981373549 623, 988030.52000000001862645 4189083.22000000020489097 837, 980723.56000000005587935 4186202.18999999994412065 629)) | |
PolygonZ ((983555.25 4200077.79999999981373549 623, 997075.91000000003259629 4194992.03000000026077032 640, 988030.52000000001862645 4189083.22000000020489097 837, 983555.25 4200077.79999999981373549 623)) | |
PolygonZ ((957341.85999999998603016 4173449.14999999990686774 458, 968416.25 4192046.33999999985098839 646, 963006.18000000005122274 4178101.87999999988824129 333, 957341.85999999998603016 4173449.14999999990686774 458)) | |
PolygonZ ((968416.25 4192046.33999999985098839 646, 983555.25 4200077.79999999981373549 623, 973036.16000000003259629 4192947.14000000013038516 873, 968416.25 4192046.33999999985098839 646)) | |
PolygonZ ((986701.2099999999627471 4155965.89000000013038516 900, 1003161.91000000003259629 4173698.75999999977648258 382, 1008400.43999999994412065 4177627.31000000005587935 874, 986701.2099999999627471 4155965.89000000013038516 900)) |
questo formato va modificato per utilizzarlo in seguito: elimino il testo (PoligonZ), le parentesi e aggiungo una virgola per separare le coordinate, ottenendo un file CSV:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 954254.42000000004190952 | 4152822.06000000005587935 | 755 | 957341.85999999998603016 | 4173449.14999999990686774 | 458 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 959935.60999999998603016 | 4147696.77000000001862645 | 669 | 954254.42000000004190952 | 4152822.06000000005587935 | 755 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 973804.56999999994877726 | 4151234.29999999981373549 | 883 | 959935.60999999998603016 | 4147696.77000000001862645 | 669 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 976720.17000000004190952 | 4165318.29999999981373549 | 657 | 973804.56999999994877726 | 4151234.29999999981373549 | 883 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 981652.81999999994877726 | 4173070.77000000001862645 | 466 | 976720.17000000004190952 | 4165318.29999999981373549 | 657 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 973609.97999999998137355 | 4180161.54999999981373549 | 739 | 981652.81999999994877726 | 4173070.77000000001862645 | 466 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 963006.18000000005122274 | 4178101.87999999988824129 | 333 | 973609.97999999998137355 | 4180161.54999999981373549 | 739 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
967569.83999999996740371 | 4165799.08000000007450581 | 829 | 957341.85999999998603016 | 4173449.14999999990686774 | 458 | 963006.18000000005122274 | 4178101.87999999988824129 | 333 | 967569.83999999996740371 | 4165799.08000000007450581 | 829 | |
976720.17000000004190952 | 4165318.29999999981373549 | 657 | 986701.2099999999627471 | 4155965.89000000013038516 | 900 | 973804.56999999994877726 | 4151234.29999999981373549 | 883 | 976720.17000000004190952 | 4165318.29999999981373549 | 657 | |
976720.17000000004190952 | 4165318.29999999981373549 | 657 | 981652.81999999994877726 | 4173070.77000000001862645 | 466 | 986701.2099999999627471 | 4155965.89000000013038516 | 900 | 976720.17000000004190952 | 4165318.29999999981373549 | 657 | |
986701.2099999999627471 | 4155965.89000000013038516 | 900 | 989900.02000000001862645 | 4176380.87999999988824129 | 459 | 1003161.91000000003259629 | 4173698.75999999977648258 | 382 | 986701.2099999999627471 | 4155965.89000000013038516 | 900 | |
986701.2099999999627471 | 4155965.89000000013038516 | 0 | 981652.81999999994877726 | 4173070.77000000001862645 | 466 | 989900.02000000001862645 | 4176380.87999999988824129 | 459 | 986701.2099999999627471 | 4155965.89000000013038516 | 0 | |
1003161.91000000003259629 | 4173698.75999999977648258 | 382 | 997619.93000000005122274 | 4182769.43999999994412065 | 377 | 1008400.43999999994412065 | 4177627.31000000005587935 | 874 | 1003161.91000000003259629 | 4173698.75999999977648258 | 382 | |
997619.93000000005122274 | 4182769.43999999994412065 | 377 | 1003161.91000000003259629 | 4173698.75999999977648258 | 382 | 989900.02000000001862645 | 4176380.87999999988824129 | 459 | 997619.93000000005122274 | 4182769.43999999994412065 | 377 | |
980723.56000000005587935 | 4186202.18999999994412065 | 629 | 989900.02000000001862645 | 4176380.87999999988824129 | 459 | 981652.81999999994877726 | 4173070.77000000001862645 | 466 | 980723.56000000005587935 | 4186202.18999999994412065 | 629 | |
980723.56000000005587935 | 4186202.18999999994412065 | 629 | 988030.52000000001862645 | 4189083.22000000020489097 | 837 | 989900.02000000001862645 | 4176380.87999999988824129 | 459 | 980723.56000000005587935 | 4186202.18999999994412065 | 629 | |
988030.52000000001862645 | 4189083.22000000020489097 | 837 | 997619.93000000005122274 | 4182769.43999999994412065 | 377 | 989900.02000000001862645 | 4176380.87999999988824129 | 459 | 988030.52000000001862645 | 4189083.22000000020489097 | 837 | |
988030.52000000001862645 | 4189083.22000000020489097 | 837 | 997075.91000000003259629 | 4194992.03000000026077032 | 640 | 997619.93000000005122274 | 4182769.43999999994412065 | 377 | 988030.52000000001862645 | 4189083.22000000020489097 | 837 | |
997075.91000000003259629 | 4194992.03000000026077032 | 640 | 1008400.43999999994412065 | 4177627.31000000005587935 | 874 | 997619.93000000005122274 | 4182769.43999999994412065 | 377 | 997075.91000000003259629 | 4194992.03000000026077032 | 640 | |
973609.97999999998137355 | 4180161.54999999981373549 | 739 | 980723.56000000005587935 | 4186202.18999999994412065 | 629 | 981652.81999999994877726 | 4173070.77000000001862645 | 466 | 973609.97999999998137355 | 4180161.54999999981373549 | 739 | |
963006.18000000005122274 | 4178101.87999999988824129 | 333 | 968416.25 | 4192046.33999999985098839 | 646 | 973609.97999999998137355 | 4180161.54999999981373549 | 739 | 963006.18000000005122274 | 4178101.87999999988824129 | 333 | |
968416.25 | 4192046.33999999985098839 | 646 | 973036.16000000003259629 | 4192947.14000000013038516 | 873 | 973609.97999999998137355 | 4180161.54999999981373549 | 739 | 968416.25 | 4192046.33999999985098839 | 646 | |
973036.16000000003259629 | 4192947.14000000013038516 | 873 | 980723.56000000005587935 | 4186202.18999999994412065 | 629 | 973609.97999999998137355 | 4180161.54999999981373549 | 739 | 973036.16000000003259629 | 4192947.14000000013038516 | 873 | |
973036.16000000003259629 | 4192947.14000000013038516 | 873 | 983555.25 | 4200077.79999999981373549 | 623 | 980723.56000000005587935 | 4186202.18999999994412065 | 629 | 973036.16000000003259629 | 4192947.14000000013038516 | 873 | |
980723.56000000005587935 | 4186202.18999999994412065 | 629 | 983555.25 | 4200077.79999999981373549 | 623 | 988030.52000000001862645 | 4189083.22000000020489097 | 837 | 980723.56000000005587935 | 4186202.18999999994412065 | 629 | |
983555.25 | 4200077.79999999981373549 | 623 | 997075.91000000003259629 | 4194992.03000000026077032 | 640 | 988030.52000000001862645 | 4189083.22000000020489097 | 837 | 983555.25 | 4200077.79999999981373549 | 623 | |
957341.85999999998603016 | 4173449.14999999990686774 | 458 | 968416.25 | 4192046.33999999985098839 | 646 | 963006.18000000005122274 | 4178101.87999999988824129 | 333 | 957341.85999999998603016 | 4173449.14999999990686774 | 458 | |
968416.25 | 4192046.33999999985098839 | 646 | 983555.25 | 4200077.79999999981373549 | 623 | 973036.16000000003259629 | 4192947.14000000013038516 | 873 | 968416.25 | 4192046.33999999985098839 | 646 | |
986701.2099999999627471 | 4155965.89000000013038516 | 900 | 1003161.91000000003259629 | 4173698.75999999977648258 | 382 | 1008400.43999999994412065 | 4177627.31000000005587935 | 874 | 986701.2099999999627471 | 4155965.89000000013038516 | 900 |
noterete che ogni riga ha quattro triplette di coordinate (x,y,z), questo perchè ogni poligono chiuso (i triangoli) il primo e l’ultimo vertice coincidono.
Questo file (tring_3D.csv) sarà utilizzato nello script Python per calcolare l’area dei triangoli (in 3D) con la formula di Erone:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
/*************************************************************************** | |
Name : Erone https://it.wikipedia.org/wiki/Formula_di_Erone | |
Description : Calcolo superficie PoligonZ da file CSV (XYZ) | |
Date : 25 – marzo – 2016 | |
copyright : (C) 2016 by Salvatore Fiandaca | |
email : pigrecoinfinito@gmail.com | |
***************************************************************************/ | |
/*************************************************************************** | |
* * | |
* This program is free software; you can redistribute it and/or modify * | |
* it under the terms of the GNU General Public License as published by * | |
* the Free Software Foundation; either version 2 of the License, or * | |
* (at your option) any later version. * | |
* * | |
***************************************************************************/ | |
""" | |
def lungh (x1,y1,z1,x2,y2,z2): #funzione lunghezza | |
dx,dy,dz= x1–x2, y1–y2, z1–z2 | |
return (dx**2+dy**2+dz**2)**0.5,(dx**2+dy**2)**0.5 | |
def Erone (a,b,c): #funzione formula di Erone | |
p = (a+b+c)/2.0 | |
return (p*(p–a)*(p–b)*(p–c))**0.5 | |
# =============== importo il file CSV e creo lista coords =================== | |
import csv | |
with open ('triangoli3D.csv') as csvfile: | |
readCSV = csv.reader(csvfile, delimiter=',') | |
coords=[] #creo liste | |
for row in readCSV: #popolo lista | |
coords+=row | |
# ========= calcolo lunghezze lati triangolo e creazione liste ============== | |
lista_3D,lista_2D = [],[] #creo liste | |
for i in range (0,len(coords)–3,3): | |
x1,y1,z1=eval(coords [i]),eval(coords[i+1]),eval(coords[i+2]) | |
x2,y2,z2=eval(coords [i+3]),eval(coords[i+4]),eval(coords[i+5]) | |
lun3D,lun2D =lungh (x1,y1,z1,x2,y2,z2) #lunghezza lati 3D/2D | |
lista_3D+=[lun3D] #popolo lista lunghezze lati 3D | |
lista_2D+=[lun2D] #popolo lista lunghezze lati 2D | |
# ================= calcolo elementi per formula di Erone =================== | |
sup3D,sup2D = 0,0 | |
for j in range (0, len(lista_3D)–2,4): | |
a,b,c= lista_3D [j],lista_3D [j+1],lista_3D [j+2] | |
a2,b2,c2 = lista_2D [j],lista_2D [j+1],lista_2D [j+2] | |
Erone_3D,Erone_2D= Erone (a,b,c),Erone (a2,b2,c2) #formula di Erone | |
sup3D+=Erone_3D | |
sup2D+=Erone_2D | |
# ========================== stampa risultati =============================== | |
print "*==================*===================*" | |
print sup3D,'mq Area 3D\n' | |
print sup2D,'mq Area 2D\n' | |
print sup3D–sup2D,'mq differenza Area 3D-2D\n' | |
print round((sup3D–sup2D)/sup3D*100,3),'%' | |
print "<+++++++++++++++pigreco++++++++++++++++>" |
Note finali: con questo articolo voglio dimostrare che con poche conoscenze di Python e con nozioni di matematica è possibile creare script per superare alcuni limiti di QGIS. Lo script di python è certamente migliorabile soprattutto nell’importazione del file csv.
Per chi volesse provare questo programma in python, mi raccomando, create il file csv per come spiegato sopra.
video.
Buon giorno e complimenti per gli articoli, sempre chiari e puntuali
Volevo chiederti se è possibile disegnare un poligono rettangolare partendo da un shp punto e dalle informazioni della geometria contenute nei campi: lato maggiore, lato minore e orientamento.
"Mi piace"Piace a 1 persona
Ciao,
credo di sì.
Ma non ho mai provato.
"Mi piace""Mi piace"