Skip to content

Instantly share code, notes, and snippets.

@jackdpage
Created January 28, 2022 23:08
Show Gist options
  • Save jackdpage/c73fbc014f18ed7fedeaed26cc28a175 to your computer and use it in GitHub Desktop.
Save jackdpage/c73fbc014f18ed7fedeaed26cc28a175 to your computer and use it in GitHub Desktop.
Creates underground-style route line diagram for a linear highway from json definition
import json
import xml.etree.ElementTree as ET
N = 50
CLASS_COLOUR = {
'motorway': '#0079c1',
'trunk': '#00703c',
'primary': '#ffffff'
}
CLASS_BORDER = {
'motorway': 0,
'trunk': 0,
'primary': 1
}
CLASS_BORDER_COLOUR = {
'primary': '#000000'
}
CLASS_TEXT_COLOUR = {
'motorway': '#ffffff',
'trunk': '#ffd200',
'primary': '#000000'
}
def main():
with open('routes.json', 'r') as f:
route_data = f.read()
routes = json.loads(route_data)['routes']
for route in routes:
route_to_text(route)
route_to_svg(route)
def get_route_segment(route, stop):
group = ET.Element('g')
line = ET.Element('line')
line.set('x1', str(N*-0.5))
line.set('x2', str(N*-0.5))
line.set('y1', str(N*-3))
line.set('y2', str(N*3))
line.set('stroke', CLASS_COLOUR[route['class']])
line.set('stroke-width', str(N))
if stop['type'] == 'stop':
stop_icon = ET.Element('rect')
stop_icon.set('x', '0')
stop_icon.set('y', str(N*-0.33))
stop_icon.set('width', str(N*0.66))
stop_icon.set('height', str(N*0.66))
stop_icon.set('fill', CLASS_COLOUR[route['class']])
elif stop['type'] == 'interchange':
stop_icon = ET.Element('ellipse')
stop_icon.set('cx', str(N*-0.5))
stop_icon.set('cy', '0')
stop_icon.set('rx', str(N))
stop_icon.set('ry', str(N))
stop_icon.set('fill', '#ffffff')
stop_icon.set('stroke-width', str(N*0.5))
stop_icon.set('stroke', '#000000')
text = ET.Element('text')
text.text = stop['name']
text.set('x', str(N*3))
text.set('y', str(N*0.5))
text.set('style', 'font-family:London Tube;font-size:'+str(N*2))
if stop['type'] == 'interchange':
interchange_group = ET.Element('g')
for i in range(0, len(stop['interchanges'])):
interchange = stop['interchanges'][i]
container = ET.Element('rect')
container.set('x', '0')
container.set('y', str(N*1.5*i))
container.set('width', str(N*10))
container.set('height', str(N*1.5))
container.set('fill', CLASS_COLOUR[interchange['class']])
if CLASS_BORDER[interchange['class']] == 1:
container.set('stroke', CLASS_BORDER_COLOUR[interchange['class']])
container.set('stroke-width', str(N*0.08))
interchange_group.append(container)
interchange_group.set('transform', 'translate('+str(N*(len(stop['name'])+5))+','+str(N*-0.75*len(stop['interchanges']))+')')
group.append(interchange_group)
group.append(line)
group.append(stop_icon)
group.append(text)
return group
def route_to_svg(route):
page = ET.Element('svg')
page.set('xmlns', 'http://www.w3.org/2000/svg')
for i in range(0, len(route['stops'])):
stop_group = get_route_segment(route, route['stops'][i])
stop_group.set('transform', 'translate(0,'+str(N*6*i)+')')
page.append(stop_group)
ET.ElementTree(element=page).write('output.svg')
def route_to_text(route):
for stop in route['stops']:
if stop['type'] == 'interchange':
icon = 'X'
interchange_text = ''.join([' ('+i['name']+')' for i in stop['interchanges']])
else:
icon = '-'
interchange_text = ''
print(''.join([icon, ' ', stop['name'], interchange_text]))
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment