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!