Hi
Anyone any ideas how I can do a spatial join that is similar to the "within distance of" but looks at the outline of the initial feature?
So, for example, I have a polygon and some points. I want to join the two layers where the points are within a set distance of the OUTLINE - so if it is 1 m from the outline, either outside the polygon or inside it gets counted. If it is 1 metre away from the outline INSIDE the polygon it gets ignored.
Cheers
ACM
Edit - as I work around I have used FME to create a polyline version of the feature, retaining the origional object ID, the doing the join, then hoplefully atribute join the original layer back to get the joincount - which is the field I am after.
Solved! Go to Solution.
Select by Location within a distance of ... Select Layer By Location—Help | ArcGIS for Desktop
spatial join with the same option Spatial Join—Help | ArcGIS for Desktop and
near are your options Near—Help | ArcGIS for Desktop
if a polygon is used and something is inside, its distance is 0 so a point overlapping a polygon would get selected, however, if the destination feature was converted to a polyline, then it may not be. You have to choose which option you want
Select by Location within a distance of ... Select Layer By Location—Help | ArcGIS for Desktop
spatial join with the same option Spatial Join—Help | ArcGIS for Desktop and
near are your options Near—Help | ArcGIS for Desktop
if a polygon is used and something is inside, its distance is 0 so a point overlapping a polygon would get selected, however, if the destination feature was converted to a polyline, then it may not be. You have to choose which option you want
If you have already converted the polygon boundaries into a polyline featureclass, you can best you the Select By Location described by Dan. It would be nice to be able to use the polygons directly as input, but the options "touch the boundary of the source layer" and "are crossed by the outline of the source layer" do not allow you to specify a buffer distance.
As an alternative you could also buffer the polygon with 1 m and with -1 m, and erase the area (-1 m) from the other buffer area (1m) and use the Select By Location with the intesect option. This would require Advanced license and contains more steps than the converting the polygon outlines to line features.
Cheers - the polyline method seemed to work fine, gave me what I wanted, but a shame I had to use another program to create the polylines - we've only got an ArcEditor license, so the Esri tool wasn't available.
You are right, there are a number of very common features that are only available with the Advanced license level. It is however, quite simple to create a tool (using some Python code) to generate the outlines based on the polygon boundaries.
It you are interested, I can see what I can do.
Thanks - but as I have FME as well, it was very simple.
In fact, I already made a tool that extracts the polygon outline and creates a polyline featureclass. Below the code of the tool:
The parameters are:
#------------------------------------------------------------------------------- # Name: FeatureToLine.py # Purpose: Convertir feature a punto # # Author: xbakker # # Created: 14/10/2015 #------------------------------------------------------------------------------- import arcpy import os def main(): # parameters fc_in = arcpy.GetParameterAsText(0) fc_out = arcpy.GetParameterAsText(1) preserve_atts = arcpy.GetParameter(2) # true o false # geometria de salida geomtype = "POLYLINE" sr = arcpy.Describe(fc_in).spatialReference # recreate fc_out based on fc_lines (in) using template ws_name, fc_name = os.path.split(fc_out) if preserve_atts: createFeatureClassTemplate(fc_out, fc_in, geomtype, fc_in, sr) else: createFeatureClass(fc_out, fc_in, geomtype, sr) # cursors: cnt = 0 if preserve_atts: flds = getAllFieldsWithoutGeometryFields(fc_in) else: flds = ('SHAPE@') with arcpy.da.InsertCursor(fc_out, flds) as curs_out: with arcpy.da.SearchCursor(fc_in, flds) as curs: for row in curs: polygon = row[0] polyline = polygon.boundary() if preserve_atts: lst_row = list(row) lst_row[0] = polyline row_out = tuple(lst_row) else: row_out = (polyline, ) # store polyline cnt += 1 if cnt % 100 == 0: arcpy.AddMessage("Procesando feature: {0}".format(cnt)) curs_out.insertRow(row_out) arcpy.AddMessage("{0} features procesados...".format(cnt)) def getAllFieldsWithoutGeometryFields(fc): flds = [fld.name for fld in arcpy.ListFields(fc)] desc = arcpy.Describe(fc) fld_length = desc.lengthFieldName fld_area = desc.areaFieldName fld_shape = desc.shapeFieldName if fld_length in flds: flds.pop(flds.index(fld_length)) if fld_area in flds: flds.pop(flds.index(fld_area)) if fld_shape in flds: flds.pop(flds.index(fld_shape)) flds.insert(0, 'SHAPE@') return flds def createFeatureClass(fc_out, fc_in, geomtype, sr): ws_name, fc_name = os.path.split(fc_out) arcpy.CreateFeatureclass_management(ws_name, fc_name, geomtype, spatial_reference=sr) def createFeatureClassTemplate(fc_out, fc_in, geomtype, template, sr): ws_name, fc_name = os.path.split(fc_out) arcpy.CreateFeatureclass_management(ws_name, fc_name, geomtype, template, spatial_reference=sr) if __name__ == '__main__': main()