Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,8 @@ export class AppComponent {
weatherApi: false,
radarApi: false,
notificationApi: false,
buddyList: false
buddyList: false,
tidalApi: false
};
this.signalk.get('/signalk/v2/features?enabled=1').subscribe(
(res: {
Expand Down Expand Up @@ -867,6 +868,11 @@ export class AppComponent {
this.app.debug('*** found PMTiles plugin');
hasPlugin.pmTiles = true;
}
// tidal currents
if (p.id === 'signalk-tidal-currents') {
this.app.debug('*** found signalk-tidal-currents plugin');
ff.tidalApi = true;
}
});
this.app.featureFlags.update((current) => {
return Object.assign({}, current, ff);
Expand Down
9 changes: 7 additions & 2 deletions src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ export function cleanConfig(
resourceSets: {},
infolayers: null,
weatherWindEnabled: false,
oceanCurrentsEnabled: false
oceanCurrentsEnabled: false,
tidalCurrentsEnabled: false
};
}

Expand Down Expand Up @@ -413,6 +414,9 @@ export function cleanConfig(
if (typeof settings.selections.oceanCurrentsEnabled === 'undefined') {
settings.selections.oceanCurrentsEnabled = false;
}
if (typeof settings.selections.tidalCurrentsEnabled === 'undefined') {
settings.selections.tidalCurrentsEnabled = false;
}

// ensure legacy notes selections section is removed
if (typeof (settings as any).selections.notes) {
Expand Down Expand Up @@ -618,7 +622,8 @@ export function defaultConfig(): IAppConfig {
resourceSets: {}, // additional resources
infolayers: null,
weatherWindEnabled: false,
oceanCurrentsEnabled: false
oceanCurrentsEnabled: false,
tidalCurrentsEnabled: false
}
};
}
Expand Down
4 changes: 3 additions & 1 deletion src/app/app.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export class AppFacade extends InfoService {
resourceTracks: boolean;
infoLayers: boolean;
buddyList: boolean;
tidalApi: boolean;
}>({
anchorApi: true, // default true until API is available
autopilotApi: false,
Expand All @@ -235,7 +236,8 @@ export class AppFacade extends InfoService {
resourceGroups: false, // ability to store resource groups
resourceTracks: false, // ability to store track resources
infoLayers: false, // ability to store map information overlays
buddyList: false
buddyList: false,
tidalApi: false
});

selfLines = signal<{ cog: LineStyleDef; heading: LineStyleDef }>({
Expand Down
33 changes: 33 additions & 0 deletions src/app/modules/map/fb-map.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,33 @@
>
</s57-popover>
}
@if (this.overlay().type === 'tidal') {
<ap-popover
[canClose]="app.config.map.popoverMulti"
[compact]="true"
(closed)="popoverClosed()"
>
<div style="display: flex; align-items: center; gap: 8px">
<mat-icon style="font-size: 22px; height: 22px; width: 22px"
>water</mat-icon
>
<div style="display: flex; flex-direction: column; gap: 2px">
<div style="display: flex; align-items: center; gap: 6px">
<mat-icon style="font-size: 16px; height: 16px; width: 16px"
>air</mat-icon
>
<span>{{ overlay().tidal?.speedLabel }}</span>
</div>
<div style="display: flex; align-items: center; gap: 6px">
<mat-icon style="font-size: 16px; height: 16px; width: 16px"
>explore</mat-icon
>
<span>{{ overlay().tidal?.directionLabel }}</span>
</div>
</div>
</div>
</ap-popover>
}
@if (
overlay().type === 'destination' ||
overlay().type === 'waypoint' ||
Expand Down Expand Up @@ -852,6 +879,12 @@
>
</fb-weather-currents>

<fb-tidal-currents
[show]="app.config.selections.tidalCurrentsEnabled"
[opacity]="0.7"
>
</fb-tidal-currents>

<!-- chart boundaries-->
@if (app.data.chartBounds.show) {
<fb-chart-bounds
Expand Down
36 changes: 35 additions & 1 deletion src/app/modules/map/fb-map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ import { MapService } from './ol/lib/map.service';
import { AppIconDef } from '../icons';
import { LayerWindWeatherComponent } from './ol/lib/resources/layer-wind-weather.component';
import { LayerCurrentsWeatherComponent } from './ol/lib/resources/layer-currents-weather.component';
import { TidalCurrentsLayerComponent } from './ol/lib/resources/tidal-currents-layer.component';

interface IResource {
id: string;
Expand Down Expand Up @@ -172,7 +173,8 @@ enum INTERACTION_MODE {
VesselPopoverComponent,
S57PopoverComponent,
LayerWindWeatherComponent,
LayerCurrentsWeatherComponent
LayerCurrentsWeatherComponent,
TidalCurrentsLayerComponent
],
templateUrl: './fb-map.component.html',
styleUrls: ['./fb-map.component.css']
Expand Down Expand Up @@ -1293,6 +1295,18 @@ export class FBMapComponent implements OnInit, OnDestroy {
aircraft = this.app.data.aircraft.get(id);
text = aircraft ? aircraft.name || aircraft.mmsi : '';
break;
case 'tidal':
addToFeatureList = true;
icon = {
name: 'water',
svgIcon: undefined
};
text = feature.get('name');
this.tidalFeatures[id] = {
speedKn: Number(feature.get('driftKts')) || 0,
direction: Number(feature.get('setDeg')) || 0
};
break;
Comment on lines +1303 to +1314

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add a case 'tidal' handler in formatPopover to show a popover when tidal features are clicked.

processMapClick correctly adds tidal features to the feature list, but formatPopover (lines 1391–1600) has no case 'tidal' — it falls through to default: return; at line 1598. This means:

  • Single tidal feature click: formatPopover('tidal.0', coord) is called → default: return; → no popover appears.
  • Multi-feature list: Selecting a tidal feature calls formatPopover('tidal.0', coord) → same default: return; → no popover.

The PR objective states click handling is routed through processMapClick for "consistent popovers," but the popover is never shown. A case 'tidal' in formatPopover and a corresponding popover template in the HTML are needed to complete the flow.

🐛 Proposed fix: add `case 'tidal'` to `formatPopover`
       case 'aircraft':
         if (!this.app.data.aircraft.has(id)) {
           return false;
         }
         poData.type = t[0];
         poData.id = id;
         poData.aircraft = this.app.data.aircraft.get(id);
         poData.position = poData.aircraft.position;
         poData.show = true;
         break;
+      case 'tidal':
+        poData.id = id;
+        poData.type = 'tidal';
+        poData.title = 'Tidal Current';
+        poData.position = coord;
+        poData.show = true;
+        poData.readOnly = true;
+        break;
       case 'region':

A corresponding @if (overlay().type === 'tidal') block will also be needed in fb-map.component.html to render the popover content (e.g., displaying feature.get('name')).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/modules/map/fb-map.component.ts` around lines 1298 - 1305,
`formatPopover` currently has no `case 'tidal'`, so tidal clicks still fall
through to the default return and never render a popover even though
`processMapClick` routes them there. Add a `case 'tidal'` branch in
`fb-map.component.ts`’s `formatPopover` to populate the tidal overlay data
(using the existing feature name/details flow), and add the matching `@if
(overlay().type === 'tidal')` popover block in `fb-map.component.html` so
single-feature and list selections both display correctly.

}
} else if (!id && feature.getProperties) {
const props = feature.getProperties();
Expand Down Expand Up @@ -1340,6 +1354,7 @@ export class FBMapComponent implements OnInit, OnDestroy {
}

private s57Features: Record<string, Record<string, string | number>> = {};
private tidalFeatures: Record<string, { speedKn: number; direction: number }> = {};

// ******** POPOVER ACTIONS ************

Expand Down Expand Up @@ -1486,6 +1501,25 @@ export class FBMapComponent implements OnInit, OnDestroy {
poData.position = poData.aircraft.position;
poData.show = true;
break;
case 'tidal': {
const tf = this.tidalFeatures[id];
poData.id = id;
poData.type = 'tidal';
poData.position = coord;
poData.show = true;
poData.readOnly = true;
if (tf) {
poData.tidal = {
speedLabel: this.app.formatValueForDisplay(
tf.speedKn / 1.94384,
'm/s',
{ precision: 1 }
),
directionLabel: `${this.app.formatValueForDisplay(tf.direction, 'deg', { precision: 0 })}T`
};
}
break;
}
case 'region':
item = [this.skres.fromCache('regions', t[1])];
if (!item) {
Expand Down
1 change: 1 addition & 0 deletions src/app/modules/map/fbmap-interact.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface IPopover {
aircraft?: SKAircraft;
alarm?: AlertData;
s57Feature?: Record<string, string | number>;
tidal?: { speedLabel: string; directionLabel: string };
readOnly: boolean;
}

Expand Down
2 changes: 2 additions & 0 deletions src/app/modules/map/ol/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import { RadarComponent } from './lib/radar/layer-radar.component';
export * from './lib/util';
export { MapService } from './lib/map.service';
export { S57Service } from './lib/charts/s57.service';
export { TidalCurrentsService } from './lib/tidal-currents.service';

export { ContentComponent } from './lib/content.component';
export { ControlsDirective } from './lib/controls.directive';
Expand Down Expand Up @@ -110,6 +111,7 @@ export { MapStyleJsonChartLayerComponent } from './lib/charts/layer-mapstylejson
export { S57ChartLayerComponent } from './lib/charts/layer-s57-chart.component';
export { ChartBoundsLayerComponent } from './lib/charts/layer-chart-bounds.component';
export { RadarComponent } from './lib/radar/layer-radar.component';
export { TidalCurrentsLayerComponent } from './lib/resources/tidal-currents-layer.component';

const declarations = [
ContentComponent,
Expand Down
Loading