15

I keep thinking that I must be missing something, but there does not seem to be a tool in ArcGIS 10 to select features (in particular polygons) from a layer at a point (X,Y) location via ArcPy. The parameters for such a tool would just be a layer name and an XY location.

At the moment I workaround this by creating a point featureclass containing the point and performing a SelectLayerByLocation on it. However, when the polygon feature class is in Oracle (accessed via ArcSDE 9.x) and contains 3.5 million polygons the time taken to make the selection can be more than 5 mins when I think a second or two (with less code) would be more appropriate. The feature class has a spatial index and I've tried using arcpy.env.extent (which SelectLayerByLocation appears to ignore) to restrict the geographic area accessed but the performance remains very poor.

Is there a quicker way to do this using ArcGIS Desktop 10 and ArcPy?

2

3 Answers 3

9

Another approach to this would be to use the Spatial Join tool. Use the point as your input feature layer as above and the polygon layer as your identity features.
Unlike SelectLayerByLocation, SpatialJoin does honor the extent environment.

targetlayer = layername
joinlayer=arcpy.PointGeometry(arcpy.Point(x, y))
fieldmappings = arcpy.FieldMappings()
fieldmappings.addTable(targetlayer)
arcpy.SpatialJoin_analysis(targetlayer, joinlayer, outputlayer, "JOIN_ONE_TO_MANY", "KEEP_COMMON", fieldmappings)

JOIN_ONE_TO_MANY might seem counter-intuitive, but since you only have one join feature, the main function of this option is to turn off aggregationand merge rules. KEEP_COMMON will make sure that your output is restricted only to the polygon that intersects your point. The Fieldmappings will restrict the output attributes to the shape and attributes of the polygon layer only; the default would include the point layer's attributes too.

The rest of the defaults will work fine, so you can leave off the remaining arguments.

3
  • Many thanks for this code which contained a couple of techniques that I had not tried. I had earlier tried SpatialJoin (so that I could have the geoprocessing environment respected) but that testing, as well as a test of your technique just now, still left me with 4-5 minute response times compared to 10-12 seconds for the way Chris Snyder led me to.
    – PolyGeo
    Aug 4, 2011 at 0:03
  • Have you tried Chris Snyder's technique with SpatialJoin too? I think the main reason the buffer technique is so fast is that it uses an in memory copy of the polygon class. I -think- selection by location should be faster than spatial join, but I am not sure. Aug 4, 2011 at 16:57
  • Ended up not using the in_memory bit. It was already sped up so much that I kept that in reserve. I think the key thing was setting the extent to get the one/few polygons (from 3.5 million), that I needed to check the X,Y against, quickly copied out into a local file geodatabase. So doing that part before the SpatialJoin would I think lead to the same/similar performance improvement.
    – PolyGeo
    Aug 4, 2011 at 22:54
1

I just realized something...

If you are using this to implement a Geoprocessing Service, you could also implement a Feature Service with your polygon layer instead and use the Query operation on the feature service.

You can use a simple XY location with Feature Service Query operation, as well as control the output attributes including shape.

You might have restrictions on how much you can expose the polygon feature class, but if you are already making it accessible to the geoprocessing service, then you should be able to build a Feature Service as well.

2
  • This is a useful thought to meet other requirements but, in this case, the client application is very simple, and out of my control, so I am only able to provide a Geoprocessing Service.
    – PolyGeo
    Aug 8, 2011 at 0:04
  • I figured there might be a restriction on using anything other than a Geoprocessing Service :) Ironically, I think a Feature Service is a much more simple route to implement and maintain. This might also explain why the functionality you want is not available; you can already do it in every application level. Make sure you send in a request to ESRI to implement it as a tool in the next version. Aug 8, 2011 at 11:12
1

This answer came from the old ArcGIS Discussion Forums.

Thanks Jason Scheirer for some more concise code:

SelectLayerByLocation(in_layer=arcpy.PointGeometry(arcpy.Point(x, y)), select_features="mylayer") 

And especially to Chris Snyder for a performance tip:

A speedier work around might be to buffer your point a bit and then use the buffer extent as the analysis extent to make an in_memory copy (CopyFeatures tool) of your SDE data, and then do a SelectByLocation on the smaller and local in_memory dataset. That way you are sort of making the SelectByLocation tool honor the analysis extent environment, which it would not normally do. BTW: Any features that overlap with the analysis extent will be copied with the CopyFeatures tool. I sure wish the SelectByLocation tool and the cursors methods honored the analysis extent...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.