NOSTALGIC FOODSCAPE

JIANWEI LI
Data Mining the City
5 min readOct 20, 2017
Nostalgic

Jackie, a Chinese student from Columbia University, has been struggling to adapt himself to different western food around the campus.

Shake Shack
Mexican Food Truck
Famiglia

He always felt stressful of the choice of that unfamiliar food and he misses all the cuisines of his hometown that would make him feel home.

Five Guys

Jackie started to look up the Chinese restaurants on Yelp and Google, however, the searching process is tedious, and sometimes irrelevant to what he is expecting.

Chinese Food Truck

Plus, Jackie has a very particular interest to the specialties of different Chinese restaurants and he is longing for a easier way to find a real taste of home without a time-consuming searching or an unsatisfied experience.

So, How could we make the search more fun, more efficient and more readable?

This “Nostalgic foodscape UI” navigation interface is designed for thousands of Chinese Student, like Jackie, in New York City to find their way home through the savor of authentic Chinese cuisine.

The idea is to capture the real-time location of the user and provide the nearby high-rated Chinese restaurants within a proper walking distance. It will identify the specialties of those restaurants within the proximity, visualize the walking path as well as the time it takes, as well as the cuisine they famous for. The track between their original location to their choice of the restaurant will be presented as their path to retrieve the sense of home.

108 Dry Hot Pot

We hope this little application could remind all the Chinese suffering from nostalgia of what’s home taste like.

108 Dry Hot Pot
108 Dry Hot Pot
Junzi

Especially of HOME.

Jackie’s Footprints

Following is the Python code.

import spatialpixel.mapping.slippymapper as slippymapper
import spatialpixel.google.directions as directions
import csv
import math
import time
def setup():
size(750, 750, P2D)
global ppin
ppin = loadImage("https://s3.amazonaws.com/spatialpixel/maps/map-pin-10px.png")
global pin
pin = loadImage("mark copy-2.png")
global head
head = loadImage("start_head.png")

# global all the icons
global bun
bun = loadImage("bun.png")
global cabbage
cabbage = loadImage("cabbage.png")
global chicken
chicken = loadImage("chicken.png")
global lunchbox
lunchbox = loadImage("lunchbox.png")
global noodle
noodle = loadImage("noodle.png")
global rice
rice = loadImage("rice.png")
global springroll
springroll = loadImage("springroll.png")
global nyc,zoom
zoom=13
nyc = slippymapper.SlippyMapper(
40.7833, -73.967, zoom, 'carto-light', width, height)
apikey = 'AIzaSyAS92FgIPVIwPLHR7aMxUPAMX3PP2-mtsE'
global test
test = directions.RenderGoogleDirections(apikey)
global dataDic
global choices
choices = directions.SlippyLayer(apikey)
nyc.addLayer(choices)
global lat,lon
global data

global indlist,dMax,times
indlist=[]
with open('dataofchineserestaurantswithtype.csv') as chinesept:
reader = csv.reader(chinesept)
header = reader.next()
dataDic={'id':[],
'name':[],
'lat':[],
'lon':[],
'rate':[],
'time':[],
'type':[],
'image':[]
}
for row in reader:
id = int(row[0])
lat = float(row[4])
lon = float(row[3])
name = row[1]
type = row[6]
data = {
'id': id,
'name': name,
'lat': lat,
'lon': lon,
'type':type
}
nyc.addMarker(lat, lon, RestaurantMarkerInvisible(data))
dataDic['id'].append(data['id'])
dataDic['name'].append(data['name'])
dataDic['lat'].append(data['lat'])
dataDic['lon'].append(data['lon'])
dataDic['type'].append(data['type'])
#print dataDic
nyc.render()
def mouseClicked():
global nyc,zoom
global clocation
global lat,lon,test
global latY,lonX
global indlist,dMax,times
global nameList
global choices,yPiList,xPiList,nameList,dataDic

found = []
foundX = []
foundY = []

indlist=[]
if mouseButton == LEFT:

lat = nyc.yToLat(mouseY)
lon = nyc.xToLon(mouseX)
nyc.setCenter(lat, lon)
latY = nyc.yToLat(mouseY)
lonX = nyc.xToLon(mouseX)
for marker in nyc.markers:
x = nyc.lonToX(marker.longitude)
y = nyc.latToY(marker.latitude)
if dist(mouseX, mouseY, x, y) < 50*(zoom-12):
found.append(marker)
foundX.append(marker.longitude)
foundY.append(marker.latitude)
print len(foundX)
all=(foundX,foundY)
clocation = [list(x) for x in zip(*all[::-1])]
print clocation

for destination in clocation:

ind = dataDic['lat'].index(destination[0])
indlist.append(ind)

# print selected index
#print len(indlist)

print indlist
dMax=len(foundX)
print dMax

times = []
for destination in clocation:


test.request((latY,lonX),(destination[0],destination[1]),mode = ('walking'))


dataset=test.data
#minutes = dataset[u'routes'][0][u'legs'][0][u'duration'][u'text']
seconds = dataset[u'routes'][0][u'legs'][0][u'duration'][u'value']
mins = str(int(round(seconds/60)))+" mins"

times.append(mins)

print times



i = 0

incLat = 0
incLon = 3
yPiList = []
xPiList = []
tyList = []
nameList=[]
print indlist
while i < len(indlist):
markerName = dataDic['name'][indlist[i]]
markerLat = dataDic['lat'][indlist[i]]
markerLon = dataDic['lon'][indlist[i]]
markerType = dataDic['type'][indlist[i]]
markerTime = times[i]


yPixel = nyc.latToY(markerLat)
xPixel = nyc.lonToX(markerLon)

yPiList.append(yPixel)
xPiList.append(xPixel)
nameList.append(markerName)
markerTime = times[i]
choices.addRoute((lat, lon), (markerLat, markerLon), 'walking', strokeColor=color(0))
#nyc.addMarker(markerLat,markerLon)
#nyc.addMarker(lat,lon,head)
#print dataDic['type'][indlist[i]]

nyc.addMarker(markerLat,markerLon,loadImage(markerType+".png"))
#nyc.addMarker(markerLat+0.0004,markerLon+0.0006,markerName)


i+=1
print nameList
nyc.render()

def keyPressed():
# making zoom in
global nyc,zoom
lat = nyc.yToLat(mouseY)
lon = nyc.xToLon(mouseX)

if key == '=':
zoom += 1
# defining maximum zoom in
if zoom > 18:
zoom = 18
nyc.setCenter(lat, lon)


# making zoom out
elif key == '-':
zoom=13
nyc.setCenter(40.7833, -73.967)

nyc.setZoom(zoom)
nyc.render()
def draw():

global nyc,zoom
global clocation
global lat,lon,test
global latY,lonX
global dMax,times,xPiList,yPiList
global indlist,nameList

background(255)
textSize(14)
fill(230,0,0)
nyc.draw()

global head

if mouseClicked:
if mouseButton == LEFT:
image(head,width/2-20,height/2-20)
textSize(16)
fill(230,0,0)
dMax = len(indlist)
if dMax !=0:
text('I found the taste of home!!!',width/2+23,50)
d = 0
while d < dMax:
textSize(14)
fill(230,0,0)
text(nameList[d],xPiList[d]+12,yPiList[d]-12)
textSize(12)
fill(0)
text(times[d],xPiList[d]+12,yPiList[d]-1)
d+=1
else:
time.sleep(2)
text('Here is too far away from home!!!',width/2+23,height/2)

textSize(24)
fill(230,0,0)
text('NOSTALGIC FOODSCAPE', 30,50)
textSize(24)
fill(230,0,0)
text('NOSTALGIC FOODSCAPE', 30,50)
textSize(18)
fill(230,0,0)
text('Redrawing NYC as CHINA', 30,70)
textSize(20)
fill(155,211,255)
text('GSAPP #DATAMININGTHECITY', 30,730)
textSize(20)
fill(155,211,255)
text('GSAPP #DATAMININGTHECITY', 30,730)
textSize(15)
fill(0)
text('CREATED BY LEO & CHRIS', 550,730)
textSize(12)
fill(0)
text('CLICK AND REMIND YOU THE TASTE OF HOME', 30,87)
class RestaurantMarker(slippymapper.DataMarker):
def drawMarker(self, x, y, marker):
global pin,dataDic
marker.image(pin, x, y)
marker.fill(0)
marker.text(self.data['name'], x, y)
if 'image' in self.data:
# draw the image.
image(self.data['image'])


class RestaurantMarkerInvisible(slippymapper.DataMarker):
def drawMarker(self, x, y, marker):
global pin
noFill()
marker.fill(0)
if 'image' in self.data:
# draw the image.
image(self.data['image'])

Credit to JIANWEI LI & XIANYAO XIA

Special thanks to Violet, William, Zach and Jackie.

Data sources: yelp.com / Google Map Direction

--

--