Commit 1059c21eab2e78363d79bae99f1cd37c90f1ad9f

Authored by Vladyslav
Committed by Igor Kulikov
1 parent ac8e67ef

Fix calculate trip to big interval time (#2161)

@@ -128,7 +128,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -128,7 +128,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
128 vm.index = 0; 128 vm.index = 0;
129 vm.dsIndex = 0; 129 vm.dsIndex = 0;
130 vm.minTime = 0; 130 vm.minTime = 0;
131 - vm.maxTime = 0; 131 + vm.minTimeIndex = 0;
  132 + vm.maxTimeIndex = 0;
132 vm.isPlaying = false; 133 vm.isPlaying = false;
133 vm.trackingLine = { 134 vm.trackingLine = {
134 "type": "FeatureCollection", 135 "type": "FeatureCollection",
@@ -200,10 +201,10 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -200,10 +201,10 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
200 vm.moveNext = function () { 201 vm.moveNext = function () {
201 vm.stopPlay(); 202 vm.stopPlay();
202 if (vm.staticSettings.usePointAsAnchor) { 203 if (vm.staticSettings.usePointAsAnchor) {
203 - let newIndex = vm.maxTime;  
204 - for (let index = vm.index+1; index < vm.maxTime; index++) { 204 + let newIndex = vm.maxTimeIndex;
  205 + for (let index = vm.index + 1; index < vm.maxTimeIndex; index++) {
205 if (vm.trips.some(function (trip) { 206 if (vm.trips.some(function (trip) {
206 - return trip.timeRange[index].hasAnchor; 207 + return calculateCurrentDate(trip.timeRange, index).hasAnchor;
207 })) { 208 })) {
208 newIndex = index; 209 newIndex = index;
209 break; 210 break;
@@ -216,27 +217,27 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -216,27 +217,27 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
216 vm.movePrev = function () { 217 vm.movePrev = function () {
217 vm.stopPlay(); 218 vm.stopPlay();
218 if (vm.staticSettings.usePointAsAnchor) { 219 if (vm.staticSettings.usePointAsAnchor) {
219 - let newIndex = vm.minTime;  
220 - for (let index = vm.index-1; index > vm.minTime; index--) { 220 + let newIndex = vm.minTimeIndex;
  221 + for (let index = vm.index - 1; index > vm.minTimeIndex; index--) {
221 if (vm.trips.some(function (trip) { 222 if (vm.trips.some(function (trip) {
222 - return trip.timeRange[index].hasAnchor;  
223 - })) { 223 + return calculateCurrentDate(trip.timeRange, index).hasAnchor;
  224 + })) {
224 newIndex = index; 225 newIndex = index;
225 break; 226 break;
226 } 227 }
227 } 228 }
228 moveToIndex(newIndex); 229 moveToIndex(newIndex);
229 - } else moveInc(-1); 230 + } else moveInc(-1);
230 }; 231 };
231 232
232 vm.moveStart = function () { 233 vm.moveStart = function () {
233 vm.stopPlay(); 234 vm.stopPlay();
234 - moveToIndex(vm.minTime); 235 + moveToIndex(vm.minTimeIndex);
235 }; 236 };
236 237
237 vm.moveEnd = function () { 238 vm.moveEnd = function () {
238 vm.stopPlay(); 239 vm.stopPlay();
239 - moveToIndex(vm.maxTime); 240 + moveToIndex(vm.maxTimeIndex);
240 }; 241 };
241 242
242 vm.stopPlay = function () { 243 vm.stopPlay = function () {
@@ -252,8 +253,9 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -252,8 +253,9 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
252 } 253 }
253 254
254 function moveToIndex(newIndex) { 255 function moveToIndex(newIndex) {
255 - if (newIndex > vm.maxTime || newIndex < vm.minTime) return; 256 + if (newIndex > vm.maxTimeIndex || newIndex < vm.minTimeIndex) return;
256 vm.index = newIndex; 257 vm.index = newIndex;
  258 + vm.animationTime = vm.minTime + vm.index * vm.staticSettings.normalizationStep;
257 recalculateTrips(); 259 recalculateTrips();
258 } 260 }
259 261
@@ -263,12 +265,6 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -263,12 +265,6 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
263 }) 265 })
264 } 266 }
265 267
266 - function findAngle(lat1, lng1, lat2, lng2) {  
267 - let angle = Math.atan2(0, 0) - Math.atan2(lat2 - lat1, lng2 - lng1);  
268 - angle = angle * 180 / Math.PI;  
269 - return parseInt(angle.toFixed(2));  
270 - }  
271 -  
272 function initialize() { 268 function initialize() {
273 $scope.currentDate = $filter('date')(0, "yyyy.MM.dd HH:mm:ss"); 269 $scope.currentDate = $filter('date')(0, "yyyy.MM.dd HH:mm:ss");
274 270
@@ -445,7 +441,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -445,7 +441,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
445 } 441 }
446 } 442 }
447 443
448 - function configureTripSettings(trip, index, apply) { 444 + function configureTripSettings(trip, apply) {
449 trip.settings = {}; 445 trip.settings = {};
450 trip.settings.color = calculateColor(trip); 446 trip.settings.color = calculateColor(trip);
451 trip.settings.polygonColor = calculatePolygonColor(trip); 447 trip.settings.polygonColor = calculatePolygonColor(trip);
@@ -478,17 +474,17 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -478,17 +474,17 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
478 let labelText = vm.staticSettings.label; 474 let labelText = vm.staticSettings.label;
479 if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) { 475 if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) {
480 try { 476 try {
481 - labelText = vm.staticSettings.labelFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dsIndex); 477 + labelText = vm.staticSettings.labelFunction(vm.ctx.data, calculateCurrentDate(trip.timeRange, vm.index), trip.dsIndex);
482 } catch (e) { 478 } catch (e) {
483 labelText = null; 479 labelText = null;
484 } 480 }
485 } 481 }
486 labelText = vm.utils.createLabelFromDatasource(trip.dataSource, labelText); 482 labelText = vm.utils.createLabelFromDatasource(trip.dataSource, labelText);
487 labelReplaceInfo = processPattern(labelText, vm.ctx.datasources, trip.dSIndex); 483 labelReplaceInfo = processPattern(labelText, vm.ctx.datasources, trip.dSIndex);
488 - label = fillPattern(labelText, labelReplaceInfo, trip.timeRange[vm.index]); 484 + label = fillPattern(labelText, labelReplaceInfo, calculateCurrentDate(trip.timeRange, vm.index));
489 if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) { 485 if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) {
490 try { 486 try {
491 - labelText = vm.staticSettings.labelFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); 487 + labelText = vm.staticSettings.labelFunction(vm.ctx.data, calculateCurrentDate(trip.timeRange, vm.index), trip.dSIndex);
492 } catch (e) { 488 } catch (e) {
493 labelText = null; 489 labelText = null;
494 } 490 }
@@ -504,14 +500,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -504,14 +500,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
504 let tooltipText = vm.staticSettings.tooltipPattern; 500 let tooltipText = vm.staticSettings.tooltipPattern;
505 if (vm.staticSettings.useTooltipFunction && angular.isDefined(vm.staticSettings.tooltipFunction)) { 501 if (vm.staticSettings.useTooltipFunction && angular.isDefined(vm.staticSettings.tooltipFunction)) {
506 try { 502 try {
507 - tooltipText = vm.staticSettings.tooltipFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); 503 + tooltipText = vm.staticSettings.tooltipFunction(vm.ctx.data, calculateCurrentDate(trip.timeRange, vm.index), trip.dSIndex);
508 } catch (e) { 504 } catch (e) {
509 tooltipText = null; 505 tooltipText = null;
510 } 506 }
511 } 507 }
512 tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText); 508 tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText);
513 tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex); 509 tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex);
514 - tooltip = fillPattern(tooltipText, tooltipReplaceInfo, trip.timeRange[vm.index]); 510 + tooltip = fillPattern(tooltipText, tooltipReplaceInfo, calculateCurrentDate(trip.timeRange, vm.index));
515 tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null); 511 tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null);
516 512
517 } 513 }
@@ -525,14 +521,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -525,14 +521,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
525 let tooltipText = vm.staticSettings.polygonTooltipPattern; 521 let tooltipText = vm.staticSettings.polygonTooltipPattern;
526 if (vm.staticSettings.usePolygonTooltipFunction && angular.isDefined(vm.staticSettings.polygonTooltipFunction)) { 522 if (vm.staticSettings.usePolygonTooltipFunction && angular.isDefined(vm.staticSettings.polygonTooltipFunction)) {
527 try { 523 try {
528 - tooltipText = vm.staticSettings.polygonTooltipFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); 524 + tooltipText = vm.staticSettings.polygonTooltipFunction(vm.ctx.data, calculateCurrentDate(trip.timeRange, vm.index), trip.dSIndex);
529 } catch (e) { 525 } catch (e) {
530 tooltipText = null; 526 tooltipText = null;
531 } 527 }
532 } 528 }
533 tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText); 529 tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText);
534 tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex); 530 tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex);
535 - tooltip = fillPattern(tooltipText, tooltipReplaceInfo, trip.timeRange[vm.index]); 531 + tooltip = fillPattern(tooltipText, tooltipReplaceInfo, calculateCurrentDate(trip.timeRange, vm.index));
536 tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null); 532 tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null);
537 533
538 } 534 }
@@ -546,14 +542,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -546,14 +542,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
546 let tooltipText = vm.staticSettings.tooltipPattern; 542 let tooltipText = vm.staticSettings.tooltipPattern;
547 if (vm.staticSettings.useTooltipFunction && angular.isDefined(vm.staticSettings.tooltipFunction)) { 543 if (vm.staticSettings.useTooltipFunction && angular.isDefined(vm.staticSettings.tooltipFunction)) {
548 try { 544 try {
549 - tooltipText = vm.staticSettings.tooltipFunction(vm.ctx.data, trip.timeRange[index], trip.dSIndex); 545 + tooltipText = vm.staticSettings.tooltipFunction(vm.ctx.data, calculateCurrentDate(trip.timeRange, index), trip.dSIndex);
550 } catch (e) { 546 } catch (e) {
551 tooltipText = null; 547 tooltipText = null;
552 } 548 }
553 } 549 }
554 tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText); 550 tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText);
555 tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex); 551 tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex);
556 - tooltip = fillPattern(tooltipText, tooltipReplaceInfo, trip.timeRange[index]); 552 + tooltip = fillPattern(tooltipText, tooltipReplaceInfo, calculateCurrentDate(trip.timeRange, index));
557 tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null); 553 tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null);
558 554
559 } 555 }
@@ -565,7 +561,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -565,7 +561,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
565 let colorFn; 561 let colorFn;
566 if (vm.staticSettings.usePathColorFunction && angular.isDefined(vm.staticSettings.colorFunction)) { 562 if (vm.staticSettings.usePathColorFunction && angular.isDefined(vm.staticSettings.colorFunction)) {
567 try { 563 try {
568 - colorFn = vm.staticSettings.colorFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); 564 + colorFn = vm.staticSettings.colorFunction(vm.ctx.data, calculateCurrentDate(trip.timeRange, vm.index), trip.dSIndex);
569 } catch (e) { 565 } catch (e) {
570 colorFn = null; 566 colorFn = null;
571 } 567 }
@@ -581,7 +577,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -581,7 +577,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
581 let colorFn; 577 let colorFn;
582 if (vm.staticSettings.usePolygonColorFunction && angular.isDefined(vm.staticSettings.polygonColorFunction)) { 578 if (vm.staticSettings.usePolygonColorFunction && angular.isDefined(vm.staticSettings.polygonColorFunction)) {
583 try { 579 try {
584 - colorFn = vm.staticSettings.polygonColorFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); 580 + colorFn = vm.staticSettings.polygonColorFunction(vm.ctx.data, calculateCurrentDate(trip.timeRange, vm.index), trip.dSIndex);
585 } catch (e) { 581 } catch (e) {
586 colorFn = null; 582 colorFn = null;
587 } 583 }
@@ -597,7 +593,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -597,7 +593,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
597 if (vm.staticSettings.useMarkerImageFunction && angular.isDefined(vm.staticSettings.markerImageFunction)) { 593 if (vm.staticSettings.useMarkerImageFunction && angular.isDefined(vm.staticSettings.markerImageFunction)) {
598 let rawIcon; 594 let rawIcon;
599 try { 595 try {
600 - rawIcon = vm.staticSettings.markerImageFunction(vm.ctx.data, vm.staticSettings.markerImages, trip.timeRange[vm.index], trip.dSIndex); 596 + rawIcon = vm.staticSettings.markerImageFunction(vm.ctx.data, vm.staticSettings.markerImages, calculateCurrentDate(trip.timeRange, vm.index), trip.dSIndex);
601 } catch (e) { 597 } catch (e) {
602 rawIcon = null; 598 rawIcon = null;
603 } 599 }
@@ -658,8 +654,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -658,8 +654,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
658 }); 654 });
659 vm.initBounds = true; 655 vm.initBounds = true;
660 } 656 }
661 - let normalizedTimeRange = createNormalizedTime(vm.data, vm.staticSettings.normalizationStep);  
662 - createNormalizedTrips(normalizedTimeRange, vm.datasources); 657 + createNormalizedTime(vm.data, vm.staticSettings.normalizationStep);
  658 + createNormalizedTrips(vm.datasources, vm.data, vm.staticSettings.normalizationStep);
663 createTripsOnMap(apply); 659 createTripsOnMap(apply);
664 if (vm.initBounds && !vm.initTrips) { 660 if (vm.initBounds && !vm.initTrips) {
665 vm.trips.forEach(function (trip) { 661 vm.trips.forEach(function (trip) {
@@ -701,127 +697,82 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -701,127 +697,82 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
701 697
702 function createNormalizedTime(data, step) { 698 function createNormalizedTime(data, step) {
703 if (!step) step = 1000; 699 if (!step) step = 1000;
704 - let max_time = null;  
705 - let min_time = null;  
706 - let normalizedArray = [];  
707 - if (data && data.length > 0) {  
708 - vm.data.forEach(function (data) {  
709 - if (data.data.length > 0) {  
710 - data.data.forEach(function (sData) {  
711 - if (max_time === null) {  
712 - max_time = sData[0];  
713 - } else if (max_time < sData[0]) {  
714 - max_time = sData[0]  
715 - }  
716 - if (min_time === null) {  
717 - min_time = sData[0];  
718 - } else if (min_time > sData[0]) {  
719 - min_time = sData[0];  
720 - }  
721 - }) 700 + let max_time = -Infinity;
  701 + let min_time = Infinity;
  702 + if (data) {
  703 + for (let i = 0; i < data.length; i++) {
  704 + for (let j = 0; j < data[i].data.length; j++) {
  705 + if (max_time < data[i].data[j][0]) {
  706 + max_time = data[i].data[j][0]
  707 + }
  708 + if (min_time > data[i].data[j][0]) {
  709 + min_time = data[i].data[j][0];
  710 + }
722 } 711 }
723 - });  
724 - for (let i = min_time; i < max_time; i += step) {  
725 - normalizedArray.push({ts: i, formattedTs: $filter('date')(i, 'medium')});  
726 -  
727 - }  
728 - if (normalizedArray[normalizedArray.length - 1] && normalizedArray[normalizedArray.length - 1].ts !== max_time) {  
729 - normalizedArray.push({ts: max_time, formattedTs: $filter('date')(max_time, 'medium')});  
730 } 712 }
731 } 713 }
732 - vm.maxTime = normalizedArray.length - 1;  
733 - //vm.minTime = vm.maxTime > 1 ? 1 : 0;  
734 - if (vm.index < vm.minTime) {  
735 - vm.index = vm.minTime;  
736 - } else if (vm.index > vm.maxTime) {  
737 - vm.index = vm.maxTime; 714 + vm.minTime = vm.animationTime = min_time;
  715 + if(min_time === Infinity){
  716 + vm.animationTime = null;
  717 + } else {
  718 + vm.animationTime = min_time
  719 + }
  720 + vm.maxTimeIndex = Math.ceil((max_time - min_time) / step);
  721 + if (vm.index < vm.minTimeIndex) {
  722 + vm.index = vm.minTimeIndex;
  723 + } else if (vm.index > vm.maxTimeIndex) {
  724 + vm.index = vm.maxTimeIndex;
738 } 725 }
739 - return normalizedArray;  
740 } 726 }
741 727
742 - function createNormalizedTrips(timeRange, dataSources) { 728 + function createNormalizedTrips(dataSources, data, step) {
743 vm.trips = []; 729 vm.trips = [];
744 - if (timeRange && timeRange.length > 0 && dataSources && dataSources.length > 0 && vm.data && vm.data.length > 0) {  
745 - dataSources.forEach(function (dS, index) { 730 + step = step || 1000;
  731 + if (dataSources && data) {
  732 + for (let i = 0; i < dataSources.length; i++) {
746 vm.trips.push({ 733 vm.trips.push({
747 - dataSource: dS,  
748 - dSIndex: index,  
749 - timeRange: angular.copy(timeRange) 734 + dataSource: dataSources[i],
  735 + dSIndex: i,
  736 + timeRange: {}
750 }) 737 })
751 - }); 738 + }
752 739
753 - vm.data.forEach(function (data) {  
754 - let ds = data.datasource; 740 + for (let i = 0; i < data.length; i++) {
  741 + let ds = data[i].datasource;
755 let tripIndex = vm.trips.findIndex(function (el) { 742 let tripIndex = vm.trips.findIndex(function (el) {
756 return el.dataSource.entityId === ds.entityId; 743 return el.dataSource.entityId === ds.entityId;
757 }); 744 });
758 -  
759 if (tripIndex > -1) { 745 if (tripIndex > -1) {
760 - createNormalizedValue(data.data, data.dataKey.label, vm.trips[tripIndex].timeRange); 746 + createNormalizedValue(data[i].data, data[i].dataKey.label, vm.trips[tripIndex].timeRange, step);
761 } 747 }
762 - }) 748 + }
763 } 749 }
764 750
765 createNormalizedLatLngs(); 751 createNormalizedLatLngs();
766 } 752 }
767 753
768 - function createNormalizedValue(dataArray, dataKey, timeRangeArray) {  
769 - timeRangeArray.forEach(function (timeStamp) {  
770 - let targetTDiff = null;  
771 - let value = null;  
772 - for (let i = 0; i < dataArray.length; i++) {  
773 - let tDiff = dataArray[i][0] - timeStamp.ts;  
774 - if (targetTDiff === null || (tDiff <= 0 && targetTDiff < tDiff)) {  
775 - targetTDiff = tDiff;  
776 - value = dataArray[i][1];  
777 -  
778 - }  
779 - }  
780 - if (value !== null) timeStamp[dataKey] = value;  
781 - }); 754 + function createNormalizedValue(dataArray, dataKey, timeRange, step) {
  755 + for (let i = 0; i < dataArray.length; i++) {
  756 + let normalizeTime = vm.minTime + Math.ceil((dataArray[i][0] - vm.minTime) / step) * step;
  757 + timeRange[normalizeTime] = timeRange[normalizeTime] || {};
  758 + timeRange[normalizeTime][dataKey] = dataArray[i][1];
  759 + }
782 } 760 }
783 761
784 function createNormalizedLatLngs() { 762 function createNormalizedLatLngs() {
785 - vm.trips.forEach(function (el) {  
786 - el.latLngs = [];  
787 - el.timeRange.forEach(function (data) {  
788 - let lat = data[vm.staticSettings.latKeyName];  
789 - let lng = data[vm.staticSettings.lngKeyName];  
790 - if (lat && lng && vm.map) {  
791 - data.latLng = vm.map.createLatLng(lat, lng);  
792 - }  
793 - el.latLngs.push(data.latLng);  
794 - });  
795 - addAngleForTrip(el);  
796 - })  
797 - }  
798 -  
799 - function addAngleForTrip(trip) {  
800 - if (trip.timeRange && trip.timeRange.length > 0) {  
801 - trip.timeRange.forEach(function (point, index) {  
802 - let nextPoint, prevPoint;  
803 - nextPoint = index === (trip.timeRange.length - 1) ? trip.timeRange[index] : trip.timeRange[index + 1];  
804 - prevPoint = index === 0 ? trip.timeRange[0] : trip.timeRange[index - 1];  
805 - let nextLatLng = {  
806 - lat: nextPoint[vm.staticSettings.latKeyName],  
807 - lng: nextPoint[vm.staticSettings.lngKeyName]  
808 - };  
809 - let prevLatLng = {  
810 - lat: prevPoint[vm.staticSettings.latKeyName],  
811 - lng: prevPoint[vm.staticSettings.lngKeyName]  
812 - };  
813 - if (nextLatLng.lat === prevLatLng.lat && nextLatLng.lng === prevLatLng.lng) {  
814 - if (angular.isNumber(prevPoint.h)) {  
815 - point.h = prevPoint.h;  
816 - } else {  
817 - point.h = vm.staticSettings.rotationAngle; 763 + vm.trips.forEach(function (item) {
  764 + item.latLngs = [];
  765 + for (let timestamp in item.timeRange) {
  766 + if(Object.prototype.hasOwnProperty.call(item.timeRange, timestamp)) {
  767 + let lat = item.timeRange[timestamp][vm.staticSettings.latKeyName];
  768 + let lng = item.timeRange[timestamp][vm.staticSettings.lngKeyName];
  769 + if (lat && lng && vm.map) {
  770 + item.timeRange[timestamp].latLng = vm.map.createLatLng(lat, lng);
818 } 771 }
819 - } else {  
820 - point.h = findAngle(prevLatLng.lat, prevLatLng.lng, nextLatLng.lat, nextLatLng.lng);  
821 - point.h += vm.staticSettings.rotationAngle; 772 + item.latLngs.push(item.timeRange[timestamp].latLng);
822 } 773 }
823 - });  
824 - } 774 + }
  775 + });
825 } 776 }
826 777
827 function createPointPopup(point, index, trip) { 778 function createPointPopup(point, index, trip) {
@@ -834,14 +785,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -834,14 +785,14 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
834 function createTripsOnMap(apply) { 785 function createTripsOnMap(apply) {
835 if (vm.trips.length > 0) { 786 if (vm.trips.length > 0) {
836 vm.trips.forEach(function (trip) { 787 vm.trips.forEach(function (trip) {
837 - configureTripSettings(trip, vm.index, apply);  
838 - if (trip.timeRange.length > 0 && trip.latLngs.every(el => angular.isDefined(el))) { 788 + configureTripSettings(trip, apply);
  789 + if (Object.keys(trip.timeRange).length > 0 && trip.latLngs.every(el => angular.isDefined(el))) {
839 if (vm.staticSettings.showPoints) { 790 if (vm.staticSettings.showPoints) {
840 trip.points = []; 791 trip.points = [];
841 - trip.timeRange.forEach(function (tRange, index) {  
842 - if (tRange && tRange.latLng  
843 - && (!vm.staticSettings.usePointAsAnchor || vm.staticSettings.pointAsAnchorFunction(vm.ctx.data, tRange, trip.dSIndex))) {  
844 - let point = L.circleMarker(tRange.latLng, { 792 + Object.keys(trip.timeRange).forEach(function (tRange, index) {
  793 + if (trip.timeRange[tRange] && trip.timeRange[tRange].latLng
  794 + && (!vm.staticSettings.usePointAsAnchor || vm.staticSettings.pointAsAnchorFunction(vm.ctx.data, trip.timeRange[tRange], trip.dSIndex))) {
  795 + let point = L.circleMarker(trip.timeRange[tRange].latLng, {
845 color: trip.settings.pointColor, 796 color: trip.settings.pointColor,
846 radius: trip.settings.pointSize 797 radius: trip.settings.pointSize
847 }).addTo(vm.map.map); 798 }).addTo(vm.map.map);
@@ -852,7 +803,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -852,7 +803,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
852 showHidePointTooltip(calculatePointTooltip(trip, index), index); 803 showHidePointTooltip(calculatePointTooltip(trip, index), index);
853 }); 804 });
854 } 805 }
855 - if (vm.staticSettings.usePointAsAnchor) tRange.hasAnchor = true; 806 + if (vm.staticSettings.usePointAsAnchor) trip.timeRange[tRange].hasAnchor = true;
856 trip.points.push(point); 807 trip.points.push(point);
857 } 808 }
858 }); 809 });
@@ -872,7 +823,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -872,7 +823,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
872 polygon: false, 823 polygon: false,
873 pathOptions: { 824 pathOptions: {
874 color: vm.staticSettings.useDecoratorCustomColor ? vm.staticSettings.decoratorCustomColor : trip.settings.color, 825 color: vm.staticSettings.useDecoratorCustomColor ? vm.staticSettings.decoratorCustomColor : trip.settings.color,
875 - stroke: true} 826 + stroke: true
  827 + }
876 }) 828 })
877 } 829 }
878 ], 830 ],
@@ -882,8 +834,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -882,8 +834,8 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
882 } 834 }
883 835
884 836
885 - if (trip.timeRange && trip.timeRange.length && angular.isUndefined(trip.marker)) {  
886 - trip.marker = L.marker(trip.timeRange[vm.index].latLng); 837 + if (trip.timeRange && Object.keys(trip.timeRange).length && angular.isUndefined(trip.marker)) {
  838 + trip.marker = L.marker(calculateCurrentDate(trip.timeRange, vm.index).latLng);
887 trip.marker.setZIndexOffset(1000); 839 trip.marker.setZIndexOffset(1000);
888 trip.marker.setIcon(vm.staticSettings.icon); 840 trip.marker.setIcon(vm.staticSettings.icon);
889 trip.marker.setRotationOrigin('center center'); 841 trip.marker.setRotationOrigin('center center');
@@ -895,7 +847,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -895,7 +847,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
895 } 847 }
896 } 848 }
897 849
898 - if (vm.staticSettings.showPolygon && angular.isDefined(trip.timeRange[vm.index][vm.staticSettings.polKeyName])) { 850 + if (vm.staticSettings.showPolygon && angular.isDefined(calculateCurrentDate(trip.timeRange, vm.index)[vm.staticSettings.polKeyName])) {
899 let polygonSettings = { 851 let polygonSettings = {
900 fill: true, 852 fill: true,
901 fillColor: trip.settings.polygonColor, 853 fillColor: trip.settings.polygonColor,
@@ -904,7 +856,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -904,7 +856,7 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
904 fillOpacity: trip.settings.polygonOpacity, 856 fillOpacity: trip.settings.polygonOpacity,
905 opacity: trip.settings.polygonStrokeOpacity 857 opacity: trip.settings.polygonStrokeOpacity
906 }; 858 };
907 - let polygonLatLngsRaw = mapPolygonArray(angular.fromJson(trip.timeRange[vm.index][vm.staticSettings.polKeyName])); 859 + let polygonLatLngsRaw = mapPolygonArray(angular.fromJson(calculateCurrentDate(trip.timeRange, vm.index)[vm.staticSettings.polKeyName]));
908 trip.polygon = L.polygon(polygonLatLngsRaw, polygonSettings).addTo(vm.map.map); 860 trip.polygon = L.polygon(polygonLatLngsRaw, polygonSettings).addTo(vm.map.map);
909 trip.polygon.on('click',function(){showHidePolygonTooltip(trip)}); 861 trip.polygon.on('click',function(){showHidePolygonTooltip(trip)});
910 } 862 }
@@ -912,6 +864,35 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -912,6 +864,35 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
912 } 864 }
913 } 865 }
914 866
  867 + function calculateCurrentDate(tripTimeRange, index) {
  868 + let time = vm.minTime + index * vm.staticSettings.normalizationStep;
  869 + if (Object.hasOwnProperty.call(tripTimeRange, time)) {
  870 + return tripTimeRange[time];
  871 + } else {
  872 + let timeInterval = Object.keys(tripTimeRange);
  873 + for (let i = 1; i < timeInterval.length; i++) {
  874 + if (timeInterval[i - 1] < time && timeInterval[i] > time) {
  875 + let calcPosition = angular.copy(tripTimeRange[timeInterval[i - 1]]);
  876 + let startLatLng = tripTimeRange[timeInterval[i - 1]].latLng;
  877 + let finishLatLng = tripTimeRange[timeInterval[i]].latLng;
  878 + let percentRouteComplete = (time - timeInterval[i - 1]) / (timeInterval[i] - timeInterval[i - 1]);
  879 + calcPosition[vm.staticSettings.latKeyName] = startLatLng.lat + (finishLatLng.lat - startLatLng.lat) * percentRouteComplete;
  880 + calcPosition[vm.staticSettings.lngKeyName] = startLatLng.lng + (finishLatLng.lng - startLatLng.lng) * percentRouteComplete;
  881 + calcPosition.latLng = vm.map.createLatLng(calcPosition[vm.staticSettings.latKeyName], calcPosition[vm.staticSettings.lngKeyName]);
  882 + calcPosition.angle = vm.staticSettings.rotationAngle + findAngle(startLatLng, finishLatLng);
  883 + return calcPosition;
  884 + }
  885 + }
  886 + }
  887 + return {};
  888 + }
  889 +
  890 + function findAngle(startPoint, endPoint) {
  891 + let angle = -Math.atan2(endPoint.lat - startPoint.lat, endPoint.lng - startPoint.lng);
  892 + angle = angle * 180 / Math.PI;
  893 + return parseInt(angle.toFixed(2));
  894 + }
  895 +
915 function mapPolygonArray(rawArray) { 896 function mapPolygonArray(rawArray) {
916 return rawArray.map(function (el) { 897 return rawArray.map(function (el) {
917 if (el.length === 2) { 898 if (el.length === 2) {
@@ -931,15 +912,16 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -931,15 +912,16 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
931 } 912 }
932 913
933 function moveMarker(trip) { 914 function moveMarker(trip) {
934 - if (angular.isDefined(trip.timeRange[vm.index].latLng)) { 915 + let postionMarker = calculateCurrentDate(trip.timeRange, vm.index);
  916 + if (angular.isDefined(postionMarker)) {
935 if (angular.isDefined(trip.marker)) { 917 if (angular.isDefined(trip.marker)) {
936 trip.markerAngleIsSet = true; 918 trip.markerAngleIsSet = true;
937 - trip.marker.setLatLng(trip.timeRange[vm.index].latLng);  
938 - trip.marker.setRotationAngle(trip.timeRange[vm.index].h); 919 + trip.marker.setLatLng(postionMarker.latLng);
  920 + trip.marker.setRotationAngle(postionMarker.angle);
939 trip.marker.update(); 921 trip.marker.update();
940 } else { 922 } else {
941 if (trip.timeRange && trip.timeRange.length) { 923 if (trip.timeRange && trip.timeRange.length) {
942 - trip.marker = L.marker(trip.timeRange[vm.index].latLng); 924 + trip.marker = L.marker(postionMarker.latLng);
943 trip.marker.setZIndexOffset(1000); 925 trip.marker.setZIndexOffset(1000);
944 trip.marker.setIcon(vm.staticSettings.icon); 926 trip.marker.setIcon(vm.staticSettings.icon);
945 trip.marker.setRotationOrigin('center center'); 927 trip.marker.setRotationOrigin('center center');
@@ -1000,4 +982,4 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt @@ -1000,4 +982,4 @@ function tripAnimationController($document, $scope, $log, $http, $timeout, $filt
1000 if (trip && vm.activeTripIndex !== trip.dSIndex) vm.activeTripIndex = trip.dSIndex; 982 if (trip && vm.activeTripIndex !== trip.dSIndex) vm.activeTripIndex = trip.dSIndex;
1001 vm.mainTooltip = vm.trips[vm.activeTripIndex].settings.polygonTooltipText; 983 vm.mainTooltip = vm.trips[vm.activeTripIndex].settings.polygonTooltipText;
1002 } 984 }
1003 -}  
  985 +}
@@ -27,8 +27,10 @@ @@ -27,8 +27,10 @@
27 <ng-md-icon icon="info_outline"></ng-md-icon> 27 <ng-md-icon icon="info_outline"></ng-md-icon>
28 </md-button> 28 </md-button>
29 </div> 29 </div>
30 - <div class="trip-animation-tooltip md-whiteframe-z4" layout="column" ng-class="!vm.staticSettings.showTooltip ? 'trip-animation-tooltip-hidden':''" ng-bind-html="vm.mainTooltip"  
31 - ng-style="{'background-color': vm.staticSettings.tooltipColor, 'opacity': vm.staticSettings.tooltipOpacity, 'color': vm.staticSettings.tooltipFontColor}"> 30 + <div class="trip-animation-tooltip md-whiteframe-z4" layout="column"
  31 + ng-class="!vm.staticSettings.showTooltip ? 'trip-animation-tooltip-hidden':''"
  32 + ng-bind-html="vm.mainTooltip"
  33 + ng-style="{'background-color': vm.staticSettings.tooltipColor, 'opacity': vm.staticSettings.tooltipOpacity, 'color': vm.staticSettings.tooltipFontColor}">
32 </div> 34 </div>
33 </div> 35 </div>
34 <div class="trip-animation-control-panel"> 36 <div class="trip-animation-control-panel">
@@ -39,7 +41,7 @@ @@ -39,7 +41,7 @@
39 <md-button class="md-icon-button" aria-label="Previous" ng-click="vm.movePrev()"> 41 <md-button class="md-icon-button" aria-label="Previous" ng-click="vm.movePrev()">
40 <md-icon class="material-icons" ng-style="{'color': vm.staticSettings.buttonColor}">skip_previous</md-icon> 42 <md-icon class="material-icons" ng-style="{'color': vm.staticSettings.buttonColor}">skip_previous</md-icon>
41 </md-button> 43 </md-button>
42 - <md-slider ng-model="vm.index" min="{{vm.minTime}}" max="{{vm.maxTime}}" ng-change="vm.recalculateTrips()"></md-slider> 44 + <md-slider ng-model="vm.index" min="{{vm.minTimeIndex}}" max="{{vm.maxTimeIndex}}" ng-change="vm.recalculateTrips()"></md-slider>
43 <md-button class="md-icon-button" aria-label="Next" ng-click="vm.moveNext()"> 45 <md-button class="md-icon-button" aria-label="Next" ng-click="vm.moveNext()">
44 <md-icon class="material-icons" ng-style="{'color': vm.staticSettings.buttonColor}">skip_next</md-icon> 46 <md-icon class="material-icons" ng-style="{'color': vm.staticSettings.buttonColor}">skip_next</md-icon>
45 </md-button> 47 </md-button>
@@ -61,7 +63,9 @@ @@ -61,7 +63,9 @@
61 </md-icon> 63 </md-icon>
62 </md-button> 64 </md-button>
63 </md-slider-container> 65 </md-slider-container>
64 - <div class="panel-timer">{{vm.trips[vm.activeTripIndex].timeRange[vm.index].ts | date:'medium'}} 66 + <div class="panel-timer">
  67 + <span ng-show="vm.animationTime">{{ vm.animationTime | date:'medium'}}</span>
  68 + <span ng-hide="vm.animationTime">{{ "widget.no-data" | translate}}</span>
65 </div> 69 </div>
66 </div> 70 </div>
67 </div> 71 </div>