AnsweredAssumed Answered

Use ArcGIS API for Python to snap points to nearest line?

Question asked by ezhatcher on Mar 3, 2020
Latest reply on Mar 4, 2020 by ezhatcher

I'm trying to snap multiple point features to a line using the arcgis API for Python. The arcpy method isn't viable for the end-users of this tool as they don't have consistent access to an Advanced Use license.


What I'd like to be able to do is find the nearest line to each point, then snap that point to that nearest line. I've tried two methods here, iterating through the features in the feature service as below...

import arcgis
from arcgis.features import FeatureLayer, use_proximity
from arcgis.geometry import Geometry, Point, Polyline

point_svc = "service url"
line_svc = "service url"

point_ft = FeatureLayer(point_svc).query().features
line_ft = FeatureLayer(line_svc)

# Go through each point in the point feature layer, and find its nearest line feature. Then,
#snap that given point to the nearest line feature.
for p in point_ft:
    ## The FeatureInput documentation states that both the analysis and near
    ##features need to   be items, a FeatureLayer or FeatureCollection instance, or a Feature
    ##Service URL string.
    nearest = use_proximity.find_nearest(p, line_ft)
    new_pt = p.snap_to_line(nearest)


This option, predictably according to the FeatureInput documentation, doesn't like the input layer formats.


What does work for at least creating a nearest line layer is using the point_svc and line_svc as inputs, but I'm very lost as to how I can use the resulting feature layer collections to snap the points to the lines...

nearest = use_proximity.find_nearest(point_svc, line_svc)
{'nearest_layer': <FeatureCollection>, 'connecting_lines_layer': <FeatureCollection>}


The 'nearest_layer' Feature Collection that's output has a "SNAP_" and "SNAP_ID" field that I would assume relate to the Object ID of the points in the analysis layer, but unfortunately, they don't relate, and I can find no other field in that output Feature Collection that relates to the point on which the find_nearest was based (unless find_nearest doesn't compare features to features, but rather entire services to services...).


Point service OIDs (three points in total):


find_nearest output Feature Collection item attributes:


Does anyone know any cleaner methods of accomplishing this task using the API, or how to then work with the nearest feature collection to then reference the points in the points feature service to those nearest lines and then snap them?