Map Based On Time

Jujie Xu
Data Mining the City
3 min readOct 20, 2017

Maps are reductive because they only show spatial relationships from birds eye view, the only way people experience what’s drawn on a map is through time. I want to show the distance in TIME between two points.

GSAAP LIFE — depends on time not distance
BEFORE FINAL REVIEW
STUDIO HOURS
SATURDAY AFTERNOON

As a gsapp student, my entire life depends on time. Before some final review, I find it’s almost time for pin up, my sweet home (and sleep as well) seems outside galaxy, and what’s further is getting all things done. And when the output shop says sorry your printing won’t be ready in 4 hours just before studio critic, the next step would be to check which printing shop is the shortest time to get. Or on a sunny Saturday afternoon I want to spend some time exploring New York city but would better not go that far cause studio work in mind, the map is somehow cheating for the MOMA actually needs less time to get than that of shopping mall in midtown, which in map shows the opposite. This based-on-time map is not only a useful tool to check time distance, which could be quite different from what shows on map, but also a great way to describe my gsapp life using data.

import spatialpixel.mapping.slippymapper as slippymapper
import spatialpixel.google.directions as directions
import csv
def setup():
size (1024,1024)
background(0, 102, 153)
translate(width/2, height/2)

global newyork
newyork = slippymapper.SlippyMapper(40.807993,-73.963833,12,'toner',width,height)

global locations
global latitudes
latitudes=[]
global longitudes
longitudes=[]
global names
names = []
locations=[latitudes, longitudes, names]

with open('diagram3.csv') as f1:
reader=csv.reader(f1)

for row in reader:
latitude = float(row[0])
latitudes.append(latitude)
longitude = float(row[1])
longitudes.append(longitude)
name = str(row[2])
names.append(name)

apikey= 'apikey'
centre=(40.807993,-73.963833)
print(names)
number=len(longitudes)
global duration
duration = []
for i in xrange(number):
location_n=(locations[0][i],locations[1][i])
location_n_route=directions.RenderGoogleDirections(apikey)
testjson=location_n_route.request(centre,location_n,'bus')
data=location_n_route.data
duration.append(data['routes'][0]['legs'][0]['duration']['value'])
print(duration)

global info
info = {}
global relative_info
relative_info = {}
max_duration = max(duration)
print(max_duration)
for i in range(len(names)):
info[names[i]] = [locations[0][i], locations[1][i]]
relative_info[names[i]] = [locations[0][i] - centre[0], locations[1][i] - centre[1], 450*duration[i]/max_duration]
print(info)
textSize(30)
noStroke()
ellipse(0, 0, 30, 30)
fill(0)
text('GSAPP', -45, 45)
global longi_point
longi_point = []
global latti_point
latti_point = []
for name in names:
strokeWeight(1.0)
noFill()
stroke(255)
ellipse(0, 0, 2*relative_info[name][2], 2*relative_info[name][2])
# print(relative_info[location][0], relative_info[location][1])
distance = (relative_info[name][0]**2 + relative_info[name][1]**2) ** 0.5
# print(distance)
longi_point.append(relative_info[name][0] / distance * relative_info[name][2])
latti_point.append(relative_info[name][1] / distance * relative_info[name][2])
strokeWeight(12.0)
point(latti_point[-1], -longi_point[-1])
# print(longi_point[-1], latti_point[-1])
fill(0)

arclength = -5.0
w = 0
for i in range(len(name)):
arclength = arclength - w
currentChar = name[i]
w = textWidth(currentChar)
theta = PI + atan(-longi_point[-1]/latti_point[-1]) + arclength / relative_info[name][2]
#print(theta)
pushMatrix()
translate(relative_info[name][2]*cos(theta), relative_info[name][2]*sin(theta))
rotate(theta - PI / 2)
fill(255)
textSize(24)
text(currentChar, 0, 0)
popMatrix()
def draw():
translate(width/2, height/2)

#line(mouseX-width/2, mouseY-height/2, 0, 0)
for i in xrange(len(longi_point)):
mouseIsOverColumn = latti_point[i] - 20 < mouseX-width/2 and mouseX-width/2 < latti_point[i] + 20
mouseIsOverRow = -longi_point[i] - 20 < mouseY-height/2 and mouseY-height/2 < -longi_point[i] + 20
mouseIsOverTheRectangle = mouseIsOverColumn and mouseIsOverRow
if mouseIsOverTheRectangle:
fill(255)
noStroke()
rect(-550, 400, 300, 200)
fill(0, 102, 153)
textSize(20)
text(names[i], -490, 430)
text('TIME/min: ', -490, 450)
text(duration[i]/60, -380, 450)

--

--