diff --git a/VERSION b/VERSION index bcad85486c9cd9d18f67e21823dd267b0cb2a00e..0e4c1b3f9084417d02e8328b44ec4bae13645964 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 5b69e518251dd20c9e3ceb9186cc2c2479c09616..407107201bb279d454518241abb4e063bfe535cd 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 0000000000000000000000000000000000000000..7d0e148f0126a64e361b1a8f9c1dd4592c51eceb --- /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 0000000000000000000000000000000000000000..770e21f0ced058b0cc600d07825bf3f39f7d0227 --- /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 0000000000000000000000000000000000000000..fadeef6f87231bd4b0f338dfde1593e6b361e7c1 --- /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 5da7a3690a4e3d570b5c454322c484d0137b38b6..b7ec57c522e6788fe6943f5ac4e4b22173ae1e7a 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 8352b739ab7c35ddf21a555e0724c530765dd886..1d258bf42b7256a6d8fb658680ead0b85de001c6 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 54b6f0e4587dee88bfa4acbeb713522369af40f7..147202c05e0256d435c44eecf1fb2ef6e928acff 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 0000000000000000000000000000000000000000..d8ad11418658a3f4d066172f0a1e441f679ad00e --- /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 0000000000000000000000000000000000000000..4a697344e2d8d4b231f652210421eb90bb02bb96 --- /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 47be3702536ddfc6763dc613377aa23870b247f2..eabf8183f0700124d2fa2c778d0fd500ee289d21 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 0000000000000000000000000000000000000000..c01f3c2f4f2ccd0c73bd3f8b5e652a276e673ba8 --- /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