J'ai une couche d'entités polygonale que je voudrais numéroter automatiquement mais en spirale (En escargot). De facon à avoir une continuité par voisinage. je suis un débutant en python, merci de m'aider. Merci
Translation: I have a layer of polygonal entities that I would like to automatically number but spiral. In order to have continuity by neighborhood. I am a beginner in python, thank you for helping me. Thank you
Question: Do you want the spiral in a clockwise or counterclockwise direction? ( Voulez-vous la spirale dans le sens des aiguilles d'une montre ou dans le sens contraire?)
Tagging https://community.esri.com/community/developers/gis-developers/python
Thank you, I would like to have a spiral in a clockwise !
Many thanks!
See Dan Patterson's comment in this thread: numbering polygon in clockwise. Although the message doesn't have a code example, it gives a suggestion on how this problem might be approached.
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">angle_2pnts</SPAN><SPAN class="punctuation token">(</SPAN>p0<SPAN class="punctuation token">,</SPAN> p1<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">"""Two point angle : angle = atan2(vector2.y, vector2.x) - atan2(vector1.y, vector1.x); : Accepted answer from the poly_angles link """</SPAN> ba <SPAN class="operator token">=</SPAN> p1 <SPAN class="operator token">-</SPAN> p0 ang_ab <SPAN class="operator token">=</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> <SPAN class="keyword token">return</SPAN> np<SPAN class="punctuation token">.</SPAN>rad2deg<SPAN class="punctuation token">(</SPAN>ang_ab <SPAN class="operator token">%</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="number token">2</SPAN> <SPAN class="operator token">*</SPAN> np<SPAN class="punctuation token">.</SPAN>pi<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> p1 <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>array<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> p0 <SPAN class="operator token">=</SPAN> np<SPAN class="punctuation token">.</SPAN>array<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> angle_2pnts<SPAN class="punctuation token">(</SPAN>p0<SPAN class="punctuation token">,</SPAN> p1<SPAN class="punctuation token">)</SPAN> <SPAN class="number token">45.0</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>
Sadly for some, I use numpy to perform all my calculations, but this may help
p0... consider that your center point
p1.... pN are all your other points.
If you had a list of points, I could modify my example or you could translate this into straight python using elementary geometry
In short, the angles are relative to the X-axis ranging from 180 to -180... sort in descending order to give you a clockwise direction, sort in ascending order to get counterclockwise.
If you have data in a particular form, I can provide a field calculator expression, and I have a toolbox somewhere that does radial, lexicographic and other sorting types if needed (I have probably done a blog post at some time as well)
Ok... I found some field calculations.
If you have a featureclass/shapefile, this field calculator will do the calculations for you.
You must have projected coordinates!
If you copy that file into a text editor and save it with as .... azimuth_to.cal .... you can load it up into the field calculator. It is the same principle, but it does the azimuth to... but you can then sort it using
Sort .... since you are only sorting on a regular field.
Normally the Sort tool (in Map or PRO) is only available at the advanced license if you want to sort on the Shape field or to use multiple fields.
<SPAN class="comment token"># -*- coding: UTF-8 -*-</SPAN> <SPAN class="string token">"""----------------------------------------- Input shape field: returns angle between 0 and <360 based upon the first and last point azimuth_to(!Shape!,from_x, from_y, from_north=True) ie azimuth_to(!Shape!, 300050, 5000050, True) """</SPAN> <SPAN class="keyword token">import</SPAN> math <SPAN class="keyword token">def</SPAN> <SPAN class="token function">azimuth_to</SPAN><SPAN class="punctuation token">(</SPAN>shape<SPAN class="punctuation token">,</SPAN> from_x<SPAN class="punctuation token">,</SPAN> from_y<SPAN class="punctuation token">,</SPAN> from_north<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> x <SPAN class="operator token">=</SPAN> shape<SPAN class="punctuation token">.</SPAN>centroid<SPAN class="punctuation token">.</SPAN>X y <SPAN class="operator token">=</SPAN> shape<SPAN class="punctuation token">.</SPAN>centroid<SPAN class="punctuation token">.</SPAN>Y radian <SPAN class="operator token">=</SPAN> math<SPAN class="punctuation token">.</SPAN>atan2<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">(</SPAN>y <SPAN class="operator token">-</SPAN> from_y<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN>x <SPAN class="operator token">-</SPAN> from_x<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> angle <SPAN class="operator token">=</SPAN> math<SPAN class="punctuation token">.</SPAN>degrees<SPAN class="punctuation token">(</SPAN>radian<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> from_north<SPAN class="punctuation token">:</SPAN> angle <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="number token">450</SPAN> <SPAN class="operator token">-</SPAN> angle<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">%</SPAN> <SPAN class="number token">360</SPAN> <SPAN class="keyword token">return</SPAN> angle __esri_field_calculator_splitter__ azimuth_to<SPAN class="punctuation token">(</SPAN>!Shape!<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">300050</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">5000050</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="token boolean">True</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>
NOW see the last line... the 300050 and 5000050 are the centre X and Y values... you will need to use the python parser in the field calculator and determine and enter your central points. If you want them from North, then entre True, otherwise you get the angles from the X-axis.
If set to False, then you have to sort in descending order.
if set to True, then you will be sorting in ascending order.
Hope this is clear as mud... draw a picture if it helps.
Hi Ned Charles ,
If you want to number them as a "spiral", I assume that distance from the first (center) also influences.the resulting numbering as well as the start angle:
or for instance this way
Can you provide a screenshot or sample of your data to see what it looks like?
Yes, I'm trying to understand his approach to adapting it. But it will not be for tomorrow.
Thanks
Thank you Dan,
what do you think if I send you an example of a shapefile.
I can't apply it to my polygons.
Many thanks
The parcels are in red and the black line is the neighborhood numbering direction.
I see, you want to flip between max Y and max X and min Y and min X pairs. A Peano sort won't cut it. I suspect you will have to generate the spiral from the centre with a repeating angle and an increasing distance increment. The rate at which the distance from the centre changes (ie what function, if any, sin, cos etc) will determine the shape of the spiral.
I am sure it has a name, but the market for spiral generation outside of mazes and shellfish is somewhat limited
Although a reversed squished Archimede's spiral looks promising https://en.wikipedia.org/wiki/Spiral
rigid solutions exist already in rosetta code https://rosettacode.org/wiki/Spiral_matrix#Python the trick is to oblate the spiral and smooth the steps
Dear Dan,Based on our last discussions(Spiral matrix !) , I see that you understand the problem very well. Your beginnings of solution are very good but I would like to be able to apply them to a layers of polygons. Thank you for explaining to me how to number this layer of polygons.
Thank you so much, we are close to the solution
Interesting what you can get if you don't create a "rectangular spiral" as in the image the OP provided, but just follow the line of a somewhat oval spiral (since the input area is a rectangle and not a square):
However, this is not what the OP wants...
I do think that the spacing used between the lines of the spiral will influence the resulting order. This might be something to look at.
While the OP snoozes away, I have gone down another avenue... extent centroid to polygon centroid, angle and distance calculations and ranking... lacking sufficient coffee, I will pack in for now
If only it were a fishnet... it would be so easy
Just to add some explanation of what I did. I created two scripts, one to create the spiral and the other one to order the polygons.
The first script to create the spiral looks like this:
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">main</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># formulas:</SPAN> <SPAN class="comment token"># x = phi cos phi</SPAN> <SPAN class="comment token"># y = phi sin phi</SPAN> <SPAN class="keyword token">import</SPAN> arcpy <SPAN class="keyword token">from</SPAN> math <SPAN class="keyword token">import</SPAN> pi<SPAN class="punctuation token">,</SPAN> sin<SPAN class="punctuation token">,</SPAN> cos arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>overwriteOutput <SPAN class="operator token">=</SPAN> <SPAN class="token boolean">True</SPAN> <SPAN class="comment token"># settings</SPAN> fc_parcels <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\Spiral\Parcels.shp'</SPAN> fc <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\Spiral\data.gdb\oval_spiral_v01'</SPAN> sr <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Describe<SPAN class="punctuation token">(</SPAN>fc_parcels<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>spatialReference scale_extent <SPAN class="operator token">=</SPAN> <SPAN class="number token">1.25</SPAN> <SPAN class="comment token"># size it to 125%</SPAN> pnts_cnt <SPAN class="operator token">=</SPAN> <SPAN class="number token">1000</SPAN> pnts_div <SPAN class="operator token">=</SPAN> <SPAN class="number token">40.0</SPAN> <SPAN class="comment token"># determine output extent</SPAN> ext <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Describe<SPAN class="punctuation token">(</SPAN>fc_parcels<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>extent ext <SPAN class="operator token">=</SPAN> ScaleExtent<SPAN class="punctuation token">(</SPAN>ext<SPAN class="punctuation token">,</SPAN> scale_extent<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># run 1, create the normal spiral</SPAN> lst_x<SPAN class="punctuation token">,</SPAN> lst_y<SPAN class="punctuation token">,</SPAN> lst_xy <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> lst <SPAN class="operator token">=</SPAN> range<SPAN class="punctuation token">(</SPAN>pnts_cnt<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">for</SPAN> i <SPAN class="keyword token">in</SPAN> reversed<SPAN class="punctuation token">(</SPAN>lst<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> phi <SPAN class="operator token">=</SPAN> float<SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">/</SPAN> pnts_div <SPAN class="operator token">*</SPAN> pi x <SPAN class="operator token">=</SPAN> phi <SPAN class="operator token">*</SPAN> cos<SPAN class="punctuation token">(</SPAN>phi<SPAN class="punctuation token">)</SPAN> y <SPAN class="operator token">=</SPAN> phi <SPAN class="operator token">*</SPAN> sin<SPAN class="punctuation token">(</SPAN>phi<SPAN class="punctuation token">)</SPAN> lst_x<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">)</SPAN> lst_y<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>y<SPAN class="punctuation token">)</SPAN> lst_xy<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN> y<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># determine scaling of spiral</SPAN> x_factor<SPAN class="punctuation token">,</SPAN> y_factor<SPAN class="punctuation token">,</SPAN> x_offset<SPAN class="punctuation token">,</SPAN> y_offset <SPAN class="operator token">=</SPAN> DefineScaling<SPAN class="punctuation token">(</SPAN>lst_x<SPAN class="punctuation token">,</SPAN> lst_y<SPAN class="punctuation token">,</SPAN> ext<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># run 2, translate the spiral</SPAN> pnts <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> xy <SPAN class="keyword token">in</SPAN> lst_xy<SPAN class="punctuation token">:</SPAN> x <SPAN class="operator token">=</SPAN> xy<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">*</SPAN> x_factor <SPAN class="operator token">+</SPAN> x_offset y <SPAN class="operator token">=</SPAN> xy<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">*</SPAN> y_factor <SPAN class="operator token">+</SPAN> y_offset pnt <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Point<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN> y<SPAN class="punctuation token">)</SPAN> pnts<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>pnt<SPAN class="punctuation token">)</SPAN> polyline <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Polyline<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Array<SPAN class="punctuation token">(</SPAN>pnts<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> sr<SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>CopyFeatures_management<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN>polyline<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> fc<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">def</SPAN> <SPAN class="token function">ScaleExtent</SPAN><SPAN class="punctuation token">(</SPAN>ext<SPAN class="punctuation token">,</SPAN> scale_extent<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> new_width <SPAN class="operator token">=</SPAN> ext<SPAN class="punctuation token">.</SPAN>width <SPAN class="operator token">*</SPAN> scale_extent new_height <SPAN class="operator token">=</SPAN> ext<SPAN class="punctuation token">.</SPAN>height <SPAN class="operator token">*</SPAN> scale_extent x_cc <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>ext<SPAN class="punctuation token">.</SPAN>XMin <SPAN class="operator token">+</SPAN> ext<SPAN class="punctuation token">.</SPAN>XMax<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">/</SPAN> <SPAN class="number token">2.0</SPAN> y_cc <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>ext<SPAN class="punctuation token">.</SPAN>YMin <SPAN class="operator token">+</SPAN> ext<SPAN class="punctuation token">.</SPAN>YMax<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">/</SPAN> <SPAN class="number token">2.0</SPAN> <SPAN class="keyword token">return</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Extent<SPAN class="punctuation token">(</SPAN>x_cc <SPAN class="operator token">-</SPAN> new_width <SPAN class="operator token">/</SPAN> <SPAN class="number token">2.0</SPAN><SPAN class="punctuation token">,</SPAN> y_cc <SPAN class="operator token">-</SPAN> new_height <SPAN class="operator token">/</SPAN> <SPAN class="number token">2.0</SPAN><SPAN class="punctuation token">,</SPAN> x_cc <SPAN class="operator token">+</SPAN> new_width <SPAN class="operator token">/</SPAN> <SPAN class="number token">2.0</SPAN><SPAN class="punctuation token">,</SPAN> y_cc <SPAN class="operator token">+</SPAN> new_height <SPAN class="operator token">/</SPAN> <SPAN class="number token">2.0</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">def</SPAN> <SPAN class="token function">DefineScaling</SPAN><SPAN class="punctuation token">(</SPAN>lst_x<SPAN class="punctuation token">,</SPAN> lst_y<SPAN class="punctuation token">,</SPAN> ext_out<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> xmin<SPAN class="punctuation token">,</SPAN> xmax <SPAN class="operator token">=</SPAN> min<SPAN class="punctuation token">(</SPAN>lst_x<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> max<SPAN class="punctuation token">(</SPAN>lst_x<SPAN class="punctuation token">)</SPAN> ymin<SPAN class="punctuation token">,</SPAN> ymax <SPAN class="operator token">=</SPAN> min<SPAN class="punctuation token">(</SPAN>lst_y<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> max<SPAN class="punctuation token">(</SPAN>lst_y<SPAN class="punctuation token">)</SPAN> width_in <SPAN class="operator token">=</SPAN> xmax <SPAN class="operator token">-</SPAN> xmin height_in <SPAN class="operator token">=</SPAN> ymax <SPAN class="operator token">-</SPAN> ymin x_factor <SPAN class="operator token">=</SPAN> ext_out<SPAN class="punctuation token">.</SPAN>width <SPAN class="operator token">/</SPAN> width_in y_factor <SPAN class="operator token">=</SPAN> ext_out<SPAN class="punctuation token">.</SPAN>height <SPAN class="operator token">/</SPAN> height_in x_offset <SPAN class="operator token">=</SPAN> ext_out<SPAN class="punctuation token">.</SPAN>XMin <SPAN class="operator token">-</SPAN> xmin <SPAN class="operator token">*</SPAN> x_factor y_offset <SPAN class="operator token">=</SPAN> ext_out<SPAN class="punctuation token">.</SPAN>YMin <SPAN class="operator token">-</SPAN> ymin <SPAN class="operator token">*</SPAN> y_factor <SPAN class="keyword token">return</SPAN> x_factor<SPAN class="punctuation token">,</SPAN> y_factor<SPAN class="punctuation token">,</SPAN> x_offset<SPAN class="punctuation token">,</SPAN> y_offset <SPAN class="keyword token">if</SPAN> __name__ <SPAN class="operator token">==</SPAN> <SPAN class="string token">'__main__'</SPAN><SPAN class="punctuation token">:</SPAN> main<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></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>
And it creates the spiral line.
Just to validate if it crosses all the polygons I manually did a select by location (but you can easily script this too).In case it doesn't select all the parcels, one should play with the values for pnts_cnt and pnts_div which define the number of spins.
In case it does select all the second step is to define the order of the parcels. This is done by first performing an intersect between the spiral line and the parcels. This too I did manually, but you can script this also. The resulting line featureclass will have all the intersecting segments. Next you will have to do a Multipart to Singlepart to ceate a feature for each part.
The order is then defined by the second script that validate the center of the segment on its position on the spiral. The lower this position (0-100%) the lower the assign value for the order.
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">main</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">import</SPAN> arcpy fc <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\Spiral\data.gdb\spiral_parcel_intersect_mp2sp_v01'</SPAN> fld_id <SPAN class="operator token">=</SPAN> <SPAN class="string token">'FID_Parcels'</SPAN> fc_spiral <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\Spiral\data.gdb\oval_spiral_v01'</SPAN> fc_parcels <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\Spiral\Parcels.shp'</SPAN> fld_out <SPAN class="operator token">=</SPAN> <SPAN class="string token">'Result'</SPAN> <SPAN class="comment token"># get data into dcts</SPAN> dct_fc <SPAN class="operator token">=</SPAN><SPAN class="punctuation token">{</SPAN>r<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>r<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> r<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> r <SPAN class="keyword token">in</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'OID@'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'SHAPE@'</SPAN><SPAN class="punctuation token">,</SPAN> fld_id<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">}</SPAN> spiral <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc_spiral<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'SHAPE@'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>next<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="comment token"># create the dictionary with the position</SPAN> dct_parcels <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">for</SPAN> oid<SPAN class="punctuation token">,</SPAN> lst <SPAN class="keyword token">in</SPAN> dct_fc<SPAN class="punctuation token">.</SPAN>items<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> polyline <SPAN class="operator token">=</SPAN> lst<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> fid <SPAN class="operator token">=</SPAN> lst<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> pntg <SPAN class="operator token">=</SPAN> polyline<SPAN class="punctuation token">.</SPAN>positionAlongLine<SPAN class="punctuation token">(</SPAN><SPAN class="number token">0.5</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">)</SPAN> pos <SPAN class="operator token">=</SPAN> spiral<SPAN class="punctuation token">.</SPAN>measureOnLine<SPAN class="punctuation token">(</SPAN>pntg<SPAN class="punctuation token">,</SPAN> <SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> fid <SPAN class="keyword token">in</SPAN> dct_parcels<SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># there can be multiple intersects</SPAN> min_pos <SPAN class="operator token">=</SPAN> dct_parcels<SPAN class="punctuation token">[</SPAN>fid<SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> pos <SPAN class="operator token"><</SPAN> min_pos<SPAN class="punctuation token">:</SPAN> dct_parcels<SPAN class="punctuation token">[</SPAN>fid<SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> pos <SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN> dct_parcels<SPAN class="punctuation token">[</SPAN>fid<SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> pos <SPAN class="comment token"># assign the order based on position</SPAN> dct_res <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN> cnt <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN> <SPAN class="keyword token">for</SPAN> fid<SPAN class="punctuation token">,</SPAN> pos <SPAN class="keyword token">in</SPAN> sorted<SPAN class="punctuation token">(</SPAN>dct_parcels<SPAN class="punctuation token">.</SPAN>items<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> key<SPAN class="operator token">=</SPAN><SPAN class="keyword token">lambda</SPAN> x<SPAN class="punctuation token">:</SPAN> x<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> cnt <SPAN class="operator token">+=</SPAN> <SPAN class="number token">1</SPAN> dct_res<SPAN class="punctuation token">[</SPAN>fid<SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> cnt <SPAN class="comment token"># add output field to the parcels</SPAN> <SPAN class="keyword token">if</SPAN> len<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>ListFields<SPAN class="punctuation token">(</SPAN>fc_parcels<SPAN class="punctuation token">,</SPAN> fld_out<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">==</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">:</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>AddField_management<SPAN class="punctuation token">(</SPAN>fc_parcels<SPAN class="punctuation token">,</SPAN> fld_out<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"SHORT"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># update the parcels</SPAN> flds <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'OID@'</SPAN><SPAN class="punctuation token">,</SPAN> fld_out<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>UpdateCursor<SPAN class="punctuation token">(</SPAN>fc_parcels<SPAN class="punctuation token">,</SPAN> flds<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> curs<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> curs<SPAN class="punctuation token">:</SPAN> fid <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> fid <SPAN class="keyword token">in</SPAN> dct_res<SPAN class="punctuation token">:</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> dct_res<SPAN class="punctuation token">[</SPAN>fid<SPAN class="punctuation token">]</SPAN> curs<SPAN class="punctuation token">.</SPAN>updateRow<SPAN class="punctuation token">(</SPAN>row<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> __name__ <SPAN class="operator token">==</SPAN> <SPAN class="string token">'__main__'</SPAN><SPAN class="punctuation token">:</SPAN> main<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>
The result will look like this:
Since your spiral is more rectangular, the code would have to generate the "spiral" in a different way.
Looks good! If distance and direction to the parcel centroids are needed, I can provide those pieces to supplement this.
The minimum spiral tightness to ensure complete selection of all the parcels could be an iterative process, but I suspect 'corner-cases' can be found for any implementation.
This could be a result using the "rectangular spiral":
Results depend highly on the spacing size...
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">main</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">import</SPAN> arcpy arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>overwriteOutput <SPAN class="operator token">=</SPAN> <SPAN class="token boolean">True</SPAN> <SPAN class="comment token"># settings</SPAN> fc_parcels <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\Spiral\Parcels.shp'</SPAN> fc <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\Spiral\data.gdb\rectangle_spiral_v10'</SPAN> sr <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Describe<SPAN class="punctuation token">(</SPAN>fc_parcels<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>spatialReference spacing <SPAN class="operator token">=</SPAN> <SPAN class="number token">250.0</SPAN> <SPAN class="comment token"># determine output extent</SPAN> ext <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Describe<SPAN class="punctuation token">(</SPAN>fc_parcels<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>extent x <SPAN class="operator token">=</SPAN> ext<SPAN class="punctuation token">.</SPAN>XMin y <SPAN class="operator token">=</SPAN> ext<SPAN class="punctuation token">.</SPAN>YMax <SPAN class="operator token">-</SPAN> spacing pnt <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Point<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN> y<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># loop</SPAN> finished <SPAN class="operator token">=</SPAN> <SPAN class="token boolean">False</SPAN> pnts <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN>pnt<SPAN class="punctuation token">]</SPAN> xmin <SPAN class="operator token">=</SPAN> x xmax <SPAN class="operator token">=</SPAN> ext<SPAN class="punctuation token">.</SPAN>XMax ymax <SPAN class="operator token">=</SPAN> y ymin <SPAN class="operator token">=</SPAN> ext<SPAN class="punctuation token">.</SPAN>YMin done <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">while</SPAN> finished <SPAN class="operator token">==</SPAN> <SPAN class="token boolean">False</SPAN><SPAN class="punctuation token">:</SPAN> xmax <SPAN class="operator token">-=</SPAN> spacing <SPAN class="keyword token">while</SPAN> x <SPAN class="operator token"><</SPAN> xmax<SPAN class="punctuation token">:</SPAN> xy <SPAN class="operator token">=</SPAN> "<SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="comment token">#{}".format(x, y)</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> xy <SPAN class="keyword token">in</SPAN> done<SPAN class="punctuation token">:</SPAN> done<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>xy<SPAN class="punctuation token">)</SPAN> pnts<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Point<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN> y<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> x <SPAN class="operator token">+=</SPAN> spacing ymin <SPAN class="operator token">+=</SPAN> spacing <SPAN class="keyword token">while</SPAN> y <SPAN class="operator token">></SPAN> ymin<SPAN class="punctuation token">:</SPAN> xy <SPAN class="operator token">=</SPAN> "<SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="comment token">#{}".format(x, y)</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> xy <SPAN class="keyword token">in</SPAN> done<SPAN class="punctuation token">:</SPAN> done<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>xy<SPAN class="punctuation token">)</SPAN> pnts<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Point<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN> y<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> y <SPAN class="operator token">-=</SPAN> spacing xmin <SPAN class="operator token">+=</SPAN> spacing <SPAN class="keyword token">while</SPAN> x <SPAN class="operator token">></SPAN> xmin<SPAN class="punctuation token">:</SPAN> xy <SPAN class="operator token">=</SPAN> "<SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="comment token">#{}".format(x, y)</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> xy <SPAN class="keyword token">in</SPAN> done<SPAN class="punctuation token">:</SPAN> done<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>xy<SPAN class="punctuation token">)</SPAN> pnts<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Point<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN> y<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> x <SPAN class="operator token">-=</SPAN> spacing ymax <SPAN class="operator token">-=</SPAN> spacing <SPAN class="keyword token">while</SPAN> y <SPAN class="operator token"><</SPAN> ymax<SPAN class="punctuation token">:</SPAN> xy <SPAN class="operator token">=</SPAN> "<SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="comment token">#{}".format(x, y)</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> xy <SPAN class="keyword token">in</SPAN> done<SPAN class="punctuation token">:</SPAN> done<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>xy<SPAN class="punctuation token">)</SPAN> pnts<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Point<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN> y<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> y <SPAN class="operator token">+=</SPAN> spacing <SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>xmax <SPAN class="operator token">-</SPAN> xmin<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token"><</SPAN> spacing <SPAN class="operator token">and</SPAN> <SPAN class="punctuation token">(</SPAN>ymax <SPAN class="operator token">-</SPAN> ymin<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token"><</SPAN> spacing<SPAN class="punctuation token">:</SPAN> finished <SPAN class="operator token">=</SPAN> <SPAN class="token boolean">True</SPAN> <SPAN class="comment token"># create the rectangle spiral</SPAN> polyline <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Polyline<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Array<SPAN class="punctuation token">(</SPAN>pnts<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> sr<SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>CopyFeatures_management<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN>polyline<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> fc<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> __name__ <SPAN class="operator token">==</SPAN> <SPAN class="string token">'__main__'</SPAN><SPAN class="punctuation token">:</SPAN> main<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></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Dear Xander Bakker
The "rectangular spiral" seems to me the most suitable.
Since I am a beginner, I can not run the script by copying it to the Python window on ArcGIS. I would like, if possible, to have a procedure to be able to execute it correctly. For this, I send you a small group of parcels (168) in a geodatabase. Please help me understand the parts of the script that I have to modify later for other lots of parcels.Many thanks.
PS: Some print screen could help too.
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.