Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Prefetch and cache direction tiles #294

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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