function [dout,mout,sout] = dms2mat(dms,n) % DMS2MAT Converts a dms vector format to a [deg min sec] matrix % % [d,m,s] = DMS2MAT(dms) converts a dms vector format to a % deg:min:sec matrix. The vector format is dms = 100*deg + min + sec/100. % This allows compressed dms data to be expanded to a d,m,s triple, % for easier reporting and viewing of the data. % % [d,m,s] = DMS2MAT(dms,n) uses n digits in the accuracy of the % seconds calculation. n = -2 uses accuracy in the hundredths position, % n = 0 uses accuracy in the units position. Default is n = -5. % For further discussion of the input n, see ROUNDN. % % mat = DMS2MAT(...) returns a single output argument of mat = [d m s]. % This is useful only if the input dms is a single column vector. % % See also MAT2DMS % Written by: E. Byrns, E. Brown % Revision: 1.10 $Date: 2002/03/20 21:25:06 % % GNSS-SDR is a Global Navigation Satellite System software-defined receiver. % This file is part of GNSS-SDR. % % SPDX-FileCopyrightText: 1996-2002 Systems Planning and Analysis, Inc. and The MathWorks, Inc. % SPDX-License-Identifier: GPL-3.0-or-later if nargin == 0 error('Incorrect number of arguments') elseif nargin == 1 n = -5; end % Test for empty arguments if isempty(dms); dout = []; mout = []; sout = []; return; end % Test for complex arguments if ~isreal(dms) warning('Imaginary parts of complex ANGLE argument ignored') dms = real(dms); end % Don't let seconds be rounded beyond the tens place. % If you did, then 55 seconds rounds to 100, which is not good. if n == 2; n = 1; end % Construct a sign vector which has +1 when dms >= 0 and -1 when dms < 0. signvec = sign(dms); signvec = signvec + (signvec == 0); % Ensure +1 when dms = 0 % Decompress the dms data vector dms = abs(dms); d = fix(dms/100); % Degrees m = fix(dms) - abs(100*d); % Minutes [s,msg] = roundn(100*rem(dms,1),n); % Seconds: Truncate to roundoff error if ~isempty(msg); error(msg); end % Adjust for 60 seconds or 60 minutes. % Test for seconds > 60 to allow for round-off from roundn, % Test for minutes > 60 as a ripple effect from seconds > 60 indx = find(s >= 60); if ~isempty(indx); m(indx) = m(indx) + 1; s(indx) = s(indx) - 60; end indx = find(m >= 60); if ~isempty(indx); d(indx) = d(indx) + 1; m(indx) = m(indx) - 60; end % Data consistency checks if any(m > 59) | any (m < 0) error('Minutes must be >= 0 and <= 59') elseif any(s >= 60) | any( s < 0) error('Seconds must be >= 0 and < 60') end % Determine where to store the sign of the angle. It should be % associated with the largest nonzero component of d:m:s. dsign = signvec .* (d~=0); msign = signvec .* (d==0 & m~=0); ssign = signvec .* (d==0 & m==0 & s~=0); % In the application of signs below, the comparison with 0 is used so that % the sign vector contains only +1 and -1. Any zero occurrences causes % data to be lost when the sign has been applied to a higher component % of d:m:s. Use fix function to eliminate potential round-off errors. d = ((dsign==0) + dsign).*fix(d); % Apply signs to the degrees m = ((msign==0) + msign).*fix(m); % Apply signs to minutes s = ((ssign==0) + ssign).*s; % Apply signs to seconds % Set the output arguments if nargout <= 1 dout = [d m s]; elseif nargout == 3 dout = d; mout = m; sout = s; else error('Invalid number of output arguments') end