From 587e6bf80dd3c83d7066e1960e76d502f6dc81f3 Mon Sep 17 00:00:00 2001 From: Candid Dauth Date: Fri, 10 Feb 2017 16:49:25 +0100 Subject: [PATCH] Allow more than 25 route points by sending multiple requests (fixes #52) --- server/database/helpers.js | 13 +++++++ server/database/line.js | 2 +- server/routing.js | 71 ++++++++++++++++++++++++-------------- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/server/database/helpers.js b/server/database/helpers.js index c494647b..e9c55f55 100644 --- a/server/database/helpers.js +++ b/server/database/helpers.js @@ -1,8 +1,11 @@ +var Promise = require("promise"); var Sequelize = require("sequelize"); var stream = require("stream"); var utils = require("../utils"); +const ITEMS_PER_BATCH = 5000; + module.exports = function(Database) { utils.extend(Database.prototype, { _TYPES: { @@ -321,6 +324,16 @@ module.exports = function(Database) { } return Sequelize.and.apply(Sequelize, conditions); + }, + + _bulkCreateInBatches(model, data) { + let ret = Promise.resolve([]); + for(let i=0; i { + return model.bulkCreate(data.slice(i, i+ITEMS_PER_BATCH)).then((result2) => result.concat(result2)); + }); + } + return ret; } }); }; \ No newline at end of file diff --git a/server/database/line.js b/server/database/line.js index da4c3297..a1431af6 100644 --- a/server/database/line.js +++ b/server/database/line.js @@ -199,7 +199,7 @@ module.exports = function(Database) { create.push(utils.extend({ }, trackPoints[i], { lineId: lineId })); } - return this._conn.model("LinePoint").bulkCreate(create); + return this._bulkCreateInBatches(this._conn.model("LinePoint"), create); }).then((points) => { if(!_noEvent) this.emit("linePoints", padId, lineId, points); diff --git a/server/routing.js b/server/routing.js index 3260567d..b7dfa69e 100644 --- a/server/routing.js +++ b/server/routing.js @@ -1,3 +1,4 @@ +var Promise = require("promise"); var request = require("request-promise"); var utils = require("./utils"); @@ -20,38 +21,56 @@ var ROUTING_TYPES = { var ACCESS_TOKEN = "pk.eyJ1IjoiY2RhdXRoIiwiYSI6ImNpdTYwMmZwMDAwM3AyenBhemM5NHM4ZmgifQ.93z6yuzcsxt3eZk9NxPGHA"; +var MAX_POINTS_PER_REQUEST = 25; + function calculateRouting(points, mode, simple) { - var coords = [ ]; - for(var i=0; i= MAX_POINTS_PER_REQUEST) + coordGroups.push([]); - var url = ROUTING_URL + "/" + ROUTING_TYPES[mode] + "/" + coords.join(";") - + "?alternatives=false" - + "&steps=false" - + "&geometries=geojson" - + "&overview=" + (simple ? "simplified" : "full") - + "&access_token=" + encodeURIComponent(ACCESS_TOKEN); + coordGroups[coordGroups.length-1].push(point.lon + "," + point.lat); + } - return request.get({ - url: url, - json: true, - gzip: true, - headers: { - 'User-Agent': config.userAgent - } - }).then(function(body) { - if(!body || (body.code == "OK" && (!body.legs || !body.legs[0]))) - throw "Invalid response from routing server."; + return Promise.all(coordGroups.map((coords) => { + let url = ROUTING_URL + "/" + ROUTING_TYPES[mode] + "/" + coords.join(";") + + "?alternatives=false" + + "&steps=false" + + "&geometries=geojson" + + "&overview=" + (simple ? "simplified" : "full") + + "&access_token=" + encodeURIComponent(ACCESS_TOKEN); - if(body.code != 'Ok') - throw "Route could not be calculated (" + body.code + ")."; - - var ret = { - trackPoints : body.routes[0].geometry.coordinates.map(function(it) { return { lat: it[1], lon: it[0] }; }), - distance: body.routes[0].distance/1000, - time: body.routes[0].duration + return request.get({ + url: url, + json: true, + gzip: true, + headers: { + 'User-Agent': config.userAgent + } + }); + })).then((results) => { + let ret = { + trackPoints: [], + distance: 0, + time: 0 }; + for(let body of results) { + if(!body || (body.code == "OK" && (!body.legs || !body.legs[0]))) + throw "Invalid response from routing server."; + + if(body.code != 'Ok') + throw "Route could not be calculated (" + body.code + ")."; + + let trackPoints = body.routes[0].geometry.coordinates.map(function(it) { return { lat: it[1], lon: it[0] }; }); + if(trackPoints.length > 0 && ret.trackPoints.length > 0 && trackPoints[0].lat == ret.trackPoints[ret.trackPoints.length-1].lat && trackPoints[0].lon == ret.trackPoints[ret.trackPoints.length-1].lon) + trackPoints.shift(); + + ret.trackPoints.push(...trackPoints); + ret.distance += body.routes[0].distance/1000; + ret.time += body.routes[0].duration; + } + if(!simple) _calculateZoomLevels(ret.trackPoints);