Commit 6f065804a572673f697df7a1bd0b6449964a2b5b

Authored by Igor Kulikov
Committed by GitHub
2 parents 394ec3df c639e9c3

Merge pull request #2792 from vvlladd28/improvement/map/anchor-point

Improvment anchor function and fix show point [trip-animation]
@@ -345,8 +345,8 @@ export default abstract class LeafletMap { @@ -345,8 +345,8 @@ export default abstract class LeafletMap {
345 345
346 updatePolylines(polyData: FormattedData[][], data?: FormattedData) { 346 updatePolylines(polyData: FormattedData[][], data?: FormattedData) {
347 polyData.forEach((dataSource) => { 347 polyData.forEach((dataSource) => {
348 - data = data || dataSource[0];  
349 if (dataSource.length) { 348 if (dataSource.length) {
  349 + data = data || dataSource[0];
350 if (this.polylines.get(data.$datasource.entityName)) { 350 if (this.polylines.get(data.$datasource.entityName)) {
351 this.updatePolyline(data, dataSource, this.options); 351 this.updatePolyline(data, dataSource, this.options);
352 } 352 }
@@ -860,15 +860,15 @@ export const pointSchema = @@ -860,15 +860,15 @@ export const pointSchema =
860 type: 'number', 860 type: 'number',
861 default: 10 861 default: 10
862 }, 862 },
863 - // usePointAsAnchor: {  
864 - // title: 'Use point as anchor',  
865 - // type: 'boolean',  
866 - // default: false  
867 - // },  
868 - // pointAsAnchorFunction: {  
869 - // title: 'Point as anchor function: f(data, dsData, dsIndex)',  
870 - // type: 'string'  
871 - // }, 863 + usePointAsAnchor: {
  864 + title: 'Use point as anchor',
  865 + type: 'boolean',
  866 + default: false
  867 + },
  868 + pointAsAnchorFunction: {
  869 + title: 'Point as anchor function: f(data, dsData, dsIndex)',
  870 + type: 'string'
  871 + },
872 pointTooltipOnRightPanel: { 872 pointTooltipOnRightPanel: {
873 title: 'Independant point tooltip', 873 title: 'Independant point tooltip',
874 type: 'boolean', 874 type: 'boolean',
@@ -884,11 +884,11 @@ export const pointSchema = @@ -884,11 +884,11 @@ export const pointSchema =
884 type: 'color' 884 type: 'color'
885 }, 885 },
886 'pointSize', 886 'pointSize',
887 - // 'usePointAsAnchor',  
888 - // {  
889 - // key: 'pointAsAnchorFunction',  
890 - // type: 'javascript'  
891 - // }, 887 + 'usePointAsAnchor',
  888 + {
  889 + key: 'pointAsAnchorFunction',
  890 + type: 'javascript'
  891 + },
892 'pointTooltipOnRightPanel', 892 'pointTooltipOnRightPanel',
893 ] 893 ]
894 }; 894 };
@@ -37,5 +37,7 @@ @@ -37,5 +37,7 @@
37 [minTime]="minTime" 37 [minTime]="minTime"
38 [maxTime]="maxTime" 38 [maxTime]="maxTime"
39 [step]="normalizationStep" 39 [step]="normalizationStep"
  40 + [anchors]="anchors"
  41 + [useAnchors]="useAnchors"
40 (timeUpdated)="timeUpdated($event)"></tb-history-selector> 42 (timeUpdated)="timeUpdated($event)"></tb-history-selector>
41 </div> 43 </div>
@@ -29,6 +29,7 @@ import { @@ -29,6 +29,7 @@ import {
29 getRatio, 29 getRatio,
30 interpolateOnLineSegment, 30 interpolateOnLineSegment,
31 parseArray, 31 parseArray,
  32 + parseFunction,
32 parseWithTranslation, 33 parseWithTranslation,
33 safeExecute 34 safeExecute
34 } from '../lib/maps/maps-utils'; 35 } from '../lib/maps/maps-utils';
@@ -65,7 +66,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -65,7 +66,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
65 minTimeFormat: string; 66 minTimeFormat: string;
66 maxTime: number; 67 maxTime: number;
67 maxTimeFormat: string; 68 maxTimeFormat: string;
68 - anchors = []; 69 + anchors: number[] = [];
69 useAnchors: boolean; 70 useAnchors: boolean;
70 71
71 static getSettingsSchema(): JsonSettingsSchema { 72 static getSettingsSchema(): JsonSettingsSchema {
@@ -94,6 +95,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -94,6 +95,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
94 } 95 }
95 this.settings = { ...settings, ...this.ctx.settings }; 96 this.settings = { ...settings, ...this.ctx.settings };
96 this.useAnchors = this.settings.showPoints && this.settings.usePointAsAnchor; 97 this.useAnchors = this.settings.showPoints && this.settings.usePointAsAnchor;
  98 + this.settings.pointAsAnchorFunction = parseFunction(this.settings.pointAsAnchorFunction, ['data', 'dsData', 'dsIndex']);
97 this.settings.fitMapBounds = true; 99 this.settings.fitMapBounds = true;
98 this.normalizationStep = this.settings.normalizationStep; 100 this.normalizationStep = this.settings.normalizationStep;
99 const subscription = this.ctx.subscriptions[Object.keys(this.ctx.subscriptions)[0]]; 101 const subscription = this.ctx.subscriptions[Object.keys(this.ctx.subscriptions)[0]];
@@ -141,11 +143,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -141,11 +143,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
141 this.mapWidget.map.updatePolygons(this.interpolatedTimeData); 143 this.mapWidget.map.updatePolygons(this.interpolatedTimeData);
142 } 144 }
143 if (this.settings.showPoints) { 145 if (this.settings.showPoints) {
144 - this.mapWidget.map.updatePoints(this.interpolatedTimeData, this.calcTooltip);  
145 - // this.anchors = this.interpolatedTimeData  
146 - // .filter(data =>  
147 - // this.settings.usePointAsAnchor ||  
148 - // safeExecute(this.settings.pointAsAnchorFunction, [this.interpolatedTimeData, data, data.dsIndex])).map(data => data.time); 146 + this.mapWidget.map.updatePoints(_.values(_.union(this.interpolatedTimeData)[0]), this.calcTooltip);
149 } 147 }
150 this.mapWidget.map.updateMarkers(currentPosition); 148 this.mapWidget.map.updateMarkers(currentPosition);
151 } 149 }
@@ -162,7 +160,12 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -162,7 +160,12 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
162 this.maxTimeFormat = this.maxTime !== -Infinity ? moment(this.maxTime).format('YYYY-MM-DD HH:mm:ss') : ''; 160 this.maxTimeFormat = this.maxTime !== -Infinity ? moment(this.maxTime).format('YYYY-MM-DD HH:mm:ss') : '';
163 this.interpolatedTimeData[index] = this.interpolateArray(dataSource); 161 this.interpolatedTimeData[index] = this.interpolateArray(dataSource);
164 }); 162 });
165 - 163 + if (this.useAnchors) {
  164 + const anchorDate = Object.entries(_.union(this.interpolatedTimeData)[0]);
  165 + this.anchors = anchorDate
  166 + .filter((data: [string, FormattedData]) => safeExecute(this.settings.pointAsAnchorFunction, [data[1], anchorDate, data[1].dsIndex]))
  167 + .map(data => parseInt(data[0], 10));
  168 + }
166 } 169 }
167 170
168 calcTooltip = (point?: FormattedData, setTooltip = true) => { 171 calcTooltip = (point?: FormattedData, setTooltip = true) => {
@@ -200,20 +203,17 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -200,20 +203,17 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
200 const result = {}; 203 const result = {};
201 const latKeyName = this.settings.latKeyName; 204 const latKeyName = this.settings.latKeyName;
202 const lngKeyName = this.settings.lngKeyName; 205 const lngKeyName = this.settings.lngKeyName;
203 - for (let i = 0; i < originData.length; i++) {  
204 - const currentTime = originData[i].time; 206 + for (const data of originData) {
  207 + const currentTime = data.time;
205 const normalizeTime = this.minTime + Math.ceil((currentTime - this.minTime) / this.normalizationStep) * this.normalizationStep; 208 const normalizeTime = this.minTime + Math.ceil((currentTime - this.minTime) / this.normalizationStep) * this.normalizationStep;
206 - if (i !== originData.length - 1) {  
207 - result[normalizeTime] = {  
208 - ...originData[i],  
209 - rotationAngle: this.settings.rotationAngle + findAngle(originData[i], originData[i + 1], latKeyName, lngKeyName)  
210 - };  
211 - } else {  
212 - result[normalizeTime] = {  
213 - ...originData[i],  
214 - rotationAngle: this.settings.rotationAngle + findAngle(originData[i - 1], originData[i], latKeyName, lngKeyName)  
215 - };  
216 - } 209 + result[normalizeTime] = {
  210 + ...data,
  211 + rotationAngle: this.settings.rotationAngle
  212 + };
  213 + }
  214 + const timeStamp = Object.keys(result);
  215 + for(let i = 0; i < timeStamp.length - 1; i++){
  216 + result[timeStamp[i]].rotationAngle += findAngle(result[timeStamp[i]], result[timeStamp[i + 1]], latKeyName, lngKeyName)
217 } 217 }
218 return result; 218 return result;
219 } 219 }
@@ -30,6 +30,8 @@ export class HistorySelectorComponent implements OnInit, OnChanges { @@ -30,6 +30,8 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
30 @Input() minTime: number; 30 @Input() minTime: number;
31 @Input() maxTime: number; 31 @Input() maxTime: number;
32 @Input() step = 1000; 32 @Input() step = 1000;
  33 + @Input() anchors = [];
  34 + @Input() useAnchors = false;
33 35
34 @Output() timeUpdated: EventEmitter<number> = new EventEmitter(); 36 @Output() timeUpdated: EventEmitter<number> = new EventEmitter();
35 37
@@ -95,19 +97,37 @@ export class HistorySelectorComponent implements OnInit, OnChanges { @@ -95,19 +97,37 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
95 } 97 }
96 98
97 moveNext() { 99 moveNext() {
98 - if (this.index <= this.maxTimeIndex) {  
99 - this.index++; 100 + if (this.index < this.maxTimeIndex) {
  101 + if (this.useAnchors) {
  102 + const anchorIndex = this.findIndex(this.currentTime, this.anchors) + 1;
  103 + this.index = Math.floor((this.anchors[anchorIndex] - this.minTime) / this.step);
  104 + } else {
  105 + this.index++;
  106 + }
100 } 107 }
101 this.pause(); 108 this.pause();
102 } 109 }
103 110
104 movePrev() { 111 movePrev() {
105 if (this.index > this.minTimeIndex) { 112 if (this.index > this.minTimeIndex) {
106 - this.index--; 113 + if (this.useAnchors) {
  114 + const anchorIndex = this.findIndex(this.currentTime, this.anchors) - 1;
  115 + this.index = Math.floor((this.anchors[anchorIndex] - this.minTime) / this.step);
  116 + } else {
  117 + this.index--;
  118 + }
107 } 119 }
108 this.pause(); 120 this.pause();
109 } 121 }
110 122
  123 + findIndex(value: number, array: number[]): number {
  124 + let i = 0;
  125 + while (array[i] < value) {
  126 + i++;
  127 + }
  128 + return i;
  129 + }
  130 +
111 moveStart() { 131 moveStart() {
112 this.index = this.minTimeIndex; 132 this.index = this.minTimeIndex;
113 this.pause(); 133 this.pause();