diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts index 8ee031d433..a1280fef13 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts @@ -345,8 +345,8 @@ export default abstract class LeafletMap { updatePolylines(polyData: FormattedData[][], data?: FormattedData) { polyData.forEach((dataSource) => { - data = data || dataSource[0]; if (dataSource.length) { + data = data || dataSource[0]; if (this.polylines.get(data.$datasource.entityName)) { this.updatePolyline(data, dataSource, this.options); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts index fd8e9e5e8c..a8f565a4cb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts @@ -860,15 +860,15 @@ export const pointSchema = type: 'number', default: 10 }, - // usePointAsAnchor: { - // title: 'Use point as anchor', - // type: 'boolean', - // default: false - // }, - // pointAsAnchorFunction: { - // title: 'Point as anchor function: f(data, dsData, dsIndex)', - // type: 'string' - // }, + usePointAsAnchor: { + title: 'Use point as anchor', + type: 'boolean', + default: false + }, + pointAsAnchorFunction: { + title: 'Point as anchor function: f(data, dsData, dsIndex)', + type: 'string' + }, pointTooltipOnRightPanel: { title: 'Independant point tooltip', type: 'boolean', @@ -884,11 +884,11 @@ export const pointSchema = type: 'color' }, 'pointSize', - // 'usePointAsAnchor', - // { - // key: 'pointAsAnchorFunction', - // type: 'javascript' - // }, + 'usePointAsAnchor', + { + key: 'pointAsAnchorFunction', + type: 'javascript' + }, 'pointTooltipOnRightPanel', ] }; diff --git a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.html b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.html index cc0429660a..2ea80cf2af 100644 --- a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.html @@ -37,5 +37,7 @@ [minTime]="minTime" [maxTime]="maxTime" [step]="normalizationStep" + [anchors]="anchors" + [useAnchors]="useAnchors" (timeUpdated)="timeUpdated($event)"> diff --git a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts index 647b419e12..6ec8d377c7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts @@ -29,6 +29,7 @@ import { getRatio, interpolateOnLineSegment, parseArray, + parseFunction, parseWithTranslation, safeExecute } from '../lib/maps/maps-utils'; @@ -65,7 +66,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { minTimeFormat: string; maxTime: number; maxTimeFormat: string; - anchors = []; + anchors: number[] = []; useAnchors: boolean; static getSettingsSchema(): JsonSettingsSchema { @@ -94,6 +95,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { } this.settings = { ...settings, ...this.ctx.settings }; this.useAnchors = this.settings.showPoints && this.settings.usePointAsAnchor; + this.settings.pointAsAnchorFunction = parseFunction(this.settings.pointAsAnchorFunction, ['data', 'dsData', 'dsIndex']); this.settings.fitMapBounds = true; this.normalizationStep = this.settings.normalizationStep; const subscription = this.ctx.subscriptions[Object.keys(this.ctx.subscriptions)[0]]; @@ -141,11 +143,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { this.mapWidget.map.updatePolygons(this.interpolatedTimeData); } if (this.settings.showPoints) { - this.mapWidget.map.updatePoints(this.interpolatedTimeData, this.calcTooltip); - // this.anchors = this.interpolatedTimeData - // .filter(data => - // this.settings.usePointAsAnchor || - // safeExecute(this.settings.pointAsAnchorFunction, [this.interpolatedTimeData, data, data.dsIndex])).map(data => data.time); + this.mapWidget.map.updatePoints(_.values(_.union(this.interpolatedTimeData)[0]), this.calcTooltip); } this.mapWidget.map.updateMarkers(currentPosition); } @@ -162,7 +160,12 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { this.maxTimeFormat = this.maxTime !== -Infinity ? moment(this.maxTime).format('YYYY-MM-DD HH:mm:ss') : ''; this.interpolatedTimeData[index] = this.interpolateArray(dataSource); }); - + if (this.useAnchors) { + const anchorDate = Object.entries(_.union(this.interpolatedTimeData)[0]); + this.anchors = anchorDate + .filter((data: [string, FormattedData]) => safeExecute(this.settings.pointAsAnchorFunction, [data[1], anchorDate, data[1].dsIndex])) + .map(data => parseInt(data[0], 10)); + } } calcTooltip = (point?: FormattedData, setTooltip = true) => { @@ -200,20 +203,17 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { const result = {}; const latKeyName = this.settings.latKeyName; const lngKeyName = this.settings.lngKeyName; - for (let i = 0; i < originData.length; i++) { - const currentTime = originData[i].time; + for (const data of originData) { + const currentTime = data.time; const normalizeTime = this.minTime + Math.ceil((currentTime - this.minTime) / this.normalizationStep) * this.normalizationStep; - if (i !== originData.length - 1) { - result[normalizeTime] = { - ...originData[i], - rotationAngle: this.settings.rotationAngle + findAngle(originData[i], originData[i + 1], latKeyName, lngKeyName) - }; - } else { - result[normalizeTime] = { - ...originData[i], - rotationAngle: this.settings.rotationAngle + findAngle(originData[i - 1], originData[i], latKeyName, lngKeyName) - }; - } + result[normalizeTime] = { + ...data, + rotationAngle: this.settings.rotationAngle + }; + } + const timeStamp = Object.keys(result); + for(let i = 0; i < timeStamp.length - 1; i++){ + result[timeStamp[i]].rotationAngle += findAngle(result[timeStamp[i]], result[timeStamp[i + 1]], latKeyName, lngKeyName) } return result; } diff --git a/ui-ngx/src/app/shared/components/time/history-selector/history-selector.component.ts b/ui-ngx/src/app/shared/components/time/history-selector/history-selector.component.ts index d881eca805..6c5f4d9576 100644 --- a/ui-ngx/src/app/shared/components/time/history-selector/history-selector.component.ts +++ b/ui-ngx/src/app/shared/components/time/history-selector/history-selector.component.ts @@ -30,6 +30,8 @@ export class HistorySelectorComponent implements OnInit, OnChanges { @Input() minTime: number; @Input() maxTime: number; @Input() step = 1000; + @Input() anchors = []; + @Input() useAnchors = false; @Output() timeUpdated: EventEmitter = new EventEmitter(); @@ -95,19 +97,37 @@ export class HistorySelectorComponent implements OnInit, OnChanges { } moveNext() { - if (this.index <= this.maxTimeIndex) { - this.index++; + if (this.index < this.maxTimeIndex) { + if (this.useAnchors) { + const anchorIndex = this.findIndex(this.currentTime, this.anchors) + 1; + this.index = Math.floor((this.anchors[anchorIndex] - this.minTime) / this.step); + } else { + this.index++; + } } this.pause(); } movePrev() { if (this.index > this.minTimeIndex) { - this.index--; + if (this.useAnchors) { + const anchorIndex = this.findIndex(this.currentTime, this.anchors) - 1; + this.index = Math.floor((this.anchors[anchorIndex] - this.minTime) / this.step); + } else { + this.index--; + } } this.pause(); } + findIndex(value: number, array: number[]): number { + let i = 0; + while (array[i] < value) { + i++; + } + return i; + } + moveStart() { this.index = this.minTimeIndex; this.pause();