-
+
diff --git a/frontend/app/search/search-query.js b/frontend/app/search/search-query.js
index f08f5a9c..dc57fd6d 100644
--- a/frontend/app/search/search-query.js
+++ b/frontend/app/search/search-query.js
@@ -358,6 +358,11 @@ fm.app.factory("fmSearchQuery", function($rootScope, $compile, fmUtils, $timeout
},
search: function(query, noZoom, showAll) {
+ if(!searchUi._el.is(":visible")) {
+ routeUi.hide();
+ searchUi.show();
+ }
+
if(query != null)
scope.searchString = query;
diff --git a/frontend/app/search/search-route.js b/frontend/app/search/search-route.js
index d3b30ba9..0bf3b747 100644
--- a/frontend/app/search/search-route.js
+++ b/frontend/app/search/search-route.js
@@ -201,7 +201,9 @@ fm.app.factory("fmSearchRoute", function($rootScope, $compile, fmUtils, $timeout
},
setQueries: function(queries) {
- scope.clear();
+ scope.submittedQueries = null;
+ scope.submittedMode = null;
+ scope.destinations = [ ];
for(var i=0; i {
if(type.defaultColour && !("colour" in data))
@@ -135,7 +135,7 @@ module.exports = function(Database) {
}),
routing: (defaultVals) => {
- return this._calculateRouting(data);
+ return this._calculateRouting(data, trackPointsFromRoute);
},
createLine: (routing, defaultVals) => {
@@ -163,7 +163,7 @@ module.exports = function(Database) {
});
},
- updateLine(padId, lineId, data, doNotUpdateStyles) {
+ updateLine(padId, lineId, data, doNotUpdateStyles, trackPointsFromRoute) {
return utils.promiseAuto({
originalLine: this.getLine(padId, lineId),
@@ -175,7 +175,7 @@ module.exports = function(Database) {
data.mode = originalLine.mode || "";
if((data.mode == "track" && data.trackPoints) || !underscore.isEqual(data.routePoints, originalLine.routePoints) || data.mode != originalLine.mode)
- return this._calculateRouting(data); // Also sets data.distance and data.time
+ return this._calculateRouting(data, trackPointsFromRoute); // Also sets data.distance and data.time
},
newLine: (routing) => {
@@ -279,8 +279,21 @@ module.exports = function(Database) {
});
},
- _calculateRouting(line) {
- if(line.mode == "track" && line.trackPoints && line.trackPoints.length >= 2) {
+ getAllLinePoints(lineId) {
+ return this._conn.model("Line").build({ id: lineId }).getLinePoints({
+ attributes: [ "lat", "lon", "ele", "zoom", "idx" ]
+ });
+ },
+
+ _calculateRouting(line, trackPointsFromRoute) {
+ if(trackPointsFromRoute) {
+ line.distance = trackPointsFromRoute.distance;
+ line.time = trackPointsFromRoute.time;
+ line.ascent = trackPointsFromRoute.ascent;
+ line.descent = trackPointsFromRoute.descent;
+
+ return Promise.resolve(trackPointsFromRoute.trackPoints);
+ } else if(line.mode == "track" && line.trackPoints && line.trackPoints.length >= 2) {
line.distance = utils.calculateDistance(line.trackPoints);
line.time = null;
diff --git a/server/database/route.js b/server/database/route.js
index c64de8e2..96b75eb4 100644
--- a/server/database/route.js
+++ b/server/database/route.js
@@ -38,26 +38,22 @@ module.exports = function(Database) {
if(getCompleteBasicRoute)
cond.$or.push({ zoom: { lte: 5 } });
- let ret = new utils.ArrayStream();
-
- this._conn.model("RoutePoint").findAll({
+ return this._conn.model("RoutePoint").findAll({
where: cond,
attributes: [ "lon", "lat", "idx", "ele"],
order: "idx"
- }).then((objs) => {
- ret.receiveArray(null, objs);
- }).catch((err) => {
- ret.receiveArray(err);
});
+ },
- return ret;
+ generateRouteId() {
+ // TODO: Check if exists
+ return Promise.resolve(utils.generateRandomId(20));
},
createRoute(routePoints, mode, calculateElevation) {
- // TODO: Check if exists
- let routeId = utils.generateRandomId(20);
-
- return this.updateRoute(routeId, routePoints, mode, calculateElevation, true);
+ return this.generateRouteId().then((routeId) => {
+ return this.updateRoute(routeId, routePoints, mode, calculateElevation, true);
+ });
},
updateRoute(routeId, routePoints, mode, calculateElevation, _noClear) {
@@ -113,6 +109,50 @@ module.exports = function(Database) {
});
},
+ lineToRoute(routeId, padId, lineId) {
+ return utils.promiseAuto({
+ routeId: () => (routeId ? routeId : this.generateRouteId()),
+ clear: () => {
+ if(routeId) {
+ return this._conn.model("RoutePoint").destroy({
+ where: { routeId }
+ });
+ }
+ },
+ line: () => (this.getLine(padId, lineId)),
+ linePoints: () => (this.getAllLinePoints(lineId)),
+ update: (routeId, clear, line, linePoints) => {
+ let create = [];
+ for(let linePoint of linePoints) {
+ create.push({
+ routeId,
+ lat: linePoint.lat,
+ lon: linePoint.lon,
+ ele: linePoint.ele,
+ zoom: linePoint.zoom,
+ idx: linePoint.idx
+ });
+ }
+
+ return this._bulkCreateInBatches(this._conn.model("RoutePoint"), create);
+ }
+
+ }).then((res) => {
+ updateTimes[res.routeId] = Date.now();
+
+ return {
+ id: res.routeId,
+ mode: res.line.mode,
+ routePoints: res.line.routePoints,
+ trackPoints: res.linePoints,
+ distance: res.line.distance,
+ time: res.line.time,
+ ascent: res.line.ascent,
+ descent: res.line.descent
+ };
+ });
+ },
+
deleteRoute(routeId) {
delete updateTimes[routeId];
@@ -124,19 +164,18 @@ module.exports = function(Database) {
},
getRoutePointsByIdx(routeId, indexes) {
- let ret = new utils.ArrayStream();
-
- this._conn.model("RoutePoint").findAll({
+ return this._conn.model("RoutePoint").findAll({
where: { routeId, idx: indexes },
attributes: [ "lon", "lat", "idx", "ele" ],
order: "idx"
- }).then((objs) => {
- ret.receiveArray(null, objs);
- }).catch((err) => {
- ret.receiveArray(err);
});
+ },
- return ret;
+ getAllRoutePoints(routeId) {
+ return this._conn.model("RoutePoint").findAll({
+ where: {routeId},
+ attributes: [ "lon", "lat", "idx", "ele", "zoom"]
+ });
}
});
};
\ No newline at end of file
diff --git a/server/socket.js b/server/socket.js
index 78d1bb5e..58aaf23e 100644
--- a/server/socket.js
+++ b/server/socket.js
@@ -1,6 +1,7 @@
var socketIo = require("socket.io");
var domain = require("domain");
var Promise = require("bluebird");
+var underscore = require("underscore");
var utils = require("./utils");
var routing = require("./routing");
@@ -33,7 +34,7 @@ class SocketConnection {
this.bbox = null;
this.writable = null;
- this.routeId = null;
+ this.route = null;
this._dbHandlers = [ ];
@@ -188,8 +189,8 @@ utils.extend(SocketConnection.prototype, {
ret.marker = utils.streamToArrayPromise(this.database.getPadMarkers(this.padId, bboxWithExcept));
ret.linePoints = utils.streamToArrayPromise(this.database.getLinePointsForPad(this.padId, bboxWithExcept));
}
- if(this.routeId)
- ret.routePoints = utils.streamToArrayPromise(this.database.getRoutePoints(this.routeId, bboxWithExcept, !bboxWithExcept.except)).then((points) => ([points]));
+ if(this.route)
+ ret.routePoints = this.database.getRoutePoints(this.route.id, bboxWithExcept, !bboxWithExcept.except).then((points) => ([points]));
return Promise.props(ret);
},
@@ -198,8 +199,8 @@ utils.extend(SocketConnection.prototype, {
if(this.padId)
this.unregisterDatabaseHandlers();
- if(this.routeId) {
- this.database.deleteRoute(this.routeId).catch((err) => {
+ if(this.route) {
+ this.database.deleteRoute(this.route.id).catch((err) => {
console.error("Error clearing route", err.stack || err);
});
}
@@ -289,7 +290,10 @@ utils.extend(SocketConnection.prototype, {
if(!this.writable)
throw "In read-only mode.";
- return this.database.createLine(this.padId, data);
+ if(this.route && data.mode != "track" && underscore.isEqual(this.route.routePoints, data.routePoints))
+ return this.database.getAllRoutePoints(this.route.id);
+ }).then((trackPoints) => {
+ return this.database.createLine(this.padId, data, trackPoints && Object.assign({}, this.route, {trackPoints}));
});
},
@@ -301,7 +305,10 @@ utils.extend(SocketConnection.prototype, {
if(!this.writable)
throw "In read-only mode.";
- return this.database.updateLine(this.padId, data.id, data);
+ if(this.route && data.mode != "track" && underscore.isEqual(this.route.routePoints, data.routePoints))
+ return this.database.getAllRoutePoints(this.route.id);
+ }).then((trackPoints) => {
+ return this.database.updateLine(this.padId, data.id, data, null, trackPoints && Object.assign({}, this.route, {trackPoints}));
});
},
@@ -476,8 +483,8 @@ utils.extend(SocketConnection.prototype, {
if(!utils.stripObject(data, { routePoints: [ { lat: "number", lon: "number" } ], mode: "string", elevation: "boolean" }))
throw "Invalid parameters.";
- if(this.routeId)
- return this.database.updateRoute(this.routeId, data.routePoints, data.mode, data.elevation);
+ if(this.route)
+ return this.database.updateRoute(this.route.id, data.routePoints, data.mode, data.elevation);
else
return this.database.createRoute(data.routePoints, data.mode, data.elevation);
}).then((routeInfo) => {
@@ -487,7 +494,7 @@ utils.extend(SocketConnection.prototype, {
return;
}
- this.routeId = routeInfo.id;
+ this.route = routeInfo;
if(this.bbox)
routeInfo.trackPoints = routing.prepareForBoundingBox(routeInfo.trackPoints, this.bbox, true);
@@ -508,10 +515,39 @@ utils.extend(SocketConnection.prototype, {
clearRoute: function() {
return Promise.resolve().then(() => {
- if(this.routeId)
- return this.database.deleteRoute(this.routeId);
+ if(this.route)
+ return this.database.deleteRoute(this.route.id);
}).then(() => {
- this.routeId = null;
+ this.route = null;
+ });
+ },
+
+ lineToRoute: function(data) {
+ return Promise.resolve().then(() => {
+ if(!utils.stripObject(data, { id: "string" }))
+ throw "Invalid parameters.";
+
+ if(!this.padId)
+ throw "No collaborative map opened.";
+
+ return this.database.lineToRoute(this.route && this.route.id, this.padId, data.id);
+ }).then((routeInfo) => {
+ this.route = routeInfo;
+
+ if(this.bbox)
+ routeInfo.trackPoints = routing.prepareForBoundingBox(routeInfo.trackPoints, this.bbox, true);
+ else
+ routeInfo.trackPoints = [];
+
+ return {
+ routePoints: routeInfo.routePoints,
+ mode: routeInfo.mode,
+ time: routeInfo.time,
+ distance: routeInfo.distance,
+ ascent: routeInfo.ascent,
+ descent: routeInfo.descent,
+ trackPoints: routeInfo.trackPoints
+ };
});
},