{"id":4163,"date":"2017-03-06T13:30:13","date_gmt":"2017-03-06T12:30:13","guid":{"rendered":"https:\/\/oneteamgis.wordpress.com\/?p=4163"},"modified":"2018-03-09T12:39:41","modified_gmt":"2018-03-09T11:39:41","slug":"arcpy-come-verificare-le-interferenze-fra-le-geometrie-utilizzando-cursori","status":"publish","type":"post","link":"https:\/\/gis.oneteam.it\/index.php\/2017\/03\/06\/arcpy-come-verificare-le-interferenze-fra-le-geometrie-utilizzando-cursori\/","title":{"rendered":"ArcPy: come verificare le interferenze fra le geometrie"},"content":{"rendered":"<p style=\"text-align: justify;\">Avete mai avuto la necessit\u00e0 di eseguire un&#8217;operazione tanto semplice quando indispensabile come il dover estrarre l&#8217;area non condivisa fra due geometrie sovrapposte? In sostanza, l&#8217;opposto di un&#8217;operazione di <em>Intersect<\/em>?<\/p>\n<figure id=\"attachment_4498\" aria-describedby=\"caption-attachment-4498\" style=\"width: 425px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4498\" src=\"https:\/\/gis.oneteam.it\/wp-content\/uploads\/2017\/02\/symmetrical_difference.gif\" alt=\"symmetrical_difference\" width=\"425\" height=\"169\" \/><figcaption id=\"caption-attachment-4498\" class=\"wp-caption-text\">Differenza simmetrica<\/figcaption><\/figure>\n<p style=\"text-align: justify;\">Tale operazione pu\u00f2 essere eseguita con lo strumento <em><a href=\"http:\/\/pro.arcgis.com\/en\/pro-app\/tool-reference\/analysis\/symmetrical-difference.htm\" target=\"_blank\" rel=\"noopener\">Symmetrical Difference<\/a><\/em>. L&#8217;unico problema \u00e8 che si tratta di un tool che necessita di una licenza di livello <em>Advanced<\/em>, non sempre a disposizione di tutti gli utenti. Nessun problema! In questo post vi faremo vedere come sfruttare gli <a href=\"https:\/\/desktop.arcgis.com\/en\/arcmap\/latest\/analyze\/arcpy-classes\/geometry.htm\">oggetti Geometria<\/a> per rendere possibili questa e molte altre operazioni utilissime, superando il limite della licenza. Il tutto sfruttando Python e il modulo arcpy.<!--more-->Ma cominciamo subito con un esempio. Il seguente codice crea, a partire da uno shapefile poligonale contenente una sola geometria rettangolare, un oggetto Geometria:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport arcpy\r\ngeom_1 = arcpy.CopyFeatures_management(&quot;geom_1.shp&quot;, arcpy.Geometry())\r\n<\/pre>\n<p style=\"text-align: justify;\">Abbiamo sfruttato lo strumento <em><a href=\"https:\/\/pro.arcgis.com\/en\/pro-app\/tool-reference\/data-management\/copy-features.htm\">Copy Features<\/a><\/em> per copiare le sole geometrie contenute nello shapefile <code>geom_1.shp<\/code> in una variabile che abbiamo denominato <code>geom_1<\/code>. Il tutto specificando come parametro di output della funzione la chiamata a <code>arcpy.Geometry()<\/code>, che crea l&#8217;oggetto Geometria. Quest&#8217;oggetto ha una serie di metodi (intesi in senso <em>pythonico<\/em>), fra cui uno chiamato <code>symmetricDifference()<\/code>, che andremo a utilizzare per il nostro scopo.<\/p>\n<p style=\"text-align: justify;\">Andiamo oltre e procediamo con la creazione del secondo oggetto Geometria che sar\u00e0 sovrapposto in parte al primo precedentemente creato (proprio come nell&#8217;immagine a inizio post).<\/p>\n<pre class=\"brush: python; first-line: 3; title: ; notranslate\" title=\"\">\r\ngeom_2 = arcpy.CopyFeatures_management(&quot;geom_2.shp&quot;, arcpy.Geometry())\r\n<\/pre>\n<p style=\"text-align: justify;\">Nulla di nuovo: abbiamo replicato il codice per la creazione della prima geometria, semplicemente sostituendo il nome della variabile (<code>geom_2<\/code> anzich\u00e9 <code>geom_1<\/code>), e lo shapefile da copiare. Ora abbiamo due oggetti Geometria da poter usare come input per ottenere una terza Geometria che sia l&#8217;unione delle due geometrie meno l&#8217;intersezione fra di esse.<\/p>\n<p>Un&#8217;illustrazione render\u00e0 pi\u00f9 chiaro il funzionamento del metodo <code>symmetricDifference<\/code>.<\/p>\n<figure id=\"attachment_4766\" aria-describedby=\"caption-attachment-4766\" style=\"width: 450px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4766\" src=\"https:\/\/gis.oneteam.it\/wp-content\/uploads\/2017\/03\/symmetrical_difference.gif\" alt=\"symmetrical_difference\" width=\"450\" height=\"279\" \/><figcaption id=\"caption-attachment-4766\" class=\"wp-caption-text\">simmetricDifference<\/figcaption><\/figure>\n<p style=\"text-align: justify;\">Prima di procedere col nostro codice, vanno precisate alcune cose da tenere a mente quando si usano gli oggetti Geometria:<\/p>\n<ol>\n<li style=\"text-align: justify;\">ogni poligono, inteso come entit\u00e0 geometrica individuale, che compone lo shapefile in input, corrisponder\u00e0 ad un oggetto Geometria di tipo poligonale. Questo, insieme agli altri (eventuali) oggetti, vengono raccolti in una lista di Python. In sostanza, <code>geom_1<\/code> e <code>geom_2<\/code> sono due liste, ciascuna avente al proprio interno un solo oggetto Geometria (poligonale in questo caso come gli shapefile da cui sono derivati). In pratica se stampassimo (con la funzione <code>print<\/code>) il valore di una delle due variabili, otterremmo qualcosa di simile a:<\/li>\n<\/ol>\n<p style=\"text-align: center;\"><code>[Polygon object at 0x4d34bb0[0x26e2040]]<\/code><\/p>\n<ol start=\"2\">\n<li>gli oggetti Geometria rappresentano una posizione nello spazio e la forma ad essa associata, pertanto non contengono attributi.<\/li>\n<\/ol>\n<p>Chiariti questi punti, finalizziamo ora il codice.<\/p>\n<pre class=\"brush: python; first-line: 4; title: ; notranslate\" title=\"\">\r\ngeom_diff = geom_1&#x5B;0].symmetricDifference(geom_2&#x5B;0])\r\narcpy.CopyFeatures_management(geom_diff,&quot;geom_diff.shp&quot;)\r\n<\/pre>\n<p style=\"text-align: justify;\">Fatto! Abbiamo usato il metodo <code>symmetricDifference()<\/code> per ottenere un nuovo oggetto Geometria che rappresenta l&#8217;unione delle due geometrie meno l&#8217;intersezione fra di esse (proprio quello che fa lo strumento <em>Symmetrical Difference<\/em> dell&#8217;<em>Analysis Toolbox<\/em> in ArcMap), e l&#8217;abbiamo salvato in uno shapefile <code>geom_diff.shp<\/code> usando ancora lo strumento <em>Copy Features<\/em> (in maniera opposta rispetto alle righe 2 e 3 nel codice). Notare che alla riga 4 abbiamo dovuto specificare un indice per la variabile <code>geom_1<\/code> e <code>geom_2<\/code>, dato che in realt\u00e0 si tratta di due liste contenenti ciascuna un solo elemento, l&#8217;oggetto Geometria. Ricordiamo che <code>[0]<\/code> rappresenta un indice che punta al primo (e in questo caso unico) elemento all&#8217;interno di una lista in Python.<\/p>\n<p>Riportiamo di seguito il codice completo:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport arcpy\r\ngeom_1 = arcpy.CopyFeatures_management(&quot;geom_1.shp&quot;, arcpy.Geometry())\r\ngeom_2 = arcpy.CopyFeatures_management(&quot;geom_2.shp&quot;, arcpy.Geometry())\r\ngeom_diff = geom_1&#x5B;0].difference(geom_2&#x5B;0])\r\narcpy.CopyFeatures_management(geom_diff,&quot;geom_diff.shp&quot;)\r\n<\/pre>\n<p style=\"text-align: justify;\">Abbiamo visto in questo post come sfruttare gli oggetti Geometria e il loro metodo <code>symmetricDifference()<\/code> per replicare il funzionamento dello strumento <em>Symmetrical Difference<\/em> presente in ArcMap, ma utilizzabile solo con una licenza di livello <em>Advanced<\/em>. Questo \u00e8 utile in svariate casistiche (clausole di contenimento, individuazione delle interferenze, ecc.). Ovviamente non \u00e8 il solo metodo degli oggetti Geometria: <code>equals()<\/code> consente di confrontare due geometrie e restituisce <code>true<\/code> se sono identiche, ed \u00e8 utile per verificare che non vi siano duplicati geometrici all&#8217;interno di un proprio dataset; <code>generalize()<\/code> crea una geometria che \u00e8 la versione generalizzata (semplificata) di quella in input, utile quando si hanno troppi vertici e si vuole &#8220;snellire&#8221; il dato; l&#8217;opposto \u00e8 il metodo <code>densify()<\/code>, che invece aggiunge vertici. Per un elenco completo, si faccia riferimento a <a href=\"https:\/\/desktop.arcgis.com\/en\/arcmap\/latest\/analyze\/arcpy-classes\/geometry.htm\">questa pagina<\/a> dell&#8217;help online di ArcGIS.<\/p>\n<p style=\"text-align: justify;\">Gli oggetti Geometria possono essere utilizzati come input o output al posto di creare nuove Feature Class temporanee, applicarvi dei cursori, e alla fine cancellarle durante una fase intermedia di un processo di geoprocessing. Possono anche essere creati da zero chiamando la classe <code>Geometry()<\/code>, perfino &#8220;al volo&#8221;, se necessario, inserendoli come parametri durante una chiamata a una funzione di geoprocessing.<\/p>\n<p style=\"text-align: justify;\">Nei prossimi post vedremo come mantenere le informazioni (gli attributi) degli shapefile di partenza agganciati agli oggetti Geometria tramite l&#8217;uso dei cursori.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Avete mai avuto la necessit\u00e0 di eseguire un&#8217;operazione tanto semplice quando indispensabile come il dover estrarre l&#8217;area non condivisa fra due geometrie sovrapposte? In sostanza, l&#8217;opposto di un&#8217;operazione di Intersect? Tale operazione pu\u00f2 essere eseguita con lo strumento Symmetrical Difference. L&#8217;unico problema \u00e8 che si tratta di un tool che necessita di una licenza di&hellip;<\/p>\n","protected":false},"author":1,"featured_media":4498,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,14,29],"tags":[75,93,470,507],"class_list":["post-4163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arcgis-for-desktop","category-articoli-tecnici","category-python","tag-arcgis-desktop","tag-arcpy","tag-python","tag-script"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/posts\/4163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/comments?post=4163"}],"version-history":[{"count":2,"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/posts\/4163\/revisions"}],"predecessor-version":[{"id":6753,"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/posts\/4163\/revisions\/6753"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/media\/4498"}],"wp:attachment":[{"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/media?parent=4163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/categories?post=4163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gis.oneteam.it\/index.php\/wp-json\/wp\/v2\/tags?post=4163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}