Skip to content

Instantly share code, notes, and snippets.

@andygarfield
Last active February 15, 2016 21:25
Show Gist options
  • Save andygarfield/a0700672316b37b72076 to your computer and use it in GitHub Desktop.
Save andygarfield/a0700672316b37b72076 to your computer and use it in GitHub Desktop.
Create a line sequence feature class from GPS data
#
# CSV file must be in the format: Latitude,Longitude,datetime
# The third field is date time info from: datetime.datetime.utcnow()
#
from arcpy import Project_management, CreateFeatureclass_management, AddField_management, SpatialReference, da, Array,\
Point, Polyline, GetParameterAsText, mapping, Describe, ListFields, MakeTableView_management, GetCount_management
import os
from datetime import datetime
from math import floor
def create_datetime(datetime_string):
year = int(datetime_string.split('-')[0])
month = int(datetime_string.split('-')[1])
day = int(datetime_string.split('-')[2].split(' ')[0])
time = datetime_string.split(' ')[1]
hour = int(time.split(':')[0])
minute = int(time.split(':')[1])
second = int(floor(float(time.split(':')[2])))
microsecond = int(floor((float(time.split(':')[2]) % 1) * 1000))
return datetime(year, month, day, hour, minute, second, microsecond)
def project_better(in_dataset, out_dataset, spatial_reference):
# Script borrowed from http://joshwerts.com/blog/2015/09/10/arcpy-dot-project-in-memory-featureclass/
# Can project a dataset and put the output in an 'in_memory' workspace
path, name = os.path.split(out_dataset)
CreateFeatureclass_management(path, name, Describe(in_dataset).shapeType,
template=in_dataset,
spatial_reference=spatial_reference)
# specify copy of all fields from source to destination
fields = ["Shape@"] + [f.name for f in ListFields(in_dataset) if not f.required]
# project source geometries on the fly while inserting to destination featureclass
with da.SearchCursor(in_dataset, fields, spatial_reference=spatial_reference) as source_curs, \
da.InsertCursor(out_dataset, fields) as ins_curs:
for row in source_curs:
ins_curs.insertRow(row)
# Initial variables
mxd = mapping.MapDocument('CURRENT')
df = mxd.activeDataFrame
dfcs = df.spatialReference
CreateFeatureclass_management('in_memory', 'points', 'POINT', spatial_reference=SpatialReference(4326))
AddField_management('in_memory\\points', 'datetime', 'TEXT')
point_cur = da.InsertCursor('in_memory\\points', ['SHAPE@XY', 'datetime'])
# Create point FC from CSV file
with open(GetParameterAsText(0)) as log:
for line in log:
lat = float(line.split(',')[0])
lon = float(line.split(',')[1])
timefield = line.split(',')[2]
point_cur.insertRow([(lon, lat), timefield])
project_better('in_memory\\points', 'in_memory\\projected', dfcs)
# Set up line FC
CreateFeatureclass_management(os.path.dirname(GetParameterAsText(1)), os.path.basename(GetParameterAsText(1)),
'POLYLINE', None, None, None, dfcs)
AddField_management(GetParameterAsText(1), 'Speed', 'DOUBLE')
AddField_management(GetParameterAsText(1), 'Begin', 'TEXT')
AddField_management(GetParameterAsText(1), 'End', 'TEXT')
search_cur = da.SearchCursor('in_memory\\projected', ['SHAPE', 'datetime'])
with da.InsertCursor(GetParameterAsText(1), ['SHAPE@', 'Speed', 'Begin', 'End']) as line_cur:
# Variables for comparing to current data
prev_point = ()
prev_datetime = 0
for row in search_cur:
if prev_point == ():
# If it's the first data point, give it some values, and then loop back around
prev_point = (row[0][0], row[0][1])
prev_datetime = create_datetime(row[1])
continue
array = Array()
curr_point = (row[0][0], row[0][1])
# Give the array the points to make the line with
array.append(Point(prev_point[0], prev_point[1]))
array.append(Point(curr_point[0], curr_point[1]))
# Make a new datetime object and calculate the difference between the old one
new_datetime = create_datetime(row[1])
time_difference = (new_datetime - prev_datetime).total_seconds()
# Create the Polyline
new_line = Polyline(array)
# Calculate the speed
speed = ((new_line.length / time_difference) * 3600) / 5280
# Finally, insert the row
line_cur.insertRow([new_line, speed, prev_datetime, new_datetime])
# Set previous variables
prev_point = curr_point
prev_datetime = new_datetime
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment