mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-02-08 23:20:12 +00:00
110 lines
3.4 KiB
Matlab
110 lines
3.4 KiB
Matlab
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
|