5

As shown in the image below, I'd like to return a new field in layer 2 that for each segment stores a string:"Road C, 1 km from Road A to 0.5km From Road B".

Calculation of the distances could be considered optional; however, it must be able to return the nearest road name to each of the segments vertices. Names are just an attribute of Road C.

If there is no nearest road on the end side (Dead end) then the script should return None.

image showing location of segment from layer 2 with respect to layer 1.

What I have been able to do so far is generate a nearest table that gives me a nearest FeatureID. I join that back to the Layer 1 and return a name; however, that doesn't give me a distance or the nearest road on the other end.

Note that all of these roads are part of the linear reference system

EDIT 1:

the solution cannot pick an intersecting road that's within the "green" road's boundaries.

2
  • Initially, how are the green road/segments being flagged?
    – artwork21
    Nov 17 '14 at 16:38
  • @artwork21 Control section Linear referenced Event table that's made into a route layer
    – dassouki
    Nov 17 '14 at 16:39
5
+50

You could try something like this:

enter image description here

for the scenario shown above, the script below

import arcpy

roads1 = #path to roads layer 1
roads2 = #path to roads layer 2

r1 = [row for row in arcpy.da.SearchCursor(roads1,["SHAPE@","NAME"])]

#add field to hold required string
arcpy.AddField_management(roads2,"COMMENTS","TEXT")

with arcpy.da.UpdateCursor(roads2,["SHAPE@","NAME","COMMENTS"]) as cursor:
    for r in r1:
        for row in cursor:
            if r[0].contains(row[0]):
                print "{0} contains {1}".format(r[1],row[1])

            #start = arcpy.PointGeometry(row[0].firstPoint)
            #end = arcpy.PointGeometry(row[0].lastPoint)

            #road segments connected to the road segment from layer 1 that "contains"
            # a segment from layer 2
            connected_segments = [x for x in r1 if x[0].touches(r[0])]

            #find closest road segments
            #closest_seg_to_start = [[y[1],y[0].queryPointAndDistance(start)[2]] for y in connected_segments if len(connected_segments)]
            #closest_seg_to_end = [[y[1],y[0].queryPointAndDistance(end)[2]] for y in connected_segments if len(connected_segments)]

            closest_seg_to_start = [[y[1],y[0].distanceTo(row[0].firstPoint)] for y in connected_segments if len(connected_segments)]
            closest_seg_to_end = [[y[1],y[0].distanceTo(row[0].lastPoint)] for y in connected_segments if len(connected_segments)]

            if len(closest_seg_to_start):
                start_min_dist = min([x[1] for x in closest_seg_to_start])
                start_seg_name = [x[0] for x in closest_seg_to_start if x[1]== start_min_dist][0]
                print "{0} is {1}km from start point of {2}".format(start_seg_name,round(start_min_dist/1000.0,2),row[1])

            if len(closest_seg_to_end):
                end_min_dist = min([x[1] for x in closest_seg_to_end])
                end_seg_name = [x[0] for x in closest_seg_to_end if x[1]== end_min_dist][0]
                print "{0} is {1}km from end point of {2}".format(end_seg_name,round(end_min_dist/1000.0,2),row[1])

                comment = "{0},{1}km from {2} to {3}km from {4}".format(r[1],round(start_min_dist/1000.0,2),start_seg_name,round(end_min_dist/1000.0,2),end_seg_name)
                print comment
                row[2] = comment #add string to field

        cursor.updateRow(row)

produces these results:

enter image description here

enter image description here

3
  • 2
    the queryPointAndDistance function was introduced at 10.2.1
    – Nxaunxau
    Nov 19 '14 at 16:21
  • Thanks for the solution, I don't have 10.2. We're still on 10.1
    – dassouki
    Nov 20 '14 at 14:02
  • 1
    @dassouki - i have modified the script so it works with 10.1. I replaced the queryPointAndDistance function with the distanceTo function, which is available at 10.1
    – Nxaunxau
    Nov 20 '14 at 15:08
1

I don't have access to ArcPy at the moment, but if you are happy working in that environment, then I reckon you'll be able to code it up pretty easy.

Now, my assumption is that you can use road line endpoints, and you don't need to do any network traversal in order to build a reasonable model. Doing a network traversal would be a little harder. Here's some pseudo code, though, for a basic version that should work:

  1. Identify all the road line endpoints in your dataset, or in the vicinity of your section if that's too resource intensive
  2. Exclude the road line that intersects your segment of interest
  3. Search all the road line endpoints (from 1) to find the nearest one to each end of your segment of interest
  4. store the road ID and road name and distance on your segment.

You'll need some qualification for 3 in order to work out if you are at the end of a road. Maybe you check the road segment's full section to identify other roads that touch it, that could be your filter at 3 instead of searching all by distance?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.