From d247071081e4b63579126c8fa2f67e395b6cbe2e Mon Sep 17 00:00:00 2001
From: Oleksandr Husak <oleksandr.husak@mailbox.tu-dresden.de>
Date: Tue, 12 Apr 2022 11:58:17 +0200
Subject: [PATCH] new root marker, colors for agents in table

---
 .../chart-timeline.component.ts               |  16 +--
 src/app/components/map/map.component.ts       | 107 ++++++++++--------
 src/app/components/table/table.component.html |   4 +-
 src/app/components/table/table.component.ts   |  12 +-
 src/app/model/base-model.ts                   |  12 +-
 src/assets/marker-ball-pink.png               | Bin 0 -> 17555 bytes
 src/environments/environment.ts               |  24 ++--
 7 files changed, 100 insertions(+), 75 deletions(-)
 create mode 100644 src/assets/marker-ball-pink.png

diff --git a/src/app/components/chart-timeline/chart-timeline.component.ts b/src/app/components/chart-timeline/chart-timeline.component.ts
index 3f56f04..4646dc4 100644
--- a/src/app/components/chart-timeline/chart-timeline.component.ts
+++ b/src/app/components/chart-timeline/chart-timeline.component.ts
@@ -17,7 +17,7 @@ import {
 } from 'ng-apexcharts';
 
 import { getMarkerConfig } from 'src/environments/environment';
-import { Object, PositionUpdate, validateTypeObject} from 'src/app/model/base-model';
+import { Agent, PositionUpdate, validateTypeAgent} from 'src/app/model/base-model';
 
 export type ChartOptions = {
   series: ApexAxisChartSeries;
@@ -76,7 +76,7 @@ export class ChartTimelineComponent implements OnInit {
       try {
         let upd: PositionUpdate = JSON.parse(message.payload.toString())
         upd.objects.forEach(obj => {
-          validateTypeObject(obj)
+          validateTypeAgent(obj)
           this.addNewSeries(obj)
         });
       } catch(e) {
@@ -89,7 +89,7 @@ export class ChartTimelineComponent implements OnInit {
   ngOnInit(): void {
   }
 
-  addNewSeries(obj: Object) {
+  addNewSeries(obj: Agent) {
     // --- Get index of the agent in series
     let name = obj.id
     let idx = this.chartOptions.series.findIndex((s: { name: string; }) => s.name === name) 
@@ -104,7 +104,7 @@ export class ChartTimelineComponent implements OnInit {
     //   this.chartOptions.series[idx]["color"] = markerConf?.circle
     // }
     var markerConf = getMarkerConfig(idx+1) // 0 is root
-    this.chartOptions.series[idx]["color"] = markerConf?.circle
+    this.chartOptions.series[idx]["color"] = markerConf?.color
 
     // --- Add new data
     obj.zoneDescriptors.forEach(zone => {
@@ -116,8 +116,8 @@ export class ChartTimelineComponent implements OnInit {
             new Date(obj.lastPosUpdate).getTime(),
             new Date(obj.lastPosUpdate).getTime() + 1000
           ],
-          "fillColor": markerConf?.circle,
-          "strokeColor": markerConf?.circle
+          "fillColor": markerConf?.color,
+          "strokeColor": markerConf?.color
         }
         this.chartOptions.series[idx]["data"].push(patch)
 
@@ -130,8 +130,8 @@ export class ChartTimelineComponent implements OnInit {
             oldData['y'][0],
             new Date(obj.lastPosUpdate).getTime()
           ],
-          "fillColor": markerConf?.circle,
-          "strokeColor": markerConf?.circle
+          "fillColor": markerConf?.color,
+          "strokeColor": markerConf?.color
         }
         this.chartOptions.series[idx]["data"].push(patch)
       }
diff --git a/src/app/components/map/map.component.ts b/src/app/components/map/map.component.ts
index 9b60408..681229f 100644
--- a/src/app/components/map/map.component.ts
+++ b/src/app/components/map/map.component.ts
@@ -6,7 +6,7 @@ import 'leaflet-arrowheads';
 import { IMqttMessage, MqttService } from 'ngx-mqtt';
 
 import { environment, getMarkerConfig} from 'src/environments/environment';
-import {Position, PositionUpdate, RelativePos, WGS84, validateTypePosition, validateTypeObject} from 'src/app/model/base-model';
+import {Position, PositionUpdate, RelativePos, WGS84, validateTypePosition, validateTypeAgent} from 'src/app/model/base-model';
 
 
 @Component({
@@ -46,7 +46,7 @@ export class MapComponent implements OnInit {
         let upd: PositionUpdate = <PositionUpdate>JSON.parse(message.payload.toString())
         
         upd.objects.forEach(obj => {
-          validateTypeObject(obj)
+          validateTypeAgent(obj)
           this.registerPoint(obj.id, obj)
         });
       } catch(e) {
@@ -73,14 +73,15 @@ export class MapComponent implements OnInit {
   registerPoint(key: string, desc: { [key: string]: any }) {
     // --- Leyers for markers
     if (key in this.markOverlays) {
+      console.log(this.markOverlays)
       this.markOverlays[key].clearLayers();
     } else {
       this.markOverlays[key] = L.layerGroup().addTo(<L.Map>this.map)
     }
 
     // --- Info
-    let pos = desc["position"]
     this.agentsInfo[key] = desc
+    let pos = desc["position"]
 
     var props = undefined
     if (desc.extractedAttributes) {
@@ -101,7 +102,7 @@ export class MapComponent implements OnInit {
 
     // empty position
     if (pos==undefined) {
-      console.log("Eroro: empty position.")
+      console.log("Error: empty position.")
       return
     }
 
@@ -109,7 +110,7 @@ export class MapComponent implements OnInit {
 
     // empty point
     if (Object.values(point).every((e)=>{e==undefined})) {
-      console.log("Eroro: empty point.")
+      console.log("Error: empty point.")
       return;
     }
 
@@ -119,55 +120,65 @@ export class MapComponent implements OnInit {
       var globPos = L.latLng([point.latitude, point.longitude]);
     }
  
-    // --- Marker
-    let serialNum = Object.keys(this.markOverlays).length - 1 // because this point already exists
-    console.log(this.markOverlays)
-    console.log("serialNum ", serialNum)
-    var markerConf = getMarkerConfig(serialNum)
-
-    // if (key in MarkerColorMap) {
-    //   var markerConf = MarkerColorMap[key]
-    // } else {
-    //   var markerConf = MarkerColorMap['Default']
-    // }
+    if (key=="ROOT") {
+      // Root Marker
+      let marker = L.marker(globPos, {
+        icon: L.icon({
+          iconSize: [40, 40],
+          iconAnchor: [21, 25],
+          iconUrl: `assets/marker-ball-pink.png`,
+          className: 'true-position-marker'
+        })
+      }).bindPopup(popup).openPopup();
+      marker.addTo(this.markOverlays[key])
       
-    let marker = L.marker(globPos, {
-      icon: L.icon({
-        iconSize: [25, 41],
-        iconAnchor: [13, 41],
-        iconUrl: `assets/marker-icon-${markerConf.marker}.png`,
-        iconRetinaUrl: `assets/marker-icon-2x-${markerConf.marker}.png`,
-        shadowUrl: 'assets/marker-shadow.png',
-        className: 'true-position-marker'
-      })
-    }).bindPopup(popup).openPopup();
-    marker.addTo(this.markOverlays[key])
-
-    // --- Accuracy
-    if (pos?.accuracy) {
-      L.circle(globPos, pos.accuracy, { color: markerConf.circle}
-      ).addTo(this.markOverlays[key]);
-    }
-
-    // --- Orientation
-    if ('x' in point) {
-      let orient: RelativePos = {
-        "x": point.x + (theta ? Math.cos(theta)*3.5 : 3.5), 
-        "y": point.y + (theta ? Math.sin(theta)*3.5 : 0),
-        "z": point.z
+    } else {
+      // --- Marker config
+      let serialNum = Object.keys(this.markOverlays).indexOf(key)
+      // if (serialNum == 0 && Object.keys(this.markOverlays).length > 1) {
+      //   serialNum = 1
+      // }
+      var markerConf = getMarkerConfig(serialNum)
+
+      let marker = L.marker(globPos, {
+        icon: L.icon({
+          iconSize: [25, 41],
+          iconAnchor: [13, 41],
+          iconUrl: `assets/marker-icon-${markerConf.marker}.png`,
+          iconRetinaUrl: `assets/marker-icon-2x-${markerConf.marker}.png`,
+          shadowUrl: 'assets/marker-shadow.png',
+          className: 'true-position-marker'
+        })
+      }).bindPopup(popup).openPopup();
+      marker.addTo(this.markOverlays[key])
+
+      // --- Accuracy
+      if (pos?.accuracy) {
+        L.circle(globPos, pos.accuracy, { color: markerConf.color}
+        ).addTo(this.markOverlays[key]);
       }
-      let globPointOrient = this.ref2root(orient)
 
-      // add arrow
-      var arrow = L.polyline([globPos, globPointOrient], {color: 'grey'}).arrowheads(
-        {
-          fill: true,
-          color: 'grey'
+      // --- Orientation
+      if ('x' in point) {
+        let orient: RelativePos = {
+          "x": point.x + (theta ? Math.cos(theta)*3.5 : 3.5), 
+          "y": point.y + (theta ? Math.sin(theta)*3.5 : 0),
+          "z": point.z
         }
-      );
-      arrow.addTo(this.markOverlays[key])
+        let globPointOrient = this.ref2root(orient)
+
+        // add arrow
+        var arrow = L.polyline([globPos, globPointOrient], {color: markerConf.color}).arrowheads(
+          {
+            fill: true,
+            color: markerConf.color
+          }
+        );
+        arrow.addTo(this.markOverlays[key])
 
+      }
     }
+  
   }
 
   // @https://asymmetrik.com/ngx-leaflet-tutorial-angular-cli/
diff --git a/src/app/components/table/table.component.html b/src/app/components/table/table.component.html
index f10305d..12d2ce2 100644
--- a/src/app/components/table/table.component.html
+++ b/src/app/components/table/table.component.html
@@ -6,10 +6,10 @@
             <th mat-header-cell *matHeaderCellDef>
                 <mat-icon aria-hidden="false" aria-label="Agent">people</mat-icon> Agent
             </th>
-            <td mat-cell *matCellDef="let element"> {{element.id}} </td>
+            <td mat-cell *matCellDef="let element"><span [ngStyle]="{'color': element.color}">⬤</span> {{element.id}} </td>
         </ng-container>
 
-        <!-- Type -->
+        <!-- Type --> 
         <ng-container matColumnDef="type">
             <th mat-header-cell *matHeaderCellDef>
                 <mat-icon aria-hidden="false" aria-label="Type">style</mat-icon> Type
diff --git a/src/app/components/table/table.component.ts b/src/app/components/table/table.component.ts
index 0bebc46..0fa9088 100644
--- a/src/app/components/table/table.component.ts
+++ b/src/app/components/table/table.component.ts
@@ -1,10 +1,11 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
-import {PositionUpdate, validateTypeObject} from 'src/app/model/base-model';
+import {Agent, PositionUpdate} from 'src/app/model/base-model';
 
 import { IMqttMessage, MqttService } from 'ngx-mqtt';
 import { Subscription } from 'rxjs';
 import { MatTable } from '@angular/material/table';
 
+import { getMarkerConfig} from 'src/environments/environment';
 
 @Component({
   selector: 'app-table',
@@ -39,10 +40,19 @@ export class TableComponent implements OnInit {
         let upd: PositionUpdate = JSON.parse(message.payload.toString())
         // upd.objects.forEach(obj => validateTypeObject(obj));
         this.dataSource.push(...upd.objects);
+
+        let agentNames = [...new Set(this.dataSource.map((agent: any) => agent.id))]
+        this.dataSource.forEach((agent: any)=> {
+          let idx = agentNames.indexOf(agent.id) + 1
+          agent.color = getMarkerConfig(idx).color
+        })
+
         this.table?.renderRows();
       } catch(e) {
           console.log(e)
       }
+
+      // console.log(this.dataSource)
     });
   }
 
diff --git a/src/app/model/base-model.ts b/src/app/model/base-model.ts
index 475efd8..32c8dc7 100644
--- a/src/app/model/base-model.ts
+++ b/src/app/model/base-model.ts
@@ -1,10 +1,10 @@
    
 export interface PositionUpdate {
-    objects: Object[]
+    objects: Agent[]
     type: NotificationType
 }
 
-export interface Object {
+export interface Agent {
     id: string
     sensorId: string
     type: ObjectType
@@ -77,9 +77,9 @@ export function validateTypePosition(obj: any) {
     }
 }
   
-export function validateTypeObject(obj: any) {
-    if (!isObject(obj)) {
-        throw new TypeError("Unvalid Object: " + Object.keys(obj))  
+export function validateTypeAgent(obj: any) {
+    if (!isAgent(obj)) {
+        throw new TypeError("Unvalid Agent: " + Object.keys(obj))  
     }
 }
 
@@ -101,7 +101,7 @@ export function isPosition(obj: any): obj is Position {
     && Object.prototype.hasOwnProperty.call(obj, "refSystemId")
 } 
 
-export function isObject(obj: any): obj is Object {
+export function isAgent(obj: any): obj is Agent {
     return "id" in obj
         && "type" in obj
         && "sensorId" in obj
diff --git a/src/assets/marker-ball-pink.png b/src/assets/marker-ball-pink.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ce051e9ab53c03828c27e20e372dd91ef37a258
GIT binary patch
literal 17555
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
GGywo)!vcH&

literal 0
HcmV?d00001

diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index 373238d..6ef5e65 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -36,26 +36,30 @@ export const MQTTconfig: IMqttServiceOptions = {
 // };
 
 export const MarkerColorList: MarkerColor[]  = [
-  {"marker": "red", "circle": "#d32f2f"},
-  {"marker": "green", "circle": "#008632"},
-  {"marker": "blue", "circle": "#0076EE"},
-  {"marker": "violet", "circle": "#9700ee"},
-  {"marker": "yellow", "circle": "#eee600"},
-  {"marker": "grey", "circle": "#606060"},
+  {"marker": "red", "color": "#d32f2f"},
+  {"marker": "green", "color": "#008632"},
+  {"marker": "blue", "color": "#0076EE"},
+  {"marker": "violet", "color": "#9700ee"},
+  {"marker": "yellow", "color": "#eee600"},
+  {"marker": "grey", "color": "#606060"},
 ]
 
 interface MarkerColor {
   marker: string
-  circle: string
+  color: string 
 }
 
 export function getMarkerConfig(counter: number) {
-  let idx = counter
+
+  if (counter < 0) {
+    counter = 0
+  }
 
   if (MarkerColorList.length <= counter) {
-    idx = counter - MarkerColorList.length
+    counter = counter - MarkerColorList.length
   }
-  return MarkerColorList[idx]
+
+  return MarkerColorList[counter]
 }
 
 /*
-- 
GitLab