QGIS: Python ed ERONE

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)).

Immagine 10
punti 3D (x,y,z) – da file CSV

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:

Immagine 1
triangoli 3D

esporto lo shapefile ‘tring_3D’  utilizzando il plugin ‘wkt export‘ ottenendo un file cosi strutturato:


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))

view raw

tring_3D.wkt

hosted with ❤ by GitHub

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:



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

view raw

tring_3D.csv

hosted with ❤ by GitHub

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:


"""
/***************************************************************************
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++++++++++++++++>"

view raw

Erone.py

hosted with ❤ by GitHub


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.


file

video.

2 pensieri su “QGIS: Python ed ERONE

  1. 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.

    Piace a 1 persona

Scrivi una risposta a Giuseppe Cancella risposta

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.