1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| function [km nmi mi] = haversine(loc1, loc2
% If two inputs are given, display error
if ~isequal(nargin, 2)
error('User must supply two location inputs')
% If two inputs are given, handle data
else
locs = {loc1 loc2}; % Combine inputs to make checking easier
% Cycle through to check both inputs
for i = 1:length(locs)
% Check inputs and convert to decimal if needed
if ischar(locs{i})
% Parse lat and long info from current input
temp = regexp(locs{i}, ',', 'split');
lat = temp{1}; lon = temp{2};
clear temp
locs{i} = []; % Remove string to make room for array
% Obtain degrees, minutes, seconds, and hemisphere
temp = regexp(lat, '(\d+)\D+(\d+)\D+(\d+)(\w?)', 'tokens');
temp = temp{1};
% Calculate latitude in decimal degrees
locs{i}(1) = str2double(temp{1}) + str2double(temp{2})/60 + ...
str2double(temp{3})/3600;
% Make sure hemisphere was given
if isempty(temp{4})
error('No hemisphere given')
% If latitude is south, make decimal negative
elseif strcmpi(temp{4}, 'S')
locs{i}(1) = -locs{i}(1);
end
clear temp
% Obtain degrees, minutes, seconds, and hemisphere
temp = regexp(lon, '(\d+)\D+(\d+)\D+(\d+)(\w?)', 'tokens');
temp = temp{1};
% Calculate longitude in decimal degrees
locs{i}(2) = str2double(temp{1}) + str2double(temp{2})/60 + ...
str2double(temp{3})/3600;
% Make sure hemisphere was given
if isempty(temp{4})
error('No hemisphere given')
% If longitude is west, make decimal negative
elseif strcmpi(temp{4}, 'W')
locs{i}(2) = -locs{i}(2);
end
clear temp lat lon
end
end
end
% Check that both cells are a 2-valued array
if any(cellfun(@(x) ~isequal(length(x),2), locs))
error('Incorrect number of input coordinates')
end
% Convert all decimal degrees to radians
locs = cellfun(@deg2rad, locs, 'UniformOutput', 0);
%% Begin calculation
R = 6371; % Earth's radius in km
delta_lat = locs{2}(1) - locs{1}(1); % difference in latitude
delta_lon = locs{2}(2) - locs{1}(2); % difference in longitude
a = sin(delta_lat/2)^2 + cos(locs{1}(1)) * cos(locs{2}(1)) * ...
sin(delta_lon/2)^2;
c = 2 * atan2(sqrt(a), sqrt(1-a));
km = R * c; % distance in km
%% Convert result to nautical miles and miles
nmi = km * 0.539956803; % nautical miles
mi = km * 0.621371192; % miles |
Partager