I have many FC1(pole) and FC2(sub) in my map, I need the Arcpy code for when I select a group of one FC1 and many FC2, and place the FC3 line from FC1 to FC2s at a time.
Solved! Go to Solution.
Similar to JohannesLindner's solution but skips the need for a common field and a join. Instead relies on valid selection. There are many ways to get this kind of output.
import arcpy
# Set the name of the point feature layers
points_layer1 = "facilities"
points_layer2 = "pts"
lines_layer = "lines"
# preconditions: select one feature from points_layer1 and one or more from points_layer2
assert arcpy.management.GetCount(points_layer1)[0] == "1", "select exactly 1 point from points_layer1"
assert int(arcpy.management.GetCount(points_layer1)[0]) > 0, "select > 0 point(s) from points_layer2"
# Get the coordinates of the 1 selected feature in points_layer1
with arcpy.da.SearchCursor(points_layer1, ["SHAPE@XY"]) as cursor:
for row in cursor:
end_x, end_y = row[0]
end_point = arcpy.PointGeometry(arcpy.Point(float(end_x), float(end_y)))
# Create a new feature class to store the lines if needed
if not arcpy.Exists(lines_layer):
arcpy.management.CreateFeatureclass(arcpy.env.workspace, "lines", "POLYLINE")
# Create an array to store the line geometry
line_array = arcpy.Array()
with arcpy.da.SearchCursor(points_layer2, ["SHAPE@XY"]) as cursor:
for row in cursor:
start_x, start_y = row[0]
start_point = arcpy.PointGeometry(arcpy.Point(float(start_x), float(start_y)))
# Append the start and end points to the line array
line_array.append(start_point.centroid)
line_array.append(end_point.centroid)
# Create a polyline object from the line array
line = arcpy.Polyline(line_array)
line_array.removeAll()
# use the insert cursor to insert the line into the lines feature class
with arcpy.da.InsertCursor(lines_layer, ["SHAPE@"]) as icursor:
icursor.insertRow([line])
# re-add the lines layer to the map to help refresh the display, symbology is preserved
arcpy.management.MakeFeatureLayer(lines_layer,"lines")
Ah thanks for finding that typo. I'm not seeing the "one long line is placed on the downside" on my end. Could it be left over from before you fixed the typo?
As far as the lines layer being already present in the map, that should be taken care of by:
if not arcpy.Exists(lines_layer):
I hope that helps! Have a good one.
pole_fc = "TestPoints2"
sub_fc = "TestPoints"
line_fc = "TestLines"
common_field = "IntegerField"
# read the pole shapes
pole_dict = {
id: shape
for id, shape in arcpy.da.SearchCursor(pole_fc, [common_field, "SHAPE@"])
)
# start inserting into the line fc
with arcpy.da.InsertCursor(line_fc, ["SHAPE@"]) as i_cursor:
# loop over the sub fc
with arcpy.da.SearchCursor(sub_fc, [common_field, "SHAPE@"]) as s_cursor:
for id, shape in s_cursor:
# get the corresponding pole, skip if not found
try:
pole = pole_dict[id]
except KeyError:
continue
# construct and insert the new line
line_shape = arcpy.Polyline(arcpy.Array([pole.firstPoint, shape.firstPoint]), pole.spatialReference)
i_cursor.insertRow([line_shape])
Similar to JohannesLindner's solution but skips the need for a common field and a join. Instead relies on valid selection. There are many ways to get this kind of output.
import arcpy
# Set the name of the point feature layers
points_layer1 = "facilities"
points_layer2 = "pts"
lines_layer = "lines"
# preconditions: select one feature from points_layer1 and one or more from points_layer2
assert arcpy.management.GetCount(points_layer1)[0] == "1", "select exactly 1 point from points_layer1"
assert int(arcpy.management.GetCount(points_layer1)[0]) > 0, "select > 0 point(s) from points_layer2"
# Get the coordinates of the 1 selected feature in points_layer1
with arcpy.da.SearchCursor(points_layer1, ["SHAPE@XY"]) as cursor:
for row in cursor:
end_x, end_y = row[0]
end_point = arcpy.PointGeometry(arcpy.Point(float(end_x), float(end_y)))
# Create a new feature class to store the lines if needed
if not arcpy.Exists(lines_layer):
arcpy.management.CreateFeatureclass(arcpy.env.workspace, "lines", "POLYLINE")
# Create an array to store the line geometry
line_array = arcpy.Array()
with arcpy.da.SearchCursor(points_layer2, ["SHAPE@XY"]) as cursor:
for row in cursor:
start_x, start_y = row[0]
start_point = arcpy.PointGeometry(arcpy.Point(float(start_x), float(start_y)))
# Append the start and end points to the line array
line_array.append(start_point.centroid)
line_array.append(end_point.centroid)
# Create a polyline object from the line array
line = arcpy.Polyline(line_array)
line_array.removeAll()
# use the insert cursor to insert the line into the lines feature class
with arcpy.da.InsertCursor(lines_layer, ["SHAPE@"]) as icursor:
icursor.insertRow([line])
# re-add the lines layer to the map to help refresh the display, symbology is preserved
arcpy.management.MakeFeatureLayer(lines_layer,"lines")
Danny, the code is running without errors but the lines are placed somewhere not to the pts! and m using WGS 1984 Web Mercator(auxiliary sphere) coordinate system
To fix this issue, i replaced float(start_x), float(start_x) with float(start_x), float(start_y). this time, lines are placed on the pts, but one long line is placed on the downside!!!, and I need one more correction in the code please, the lines layer will be already present in the map, code has to use the same line layer for all the pts. no need to create a line feature every time. ( the line has to start from pole_fc to Subsfc)
Ah thanks for finding that typo. I'm not seeing the "one long line is placed on the downside" on my end. Could it be left over from before you fixed the typo?
As far as the lines layer being already present in the map, that should be taken care of by:
if not arcpy.Exists(lines_layer):
I hope that helps! Have a good one.