/public-traffic

An attempt to create map directions for NYC using a public and free database. Written in Python 2.7 and uses Pandas.

Primary LanguagePython

Public Traffic

About

Using public data about congestion and traffic in New York City, this program attempts to give directions based on traffic densities at given times. A congestion map and geolocation map were constructed seperately and can be used in finding directions.

Example Run

Data Into

The two main types of data were traffic densities overtime on roadways and the geolocation of each intersection. Since the goal of this project was to only use public and free data, many details were left out and had to be interpolated. Intersections were determined from matching patterns between concurrent street intersections. With these intersections identified the geolocations can be applied.

The following code goes over the data used.

import pandas as pd

congestion_path = 'https://data.cityofnewyork.us/resource/ry4b-kref.json'
congestion_data = pd.read_json(congestion_path)
congestion_data.describe()
_10_00_11_00am _10_00_11_00pm _11_00_12_00am _11_00_12_00pm _12_00_1_00_am _12_00_1_00pm _1_00_2_00am _1_00_2_00pm _2_00_3_00am _2_00_3_00pm ... _6_00_7_00am _6_00_7_00pm _7_00_8_00am _7_00_8_00pm _8_00_9_00am _8_00_9_00pm _9_00_10_00am _9_00_10_00pm id segment_id
count 5945.00000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 ... 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000 5945.000000
mean 487.28545 362.049790 318.573759 500.595795 268.121110 518.770227 199.495542 533.232464 158.692710 567.876198 ... 298.851135 578.716232 449.667142 521.869638 516.786123 459.429268 495.612616 403.548360 194.338099 72266.300757
std 543.55638 488.597643 455.668074 542.300931 397.695541 559.326384 321.381335 571.878622 283.657075 608.448369 ... 496.852700 632.129919 615.741179 597.114398 618.118818 549.351007 569.209612 510.630172 112.834724 52561.851711
min 0.00000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 2153.000000
25% 195.00000 110.000000 87.000000 208.000000 64.000000 219.000000 41.000000 228.000000 28.000000 247.000000 ... 71.000000 234.000000 123.000000 197.000000 170.000000 164.000000 184.000000 134.000000 87.000000 28934.000000
50% 323.00000 202.000000 170.000000 337.000000 136.000000 353.000000 92.000000 366.000000 66.000000 395.000000 ... 148.000000 391.000000 264.000000 339.000000 340.000000 289.000000 326.000000 238.000000 209.000000 51933.000000
75% 579.00000 394.000000 335.000000 598.000000 277.000000 621.000000 207.000000 645.000000 161.000000 691.000000 ... 319.000000 702.000000 530.000000 620.000000 627.000000 533.000000 584.000000 454.000000 292.000000 110445.000000
max 5577.00000 4468.000000 4815.000000 5592.000000 4463.000000 5766.000000 4489.000000 5247.000000 4818.000000 6171.000000 ... 5166.000000 5810.000000 9226.330000 5249.000000 7302.000000 5102.000000 5788.000000 4986.000000 377.000000 192292.000000

8 rows × 26 columns

geo_path = 'geolocations.json'
geo_data = pd.read_json(geo_path)
print geo_data.head()
                                         coordinates
1 AVE , EAST 120 ST        [40.7986749, -73.9334714]
1 AVE , EAST 124 ST        [40.8009838, -73.9317793]
1 AVE , EAST 97 ST         [40.7839555, -73.9442204]
1 AVE , EAST 99 ST         [40.7851892, -73.9433108]
1 AVENUE , EAST 60 STREET  [40.7602427, -73.9615112]

Running the example

In order to use the program, just set your destination and starting location, setup the traveller and run.

An important note: within the nycdrive file are booleans specific for using the congestion map and the geolocation map. Altering these will change directions given.

from nycdrive import *

inter1 = ['STAFFORD AVE', 'HUGUENOT AVE']
inter2 = ['AVE T', 'CONEY ISLAND AVE']

inter_node1 = nyc_map.get_intersection_node(inter1)
inter_node2 = nyc_map.get_intersection_node(inter2)

max_nodes = len(nyc_map.nodes)

car = Traveller(inter_node1, inter_node2, 'NA')
car.dfs_travel()

Now we can print the route.

catch_path = []
if True:
    for i in range(max_nodes):
        for n in range(max_nodes):
            if i == n:
                continue
            node_i = nyc_map.nodes[i]
            node_n = nyc_map.nodes[n]
            car = Traveller(node_i, node_n, '_9_00_10_00pm')
            if geolocation_map and not congestion_map:
                car.greedy_travel()
            else:
                car.dfs_travel()
            if len(car.path) > 7:# printed:
                printed = True
                catch_path = car.path

for pth in catch_path:
    fspk1, fspk2 = pth.spks
    sname1 = nyc_map.get_street_name(fspk1)
    sname2 = nyc_map.get_street_name(fspk2)
    print (sname1, sname2)
('SPRING ST', 'CROSBY ST')
('BROADWAY', 'SPRING ST')
('BROADWAY', 'PRINCE ST')
('BROADWAY', 'E 12 ST')
('BROADWAY', 'E 11 ST')
('BROADWAY', 'DUANE ST')
('BROADWAY', 'MORRIS ST')
('BROADWAY', 'BEAVER ST')

The output is a list of intersections that are visited from start to destination.

Concept

The idea behind this project was to see how well a public and free database could do in comparison with production quality data. Although additional details could be fleshed out through processing the data even more, overall the data does not provide enough information to construct a working directional map of NYC. Certain attributes of streets such as one-way directions were eliminated to see if the results improved, but there was little improvement.

Contribute

Feel free to use this code for your personal amusement or even add to it. Contact me with any questions you might have.