Skip to content

Instantly share code, notes, and snippets.

@quandyfactory quandyfactory/sobi_gpx.py
Last active Aug 9, 2016

Embed
What would you like to do?
#!/usr/bin/env python
from xml.dom.minidom import parseString
from xml.dom.minidom import parse
import os
segments = (
# West of Cannon Cycle Track
{
'block': 'Dundurn to Kinnell (West of Cycle Track)',
'shape': (
(43.26796, -79.88582),
(43.26833, -79.88528),
(43.26695, -79.88321),
(43.26649, -79.88362),
)
},
{
'block': 'Kinnell to Inchbury (West of Cycle Track)',
'shape': (
(43.26649, -79.88362),
(43.26695, -79.88321),
(43.26631, -79.88217),
(43.26563, -79.88246),
)
},
{
'block': 'Inchbury to Locke (West of Cycle Track)',
'shape': (
(43.26563, -79.88246),
(43.26631, -79.88217),
(43.26577, -79.88136),
(43.26521, -79.88158),
)
},
{
'block': 'Locke to Crooks (West of Cycle Track)',
'shape': (
(43.26521, -79.88158),
(43.26577, -79.88136),
(43.26529, -79.88052),
(43.26476, -79.88091),
)
},
{
'block': 'Crooks to Magill (West of Cycle Track)',
'shape': (
(43.26476, -79.88091),
(43.26529, -79.88052),
(43.26476, -79.87973),
(43.26427, -79.88007),
)
},
{
'block': 'Magill to Ray (West of Cycle Track)',
'shape': (
(43.26427, -79.88007),
(43.26476, -79.87973),
(43.26426, -79.87896),
(43.26383, -79.87933),
)
},
{
'block': 'Ray to Oxford (West of Cycle Track)',
'shape': (
(43.26383, -79.87933),
(43.26426, -79.87896),
(43.26378, -79.87827),
(43.26337, -79.87866),
)
},
{
'block': 'Oxford to Queen (West of Cycle Track)',
'shape': (
(43.26337, -79.87866),
(43.26378, -79.87827),
(43.26306, -79.87717),
(43.26262, -79.87735),
)
},
{
'block': 'Queen to Hess (West of Cycle Track)',
'shape': (
(43.26262, -79.87735),
(43.26306, -79.87717),
(43.26276, -79.87561),
(43.26241, -79.87576),
)
},
# Cannon Cycle Track
{
'block': 'Hess to Caroline (Inside Cycle Track)',
'shape': (
(43.26241, -79.87576),
(43.26276, -79.87561),
(43.26253, -79.8739),
(43.26205, -79.87414),
)
},
{
'block': 'Caroline to Bay (Inside Cycle Track)',
'shape': (
(43.26205, -79.87414),
(43.26253, -79.8739),
(43.26203, -79.8721),
(43.26165, -79.87226),
)
},
{
'block': 'Bay to Park (Inside Cycle Track)',
'shape': (
(43.26165, -79.87226),
(43.26203, -79.8721),
(43.26156, -79.87035),
(43.26126, -79.8705),
)
},
{
'block': 'Park to MacNab (Inside Cycle Track)',
'shape': (
(43.26126, -79.8705),
(43.26156, -79.87035),
(43.26122, -79.8688),
(43.2609, -79.86892),
)
},
{
'block': 'MacNab to James (Inside Cycle Track)',
'shape': (
(43.2609, -79.86892),
(43.26122, -79.8688),
(43.26083, -79.86724),
(43.26054, -79.86737),
)
},
{
'block': 'James to Hughson (Inside Cycle Track)',
'shape': (
(43.26054, -79.86737),
(43.26083, -79.86724),
(43.26051, -79.86592),
(43.26021, -79.86604),
)
},
{
'block': 'Hughson to John (Inside Cycle Track)',
'shape': (
(43.26021, -79.86604),
(43.26051, -79.86592),
(43.26021, -79.86462),
(43.25992, -79.86474),
)
},
{
'block': 'John to Catharine (Inside Cycle Track)',
'shape': (
(43.25992, -79.86474),
(43.26021, -79.86462),
(43.25991, -79.86326),
(43.2596, -79.86338),
)
},
{
'block': 'Catharine to Mary (Inside Cycle Track)',
'shape': (
(43.2596, -79.86338),
(43.25991, -79.86326),
(43.25963, -79.86214),
(43.25934, -79.86223),
)
},
{
'block': 'Mary to Elgin (Inside Cycle Track)',
'shape': (
(43.25934, -79.86223),
(43.25963, -79.86214),
(43.25931, -79.86093),
(43.25904, -79.86102),
)
},
{
'block': 'Elgin to Ferguson (Inside Cycle Track)',
'shape': (
(43.25904, -79.86102),
(43.25931, -79.86093),
(43.25901, -79.85962),
(43.25872, -79.85975),
)
},
{
'block': 'Ferguson to Cathcart (Inside Cycle Track)',
'shape': (
(43.25872, -79.85975),
(43.25901, -79.85962),
(43.25871, -79.85835),
(43.25843, -79.85847),
)
},
{
'block': 'Cathcart to Wellington (Inside Cycle Track)',
'shape': (
(43.25843, -79.85847),
(43.25871, -79.85835),
(43.25848, -79.85719),
(43.25814, -79.85734),
)
},
{
'block': 'Wellington to West (Inside Cycle Track)',
'shape': (
(43.25814, -79.85734),
(43.25848, -79.85719),
(43.25813, -79.85598),
(43.25788, -79.85607),
)
},
{
'block': 'West to Victoria (Inside Cycle Track)',
'shape': (
(43.25788, -79.85607),
(43.25813, -79.85598),
(43.25783, -79.85473),
(43.25755, -79.85485),
)
},
{
'block': 'Victoria to East (Inside Cycle Track)',
'shape': (
(43.25755, -79.85485),
(43.25783, -79.85473),
(43.25749, -79.85343),
(43.25722, -79.85355),
)
},
{
'block': 'East to Emerald (Inside Cycle Track)',
'shape': (
(43.25722, -79.85355),
(43.25749, -79.85343),
(43.25723, -79.85231),
(43.25694, -79.85242),
)
},
{
'block': 'Emerald to Tisdale (Inside Cycle Track)',
'shape': (
(43.25694, -79.85242),
(43.25723, -79.85231),
(43.25691, -79.85112),
(43.25663, -79.85126),
)
},
{
'block': 'Tisdale to Steven (Inside Cycle Track)',
'shape': (
(43.25663, -79.85126),
(43.25691, -79.85112),
(43.25664, -79.85003),
(43.25638, -79.85014),
)
},
{
'block': 'Steven to Ashley (Inside Cycle Track)',
'shape': (
(43.25638, -79.85014),
(43.25664, -79.85003),
(43.25631, -79.84876),
(43.25604, -79.84886),
)
},
{
'block': 'Ashley to Wentworth (Inside Cycle Track)',
'shape': (
(43.25604, -79.84886),
(43.25631, -79.84876),
(43.25592, -79.84729),
(43.25565, -79.84738),
)
},
{
'block': 'Wentworth to Adams (Inside Cycle Track)',
'shape': (
(43.25565, -79.84738),
(43.25592, -79.84729),
(43.25566, -79.84633),
(43.25538, -79.84646),
)
},
{
'block': 'Adams to Madison (Inside Cycle Track)',
'shape': (
(43.25538, -79.84646),
(43.25566, -79.84633),
(43.25551, -79.8457),
(43.25523, -79.84584),
)
},
{
'block': 'Madison to Sanford (Inside Cycle Track)',
'shape': (
(43.25523, -79.84584),
(43.25551, -79.8457),
(43.25529, -79.84482),
(43.25502, -79.84494),
)
},
{
'block': 'Sanford to Greenway (Inside Cycle Track)',
'shape': (
(43.25502, -79.84494),
(43.25529, -79.84482),
(43.25499, -79.84379),
(43.25475, -79.84388),
)
},
{
'block': 'Greenway to Hazel (Inside Cycle Track)',
'shape': (
(43.25475, -79.84388),
(43.25499, -79.84379),
(43.25481, -79.84309),
(43.25457, -79.84318),
)
},
{
'block': 'Hazel to Stirton (Inside Cycle Track)',
'shape': (
(43.25457, -79.84318),
(43.25481, -79.84309),
(43.25465, -79.84237),
(43.25438, -79.84248),
)
},
{
'block': 'Stirton to Birch (Inside Cycle Track)',
'shape': (
(43.25438, -79.84248),
(43.25465, -79.84237),
(43.25434, -79.84119),
(43.25405, -79.84128),
)
},
{
'block': 'Birch to Gibson (Inside Cycle Track)',
'shape': (
(43.25405, -79.84128),
(43.25434, -79.84119),
(43.25406, -79.84021),
(43.25375, -79.84032),
)
},
{
'block': 'Gibson to Chestnut (Inside Cycle Track)',
'shape': (
(43.25375, -79.84032),
(43.25406, -79.84021),
(43.25383, -79.8393),
(43.25354, -79.83941),
)
},
{
'block': 'Chestnut to Kinrade (Inside Cycle Track)',
'shape': (
(43.25354, -79.83941),
(43.25383, -79.8393),
(43.25361, -79.8384),
(43.25332, -79.83852),
)
},
{
'block': 'Kinrade to Sherman (Inside Cycle Track)',
'shape': (
(43.25332, -79.83852),
(43.25361, -79.8384),
(43.25331, -79.83749),
(43.25291, -79.83769),
)
},
# east of Cannon Cycle Track
{
'block': 'Sherman to Barnesdale (East of Cycle Track)',
'shape': (
(43.25291, -79.83769),
(43.25331, -79.83749),
(43.25246, -79.83465),
(43.25213, -79.83479),
)
},
{
'block': 'Barnesdale to Lottridge (East of Cycle Track)',
'shape': (
(43.25213, -79.83479),
(43.25246, -79.83465),
(43.25199, -79.83264),
(43.25173, -79.83272),
)
},
{
'block': 'Lottridge to Melrose (East of Cycle Track)',
'shape': (
(43.25173, -79.83272),
(43.25199, -79.83264),
(43.25173, -79.83176),
(43.2513, -79.83198),
)
},
{
'block': 'Melrose to Balsam - Stadium (East of Cycle Track)',
'shape': (
(43.2513, -79.83198),
(43.25173, -79.83176),
(43.25046, -79.82945),
(43.24994, -79.82965),
)
},
{
'block': 'Balsam to Connaught (East of Cycle Track)',
'shape': (
(43.24994, -79.82965),
(43.25046, -79.82945),
(43.25022, -79.82861),
(43.24977, -79.82879),
)
},
{
'block': 'Connaught to Gage (East of Cycle Track)',
'shape': (
(43.24977, -79.82879),
(43.25022, -79.82861),
(43.25004, -79.82781),
(43.24962, -79.82796),
)
},
{
'block': 'Gage to Fairview (East of Cycle Track)',
'shape': (
(43.24962, -79.82796),
(43.25004, -79.82781),
(43.24981, -79.8268),
(43.24939, -79.82697),
)
},
{
'block': 'Fairview to East Bend (East of Cycle Track)',
'shape': (
(43.24939, -79.82697),
(43.24981, -79.8268),
(43.24955, -79.82587),
(43.24923, -79.82603),
)
},
{
'block': 'East Bend to Glendale (East of Cycle Track)',
'shape': (
(43.24923, -79.82603),
(43.24955, -79.82587),
(43.24929, -79.82452),
(43.24893, -79.82466),
)
},
{
'block': 'Glendale to Belview (East of Cycle Track)',
'shape': (
(43.24893, -79.82466),
(43.24929, -79.82452),
(43.24907, -79.82355),
(43.24873, -79.82367),
)
},
{
'block': 'Belview to Belmont (East of Cycle Track)',
'shape': (
(43.24873, -79.82367),
(43.24907, -79.82355),
(43.24893, -79.8227),
(43.24855, -79.82283),
)
},
{
'block': 'Belmont to Kensington (East of Cycle Track)',
'shape': (
(43.24855, -79.82283),
(43.24893, -79.8227),
(43.24869, -79.82175),
(43.24835, -79.82187),
)
},
{
'block': 'Kensington to Rosslyn (East of Cycle Track)',
'shape': (
(43.24835, -79.82187),
(43.24869, -79.82175),
(43.24844, -79.82076),
(43.2481, -79.82089),
)
},
{
'block': 'Rosslyn to Balmoral (East of Cycle Track)',
'shape': (
(43.2481, -79.82089),
(43.24844, -79.82076),
(43.24821, -79.81978),
(43.24785, -79.81991),
)
},
{
'block': 'Balmoral to Grosvenor (East of Cycle Track)',
'shape': (
(43.24785, -79.81991),
(43.24821, -79.81978),
(43.24798, -79.81871),
(43.24757, -79.81887),
)
},
{
'block': 'Grosvenor to Ottawa (East of Cycle Track)',
'shape': (
(43.24757, -79.81887),
(43.24798, -79.81871),
(43.24772, -79.81746),
(43.24729, -79.81762),
)
},
)
gpx_path = 'data'
output_path = 'trips_results.csv'
def point_in_poly(x,y,poly):
"""Returns True if a point is within a polygon, False if it is not.
Source: http://geospatialpython.com/2011/08/point-in-polygon-2-on-line.html"""
# check if point is a vertex
if (x,y) in poly:
return True
# check if point is on a boundary
for i in range(len(poly)):
p1 = None
p2 = None
if i==0:
p1 = poly[0]
p2 = poly[1]
else:
p1 = poly[i-1]
p2 = poly[i]
if p1[1] == p2[1] and p1[1] == y and x > min(p1[0], p2[0]) and x < max(p1[0], p2[0]):
return True
n = len(poly)
inside = False
p1x,p1y = poly[0]
for i in range(n+1):
p2x,p2y = poly[i % n]
if y > min(p1y,p2y):
if y <= max(p1y,p2y):
if x <= max(p1x,p2x):
if p1y != p2y:
xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
if p1x == p2x or x <= xints:
inside = not inside
p1x,p1y = p2x,p2y
if inside:
return True
return False
def print_to_file(line, newline='\n'):
with open(output_path, 'a') as myfile:
myfile.write('%s%s' % (line, newline))
def process_trips():
"""Used to process GPX files with multiple trips in them. Necessary hack for big files because xml.dom.minidom is a memory hog"""
files = os.listdir(gpx_path)
# print the column headers
print_to_file('Trip, Lat, Lon, Block, Inside')
for filename in files:
myfile = open('%s/%s' % (gpx_path, filename), 'r')
blob = myfile.read()
# xml.dom.minidom is terrible at memory so we split the big XML file into lots of little XML files
blobs = blob.split('<trk>\n')
del blobs[0] # first list element has XML header stuff
blobs[-1] = blobs[-1].replace('\n</gpx>', '') # drop closing </gpx> tag so the last blob doesn't fail to parse
# now we modify each element to be a valid XML file
trips = ['%s\n%s\n%s' % ('<?xml version="1.0" encoding="UTF-8"?>', '<trk>', blob) for blob in blobs]
for trip in trips:
obj = parseString(trip)
process_trip(obj)
def process_trip(obj):
name = obj.getElementsByTagName('name')[0].firstChild.nodeValue
print('Starting trip %s' % (name))
points = obj.getElementsByTagName('trkpt')
for point in points:
lat = float(point.getAttribute('lat'))
lon = float(point.getAttribute('lon'))
point_in_segment = False
for segment in segments:
if point_in_poly(lat, lon, segment['shape']) == True:
print_to_file('%s, %s, %s, %s, %s' % (name, lat, lon, segment['block'], '1'))
point_in_segment = True
if point_in_segment == False:
print_to_file('%s, %s, %s, %s, %s' % (name, lat, lon, segment['block'], '0'))
if __name__ == '__main__':
process_trips()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.