Skip to content

Commit

Permalink
laylines
Browse files Browse the repository at this point in the history
  • Loading branch information
panaaj committed Sep 5, 2024
1 parent 0510d75 commit 16ae380
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 111 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- **Added**: Setting to mute all sounds regardless of notification ALARM_METHOD value.(#178)
- **Updated**: Show total length of Route when editing. (#171)
- **Added**: Toggle charts on/of by clicking chart boundaries on map.
- **Added**: Lock in `Follow Vessel` setting to remain in this mode when map is panned. (#185)
- **Fixed**: Not rendering laylines when preferred path is `environment.wind.directionMagnetic`. (#184)

### v2.11.1

Expand Down
34 changes: 6 additions & 28 deletions src/app/app.settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,6 @@ export function cleanConfig(
settings.selections.vessel.aisCogLine = 10;
}

// changeover 2.7 - for removal
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (typeof (settings as any).vesselTrail !== 'undefined') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
settings.selections.vessel.trail = (settings as any).vesselTrail;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (settings as any).vesselTrail;
}
// changeover 2.7 - for removal
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (typeof (settings as any).vesselWindVectors !== 'undefined') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
settings.selections.vessel.windVectors = (
settings as any
).vesselWindVectors;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (settings as any).vesselWindVectors;
}

if (typeof settings.map.limitZoom === 'undefined') {
settings.map.limitZoom = false;
}
Expand All @@ -80,6 +61,10 @@ export function cleanConfig(
settings.map.invertColor = false;
}

if (typeof settings.map.lockMoveMap === 'undefined') {
settings.map.lockMoveMap = false;
}

if (typeof settings.anchorRadius === 'undefined') {
settings.anchorRadius = 40;
}
Expand All @@ -100,15 +85,6 @@ export function cleanConfig(
settings.selections.labelsMinZoom = 10;
}

// changeover 2.7 - for removal
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (typeof (settings as any).aisShowTrack !== 'undefined') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
settings.selections.aisShowTrack = (settings as any).aisShowTrack;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (settings as any).aisShowTrack;
}

if (typeof settings.toolBarButtons === 'undefined') {
settings.toolBarButtons = true;
}
Expand Down Expand Up @@ -298,6 +274,7 @@ export const DefaultConfig: IAppConfig = {
center: [0, 0],
rotation: 0,
moveMap: false,
lockMoveMap: true,
northUp: true,
animate: false,
limitZoom: false,
Expand Down Expand Up @@ -424,6 +401,7 @@ export interface IAppConfig {
center: Position;
rotation: number;
moveMap: boolean;
lockMoveMap: boolean;
northUp: boolean;
animate: boolean;
limitZoom: boolean;
Expand Down
20 changes: 10 additions & 10 deletions src/app/modules/map/fb-map.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -533,24 +533,24 @@
>
</fb-xte-path>
} @if(dfeat.navData.position && app.config.selections.vessel.laylines) {
<fb-layline
[lines]="vesselLines.laylines"
[laylineStyles]="featureStyles.layline"
[position]="app.data.vessels.active.position"
[twd]="app.data.vessels.self.wind.twd"
[mapZoom]="fbMap.zoomLevel"
[zIndex]="212"
>
</fb-layline>
<fb-target-angle
[line]="vesselLines.targetAngle"
[lineStyle]="featureStyles.targetAngle"
[position]="app.data.vessels.active.position"
[twd]="app.data.vessels.self.wind.twd"
[twd]="app.data.vessels.self.wind.direction"
[mapZoom]="fbMap.zoomLevel"
[zIndex]="212"
>
</fb-target-angle>
<fb-layline
[lines]="vesselLines.laylines"
[laylineStyles]="featureStyles.layline"
[position]="app.data.vessels.active.position"
[twd]="app.data.vessels.self.wind.direction"
[mapZoom]="fbMap.zoomLevel"
[zIndex]="212"
>
</fb-layline>
} @if(dfeat.navData.position && app.data.anchor.raised) {
<fb-bearing-line
[marker]="dfeat.navData.position"
Expand Down
164 changes: 92 additions & 72 deletions src/app/modules/map/fb-map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ import {
import { FreeboardOpenlayersModule } from 'src/app/modules/map/ol';
import { PipesModule } from 'src/app/lib/pipes';

import { computeDestinationPoint, getGreatCircleBearing } from 'geolib';
import {
computeDestinationPoint,
getGreatCircleBearing,
getDistanceFromLine,
getDistance,
getPreciseDistance
} from 'geolib';
import { toLonLat } from 'ol/proj';
import { Style, Stroke, Fill } from 'ol/style';
import { Collection, Feature } from 'ol';
Expand Down Expand Up @@ -709,8 +715,10 @@ export class FBMapComponent implements OnInit, OnDestroy {
}

public onMapPointerDrag() {
this.fbMap.movingMap = false;
this.exitedMovingMap.emit(true);
if (!this.app.config.map.lockMoveMap) {
this.fbMap.movingMap = false;
this.exitedMovingMap.emit(true);
}
}

// toggle display of resource feature
Expand Down Expand Up @@ -1215,107 +1223,119 @@ export class FBMapComponent implements OnInit, OnDestroy {
typeof this.app.data.vessels.active.heading === 'number'
) {
const twd_deg = Convert.radiansToDegrees(
this.app.data.vessels.self.wind.twd
this.app.data.vessels.self.wind.direction
);

const twd_inv = Angle.add(twd_deg, 180);

const destUpwind =
Math.abs(
Angle.difference(this.app.data.navData.bearing.value, twd_deg)
) < 90;

const ba_deg = Convert.radiansToDegrees(
this.app.data.vessels.self.performance.beatAngle ?? Math.PI / 4
);
const destInTarget =
Math.abs(
Angle.difference(this.app.data.navData.bearing.value, twd_deg)
) < ba_deg;

const ga_deg = Convert.radiansToDegrees(
this.app.data.vessels.self.performance.gybeAngle ?? Math.PI / 6
);

const destInTarget = destUpwind
? Math.abs(
Angle.difference(this.app.data.navData.bearing.value, twd_deg)
) < ba_deg
: Math.abs(
Angle.difference(this.app.data.navData.bearing.value, twd_deg)
) > ga_deg;

const dtg =
this.app.config.units.distance === 'm'
? this.app.data.navData.dtg * 1000
: Convert.nauticalMilesToKm(this.app.data.navData.dtg * 1000);

if (destInTarget) {
const bta = Angle.add(twd_deg, 90); // tack angle = 90

const hbd_rad = Convert.degreesToRadians(
Angle.difference(twd_deg, this.app.data.navData.bearing.value)
);
const dist1 = Math.sin(hbd_rad) * dtg;
const dist2 = Math.cos(hbd_rad) * dtg;
const pt1 = computeDestinationPoint(
this.app.data.vessels.active.position,
dist1,
bta
);
const pt2 = computeDestinationPoint(
this.app.data.vessels.active.position,
dist2,
twd_deg
);
const p1a = [
this.app.data.vessels.active.position,
[pt1.longitude, pt1.latitude]
];
const p1b = [
[pt1.longitude, pt1.latitude],
this.dfeat.navData.position
];
const l1 = hbd_rad < 0 ? [p1a, p1b] : [p1b, p1a];

const p2a = [
[pt2.longitude, pt2.latitude],
this.dfeat.navData.position
];
const p2b = [
this.app.data.vessels.active.position,
[pt2.longitude, pt2.latitude]
];
const l2 = hbd_rad < 0 ? [p2a, p2b] : [p2b, p2a];

vl.laylines = {
port: hbd_rad < 0 ? l2 : l1,
starboard: hbd_rad < 0 ? l1 : l2
};
}
// target angle lines
if (destUpwind && destInTarget) {
// mark laylines
let markLines = [];
if (destUpwind) {
const bapt1 = computeDestinationPoint(
this.app.data.vessels.active.position,
this.dfeat.navData.position,
dtg,
Angle.add(twd_deg, ba_deg)
Angle.add(twd_inv, ba_deg)
);
const bapt2 = computeDestinationPoint(
this.app.data.vessels.active.position,
this.dfeat.navData.position,
dtg,
Angle.add(twd_deg, 0 - ba_deg)
Angle.add(twd_inv, 0 - ba_deg)
);
vl.targetAngle = [

markLines = [
[bapt1.longitude, bapt1.latitude],
this.app.data.vessels.active.position,
this.dfeat.navData.position,
[bapt2.longitude, bapt2.latitude]
];
} else if (
!destUpwind &&
typeof this.app.data.vessels.self.performance.gybeAngle === 'number'
) {
const ga_deg = Convert.radiansToDegrees(
this.app.data.vessels.self.performance.gybeAngle
);
} else {
const gapt1 = computeDestinationPoint(
this.app.data.vessels.active.position,
this.dfeat.navData.position,
dtg,
Angle.add(this.app.data.navData.bearing.value, ga_deg)
Angle.add(twd_deg, ga_deg)
);
const gapt2 = computeDestinationPoint(
this.app.data.vessels.active.position,
this.dfeat.navData.position,
dtg,
Angle.add(this.app.data.navData.bearing.value, 0 - ga_deg)
Angle.add(twd_deg, 0 - ga_deg)
);
vl.targetAngle = [

markLines = [
[gapt1.longitude, gapt1.latitude],
this.app.data.vessels.active.position,
this.dfeat.navData.position,
[gapt2.longitude, gapt2.latitude]
];
}

vl.targetAngle = markLines;

// vessel laylines
if (destInTarget && destUpwind) {
// Vector angles
const hbd_deg = Angle.difference(
twd_deg,
this.app.data.navData.bearing.value
);
const C_RAD = Convert.degreesToRadians(ba_deg - hbd_deg);
const B_RAD = Convert.degreesToRadians(ba_deg + hbd_deg);
const A_RAD = Math.PI - (B_RAD + C_RAD);
// Vector lengths
const b = (dtg * Math.sin(B_RAD)) / Math.sin(A_RAD);
const c = (dtg * Math.sin(C_RAD)) / Math.sin(A_RAD);
// intersection points
const ipts = computeDestinationPoint(
this.app.data.vessels.active.position,
b,
Angle.add(twd_deg, ba_deg)
);
const iptp = computeDestinationPoint(
this.app.data.vessels.active.position,
c,
Angle.add(twd_deg, 0 - ba_deg)
);

vl.laylines = {
port: [
[
[iptp.longitude, iptp.latitude],
this.app.data.vessels.active.position
],
[
[ipts.longitude, ipts.latitude],
this.app.data.vessels.active.position
]
],
starboard: [
[[ipts.longitude, ipts.latitude], markLines[1]],
[markLines[1], [iptp.longitude, iptp.latitude]]
]
};
}
}

// AWA (focused)
Expand Down
11 changes: 11 additions & 0 deletions src/app/modules/settings/components/settings-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,17 @@
<mat-card class="setting-card">
<mat-card-content>
<div class="setting-card-row" style="padding-bottom: 10px">
<div class="setting-card-row-item">
<mat-checkbox
#lockMoveMap
[(ngModel)]="facade.settings.map.lockMoveMap"
(change)="onFormChange($event, lockMoveMap)"
matTooltip="Do not exit follow vessel when map is panned."
label="after"
>
Lock Follow Vessel
</mat-checkbox>
</div>
<div class="setting-card-row-item">
<mat-checkbox
#muteAllSound
Expand Down
1 change: 1 addition & 0 deletions src/app/modules/skstream/skstream.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ export class SKStreamFacade {
private processVessel(d: SKVessel) {
d.cog = this.app.useMagnetic ? d.cogMagnetic : d.cogTrue;
d.heading = this.app.useMagnetic ? d.headingMagnetic : d.headingTrue;
d.wind.direction = this.app.useMagnetic ? d.wind.mwd : d.wind.twd;
}

// ** process course data
Expand Down
Binary file modified src/assets/help/img/settings_display.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/assets/help/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1771,7 +1771,7 @@ <h4><i class="material-icons">settings</i> Settings</h4>

<b>DISPLAY:</b><br />
This section provides choices about how information is displayed.<br />
<img src="./img/settings_display.png" style="width: 300px" alt="" />
<img src="./img/settings_display.png" style="width: 350px" alt="" />
<ul>
<li>
<b>Instrument Panel App</b>: Select from a list of installed
Expand Down Expand Up @@ -1801,6 +1801,10 @@ <h4><i class="material-icons">settings</i> Settings</h4>
These selected Web App can be "switched in" for display in the
<i>Instrument Panel</i>.
</li>
<li>
<b>Lock Follow Vessel</b>: Check this box to remain in "Follow
Vessel" mode when map is panned / moved.
</li>
<li>
<b>Do not Play Sounds</b>: Check this box if you do not want any
sounds played.
Expand Down

0 comments on commit 16ae380

Please sign in to comment.