kopia lustrzana https://github.com/FacilMap/facilmap
Edit lines using routing form (fixes #17)
rodzic
bd820f9fbf
commit
fd73b7a60d
|
@ -355,6 +355,15 @@ Clear the temporary route set via [`setRoute(data)`](#setroutedata).
|
|||
|
||||
* _returns_ (Promise)
|
||||
|
||||
### `lineToRoute(data)`
|
||||
|
||||
Call [`setRoute()`](#setroutedata) with the parameters of an existing line. Saves time, as the route does not need to be
|
||||
recalculated.
|
||||
|
||||
* `data` (object): An object with the following properties:
|
||||
* `id` (string): The ID of the line
|
||||
* _returns_ (Promise<[route](#route-1)>)
|
||||
|
||||
### `addMarker(data)`
|
||||
|
||||
Create a marker.
|
||||
|
|
|
@ -168,6 +168,15 @@ class Socket {
|
|||
return this._emit("clearRoute");
|
||||
}
|
||||
|
||||
lineToRoute(data) {
|
||||
return this._emit("lineToRoute", data).then((route) => {
|
||||
this.route = route;
|
||||
this.route.trackPoints = this._mergeTrackPoints({}, route.trackPoints);
|
||||
|
||||
return this.route;
|
||||
});
|
||||
}
|
||||
|
||||
addType(data) {
|
||||
return this._emit("addType", data);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import css from './lines.scss';
|
|||
fm.app.factory("fmMapLines", function(fmUtils, $uibModal, $compile, $timeout, $rootScope) {
|
||||
return function(map) {
|
||||
var linesById = { };
|
||||
var editingLineId = null;
|
||||
|
||||
let openLine = null;
|
||||
let openLineHighlight = null;
|
||||
|
@ -21,7 +20,7 @@ fm.app.factory("fmMapLines", function(fmUtils, $uibModal, $compile, $timeout, $r
|
|||
|
||||
map.client.on("line", function(data) {
|
||||
setTimeout(function() { // trackPoints needs to be copied over
|
||||
if(map.client.filterFunc(map.client.lines[data.id]))
|
||||
if((!map.client._editingLineId || data.id != map.client._editingLineId) && map.client.filterFunc(map.client.lines[data.id]))
|
||||
linesUi._addLine(map.client.lines[data.id]);
|
||||
}, 0);
|
||||
});
|
||||
|
@ -32,14 +31,14 @@ fm.app.factory("fmMapLines", function(fmUtils, $uibModal, $compile, $timeout, $r
|
|||
|
||||
map.client.on("linePoints", function(data) {
|
||||
setTimeout(function() {
|
||||
if(map.client.filterFunc(map.client.lines[data.id]))
|
||||
if((!map.client._editingLineId || data.id != map.client._editingLineId) && map.client.filterFunc(map.client.lines[data.id]))
|
||||
linesUi._addLine(map.client.lines[data.id]);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
map.client.on("filter", function() {
|
||||
for(var i in map.client.lines) {
|
||||
var show = map.client.filterFunc(map.client.lines[i]);
|
||||
var show = (!map.client._editingLineId || i != map.client._editingLineId) && map.client.filterFunc(map.client.lines[i]);
|
||||
if(linesById[i] && !show)
|
||||
linesUi._deleteLine(map.client.lines[i]);
|
||||
else if(!linesById[i] && show)
|
||||
|
@ -55,7 +54,7 @@ fm.app.factory("fmMapLines", function(fmUtils, $uibModal, $compile, $timeout, $r
|
|||
var linesUi = {
|
||||
_addLine: function(line, _doNotRerenderPopup) {
|
||||
var trackPoints = [ ];
|
||||
var p = (editingLineId != null && editingLineId == line.id ? line.routePoints : line.trackPoints) || [ ];
|
||||
var p = line.trackPoints || [ ];
|
||||
for(var i=0; i<p.length; i++) {
|
||||
if(p[i] != null)
|
||||
trackPoints.push(L.latLng(p[i].lat, p[i].lon));
|
||||
|
@ -68,7 +67,7 @@ fm.app.factory("fmMapLines", function(fmUtils, $uibModal, $compile, $timeout, $r
|
|||
linesById[line.id] = L.polyline([ ]).addTo(map.map);
|
||||
map.map.almostOver.addLayer(linesById[line.id]);
|
||||
|
||||
if(line.id != null && line.id != editingLineId) { // We don't want a popup for lines that we are drawing right now
|
||||
if(line.id != null) { // We don't want a popup for lines that we are drawing right now
|
||||
linesById[line.id]
|
||||
.on("click", function(e) {
|
||||
linesUi.showLineInfoBox(map.client.lines[line.id]);
|
||||
|
@ -202,123 +201,6 @@ fm.app.factory("fmMapLines", function(fmUtils, $uibModal, $compile, $timeout, $r
|
|||
template.filter(".content").on("resizeend", drawElevationPlot);
|
||||
setTimeout(drawElevationPlot, 0);
|
||||
},
|
||||
_makeLineMovable: function(line) {
|
||||
var markers = [ ];
|
||||
|
||||
editingLineId = line.id;
|
||||
|
||||
// Re-add the line (because editingLineId is set)
|
||||
linesUi._deleteLine(line);
|
||||
linesUi._addLine(line);
|
||||
|
||||
// Watch if route points change (because someone else has moved the line while we are moving it
|
||||
var routePointsBkp = ng.copy(line.routePoints);
|
||||
var unregisterWatcher = $rootScope.$watch(() => (map.client.lines[line.id].routePoints), function() {
|
||||
// We do not do a deep watch, as then we will be not notified if someone edits the line without
|
||||
// actually moving it, in which case we still need to redraw it (because it gets redrawn because
|
||||
// the server sends it to us again).
|
||||
|
||||
// The line has been edited, but it has not been moved. Override its points with our current stage again
|
||||
if(ng.equals(routePointsBkp, map.client.lines[line.id].routePoints))
|
||||
map.client.lines[line.id].routePoints = line.routePoints;
|
||||
else // The line has been moved. Override our stage with the new points.
|
||||
routePointsBkp = ng.copy(line.routePoints);
|
||||
|
||||
line = map.client.lines[line.id];
|
||||
linesUi._addLine(line);
|
||||
removeTempMarkers();
|
||||
createTempMarkers();
|
||||
});
|
||||
|
||||
function createTempMarker(huge) {
|
||||
var marker = L.marker([0,0], {
|
||||
icon: fmUtils.createMarkerIcon(map.dragMarkerColour, 35, null, huge ? 1000 : null),
|
||||
draggable: true
|
||||
})
|
||||
.on("dblclick", function() {
|
||||
// Double click on temporary marker: Remove this route point
|
||||
var idx = markers.indexOf(marker);
|
||||
markers.splice(idx, 1);
|
||||
line.routePoints.splice(idx, 1);
|
||||
marker.remove();
|
||||
linesUi._addLine(line);
|
||||
})
|
||||
.on("drag", function() {
|
||||
var idx = markers.indexOf(marker);
|
||||
var latlng = marker.getLatLng();
|
||||
line.routePoints[idx] = { lat: latlng.lat, lon: latlng.lng };
|
||||
linesUi._addLine(line);
|
||||
});
|
||||
return marker;
|
||||
}
|
||||
|
||||
function createTempMarkers() {
|
||||
line.routePoints.forEach(function(it) {
|
||||
markers.push(createTempMarker().setLatLng([ it.lat, it.lon ]).addTo(map.map));
|
||||
});
|
||||
}
|
||||
|
||||
function removeTempMarkers() {
|
||||
for(var i=0; i<markers.length; i++)
|
||||
markers[i].remove();
|
||||
markers = [ ];
|
||||
}
|
||||
|
||||
// This marker is shown when we hover the line. It enables us to create new markers.
|
||||
// It is a huge one (a normal marker with 5000 px or so transparency around it, so that we can be
|
||||
// sure that the mouse is over it and dragging it will work smoothly.
|
||||
var temporaryHoverMarker;
|
||||
|
||||
function _over(e) {
|
||||
temporaryHoverMarker.setLatLng(e.latlng).addTo(map.map);
|
||||
}
|
||||
|
||||
function _move(e) {
|
||||
temporaryHoverMarker.setLatLng(e.latlng);
|
||||
}
|
||||
|
||||
function _out(e) {
|
||||
temporaryHoverMarker.remove();
|
||||
}
|
||||
|
||||
linesById[line.id].on("fm-almostover", _over).on("fm-almostmove", _move).on("fm-almostout", _out);
|
||||
|
||||
function makeTemporaryHoverMarker() {
|
||||
temporaryHoverMarker = createTempMarker(true);
|
||||
|
||||
temporaryHoverMarker.once("dragstart", function() {
|
||||
temporaryHoverMarker.once("dragend", function() {
|
||||
// We have to replace the huge icon with the regular one at the end of the dragging, otherwise
|
||||
// the dragging gets interrupted
|
||||
this.setIcon(fmUtils.createMarkerIcon("ffd700", 35));
|
||||
}, temporaryHoverMarker);
|
||||
|
||||
var latlng = temporaryHoverMarker.getLatLng();
|
||||
var idx = fmUtils.getIndexOnLine(map.map, line.routePoints, line.routePoints, latlng);
|
||||
markers.splice(idx, 0, temporaryHoverMarker);
|
||||
line.routePoints.splice(idx, 0, { lat: latlng.lat, lon: latlng.lng });
|
||||
|
||||
makeTemporaryHoverMarker();
|
||||
});
|
||||
}
|
||||
|
||||
makeTemporaryHoverMarker();
|
||||
|
||||
return {
|
||||
done : function() {
|
||||
editingLineId = null;
|
||||
unregisterWatcher();
|
||||
removeTempMarkers();
|
||||
temporaryHoverMarker.remove();
|
||||
|
||||
// Re-add the line (because editingLineId is not set anymore)
|
||||
linesUi._deleteLine(line);
|
||||
linesUi._addLine(line);
|
||||
|
||||
return line.routePoints;
|
||||
}
|
||||
};
|
||||
},
|
||||
editLine: function(line) {
|
||||
var scope = $rootScope.$new();
|
||||
scope.client = map.client;
|
||||
|
@ -406,29 +288,58 @@ fm.app.factory("fmMapLines", function(fmUtils, $uibModal, $compile, $timeout, $r
|
|||
});
|
||||
},
|
||||
moveLine: function(line) {
|
||||
var movable = linesUi._makeLineMovable(line);
|
||||
|
||||
var message = map.messages.showMessage("info", "Drag the line points around to change it. Double-click a point to remove it.", [
|
||||
{ label: "Finish", click: done.bind(null, true) },
|
||||
{ label: "Cancel", click: done.bind(null, false) }
|
||||
], null, done.bind(null, false, true));
|
||||
map.routeUi.lineToRoute(line.id).then(() => {
|
||||
map.client._editingLineId = line.id;
|
||||
linesUi._deleteLine(line);
|
||||
|
||||
function done(save, noClose) {
|
||||
var newPoints = movable.done();
|
||||
linesUi._addLine(line);
|
||||
linesUi.showLineInfoBox(line);
|
||||
let message = map.messages.showMessage("info", "Drag the line points around to change it. Double-click a point to remove it.", [
|
||||
{ label: "Finish", click: done.bind(null, true), enabled: () => (!!map.client.route) },
|
||||
{ label: "Cancel", click: done.bind(null, false) }
|
||||
], null, done.bind(null, false, true));
|
||||
|
||||
if(!noClose) {
|
||||
message.close();
|
||||
let searchBkp;
|
||||
if(map.searchUi) {
|
||||
searchBkp = map.searchUi.getCurrentSearchForHash() || "";
|
||||
map.searchUi.route(map.client.route.routePoints.map((routePoint) => (fmUtils.round(routePoint.lat, 5) + "," + fmUtils.round(routePoint.lon, 5))), map.client.route.mode, false, true);
|
||||
}
|
||||
|
||||
if(save) {
|
||||
line.trackPoints = { };
|
||||
map.client.editLine({ id: line.id, routePoints: newPoints }).catch(function(err) {
|
||||
function done(save, noClose) {
|
||||
map.client._editingLineId = null;
|
||||
linesUi._addLine(map.client.lines[line.id]);
|
||||
linesUi.showLineInfoBox(map.client.lines[line.id]);
|
||||
|
||||
if(!noClose) {
|
||||
message.close();
|
||||
}
|
||||
|
||||
if(save && !map.client.route) {
|
||||
map.messages.showMessage("danger", "No route set.");
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
if(save) {
|
||||
return map.client.editLine({ id: line.id, routePoints: map.client.route.routePoints, mode: map.client.route.mode });
|
||||
}
|
||||
}).then(() => {
|
||||
// Clear route after editing line so that the server can take the trackPoints from the route
|
||||
let ret = map.routeUi.clearRoute();
|
||||
|
||||
if(map.searchUi) {
|
||||
map.searchUi.route([], null, false, true);
|
||||
map.searchUi.search(searchBkp, true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}).catch(function(err) {
|
||||
map.messages.showMessage("danger", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log("err", err);
|
||||
map.messages.showMessage("danger", err);
|
||||
});
|
||||
},
|
||||
deleteLine: function(line) {
|
||||
map.client.deleteLine(line).catch(function(err) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div ng-repeat="message in messages" uib-alert ng-class="'alert-' + message.type" close="message.close(true)">
|
||||
<strong>{{message.message}}</strong>
|
||||
<div class="btn-group pull-right btn-group-sm">
|
||||
<a ng-repeat="button in message.buttons" href="{{button.url || 'javascript:'}}" ng-click="button.click && button.click()" class="btn btn-default">{{button.label}}</a>
|
||||
<a ng-repeat="button in message.buttons" href="{{button.url || 'javascript:'}}" ng-click="button.click && button.click()" class="btn btn-default" ng-disabled="button.enabled && !button.enabled()">{{button.label}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -275,6 +275,15 @@ fm.app.factory("fmMapRoute", function(fmUtils, $uibModal, $compile, $timeout, $r
|
|||
});
|
||||
},
|
||||
|
||||
lineToRoute(lineId) {
|
||||
return map.client.lineToRoute({
|
||||
id: lineId
|
||||
}).then(() => {
|
||||
renderRoute();
|
||||
this.showRouteInfoBox();
|
||||
});
|
||||
},
|
||||
|
||||
clearRoute() {
|
||||
map.mapEvents.$broadcast("routeClear");
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
</dl>
|
||||
<div class="fm-elevation-plot" ng-show="client.route.ascent != null"></div>
|
||||
</div>
|
||||
<div class="buttons" ng-if="!client.readonly">
|
||||
<div class="buttons" ng-if="!client.readonly && !client._editingLineId">
|
||||
<div uib-dropdown keyboard-nav="true" ng-if="(client.types | fmPropertyCount:{type:'line'}) > 1" class="dropup">
|
||||
<button id="add-type-button" type="button" class="btn btn-default" uib-dropdown-toggle>Add to map <span class="caret"></span></button>
|
||||
<button id="add-type-button" type="button" class="btn btn-default btn-sm" uib-dropdown-toggle>Add to map <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="add-type-button" uib-dropdown-menu>
|
||||
<li role="menuitem" ng-repeat="type in client.types | fmObjectFilter:{type:'line'}"><a href="javascript:" ng-click="addToMap(type)">{{type.name}}</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<queries.length; i++) {
|
||||
if(scope.destinations.length <= i)
|
||||
|
@ -209,6 +211,9 @@ fm.app.factory("fmSearchRoute", function($rootScope, $compile, fmUtils, $timeout
|
|||
|
||||
$.extend(scope.destinations[i], typeof queries[i] == "object" ? queries[i] : { query: queries[i] });
|
||||
}
|
||||
|
||||
while(scope.destinations.length < 2)
|
||||
scope.addDestination();
|
||||
},
|
||||
|
||||
setFrom: function(from, suggestions, selectedSuggestion) {
|
||||
|
|
|
@ -123,7 +123,7 @@ module.exports = function(Database) {
|
|||
return this._getPadObject("Line", padId, lineId);
|
||||
},
|
||||
|
||||
createLine(padId, data) {
|
||||
createLine(padId, data, trackPointsFromRoute) {
|
||||
return utils.promiseAuto({
|
||||
defaultVals: this.getType(padId, data.typeId).then((type) => {
|
||||
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;
|
||||
|
||||
|
|
|
@ -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"]
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
|
@ -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
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue