Is it possible to calculate the minimum angle in a polygon? I have several polygons that have sharp edges, as in the attached picture, and I would like to indicate them automatically. For example, can I create a column in the attribute table with minimum angle values in a polygon?
Thank you for the answer. I have found an easy solution in QGIS: Vector > Geometry Tools >Check Geometries > Minimum angle between segments (deg). After its finished you can export a point shapefile indicating places where polygons have lower angle than a specified threshold, and the ID of the original polygons.
PS, you picture is for polygons, so moving to Python since this isn't a Spatial Analyst thread.
Feed polygon shapes to 'angles_poly'. Numpy required
Polygons can be converted to numpy arrays using. This is the implementation for a whole featureclass converted to a numpy object array
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">poly2array</SPAN><SPAN class="punctuation token">(</SPAN>polys<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">"""Convert polyline or polygon shapes to arrays for use in the Geo class. Parameters ---------- polys : tuple, list Polyline or polygons in a list/tuple """</SPAN> <SPAN class="keyword token">def</SPAN> <SPAN class="token function">_p2p_</SPAN><SPAN class="punctuation token">(</SPAN>poly<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">"""Convert a single ``poly`` shape to numpy arrays or object"""</SPAN> sub <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> arr <SPAN class="keyword token">in</SPAN> poly<SPAN class="punctuation token">:</SPAN> pnts <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">[</SPAN>pt<SPAN class="punctuation token">.</SPAN>X<SPAN class="punctuation token">,</SPAN> pt<SPAN class="punctuation token">.</SPAN>Y<SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> pt <SPAN class="keyword token">else</SPAN> null_pnt <SPAN class="keyword token">for</SPAN> pt <SPAN class="keyword token">in</SPAN> arr<SPAN class="punctuation token">]</SPAN> sub<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>np<SPAN class="punctuation token">.</SPAN>asarray<SPAN class="punctuation token">(</SPAN>pnts<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">return</SPAN> sub <SPAN class="comment token"># ----</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> isinstance<SPAN class="punctuation token">(</SPAN>polys<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN>list<SPAN class="punctuation token">,</SPAN> tuple<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> polys <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN>polys<SPAN class="punctuation token">]</SPAN> out <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> poly <SPAN class="keyword token">in</SPAN> polys<SPAN class="punctuation token">:</SPAN> out<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>_p2p_<SPAN class="punctuation token">(</SPAN>poly<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">return</SPAN> out<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
In a script, a search cursor can be used to get a polygon, and it can be converted using _p2p_ in the above..
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">_p2p_</SPAN><SPAN class="punctuation token">(</SPAN>poly<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">"""Convert a single ``poly`` shape to numpy arrays or object"""</SPAN> sub <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> arr <SPAN class="keyword token">in</SPAN> poly<SPAN class="punctuation token">:</SPAN> pnts <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">[</SPAN>pt<SPAN class="punctuation token">.</SPAN>X<SPAN class="punctuation token">,</SPAN> pt<SPAN class="punctuation token">.</SPAN>Y<SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> pt <SPAN class="keyword token">else</SPAN> null_pnt <SPAN class="keyword token">for</SPAN> pt <SPAN class="keyword token">in</SPAN> arr<SPAN class="punctuation token">]</SPAN> sub<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>np<SPAN class="punctuation token">.</SPAN>asarray<SPAN class="punctuation token">(</SPAN>pnts<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">return</SPAN> sub<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">angles_poly</SPAN><SPAN class="punctuation token">(</SPAN>a<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">,</SPAN> inside<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN> in_deg<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">""</SPAN>"Sequential <SPAN class="number token">3</SPAN> point angles <SPAN class="keyword token">from</SPAN> a poly<SPAN class="operator token">*</SPAN> shape Parameters <SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">-</SPAN> a <SPAN class="punctuation token">:</SPAN> array an array of points<SPAN class="punctuation token">,</SPAN> derived <SPAN class="keyword token">from</SPAN> a polygon<SPAN class="operator token">/</SPAN>polyline geometry inside <SPAN class="punctuation token">:</SPAN> boolean determine inside angles<SPAN class="punctuation token">,</SPAN> outside <SPAN class="keyword token">if</SPAN> <SPAN class="token boolean">False</SPAN> in_deg <SPAN class="punctuation token">:</SPAN> boolean convert to degrees <SPAN class="keyword token">from</SPAN> radians Sample data<SPAN class="punctuation token">:</SPAN> the letter C <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> a <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>array<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">[</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">100</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">100</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">80</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">80</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> angles_poly<SPAN class="punctuation token">(</SPAN>a<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># array([ 90., 90., 90., 270., 270., 90., 90.])</SPAN> <SPAN class="string token">""</SPAN>" <SPAN class="keyword token">if</SPAN> len<SPAN class="punctuation token">(</SPAN>a<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token"><</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">return</SPAN> None <SPAN class="keyword token">if</SPAN> len<SPAN class="punctuation token">(</SPAN>a<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">==</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">:</SPAN> ba <SPAN class="operator token">=</SPAN> a<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">-</SPAN> a<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">return</SPAN> np<SPAN class="punctuation token">.</SPAN>arctan2<SPAN class="punctuation token">(</SPAN><SPAN class="operator token">*</SPAN>ba<SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">:</SPAN><SPAN class="punctuation token">:</SPAN><SPAN class="operator token">-</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> dx<SPAN class="punctuation token">,</SPAN> dy <SPAN class="operator token">=</SPAN> a<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">-</SPAN> a<SPAN class="punctuation token">[</SPAN><SPAN class="operator token">-</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> np<SPAN class="punctuation token">.</SPAN>allclose<SPAN class="punctuation token">(</SPAN>dx<SPAN class="punctuation token">,</SPAN> dy<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># closed loop</SPAN> a <SPAN class="operator token">=</SPAN> a<SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">:</SPAN><SPAN class="operator token">-</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> a0 <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>roll<SPAN class="punctuation token">(</SPAN>a<SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN> a1 <SPAN class="operator token">=</SPAN> a a2 <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>roll<SPAN class="punctuation token">(</SPAN>a<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN> ba <SPAN class="operator token">=</SPAN> a1 <SPAN class="operator token">-</SPAN> a0 bc <SPAN class="operator token">=</SPAN> a1 <SPAN class="operator token">-</SPAN> a2 cr <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>cross<SPAN class="punctuation token">(</SPAN>ba<SPAN class="punctuation token">,</SPAN> bc<SPAN class="punctuation token">)</SPAN> dt <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>einsum<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'ij,ij->i'</SPAN><SPAN class="punctuation token">,</SPAN> ba<SPAN class="punctuation token">,</SPAN> bc<SPAN class="punctuation token">)</SPAN> ang <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>arctan2<SPAN class="punctuation token">(</SPAN>cr<SPAN class="punctuation token">,</SPAN> dt<SPAN class="punctuation token">)</SPAN> two_pi <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>pi<SPAN class="operator token">*</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="keyword token">if</SPAN> inside<SPAN class="punctuation token">:</SPAN> ang <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>where<SPAN class="punctuation token">(</SPAN>ang <SPAN class="operator token"><</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> ang <SPAN class="operator token">+</SPAN> two_pi<SPAN class="punctuation token">,</SPAN> ang<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN> ang <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>where<SPAN class="punctuation token">(</SPAN>ang <SPAN class="operator token">></SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> two_pi <SPAN class="operator token">-</SPAN> ang<SPAN class="punctuation token">,</SPAN> ang<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> in_deg<SPAN class="punctuation token">:</SPAN> angles <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>degrees<SPAN class="punctuation token">(</SPAN>ang<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">return</SPAN> angles <SPAN class="comment token"># ---- demo --- a polygon "C"</SPAN> <SPAN class="keyword token">import</SPAN> numpy <SPAN class="keyword token">as</SPAN> np a <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>array<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">[</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">100</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">100</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">80</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">80</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> angles <SPAN class="operator token">=</SPAN> angles_poly<SPAN class="punctuation token">(</SPAN>a<SPAN class="punctuation token">,</SPAN> inside<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN> in_deg<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">)</SPAN> min<SPAN class="punctuation token">(</SPAN>angles<SPAN class="punctuation token">)</SPAN> <SPAN class="number token">90.0</SPAN> angles array<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="number token">270</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">270</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">270</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">270</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">90</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">90</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">270</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">270</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
So the code would entail
open a search cursor
convert each shape to an array using _p2p_
call angles_poly
take its minimum
To find sharp edges you can convert the polygons to raster, boundary clean, reconvert to polygon, buffer with a appropriate distance and clip?
Aangemelde leden kunnen berichten plaatsen, updates volgen en meer. Nieuw hier? Registreer een gratis account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.