diff --git a/.eslintrc b/.eslintrc index 6096a76..8991392 100644 --- a/.eslintrc +++ b/.eslintrc @@ -20,6 +20,7 @@ "no-alert": 0, "no-debugger": 2, "no-return-assign": [1, "always"], + "no-plusplus": 0, "max-len": [1, { "code": 150, "tabWidth": 2 diff --git a/ios/lightrail/Info.plist b/ios/lightrail/Info.plist index 27d86e0..848a9a1 100644 --- a/ios/lightrail/Info.plist +++ b/ios/lightrail/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0 + 2.1 CFBundleSignature ???? CFBundleVersion - 3 + 6 LSApplicationQueriesSchemes comgooglemaps diff --git a/package.json b/package.json index 27145e5..d93c0c9 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "node": "^6.9.2" }, "dependencies": { + "geolib": "^2.0.24", "moment": "2.15.2", "prop-types": "15.5.10", "react": "15.3.2", diff --git a/src/components/StationCard/StationCard.js b/src/components/StationCard/StationCard.js index 1ffa3d0..825c75c 100644 --- a/src/components/StationCard/StationCard.js +++ b/src/components/StationCard/StationCard.js @@ -33,7 +33,7 @@ export default class StationCard extends React.Component { renderDistanceText = () => { const { stationIndex, stationDistances, mode } = this.props; - if (stationDistances) { + if (stationDistances && stationDistances[stationIndex].duration) { return `${stationDistances[stationIndex].durationText} ${mode === 'driving' ? 'drive' : 'walk'}`; } return null; diff --git a/src/helpers/mapboxDistanceAPI.js b/src/helpers/mapboxDistanceAPI.js index 4d2d3c2..563061f 100644 --- a/src/helpers/mapboxDistanceAPI.js +++ b/src/helpers/mapboxDistanceAPI.js @@ -1,14 +1,48 @@ +import geolib from 'geolib'; import { mapboxApiKey } from './config'; + +const orderByDistance = (origin, destinations) => { + const currentLocation = { latitude: origin[1], longitude: origin[0] }; + const stations = destinations.map(latlng => ({ latitude: latlng[1], longitude: latlng[0] })); + + const nearestStationDistances = geolib + .orderByDistance(currentLocation, stations) + .slice(0, 3) + .sort((a, b) => a.key - b.key); + + const nearestStationCoordinates = nearestStationDistances.map(item => destinations[item.key]); + const nearestStationIndices = nearestStationDistances.map(item => item.key); + + return { coordinates: nearestStationCoordinates, indices: nearestStationIndices }; +}; + export const mapboxDistanceAPI = { getDistance(origin, destinations, mode) { - const coordinates = destinations; - coordinates.unshift(origin); + // First, get the nearest three stations as-the-crow-flies, to save on API calls. + const { coordinates, indices } = orderByDistance(origin, destinations); + // Prepare the URL for the GET request. + coordinates.unshift(origin); const endpoint = `directions-matrix/v1/mapbox/${mode}`; const coordinatesString = coordinates.map(coordinate => coordinate.toString()); const coordinatesQuery = coordinatesString.join(';'); const url = `https://api.mapbox.com/${endpoint}/${coordinatesQuery}?sources=0&access_token=${mapboxApiKey}`; - return fetch(url).then(res => res.json()); + + // Fetch the datat from the Mapbox API. + return fetch(url) + .then(res => res.json()) + .then(res => res.durations[0].slice(1)) // remove our current location from the results + .then((res) => { // build out an array representing the station distances, with null values for stations that were not queried + const distances = []; + for (let i = 0; i < destinations.length; i++) { + if (indices.includes(i.toString())) { + distances.push(res.shift()); + } else { + distances.push(null); + } + } + return distances; + }); } }; diff --git a/src/scenes/RailMap/RailMap.js b/src/scenes/RailMap/RailMap.js index 76ad030..0791c0a 100644 --- a/src/scenes/RailMap/RailMap.js +++ b/src/scenes/RailMap/RailMap.js @@ -223,27 +223,29 @@ export default class RailMap extends React.Component { .map(stop => [stop.latlng.longitude, stop.latlng.latitude]); mapboxDistanceAPI.getDistance(origin, destinations, mode) - .then((res) => { - const stationDistances = res.durations[0] - .slice(1) // get rid of first item, which is the distance of current location to itself (0) - .map((duration, index) => ({ index, duration, durationText: distanceTimeConverter(duration) })); // this index is used to map to blueStops index - - const nearestStation = stationDistances.reduce((prev, curr) => { - if (prev.duration < curr.duration) { - return prev; - } - return curr; - }); - const nearestIndex = nearestStation.index; + .then((durations) => { + console.log(durations); + const stationDistances = durations + .map((duration, index) => ({ + index, // this index is used to map to blueStops index + duration, + durationText: duration ? distanceTimeConverter(duration) : '' + })); + + const nearestStationIndex = stationDistances + .filter(item => item.duration) + .sort((a, b) => a.duration > b.duration)[0] + .index; // set station marker colors - this.setNearestMarkerColor(nearestIndex); + this.setNearestMarkerColor(nearestStationIndex); + // REVIEW: Parts of updatedStationDistances might be superfluous. Refactor as necessary. const updatedStationDistances = {}; stationDistances.forEach((stop, index) => { updatedStationDistances[`stopCallout${index}`] = { ...this.state[`stopCallout${index}`], - durationText: distanceTimeConverter(stationDistances[index].duration), + durationText: stationDistances[index].duration ? distanceTimeConverter(stationDistances[index].duration) : '', inbound: getNextTrainTime('inbound', index), outbound: getNextTrainTime('outbound', index) }; @@ -253,13 +255,13 @@ export default class RailMap extends React.Component { ...updatedStationDistances, connected: true, loading: false, - nearestStationIndex: nearestIndex, + nearestStationIndex, stationDistances }); // Show nearest station callout. We pass stationDistances because sometimes showCallout() gets // called before the setState above happens, and showCallout depends on stationDistances. - this.showCallout(nearestIndex, stationDistances); + this.showCallout(nearestStationIndex, stationDistances); }) .catch((err) => { this.setState({ error: 'mapboxDistanceAPI' }); diff --git a/yarn.lock b/yarn.lock index 7280750..b04cfe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2334,6 +2334,10 @@ generate-object-property@^1.1.0: dependencies: is-property "^1.0.0" +geolib@^2.0.24: + version "2.0.24" + resolved "https://registry.yarnpkg.com/geolib/-/geolib-2.0.24.tgz#eb3d7fbc65f5ea3354a5af6054563ebe9f33e5f4" + get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"