Select to view content in your preferred language

i need to place line between two feature class

810
4
Jump to solution
02-01-2023 05:55 AM
YuvarajuDhananjay
New Contributor II

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. 

YuvarajuDhananjay_1-1675259632425.png

 

0 Kudos
2 Solutions

Accepted Solutions
DannyMcVey
Esri Contributor

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")

 

 

 

DannyMcVey_0-1675271817825.png

 

View solution in original post

0 Kudos
DannyMcVey
Esri Contributor

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):

2023-02-02_9-49-59.gif

 

I hope that helps! Have a good one.

View solution in original post

4 Replies
JohannesLindner
MVP Frequent Contributor

 

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])

 

JohannesLindner_0-1675267544426.png

 

 


Have a great day!
Johannes
DannyMcVey
Esri Contributor

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")

 

 

 

DannyMcVey_0-1675271817825.png

 

0 Kudos
YuvarajuDhananjay
New Contributor II

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

YuvarajuDhananjay_0-1675320925445.png

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)

YuvarajuDhananjay_2-1675321768686.png

 

 

 

0 Kudos
DannyMcVey
Esri Contributor

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):

2023-02-02_9-49-59.gif

 

I hope that helps! Have a good one.