function [x, y, z] = geodetic2ecefFormula(spheroid, phi, lambda, h, inDegrees)
%Transform geodetic to geocentric (ECEF) coordinates
%
%   The outputs are the same as in GEODETIC2ECEF. The inputs are also the same,
%   except that the angleUnit string is replaced by logical scalar,
%   inDegrees, which is true when LAT0 and LON0 are in degrees and false
%   when they are in radians.

% Copyright 2019-2020 The MathWorks, Inc.

%#codegen

% Reference
% ---------
% Paul R. Wolf and Bon A. Dewitt, "Elements of Photogrammetry with
% Applications in GIS," 3rd Ed., McGraw-Hill, 2000 (Appendix F-3).

    if isobject(spheroid)
        coder.ignoreCatch
        try %#ok<EMTC>
            % When numel(spheroid) > 0 (but it has properties a and
            % Flattening), the following throws a MATLAB:TooManyInputs
            % error, because spheroid.a and spheroid.Flattening each
            % contribute 2 or more elements to the comma-separated inputs.
            [rho, z] = geodetic2cylindrical(phi, h, spheroid.a, spheroid.Flattening, inDegrees);
        catch e
            if ~isscalar(spheroid) || ~isa(spheroid,'map.geodesy.Spheroid')
                error(message('geodesy:spheroid:ExpectedScalarSpheroid',upper('spheroid')))
            else
                % Just in case ...
                rethrow(e)
            end
        end
    else
        [a, f] = semimajorAxisAndFlattening(spheroid);
        [rho, z] = geodetic2cylindrical(phi, h, a, f, inDegrees);
    end
    if inDegrees
        x = rho .* cosd(lambda);
        y = rho .* sind(lambda);
    else
        x = rho .* cos(lambda);
        y = rho .* sin(lambda);
    end
end


function [rho, z] = geodetic2cylindrical(phi, h, a, f, inDegrees)
    if f == 0
        r = h + a;
        if inDegrees
            rho = r .* cosd(phi);
            z = r .* sind(phi);
        else
            rho = r .* cos(phi);
            z = r .* sin(phi);
        end
    else
        [rho, z] = map.geodesy.internal.geodetic2cylindrical(phi, h, a, f, inDegrees);
    end
end
