diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d6ae342..70046dc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/app/app.settings.ts b/src/app/app.settings.ts index 4a14066a..8715df88 100644 --- a/src/app/app.settings.ts +++ b/src/app/app.settings.ts @@ -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; } @@ -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; } @@ -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; } @@ -298,6 +274,7 @@ export const DefaultConfig: IAppConfig = { center: [0, 0], rotation: 0, moveMap: false, + lockMoveMap: true, northUp: true, animate: false, limitZoom: false, @@ -424,6 +401,7 @@ export interface IAppConfig { center: Position; rotation: number; moveMap: boolean; + lockMoveMap: boolean; northUp: boolean; animate: boolean; limitZoom: boolean; diff --git a/src/app/modules/map/fb-map.component.html b/src/app/modules/map/fb-map.component.html index a85ea35d..170eed56 100644 --- a/src/app/modules/map/fb-map.component.html +++ b/src/app/modules/map/fb-map.component.html @@ -533,24 +533,24 @@ > } @if(dfeat.navData.position && app.config.selections.vessel.laylines) { - - + + } @if(dfeat.navData.position && app.data.anchor.raised) { 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) diff --git a/src/app/modules/settings/components/settings-dialog.html b/src/app/modules/settings/components/settings-dialog.html index 2904a302..62f1f280 100644 --- a/src/app/modules/settings/components/settings-dialog.html +++ b/src/app/modules/settings/components/settings-dialog.html @@ -129,6 +129,17 @@
+
+ + Lock Follow Vessel + +
settings Settings DISPLAY:
This section provides choices about how information is displayed.
- +
  • Instrument Panel App: Select from a list of installed @@ -1801,6 +1801,10 @@

    settings Settings

    These selected Web App can be "switched in" for display in the Instrument Panel.
  • +
  • + Lock Follow Vessel: Check this box to remain in "Follow + Vessel" mode when map is panned / moved. +
  • Do not Play Sounds: Check this box if you do not want any sounds played.