Spatial Join - looping with arcpy - order issues of join_count fields

2733
6
02-15-2016 11:53 PM
MilenaKocher
New Contributor

I developed a python script where the user can enter

  • a polygon shapefile
  • multiple point shapefiles

and within the script the polygon shapefile is divided into 1000mx1000m grid cells and then the point shapefiles are joined to the polygon within a for loop, where the intersecting points per cell are counted.

I tested the code and everything was fine, but now I detected a huge issue. The order of the added join count fields (Join_Count, Join_Cou_1, Join_Cou_2, etc.) does not correspond to the order in which the point shapefiles were entered.

Below the input order and output order can be seen. I tried it multiple times, but it seems there is no logic behind the order, so not alphabetical, Input order, reverse order, or anything. It seems like it would be ordered randomly.

  • Bank -> Join_Count (Bank)
  • Kino -> Join_Cou_1 (Post)
  • Park -> Join_Cou_2 (Park)
  • Post -> Join_Cou_3 (Kino)

Why can this happen? Shouldn't the first point shapefile which is joined first, get the Join_Count field, the second point shapefile that is joined next, the Join_Cou_1 field and so on?

Below is my code.

import arcpy
studyarea = arcpy.GetParameterAsText(0) 
inputPoints = arcpy.GetParameterAsText(1)
outputLocation = arcpy.GetParameterAsText(2) 

arcpy.GridIndexFeatures_cartography('in_memory\studyarea_grid', studyarea, 'INTERSECTFEATURE', 'NO_USEPAGEUNIT', "#", 1000, 1000)
studyAreaGrid = arcpy.Clip_analysis('in_memory\studyarea_grid', studyarea, arcpy.Polygon)

inputPoints_set = inputPoints.split(';') 

spatialJoin = studyAreaGrid
for pointShp in inputPoints_set:
    spatialJoin = arcpy.SpatialJoin_analysis(spatialJoin, pointShp, arcpy.Polygon, 'JOIN_ONE_TO_ONE', 'KEEP_ALL', '', 'INTERSECT')


arcpy.CopyFeatures_management(spatialJoin, outputLocation)

0 Kudos
6 Replies
BenjaminMittler
Occasional Contributor III

Just taking a stab here. It's possible this is incorrect, i'm not familiar with using a arcpy.polygon as an output.

Is it possible you are overwriting your output with each iteration rather than adding to it? Wouldn't you need the output of the first iteration to become the input of the second and so on.. to me it doesnt look like this is happening.

Again, i could be wrong.

Ben

0 Kudos
WesMiller
Regular Contributor III

You could use Mapping input fields to output fields—Help | ArcGIS for Desktop to create your own fields you could then do your counts

DarrenWiens2
MVP Honored Contributor

Do you get the same results saving to a feature class rather than geometry objects?

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

The OP's script isn't copying the results into a list of geometry objects, it is creating in-memory feature classes.  I will elaborate in a comment to the OP.

0 Kudos
DanPatterson_Retired
MVP Emeritus

random order in the appearance, suggests that the results are being stored in a dictionary rather than in a list.  Unless there is some key in the dictionary to guarantee first-in-first out, then sorting this will be difficult/awkward.  Note the order of the dictionary outputs is not the same as the inputs.

ie

>>> d = {"a": 1, "b": 2, "c": 3}
>>> d
{'b': 2, 'a': 1, 'c': 3}
>>> d.keys()
dict_keys(['b', 'a', 'c'])
>>> d.items()
dict_items([('b', 2), ('a', 1), ('c', 3)])
>>> d.values()
dict_values([2, 1, 3])
JoshuaBixby
MVP Esteemed Contributor

If you don't mind me asking, what do you think the use of arcpy.Polygon is accomplishing in this script?  If the goal is to have the tool create a unique path and name for the output, the standard or best practice is to use either "#" or None (See Tool Output section in Using tools with Python).

Even though the output from the Clip tool can be a Python list of geometry objects (using arcpy.Geometry() , not arcpy.Geometry) , I don't know whether doing so will work for later processing in the script.  So, I recommend staying with feature classes as the outputs and using one of the standard methods for auto generating unique names.

Have you tried using GetParameter instead of GetParameterAsText?  I don't know why it should/would make a difference but maybe getting the parameters back as objects might be more predictable than what you are seeing getting them back as text.

0 Kudos