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?
Membros conectados podem postar, seguir atualizações e mais. Novo aqui? Registre uma conta gratuita.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.