Skip to content

Commit

Permalink
Merge pull request #294 from jkwening/151-router-google-directions
Browse files Browse the repository at this point in the history
feat: Prefetch and cache direction tiles
  • Loading branch information
jkwening authored Mar 27, 2018
2 parents ee16644 + c3059d9 commit 3ed4ad1
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 5 deletions.
30 changes: 29 additions & 1 deletion client/src/js/leaflet-tileLayer-pouchdb-cached.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,36 @@ L.TileLayer.include({
this._seedOneTile(tile, remaining, seedData);
}
}.bind(this));
}
},

cacheAhead: function(coords, done, zoom=18) {
var tile = document.createElement('img');

tile.onerror = L.bind(this._tileOnError, this, done, tile);

if (this.options.crossOrigin) {
tile.crossOrigin = '';
}

/*
Alt tag is *set to empty string to keep screen readers from reading URL and for compliance reasons
http://www.w3.org/TR/WCAG20-TECHS/H67
*/
tile.alt = '';

let tileUrl = this.getTileUrl(coords);
tileUrl = tileUrl.replace('NaN', zoom); // fix tileUrl with correct zoom value

// if available get cached tile image
this._db.get(tileUrl,
{
rev: true,
attachments: true,
binary: true, // return attachment data as Blobs instead of as base64-encoded strings
},
this._onCacheLookup(tile, tileUrl, done)
);
}
});

export default L;
20 changes: 17 additions & 3 deletions client/src/js/lrm-google.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const L = require('leaflet');
const decodePolyline = require('decode-google-map-polyline');

// app module imports
const { latLngToPoint, pointToLatLng } = require('./osm-tile-name');
const { makeRequest, BASE_ENDPOINTS } = require('./server-requests-utils')

L.Routing = L.Routing || {};
Expand All @@ -12,8 +13,9 @@ L.Routing.Google = L.Class.extend({

},

initialize: function(options) {
initialize: function(options, TILE_LAYER) {
L.Util.setOptions(this, options);
this._TILE_LAYER = TILE_LAYER;
},

route: function(waypoints, callback, context, options) {
Expand Down Expand Up @@ -65,13 +67,25 @@ L.Routing.Google = L.Class.extend({
});
});

// prefetch/cache polylines
if (this._TILE_LAYER) {
route.coordinates.forEach((latLng) => {
const coord = latLngToPoint(latLng.lat, latLng.lng, 18);

// TODO - if needed cache all four corners by looping +1 for x/y
this._TILE_LAYER.cacheAhead(coord, () => {
// console.log('cached coord: ', coord);
});
});
}

routes.push(route);
});

callback.call(context || callback, null, routes);
}
});

L.Routing.google = function(options={}) {
return new L.Routing.Google(options);
L.Routing.google = function(options={}, TILE_LAYER=null) {
return new L.Routing.Google(options, TILE_LAYER);
};
51 changes: 51 additions & 0 deletions client/src/js/osm-tile-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Module for calculating tile name for slippy maps.
*
* Source: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
*
* Notes:
* This article describes the file naming conventions for the Slippy Map application.
* - Tiles are 256 × 256 pixel PNG files
* - Each zoom level is a directory, each column is a subdirectory, and each tile in that column is a file
* - Filename(url) format is /zoom/x/y.png
* The slippy map expects tiles to be served up at URLs following this scheme, so all tile server URLs look pretty similar.
*/

// utility functions
const toRadians = (angle) => (angle * (Math.PI / 180));
const toDegrees = (radian) => (radian * (180/ Math.PI));
const getN = (zoom) => (Math.pow(2.0, zoom));
const getSec = (radian) => (1 / Math.cos(radian));

/**
* Calculate x and y coords for tile url.
*
* @param {number} lat latitude in degrees
* @param {number} lng longitude in degrees
* @param {number} zoom zoom level
*/
exports.latLngToPoint = (lat, lng, zoom) => {
const n = getN(zoom);
const latRadians = toRadians(lat);

const x = Math.floor(n * ((lng + 180) / 360));

const secLat = getSec(latRadians);
const y = Math.floor(n * (1 - (Math.log(Math.tan(latRadians) + secLat) / Math.PI)) / 2);
return { x, y, z: zoom };
};

/**
* Estimate latitude and longitude for give tile url point.
*
* @param {number} x point x
* @param {number} y point y
* @param {number} zoom zoom level
*/
exports.pointToLatLng = (x, y, zoom) => {
const n = getN(zoom);

const lng = (x / n) * 360 - 180;
const lat = Math.atan(Math.sinh(Math.PI - (y / n) * 2 * Math.PI)) * (180 / Math.PI);
return { lat, lng };
};
2 changes: 1 addition & 1 deletion client/src/routes/directions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class Directions extends Component {
showAlternatives: true,
show: false,
collapsible: false,
router: L.Routing.google(),
router: L.Routing.google({}, OSM_TILE_LAYER),
}).addTo(map);

this.control.on('routeselected', (e) => {
Expand Down

0 comments on commit 3ed4ad1

Please sign in to comment.