Select to view content in your preferred language

"Select By Location" and "Update Cursor" functionality in ArcGIS API

210
2
4 weeks ago
AdamGaudet
New Contributor III

I'm looking for a process in the ArcGIS API that would essentially function the same as "Select By Location" and "Update Cursor" in arpcy.

Basically, I have a point layer and a line layer, and I want to update attribute information of the line layer anytime the point layer intersects (or comes within 10m) of the line layer.

The best sort of quasi-solution I found so far is arcgis.features.find_locations where I can create a new output feature layer from this point-line intersection, though I don't necessarily want to create anything new - I just want to update what's already there.

I also want to build on this so that "Select By Location" changes per various where clauses, so that different line intersection queries are ran subsequently.

This is a pretty simple and straightforward workflow were I to be doing this in arcpy (Select By Location with where clause > Update Cursor > next item in list), though I can't seem to wrap my head around how I might be able to do this in the ArcGIS API. Any ideas?

0 Kudos
2 Replies
MobiusSnake
MVP

To identify the lines within 10m of a point you'll want to use the FeatureLayer.query() function, it includes a geometry_filter parameter where you can pass a filter object (this will include your point), along with the distance parameter where you set your threshold.

You can push updates to the layer using the FeatureLayer.edit_features() function, it's a little bit different approach than using a cursor however.  Iterating through features is something you want to avoid using services, you want to group your edits together into a list and push them through as a bulk edit to optimize performance.

0 Kudos
EarlMedina
Esri Regular Contributor

There's a few different ways you can do this. Here's an example that uses buffers on point data and updates an "IntersectIds" field in a line feature layer to note which points are within 10m of a line:

 

 

import pandas as pd
from arcgis import GIS
from arcgis.geometry import Geometry
from arcgis.features import FeatureLayer

gis = GIS("https://www.arcgis.com", "user", "passwd")

point_url = "https://services3.arcgis.com/ON5SbcAnb3R45678/arcgis/rest/services/point/FeatureServer/0"
point_fl = FeatureLayer(point_url, gis)
point_df = pd.DataFrame.spatial.from_layer(point_fl)

line_url = "https://services3.arcgis.com/ON5SbcAnb3Rdfghj/arcgis/rest/services/ln/FeatureServer/0"
line_fl = FeatureLayer(line_url, gis)
line_df = pd.DataFrame.spatial.from_layer(line_fl)

buffer_df = point_df.copy()
buffer_df["SHAPE"] = buffer_df["SHAPE"].apply(lambda x: x.buffer(10))

joined = line_df.spatial.join(
    buffer_df, 
    how="left", 
    op="intersects", 
    left_tag="left", 
    right_tag="right"
)

intersecting_records = joined[~joined["OBJECTID_right"].isnull()].copy()
intersecting_records["IntersectIds"] = intersecting_records["PointId"].astype(str)

intersecting_records = intersecting_records.copy()[["OBJECTID_left", "IntersectIds"]].rename(columns={"OBJECTID_left" : "OBJECTID"})

final = intersecting_records.groupby("OBJECTID")["IntersectIds"].apply(",".join).reset_index()

fs = final.spatial.to_featureset()
line_fl.edit_features(updates=fs)

 

0 Kudos