From 39896ea770b4a61243dcae07fdcbcf8a60cdecda Mon Sep 17 00:00:00 2001 From: Lewin Probst <info@emirror.de> Date: Tue, 9 Jun 2020 18:02:40 +0200 Subject: [PATCH] Added option to plot topographical lines from etopo file. The etopo file must be downloaded separately and linked as parameter etopo in the files section in artoa.ini file. --- VERSION | 2 +- artoa.ini.example | 1 + lib/+artoa/+controller/+file/loadEtopoFile.m | 25 +++++++++++ .../buttonToggleTopographicalTable.m | 18 ++++++++ .../checkboxTopographicalLines.m | 12 ++++++ .../+trajectoryOutput/clearTrajectoryPlot.m | 6 +++ .../+track/+trajectoryOutput/open.m | 19 ++++++++- .../+track/+trajectoryOutput/plot.m | 7 ++++ .../plotTopographicalLines.m | 39 +++++++++++++++++ .../tableTopographicalLinesEdit.m | 39 +++++++++++++++++ lib/+artoa/+gui/+track/trajectoryOutput.m | 42 +++++++++++++++++++ .../+versioning/+migrations/versions/v4226.m | 14 +++++++ 12 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 lib/+artoa/+controller/+file/loadEtopoFile.m create mode 100644 lib/+artoa/+controller/+track/+trajectoryOutput/buttonToggleTopographicalTable.m create mode 100644 lib/+artoa/+controller/+track/+trajectoryOutput/checkboxTopographicalLines.m create mode 100644 lib/+artoa/+controller/+track/+trajectoryOutput/plotTopographicalLines.m create mode 100644 lib/+artoa/+controller/+track/+trajectoryOutput/tableTopographicalLinesEdit.m create mode 100644 lib/+artoa/+versioning/+migrations/versions/v4226.m diff --git a/VERSION b/VERSION index bcad854..0e4c1b3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -225 \ No newline at end of file +226 \ No newline at end of file diff --git a/artoa.ini.example b/artoa.ini.example index 5b69e51..4071072 100644 --- a/artoa.ini.example +++ b/artoa.ini.example @@ -4,6 +4,7 @@ -soundsourcefile /your/filepath/here/input/HAFOS.soso -floatfile ..\HAFOS.flo % not used in artoa4 yet -bathyfile % not used in artoa4 yet +-etopo /your/filepath/here/data/etopo1_bed_c.flt [directory] -interim /your/filepath/here/ diff --git a/lib/+artoa/+controller/+file/loadEtopoFile.m b/lib/+artoa/+controller/+file/loadEtopoFile.m new file mode 100644 index 0000000..7d0e148 --- /dev/null +++ b/lib/+artoa/+controller/+file/loadEtopoFile.m @@ -0,0 +1,25 @@ +function [] = loadEtopoFile(pLatLimit, pLonLimit) +%LOADETOPOFILE Summary of this function goes here +% Detailed explanation goes here + +global artoaDataInput artoaConfig; + +if nargin ~= 2 + pLatLimit = [-90, 0]; + pLonLimit = [-180, 180]; +end + +if artoa.data.hasMember(artoaConfig, 'files', 'etopo') ... + & isfile(artoaConfig.files.etopo) + artoaDataInput.etopo = struct(); + [artoaDataInput.etopo.Z, artoaDataInput.etopo.refvec] = etopo( ... + artoaConfig.files.etopo, ... + 1, ... + pLatLimit, ... + pLonLimit ... + ); +else + warning('ETOPO file has not been found! Please download the file at http://cromwell.marine.unc.edu/data/long_bay/etopo/etopo1_bed_c.flt and set etopo parameter in the files section in your artoa.ini'); +end + +end \ No newline at end of file diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/buttonToggleTopographicalTable.m b/lib/+artoa/+controller/+track/+trajectoryOutput/buttonToggleTopographicalTable.m new file mode 100644 index 0000000..770e21f --- /dev/null +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/buttonToggleTopographicalTable.m @@ -0,0 +1,18 @@ +function [] = buttonToggleTopographicalTable(~, ~) +%BUTTONDELETEALLTRAJECTORIES Summary of this function goes here +% Detailed explanation goes here + +global artoaGui; + +%% Show/hide topographical table + +if strcmp(artoaGui.trajectoryOutput.frameTopographicalLinesList.Visible, 'off') + artoaGui.trajectoryOutput.frameTopographicalLinesList.Visible = 'on'; + artoaGui.trajectoryOutput.frameTrackList.Visible = 'off'; +else + artoaGui.trajectoryOutput.frameTopographicalLinesList.Visible = 'off'; + artoaGui.trajectoryOutput.frameTrackList.Visible = 'on'; +end + +end + diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/checkboxTopographicalLines.m b/lib/+artoa/+controller/+track/+trajectoryOutput/checkboxTopographicalLines.m new file mode 100644 index 0000000..fadeef6 --- /dev/null +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/checkboxTopographicalLines.m @@ -0,0 +1,12 @@ +function [] = checkboxTopographicalLines(~, event) +%CHECKBOXUPDATETRACKPARAMETERWINDOW Summary of this function goes here +% Detailed explanation goes here + +global artoaWorkspace; + +artoaWorkspace.trajectoryOutput.showTopographicalLines = logical(event.Source.Value); + +artoa.controller.track.trajectoryOutput.plot(); + +end + diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m b/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m index 5da7a36..b7ec57c 100644 --- a/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m @@ -25,6 +25,11 @@ if artoa.data.hasMember(artoaGui, 'trajectoryOutput', 'textScatterFloatSatData') delete(artoaGui.trajectoryOutput.textScatterFloatSatData); end +%% Topographical lines +if artoa.data.hasMember(artoaGui, 'trajectoryOutput', 'contourTopographicalLines') + deleteHandles(artoaGui.trajectoryOutput.contourTopographicalLines); +end + %% Trajectories if artoa.data.hasMember(artoaGui, {'trajectoryOutput', 'trajectoryHandles'}) trajectories = artoaGui.trajectoryOutput.trajectoryHandles; @@ -48,6 +53,7 @@ for i = 1:length(trajectories) end end + function deleteHandles(pInput) if iscell(pInput) cellfun(@deleteHandles, pInput); diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/open.m b/lib/+artoa/+controller/+track/+trajectoryOutput/open.m index 8352b73..1d258bf 100644 --- a/lib/+artoa/+controller/+track/+trajectoryOutput/open.m +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/open.m @@ -2,7 +2,7 @@ function [] = open(~, ~) %OPEN Initializes the trajectory output gui. % -global artoaGui artoaWorkspace; +global artoaGui artoaWorkspace artoaConfig; %% Check if the gui is already opened @@ -20,9 +20,12 @@ callbacks.buttonDeleteSingle = @artoa.controller.track.trajectoryOutput.buttonDe callbacks.buttonDeleteAll = @artoa.controller.track.trajectoryOutput.buttonDeleteAllTrajectories; callbacks.checkboxTrueDistance = @artoa.controller.track.trajectoryOutput.checkboxTrueDistance; callbacks.checkboxTrackVisible = ''; +callbacks.checkboxShowTopographicalLines = @artoa.controller.track.trajectoryOutput.checkboxTopographicalLines; callbacks.buttonTrackInfos = ''; callbacks.buttonVelocities = ''; +callbacks.buttonToggleTopographicalTable = @artoa.controller.track.trajectoryOutput.buttonToggleTopographicalTable; callbacks.tableGeneratedTracksSelect = @artoa.controller.track.trajectoryOutput.tableGeneratedTracksSelect; +callbacks.tableTopographicalLinesEdit = @artoa.controller.track.trajectoryOutput.tableTopographicalLinesEdit; callbacks.checkboxUpdateTrackParameterWindow = @artoa.controller.track.trajectoryOutput.checkboxUpdateTrackParameterWindow; callbacks.checkboxShowPositionDates = @artoa.controller.track.trajectoryOutput.checkboxShowPositionDates; callbacks.checkboxSynchronizeZoomToaWindow = @artoa.controller.track.trajectoryOutput.checkboxSyncZoomToaWindow; @@ -37,9 +40,11 @@ if ~isfield(artoaWorkspace, 'trajectoryOutput') artoaWorkspace.trajectoryOutput = struct(); artoaWorkspace.trajectoryOutput.updateTrackParameterWindow = false; artoaWorkspace.trajectoryOutput.showPositionDates = true; + artoaWorkspace.trajectoryOutput.topographicalLines = artoaConfig.defaults.topographicalLines; artoaWorkspace.trajectoryOutput.enableMercatorProjection = false; artoaWorkspace.trajectoryOutput.syncZoomToaWindow = true; artoaWorkspace.trajectoryOutput.enableTrueDistance = false; + artoaWorkspace.trajectoryOutput.showTopographicalLines = false; end %% Add listener to sync zoom of TOA window @@ -93,6 +98,18 @@ if artoa.data.hasMember(artoaWorkspace, {'trajectoryOutput', 'syncZoomToaWindow' else artoaGui.trajectoryOutput.checkboxSynchronizeZoomToaWindow.Value = false; end +if artoa.data.hasMember(artoaWorkspace, {'trajectoryOutput', 'showTopographicalLines'}) + artoaGui.trajectoryOutput.checkboxShowTopographicalLines.Value = ... + artoaWorkspace.trajectoryOutput.showTopographicalLines; +else + artoaGui.trajectoryOutput.checkboxShowTopographicalLines.Value = false; +end +if artoa.data.hasMember(artoaWorkspace, {'trajectoryOutput', 'topographicalLines'}) + artoaGui.trajectoryOutput.tableTopographicalLines.Data = ... + artoaWorkspace.trajectoryOutput.topographicalLines; +else + artoaGui.trajectoryOutput.checkboxShowTopographicalLines.Value = false; +end %% Plot everything available artoa.controller.track.trajectoryOutput.plot(artoaWorkspace.trajectoryOutput.enableMercatorProjection); diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m b/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m index 54b6f0e..147202c 100644 --- a/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m @@ -138,5 +138,12 @@ for i = 1:length(trajectories) end end + +%% Plot topographic lines +if artoa.data.hasMember(artoaWorkspace, 'trajectoryOutput', 'showTopographicalLines') ... + & artoaWorkspace.trajectoryOutput.showTopographicalLines + artoaGui.trajectoryOutput.contourTopographicalLines = artoa.controller.track.trajectoryOutput.plotTopographicalLines(artoaGui.trajectoryOutput.axesTrajectoryOutput); +end + end diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/plotTopographicalLines.m b/lib/+artoa/+controller/+track/+trajectoryOutput/plotTopographicalLines.m new file mode 100644 index 0000000..d8ad114 --- /dev/null +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/plotTopographicalLines.m @@ -0,0 +1,39 @@ +function [topographicalLineHandles] = plotTopographicalLines(pAxesHandle) +%PLOTSOUNDSOURCELINES Summary of this function goes here +% Detailed explanation goes here + +global artoaWorkspace artoaDataInput; + +%% Load etopo + +artoa.controller.file.loadEtopoFile( ... + pAxesHandle.YLim, ... + pAxesHandle.XLim ... + ); + + +%% Plot topographical lines + +% make handle the current axes +axes(pAxesHandle); + +hold(pAxesHandle, 'on'); +topographicalLineHandles = cell(length(artoaWorkspace.trajectoryOutput.topographicalLines), 1); + +for o = 1:length(artoaWorkspace.trajectoryOutput.topographicalLines) + if isnan(artoaWorkspace.trajectoryOutput.topographicalLines{o}) + continue; + end + [~, topographicalLineHandles{o}] = contourm( ... + artoaDataInput.etopo.Z, ... + artoaDataInput.etopo.refvec, ... + [artoaWorkspace.trajectoryOutput.topographicalLines{o}, artoaWorkspace.trajectoryOutput.topographicalLines{o}], ... + 'ShowText', 'on', ... + 'LabelSpacing', 400 ... + ); +end + +hold(pAxesHandle, 'off'); + +end + diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/tableTopographicalLinesEdit.m b/lib/+artoa/+controller/+track/+trajectoryOutput/tableTopographicalLinesEdit.m new file mode 100644 index 0000000..4a69734 --- /dev/null +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/tableTopographicalLinesEdit.m @@ -0,0 +1,39 @@ +function [] = tableTopographicalLinesEdit(~, ~) +%UPDATETABLEGENERATEDTRACKS Summary of this function goes here +% Detailed explanation goes here + +global artoaGui artoaWorkspace; + +%% Save to workspace +artoaWorkspace.trajectoryOutput.topographicalLines = artoaGui.trajectoryOutput.tableTopographicalLines.Data; + +%% Plot if required +if ~artoaWorkspace.trajectoryOutput.showTopographicalLines + return; +end + +if artoa.data.hasMember(artoaGui, 'trajectoryOutput', 'contourTopographicalLines') + deleteHandles(artoaGui.trajectoryOutput.contourTopographicalLines); +end + +artoaGui.trajectoryOutput.contourTopographicalLines = ... + artoa.controller.track.trajectoryOutput.plotTopographicalLines( ... + artoaGui.trajectoryOutput.axesTrajectoryOutput ... + ); + +%% Helper function + + function deleteHandles(pInput) + if iscell(pInput) + cellfun(@deleteHandles, pInput); + end + if isstruct(pInput) + structfun(@deleteHandles, pInput); + end + if ishandle(pInput) + delete(pInput); + end + end + +end + diff --git a/lib/+artoa/+gui/+track/trajectoryOutput.m b/lib/+artoa/+gui/+track/trajectoryOutput.m index 47be370..eabf818 100644 --- a/lib/+artoa/+gui/+track/trajectoryOutput.m +++ b/lib/+artoa/+gui/+track/trajectoryOutput.m @@ -15,8 +15,11 @@ availableCallbacks = { ... 'checkboxTrueDistance'... 'checkboxTrackVisible', ... 'tableGeneratedTracksSelect', ... + 'tableTopographicalLinesEdit', ... 'checkboxShowPositionDates', ... 'checkboxSynchronizeZoomToaWindow', ... + 'checkboxShowTopographicalLines', ... + 'buttonToggleTopographicalTable', ... 'checkboxUpdateTrackParameterWindow' ... }; @@ -254,6 +257,15 @@ artoaGui.trajectoryOutput.checkboxUpdateTrackParameterWindow = uicontrol( ... 'CallBack', pCallbacks.checkboxUpdateTrackParameterWindow ... ); +artoaGui.trajectoryOutput.buttonToggleTopographicalTable = uicontrol( ... + 'Parent', artoaGui.trajectoryOutput.frameGenericOptions, ... + 'String', 'Toggle Topo Editor', ... + 'Style', 'PushButton', ... + 'FontSize', 8, ... + 'Units', 'normalized', ... + 'Position', [.1 .1 .8 .3], ... + 'CallBack', pCallbacks.buttonToggleTopographicalTable ... +); %% Display options @@ -305,6 +317,36 @@ artoaGui.trajectoryOutput.checkboxSynchronizeZoomToaWindow = uicontrol( ... 'CallBack', pCallbacks.checkboxSynchronizeZoomToaWindow ... ); +artoaGui.trajectoryOutput.checkboxShowTopographicalLines = uicontrol( ... + 'Parent', artoaGui.trajectoryOutput.frameDisplayOptions, ... + 'String', 'Topographical Lines', ... + 'Style', 'CheckBox', ... + 'FontSize', 8, ... + 'Units', 'normalized', ... + 'Position', [.1 .4 .8 .175], ... + 'CallBack', pCallbacks.checkboxShowTopographicalLines ... +); + +%% Topographical line table +artoaGui.trajectoryOutput.frameTopographicalLinesList = uipanel( ... + 'Title', 'Topographical lines', ... + 'Units', 'normalized', ... + 'BackgroundColor', 'white', ... + 'Position', [rightSidebarLeft, .675, rightSidebarWidth, .3], ... + 'Visible', 'off' ... +); + +artoaGui.trajectoryOutput.tableTopographicalLines = uitable( ... + artoaGui.trajectoryOutput.frameTopographicalLinesList, ... + 'Units', 'normalized', ... + 'Position', [.05, .05, .9, .9], ... + 'Data', cell(3, 1), ... + 'ColumnName', {'Depth'}, ... + 'ColumnEditable', true, ... + 'ColumnWidth', {160}, ... + 'CellEditCallback', pCallbacks.tableTopographicalLinesEdit ... +); + %% Set current axes to trajectory output artoaGui.figures.trajectoryOutput.CurrentAxes = artoaGui.trajectoryOutput.axesTrajectoryOutput; diff --git a/lib/+artoa/+versioning/+migrations/versions/v4226.m b/lib/+artoa/+versioning/+migrations/versions/v4226.m new file mode 100644 index 0000000..c01f3c2 --- /dev/null +++ b/lib/+artoa/+versioning/+migrations/versions/v4226.m @@ -0,0 +1,14 @@ +%% Add topographical switch if required + +if ~artoa.data.hasMember(artoaWorkspace, 'trajectoryOutput', 'showTopographicalLines') + artoaWorkspace.trajectoryOutput.showTopographicalLines = false; +end + +%% Add defaults for topographical lines if required +if ~artoa.data.hasMember(artoaConfig, 'defaults', 'topographicalLines') + artoaConfig.defaults.topographicalLines = { ... + -1000; ... + -2000; ... + -3000 ... + }; +end \ No newline at end of file -- GitLab