From 1fd5eb5ca7e2b4cfa1f1e373a3602825d8fa07c0 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 27 Oct 2016 10:33:22 +0500 Subject: Implement live routes --- web/app/Application.js | 8 ++++++ web/app/Style.js | 4 ++- web/app/view/Map.js | 15 +++++++++++ web/app/view/MapController.js | 63 +++++++++++++++++++++++++++++++++++++++---- web/l10n/en.json | 1 + 5 files changed, 85 insertions(+), 6 deletions(-) (limited to 'web') diff --git a/web/app/Application.js b/web/app/Application.js index be75a609..743f8b11 100644 --- a/web/app/Application.js +++ b/web/app/Application.js @@ -106,6 +106,14 @@ Ext.define('Traccar.Application', { } }, + getAttributePreference: function (key, defaultValue) { + if (this.getServer().get('forceSettings')) { + return this.getServer().get('attributes')[key] || this.getUser().get('attributes')[key] || defaultValue; + } else { + return this.getUser().get('attributes')[key] || this.getServer().get('attributes')[key] || defaultValue; + } + }, + showError: function (response) { var data; if (Ext.isString(response)) { diff --git a/web/app/Style.js b/web/app/Style.js index a8e16f9f..674fe8ff 100644 --- a/web/app/Style.js +++ b/web/app/Style.js @@ -77,5 +77,7 @@ Ext.define('Traccar.Style', { coordinatePrecision: 6, numberPrecision: 2, - reportTagfieldWidth: 375 + reportTagfieldWidth: 375, + + headerButtonsMargin: '0 5' }); diff --git a/web/app/view/Map.js b/web/app/view/Map.js index 2cbd1714..a19ac7d5 100644 --- a/web/app/view/Map.js +++ b/web/app/view/Map.js @@ -43,6 +43,14 @@ Ext.define('Traccar.view.Map', { return this.geofencesSource; }, + getLiveRouteSource: function () { + return this.liveRouteSource; + }, + + getLiveRouteLayer: function () { + return this.liveRouteLayer; + }, + initMap: function () { this.callParent(); @@ -51,6 +59,13 @@ Ext.define('Traccar.view.Map', { source: this.geofencesSource })); + this.liveRouteSource = new ol.source.Vector({}); + this.liveRouteLayer = new ol.layer.Vector({ + source: this.liveRouteSource, + visible: false + }); + this.map.addLayer(this.liveRouteLayer); + this.latestSource = new ol.source.Vector({}); this.map.addLayer(new ol.layer.Vector({ source: this.latestSource diff --git a/web/app/view/MapController.js b/web/app/view/MapController.js index c2477860..36092cad 100644 --- a/web/app/view/MapController.js +++ b/web/app/view/MapController.js @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -65,18 +65,29 @@ Ext.define('Traccar.view.MapController', { init: function () { this.latestMarkers = {}; this.reportMarkers = {}; + this.liveRoutes = {}; + this.liveRouteLength = Traccar.app.getAttributePreference('web.liveRouteLength', 10); this.getView().header = { xtype: 'header', title: Strings.mapTitle, - items: [{ + defaults: { xtype: 'button', + tooltipType: 'title', + margin: Traccar.Style.headerButtonsMargin + }, + items: [{ handler: 'showGeofences', reference: 'showGeofencesButton', glyph: 'xf21d@FontAwesome', enableToggle: true, pressed: true, - tooltip: Strings.sharedGeofences, - tooltipType: 'title' + tooltip: Strings.sharedGeofences + }, { + handler: 'showLiveRoutes', + reference: 'showLiveRoutes', + glyph: 'xf1b0@FontAwesome', + enableToggle: true, + tooltip: Strings.mapLiveRoutes }] }; }, @@ -129,8 +140,13 @@ Ext.define('Traccar.view.MapController', { return Ext.getCmp('deviceFollowButton') && Ext.getCmp('deviceFollowButton').pressed; }, + showLiveRoutes: function (button) { + this.getView().getLiveRouteLayer().setVisible(button.pressed); + }, + updateLatest: function (store, data) { - var i, position, geometry, device, deviceId, marker, style; + var i, position, geometry, device, deviceId, marker, style, + liveMarker, liveStyle, liveLine, lastLiveCoordinates; if (!Ext.isArray(data)) { data = [data]; @@ -166,6 +182,43 @@ Ext.define('Traccar.view.MapController', { if (marker === this.selectedMarker && this.followSelected()) { this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); } + + if (deviceId in this.liveRoutes) { + lastLiveCoordinates = this.liveRoutes[deviceId][this.liveRoutes[deviceId].length - 1].getGeometry().getCoordinates(); + if (lastLiveCoordinates[0] === geometry.getCoordinates()[0] && + lastLiveCoordinates[1] === geometry.getCoordinates()[1]) { + continue; + } + if (this.liveRoutes[deviceId].length >= this.liveRouteLength * 2) { + this.getView().getLiveRouteSource().removeFeature(this.liveRoutes[deviceId].shift()); + this.getView().getLiveRouteSource().removeFeature(this.liveRoutes[deviceId].shift()); + } + liveLine = new ol.Feature({ + geometry: new ol.geom.LineString([ + lastLiveCoordinates, + ol.proj.fromLonLat([ + position.get('longitude'), + position.get('latitude') + ]) + ]) + }); + liveLine.setStyle(this.getRouteStyle(position.get('deviceId'))); + this.liveRoutes[deviceId].push(liveLine); + this.getView().getLiveRouteSource().addFeature(liveLine); + } else { + this.liveRoutes[deviceId] = []; + } + + liveMarker = new ol.Feature(geometry); + + this.liveRoutes[deviceId].push(liveMarker); + this.getView().getLiveRouteSource().addFeature(liveMarker); + + liveStyle = this.getReportMarker(position.get('deviceId')); + liveStyle.getImage().setRotation(position.get('course') * Math.PI / 180); + + liveMarker.setStyle(liveStyle); + } } }, diff --git a/web/l10n/en.json b/web/l10n/en.json index ff9a7c47..23bfbf73 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -105,6 +105,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapLiveRoutes": "Live Routes", "stateTitle": "State", "stateName": "Attribute", "stateValue": "Value", -- cgit v1.2.3 From 3c06d96a76f09e918ff6683596ee4ab91e774110 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 28 Oct 2016 11:21:54 +0500 Subject: - Split updateLatest function - Remove liveRoute markers - Use one lineString --- web/app/view/MapController.js | 120 +++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 61 deletions(-) (limited to 'web') diff --git a/web/app/view/MapController.js b/web/app/view/MapController.js index 36092cad..b2dcd75d 100644 --- a/web/app/view/MapController.js +++ b/web/app/view/MapController.js @@ -145,8 +145,7 @@ Ext.define('Traccar.view.MapController', { }, updateLatest: function (store, data) { - var i, position, geometry, device, deviceId, marker, style, - liveMarker, liveStyle, liveLine, lastLiveCoordinates; + var i, position, device; if (!Ext.isArray(data)) { data = [data]; @@ -154,72 +153,71 @@ Ext.define('Traccar.view.MapController', { for (i = 0; i < data.length; i++) { position = data[i]; - deviceId = position.get('deviceId'); - device = Ext.getStore('Devices').findRecord('id', deviceId, 0, false, false, true); + device = Ext.getStore('Devices').findRecord('id', position.get('deviceId'), 0, false, false, true); if (device) { - geometry = new ol.geom.Point(ol.proj.fromLonLat([ - position.get('longitude'), - position.get('latitude') - ])); - - if (deviceId in this.latestMarkers) { - marker = this.latestMarkers[deviceId]; - marker.setGeometry(geometry); - } else { - marker = new ol.Feature(geometry); - marker.set('record', device); - this.latestMarkers[deviceId] = marker; - this.getView().getLatestSource().addFeature(marker); - - style = this.getLatestMarker(this.getDeviceColor(device)); - style.getText().setText(device.get('name')); - marker.setStyle(style); - } - - marker.getStyle().getImage().setRotation(position.get('course') * Math.PI / 180); - - if (marker === this.selectedMarker && this.followSelected()) { - this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); - } - - if (deviceId in this.liveRoutes) { - lastLiveCoordinates = this.liveRoutes[deviceId][this.liveRoutes[deviceId].length - 1].getGeometry().getCoordinates(); - if (lastLiveCoordinates[0] === geometry.getCoordinates()[0] && - lastLiveCoordinates[1] === geometry.getCoordinates()[1]) { - continue; - } - if (this.liveRoutes[deviceId].length >= this.liveRouteLength * 2) { - this.getView().getLiveRouteSource().removeFeature(this.liveRoutes[deviceId].shift()); - this.getView().getLiveRouteSource().removeFeature(this.liveRoutes[deviceId].shift()); - } - liveLine = new ol.Feature({ - geometry: new ol.geom.LineString([ - lastLiveCoordinates, - ol.proj.fromLonLat([ - position.get('longitude'), - position.get('latitude') - ]) - ]) - }); - liveLine.setStyle(this.getRouteStyle(position.get('deviceId'))); - this.liveRoutes[deviceId].push(liveLine); - this.getView().getLiveRouteSource().addFeature(liveLine); - } else { - this.liveRoutes[deviceId] = []; - } - - liveMarker = new ol.Feature(geometry); + this.updateLatestMarker(position, device); + this.updateLiveRoute(position); + } + } + }, - this.liveRoutes[deviceId].push(liveMarker); - this.getView().getLiveRouteSource().addFeature(liveMarker); + updateLatestMarker: function (position, device) { + var geometry, deviceId, marker, style; + geometry = new ol.geom.Point(ol.proj.fromLonLat([ + position.get('longitude'), + position.get('latitude') + ])); + deviceId = position.get('deviceId'); + if (deviceId in this.latestMarkers) { + marker = this.latestMarkers[deviceId]; + marker.setGeometry(geometry); + } else { + marker = new ol.Feature(geometry); + marker.set('record', device); + this.latestMarkers[deviceId] = marker; + this.getView().getLatestSource().addFeature(marker); + + style = this.getLatestMarker(this.getDeviceColor(device)); + style.getText().setText(device.get('name')); + marker.setStyle(style); + } - liveStyle = this.getReportMarker(position.get('deviceId')); - liveStyle.getImage().setRotation(position.get('course') * Math.PI / 180); + marker.getStyle().getImage().setRotation(position.get('course') * Math.PI / 180); - liveMarker.setStyle(liveStyle); + if (marker === this.selectedMarker && this.followSelected()) { + this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); + } + }, + updateLiveRoute: function (position) { + var deviceId, liveLine, liveCoordinates, lastLiveCoordinates, newCoordinates; + deviceId = position.get('deviceId'); + if (deviceId in this.liveRoutes) { + liveCoordinates = this.liveRoutes[deviceId].getGeometry().getCoordinates(); + lastLiveCoordinates = liveCoordinates[liveCoordinates.length - 1]; + newCoordinates = ol.proj.fromLonLat([position.get('longitude'), position.get('latitude')]); + if (lastLiveCoordinates[0] === newCoordinates[0] && + lastLiveCoordinates[1] === newCoordinates[1]) { + return; + } + if (liveCoordinates.length >= this.liveRouteLength) { + liveCoordinates.shift(); } + liveCoordinates.push(newCoordinates); + this.liveRoutes[deviceId].getGeometry().setCoordinates(liveCoordinates); + } else { + liveLine = new ol.Feature({ + geometry: new ol.geom.LineString([ + ol.proj.fromLonLat([ + position.get('longitude'), + position.get('latitude') + ]) + ]) + }); + liveLine.setStyle(this.getRouteStyle(position.get('deviceId'))); + this.liveRoutes[deviceId] = liveLine; + this.getView().getLiveRouteSource().addFeature(liveLine); } }, -- cgit v1.2.3 From 6bcc6ab2a9cd097e543ede5ee520034221045b3e Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 28 Oct 2016 14:44:05 +0500 Subject: Use variable --- web/app/view/MapController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'web') diff --git a/web/app/view/MapController.js b/web/app/view/MapController.js index b2dcd75d..050adce1 100644 --- a/web/app/view/MapController.js +++ b/web/app/view/MapController.js @@ -215,7 +215,7 @@ Ext.define('Traccar.view.MapController', { ]) ]) }); - liveLine.setStyle(this.getRouteStyle(position.get('deviceId'))); + liveLine.setStyle(this.getRouteStyle(deviceId)); this.liveRoutes[deviceId] = liveLine; this.getView().getLiveRouteSource().addFeature(liveLine); } -- cgit v1.2.3