import arcpy, os, sys, traceback from os import path as p from datetime import datetime as d startTime = d.now() arcpy.env.overwriteOutput = True arcpy.env.qualifiedFieldNames = False def GetStartAndEndOfLine(lines, out_fc, join_field): # Get geometry objects coords = {} with arcpy.da.SearchCursor(lines, [join_field, 'SHAPE@', 'SHAPE@LENGTH', 'OID@']) as rows: ID = 1 for row in rows: st_x = float(str(row[1].firstPoint).split(' ')[0]) st_y = float(str(row[1].firstPoint).split(' ')[1]) end_x = float(str(row[1].lastPoint).split(' ')[0]) end_y = float(str(row[1].lastPoint).split(' ')[1]) coords[ID] = [st_x, st_y, end_x, end_y, row[2], row[0],row[3]] ID += 1 # Must create temp csv's for XY Event layer tmp = os.getcwd() csv_start = p.join(tmp,'temp_start_coords.csv') csv_end = p.join(tmp,'temp_end_coords.csv') # Create Start Csv with open(csv_start, 'w') as f: f.write('Line_ID,X_Coord,Y_Coord,Length,%s,JOIN_FID,Type\n' %join_field) for k,v in coords.iteritems(): f.write(','.join(str(i) for i in [k,v[0],v[1],v[4],v[5],v[6],'Start']) +'\n') # Create End Csv with open(csv_end, 'w') as f: f.write('Line_ID,X_Coord,Y_Coord,Length,%s,JOIN_FID,Type\n' %join_field) for k,v in coords.iteritems(): f.write(','.join(str(i) for i in [k,v[2],v[3],v[4],v[5],v[6],'End']) +'\n') # Get Spatial Reference info SR = arcpy.Describe(lines).spatialReference # Make_XY event layers start_xy = arcpy.MakeXYEventLayer_management(csv_start, 'X_Coord', 'Y_Coord', 'Start_xy_lyr', SR) end_xy = arcpy.MakeXYEventLayer_management(csv_end, 'X_Coord', 'Y_Coord', 'End_xy_lyr', SR) # Create output if arcpy.Exists(out_fc): arcpy.Delete_management(out_fc) arcpy.Merge_management([start_xy, end_xy], out_fc) # Clean up arcpy.Delete_management(csv_start) arcpy.Delete_management(csv_end) print 'Created "%s"' %p.basename(out_fc) arcpy.AddMessage('Created "%s"' %p.basename(out_fc)) if __name__ == '__main__': try: # Script tool params # Will try as a script tool first # lines = arcpy.GetParameterAsText(0) points = arcpy.GetParameterAsText(1) field = arcpy.GetParameterAsText(2) GetStartAndEndOfLine(lines, points, field) except: arcpy.AddMessage('ERROR') arcpy.GetMessages(2) # if not a script tool will go to stand alone # Stand alone testing # lines = r'C:\Testing\test2.gdb\roads' points = r'C:\Testing\test2.gdb\Roads_Points2' field = 'NAME1' GetStartAndEndOfLine(lines, points, field) print '(Elapsed time: %s)' %(str(d.now() - startTime)[:-3])
import arcpy, os, sys, traceback from os import path as p from datetime import datetime as d startTime = d.now() arcpy.env.overwriteOutput = True arcpy.env.qualifiedFieldNames = False def AddFields(in_fc, field, f_type, length=''): # dictionary to get correct input for add field tool type_dict = {'String': 'TEXT','SmallInteger':'SHORT', 'Integer':'LONG','Single':'FLOAT','Double':'DOUBLE'} add_fields = {'Line_ID':'LONG','X_Coord':'DOUBLE','Y_Coord':'DOUBLE', 'Length':'DOUBLE','JOIN_FID':'LONG',field:type_dict[f_type]} for f,t in add_fields.iteritems(): arcpy.AddField_management(in_fc, f, t, field_length=length) arcpy.AddField_management(in_fc, 'Type', 'TEXT', field_length=5) def GetStartAndEndOfLine(lines, out_fc, join_field): # Get geometry objects coords = {} with arcpy.da.SearchCursor(lines, [join_field, 'SHAPE@', 'SHAPE@LENGTH', 'OID@','SHAPE@XY']) as rows: ID = 1 for row in rows: st_x = float(str(row[1].firstPoint).split(' ')[0]) st_y = float(str(row[1].firstPoint).split(' ')[1]) end_x = float(str(row[1].lastPoint).split(' ')[0]) end_y = float(str(row[1].lastPoint).split(' ')[1]) st_XY = row[1].firstPoint end_XY = row[1].lastPoint coords[ID] = [st_x, st_y, end_x, end_y, row[2], row[0],row[3],st_XY,end_XY] ID += 1 # Must create temp csv's for XY Event layer tmp = 'in_memory' start = p.join(tmp,'temp_start') end = p.join(tmp,'temp_end') # Get Spatial Reference info SR = arcpy.Describe(lines).spatialReference # Get field type field_type = [f.type for f in arcpy.ListFields(lines) if f.name == join_field][0] if field_type == 'String': field_length = [f.length for f in arcpy.ListFields(lines) if f.name == join_field][0] else: field_length = '' # Create new FC for tmp_fc in [start, end]: arcpy.CreateFeatureclass_management(tmp,p.basename(tmp_fc),'POINT','','','',SR) AddFields(tmp_fc, join_field, field_type, field_length) # Insert new rows in_fields = ['Line_ID','X_Coord','Y_Coord','Length', join_field,'JOIN_FID','Type','SHAPE@XY'] with arcpy.da.InsertCursor(tmp_fc, in_fields) as rows: for k,v in sorted(coords.iteritems()): if tmp_fc == start: rows.insertRow((k,v[0],v[1],v[4],v[5],v[6],'Start',v[7])) else: rows.insertRow((k,v[2],v[3],v[4],v[5],v[6],'End',v[8])) # Create output if arcpy.Exists(out_fc): arcpy.Delete_management(out_fc) arcpy.Merge_management([start, end], out_fc) print 'Created "%s"' %p.basename(out_fc) arcpy.AddMessage('Created "%s"' %p.basename(out_fc)) if __name__ == '__main__': try: # Script tool params lines = arcpy.GetParameterAsText(0) points = arcpy.GetParameterAsText(1) field = arcpy.GetParameterAsText(2) GetStartAndEndOfLine(lines, points, field) print '(Elapsed time: %s)' %(str(d.now() - startTime)[:-3]) except: arcpy.AddMessage('ERROR') arcpy.GetMessages(2) # Stand alone testing lines = r'C:\Testing\test2.gdb\roads' points = r'C:\Testing\test2.gdb\Roads_Points' field = 'NAME1' GetStartAndEndOfLine(lines, points, field) print '(Elapsed time: %s)' %(str(d.now() - startTime)[:-3])
I know this is an old thread but i was hoping you could answer, in the code above, specifically
for k,v in sorted(coords.iteritems()):
What does the k represent? I can see the V's are parts of the coords array but i can't figure out what k refers to.
thanks
When in doubt, 'print' to find out:
>>> coords = {} ... coords[1] = ['blah1','blah2'] ... coords[2] = ['blah3','blah4'] ... for k,v in coords.iteritems(): ... print (k,v) ... (1, ['blah1', 'blah2']) (2, ['blah3', 'blah4'])
k,v is code for key, value.
thanks darren!