Commit 7a759241 authored by Sharp Hall's avatar Sharp Hall

Select only routes near user; use heading and bearing

parent 82108702
......@@ -3,12 +3,21 @@ import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import haversine from 'haversine';
import bearing from '@turf/bearing';
import { point } from '@turf/helpers';
import _ from 'lodash';
var COMING_THRESHOLD = 90;
var septaRoutes = {};
var septaStops = {routes: {}, stops: []};
var nearbyStops = [];
var selectedRoutes = [];
var flatDistanceSorted = [];
var currentLocation = {latitude: 39.949362, longitude: -75.223623};
var currentLocation = {latitude: 39.948242, longitude: -75.221204};
function milesFromObj(ref, septaObj) {
return haversine(ref, {latitude: parseFloat(septaObj.lat),
......@@ -25,17 +34,39 @@ function markRoutes(routes) {
return routes;
}
function calcDistances() {
var refreshDisplay = _.debounce(function () {
var here = point([currentLocation.longitude, currentLocation.latitude]);
// find close stops
nearbyStops = _.filter(
_.map(septaStops.stops, function (stop) {
stop.distance = haversine(currentLocation, {latitude: stop.y,
longitude: stop.x});
return stop;
}), function (stop) {
return stop.distance < 0.5;
}
);
selectedRoutes = _.uniq(_.flatten(_.map(nearbyStops, stops => { return stops.r; })));
// update distance in septa route objects according to currentLocation
_.forEach(septaRoutes, function(route) {
_.forEach(route, function(vehicle) {
vehicle.distance = milesFromObj(currentLocation, vehicle);
var p = point([parseFloat(vehicle.lng), parseFloat(vehicle.lat)]);
vehicle.bearing = bearing(p, here, {final: true});
vehicle.coming = (vehicle.heading - vehicle.bearing + 360) % 360;
});
});
flatDistanceSorted = _.sortBy(_.flatten(_.values(septaRoutes)), function (vehicle) {
flatDistanceSorted = _.sortBy(_.filter(_.flatten(_.values(septaRoutes)), v => { return selectedRoutes.includes(v.route) || selectedRoutes === []; }),
function (vehicle) {
return vehicle.distance;
});
}
console.log(flatDistanceSorted);
ReactDOM.render(<VehicleList vehicleList={flatDistanceSorted} />,
document.getElementById('routelist'));
}, 3000);
function getSeptaTransitView() {
$.ajax({
......@@ -44,15 +75,26 @@ function getSeptaTransitView() {
dataType: "jsonp",
success: function (newData) {
septaRoutes = markRoutes(newData.routes[0]);
calcDistances();
ReactDOM.render(<VehicleList vehicleList={flatDistanceSorted} />,
document.getElementById('routelist'));
refreshDisplay();
}
});
}
$(function () {
getSeptaTransitView();
setInterval(getSeptaTransitView, 30 * 1000);
$.ajax({
url: "stops.json",
success: function (stopData) {
septaStops = stopData;
refreshDisplay();
}
});
navigator.geolocation.watchPosition(function(position) {
console.log(position);
currentLocation = {latitude: position.coords.latitude, longitude: position.coords.longitude};
refreshDisplay();
});
});
class Vehicle extends React.Component {
......@@ -71,9 +113,19 @@ class Vehicle extends React.Component {
distance = (this.props.vehicleData.distance * 5280).toFixed(0) + " feet";
}
var nice_directions = Vehicle.NICE_DIRECTIONS[this.props.vehicleData.Direction];
var className = "vehicle";
if (this.props.vehicleData.coming < COMING_THRESHOLD ||
this.props.vehicleData.coming > 360 - COMING_THRESHOLD ||
this.props.vehicleData.distance < 0.2) {
className += " coming";
} else if (this.props.vehicleData.coming > 180 - COMING_THRESHOLD &&
this.props.vehicleData.coming < 180 + COMING_THRESHOLD) {
className += " going";
}
className += " route-" + this.props.vehicleData.route;
return (
<div className="vehicle">
{this.props.vehicleData.route} {nice_directions} {distance} away
<div className={className}>
{this.props.vehicleData.VehicleID} {this.props.vehicleData.route} {nice_directions} {distance} away towards {this.props.vehicleData.destination}
</div>
);
}
......
import csv
import json
def reformat_stop(stop):
return {
"n": stop["stop_name"],
"x": float(stop["stop_lon"]),
"y": float(stop["stop_lat"]),
"r": stop["routes"]
}
def reformat_route(route):
return {
"n": route["route_long_name"]
}
def main():
routes = {}
stops = {}
trips = {}
with open('google_bus/routes.txt', 'r') as f:
for route in csv.DictReader(f):
routes[route["route_id"]] = route
with open('google_bus/stops.txt', 'r') as f:
for stop in csv.DictReader(f):
stops[stop["stop_id"]] = stop
stops[stop["stop_id"]]["routes"] = []
with open('google_bus/trips.txt', 'r') as f:
for trip in csv.DictReader(f):
trips[trip["trip_id"]] = trip
with open('google_bus/stop_times.txt', 'r') as f:
for stop_time in csv.DictReader(f):
route_id = trips[stop_time["trip_id"]]["route_id"]
stop = stops[stop_time["stop_id"]]
if route_id not in stop["routes"]:
stop["routes"].append(route_id)
output = {
"routes": dict([(k, reformat_route(route)) for k, route in routes.items()]),
"stops": [reformat_stop(stop) for stop in stops.values()]
}
with open("stops.json", "w") as f:
json.dump(output, f)
main()
......@@ -849,6 +849,28 @@
"to-fast-properties": "2.0.0"
}
},
"@turf/bearing": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-6.0.1.tgz",
"integrity": "sha512-mXY1NozqV9EFfBTbUItujwfqfQF0G/Xe2fzvnZle90ekPEUfhi4Dgf5JswJTd96J9LiT8kcd6Jonp5khnx0wIg==",
"requires": {
"@turf/helpers": "6.1.4",
"@turf/invariant": "6.1.2"
}
},
"@turf/helpers": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.1.4.tgz",
"integrity": "sha512-vJvrdOZy1ngC7r3MDA7zIGSoIgyrkWcGnNIEaqn/APmw+bVLF2gAW7HIsdTxd12s5wQMqEpqIQrmrbRRZ0xC7g=="
},
"@turf/invariant": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.1.2.tgz",
"integrity": "sha512-WU08Ph8j0J2jVGlQCKChXoCtI50BB3yEH21V++V0T4cR1T27HKCxkehV2sYMwTierfMBgjwSwDIsxnR4/2mWXg==",
"requires": {
"@turf/helpers": "6.1.4"
}
},
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
......
......@@ -22,6 +22,8 @@
"dependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@turf/bearing": "^6.0.1",
"@turf/helpers": "^6.1.4",
"babel": "^6.23.0",
"babel-runtime": "^6.26.0",
"dev": "^0.1.3",
......
@import url('https://fonts.googleapis.com/css?family=Manjari&display=swap');
body {
background: #888888;
font-family: 'Manjari', sans-serif;
}
.vehicle {
......@@ -7,3 +10,22 @@ body {
padding: 4px;
background: #dddddd;
}
.coming {
font-weight:bold;
}
.going {
color:#555;
}
.route-10, .route-11, .route-13, .route-15, .route-34, .route-36, .route-101, .route-102 {
background: #66cc33;
}
.route-BSL {
background: #ff9933;
}
.route-MFL {
background: #0000df;
}
.route-NHSL {
background: #a033b3;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment