diff --git a/src/app/modules/map/fb-map.component.html b/src/app/modules/map/fb-map.component.html index 8852de5b..1db5e948 100644 --- a/src/app/modules/map/fb-map.component.html +++ b/src/app/modules/map/fb-map.component.html @@ -479,9 +479,9 @@ diff --git a/src/app/modules/map/ol/lib/navigation/layer-layline.component.ts b/src/app/modules/map/ol/lib/navigation/layer-layline.component.ts index f7168562..cbe70fd8 100644 --- a/src/app/modules/map/ol/lib/navigation/layer-layline.component.ts +++ b/src/app/modules/map/ol/lib/navigation/layer-layline.component.ts @@ -43,9 +43,9 @@ export class LaylineComponent implements OnInit, OnDestroy, OnChanges { @Input() mapZoom = 10; // eslint-disable-next-line @typescript-eslint/no-explicit-any @Input() laylineStyles: { [key: string]: any }; - @Input() heading: number; - @Input() bearing: number; - @Input() awa: number; + @Input() bearing: number; // degrees + @Input() twd: number; // radians + @Input() tackAngle = Math.PI / 4; // radians (45 deg) @Input() opacity: number; @Input() visible: boolean; @Input() extent: Extent; @@ -88,9 +88,9 @@ export class LaylineComponent implements OnInit, OnDestroy, OnChanges { for (const key in changes) { if ( key === 'lines' || - key === 'heading' || key === 'bearing' || - key === 'awa' + key === 'twd' || + key === 'tackAngle' ) { this.parseValues(); if (this.source) { @@ -121,8 +121,8 @@ export class LaylineComponent implements OnInit, OnDestroy, OnChanges { parseValues() { if ( typeof this.bearing !== 'number' || - typeof this.heading !== 'number' || - typeof this.awa !== 'number' + typeof this.twd !== 'number' || + typeof this.tackAngle !== 'number' ) { this.features = []; return; @@ -130,10 +130,13 @@ export class LaylineComponent implements OnInit, OnDestroy, OnChanges { const fa: Feature[] = []; let idx = 0; - // is destination upwind - const awd = Angle.add(this.heading, Convert.radiansToDegrees(this.awa)); - if (Math.abs(Angle.difference(this.bearing, awd)) >= 90) { - this.features = []; + + const tad = Convert.radiansToDegrees(this.tackAngle); + const wd = Convert.radiansToDegrees(this.twd); + const destUpwind = Math.abs(Angle.difference(this.bearing, wd)) < tad; + + if (!destUpwind) { + this.features = fa; return; } diff --git a/src/app/modules/skresources/resource-classes.ts b/src/app/modules/skresources/resource-classes.ts index 8fe767d2..53d044f3 100644 --- a/src/app/modules/skresources/resource-classes.ts +++ b/src/app/modules/skresources/resource-classes.ts @@ -179,6 +179,7 @@ export class SKVessel { sog: number; name: string; mmsi: string; + type: { id: number; name: string } = { id: -1, name: '' }; callsign: string; state: string; wind = { @@ -207,6 +208,9 @@ export class SKVessel { nextPoint: {}, previousPoint: {} }; + performance = { + beatAngle: null + }; properties = {}; } diff --git a/src/app/modules/skstream/skstream.facade.ts b/src/app/modules/skstream/skstream.facade.ts index 9bf191c8..2779f508 100644 --- a/src/app/modules/skstream/skstream.facade.ts +++ b/src/app/modules/skstream/skstream.facade.ts @@ -171,7 +171,8 @@ export class SKStreamFacade { { path: 'environment.wind.*', period: 1000, policy: 'fixed' }, { path: 'environment.mode', period: 1000, policy: 'fixed' }, { path: 'resources.*', period: 1000, policy: 'fixed' }, - { path: 'steering.autopilot.*', period: 1000, policy: 'fixed' } + { path: 'steering.autopilot.*', period: 1000, policy: 'fixed' }, + { path: 'performance.*', period: 1000, policy: 'fixed' } ] } }); diff --git a/src/app/modules/skstream/skstream.worker.ts b/src/app/modules/skstream/skstream.worker.ts index c0aaf9fb..56bbcc02 100644 --- a/src/app/modules/skstream/skstream.worker.ts +++ b/src/app/modules/skstream/skstream.worker.ts @@ -766,8 +766,12 @@ function processVessel(d: SKVessel, v, isSelf = false) { if (typeof v.value.buddy !== 'undefined') { d.buddy = v.value.buddy; } + } else if (v.path === 'performance.beatAngle') { + d.performance.beatAngle = v.value; } else if (v.path === 'communication.callsignVhf') { d.callsign = v.value; + } else if (v.path === 'design.aisShipType') { + d.type = v.value; } else if (v.path === 'navigation.position' && v.value) { // position is not null if (