Calculate the length of a trajectory over earth - Matlab - matlab

I have a trajectory defined in Lat/Long coordinates in "n" points. I need to estimate its length over the surface of the earth:
Lat = [la1 la2 la3 la4 la5 la6];
Lon = [lo1 lo2 lo3 lo4 lo5 lo6];
How can I do this in Matlab? I've tried to use the command distance, but it seems it doesn't do this?
Thanks!

[arclen,az] = distance(lat1,lon1,lat2,lon2)
[arclen,az] = distance(lat1,lon1,lat2,lon2,ellipsoid)
Check the matlab documentation
Something similar to this shouldn't be very hard to write:
sum = 0;
for i=1:(size(Lat)-1)
sum = sum + distance(Lat(i),Lon(i),Lat(i+1),Lon(i+1));
//end (Sorry I haven't used matlab in over a year, and forgot the syntax)

Related

Extracting data from array (interpolation)

I need some advice regarding a problem I encountered in MATLAB:
I have 4 variables, I'm not sure what is the best methodology to go about doing this. I initially thought about just computing the GreatCircle distance from each grid point to the specified location and return the corresponding row/column index that has the minimum distance. But doing it this way, I'm not sure how I can compute the interpolation.
I tried reshaping the data into a vector data of 4 columns and running meshgrid to possibly utilize interp2. But I ended up with this error:
Requested 109620x109620 (44.8GB) array exceeds maximum array size preference
What could be the most efficient way to do this?
You are working on large arrays. If interp2 cannot handle it, work on a subarray instead:
% Create data
format shortG
[Latitude,Longitude] = meshgrid(1:12,1:12);
Altitude = floor(1000+sortrows(rand(12,12))*1000);
Temperature = 10+20*rand(12,12);
Lat = 2.1;
Lon = 11.8;
% Find closest match point
[~,i_Lat] = min(abs(Latitude(1,:)-Lat));
[~,i_Lon] = min(abs(Longitude(:,1)-Lon));
% Select subarrays around this point.
% Minimum size of these matrices depend on the type of interpolation you perform
ia1 = max(1,i_Lat-5);
ia2 = min(size(Latitude,1),i_Lat+5);
io1 = max(1,i_Lon-5);
io2 = min(size(Latitude,2),i_Lon+5);
subLatitude = Latitude(io1:io2,ia1:ia2);
subLongitude = Longitude(io1:io2,ia1:ia2);
subAltitude = Altitude(io1:io2,ia1:ia2);
subTemperature = Temperature(io1:io2,ia1:ia2);
% Interpolate on these small arrays, and evaluate at target (Lat, Lon) point
A_out = interp2(subLatitude, subLongitude, subAltitude, Lat, Lon)
T_out = interp2(subLatitude, subLongitude, subTemperature, Lat, Lon)

How to see the algorithm of the defaultm projection

I'm doing a research about map projections. I use this script:
koordinat = [0 102;...
0 103.5;...
-1 103.5;...
-1 102];
lat = koordinat(:,1);
lon = koordinat(:,2);
mstruct = defaultm('utm');
mstruct.geoid = referenceEllipsoid('wgs84','meters');
mstruct.zone = utmzone(koordinat);
mstruct = defaultm(mstruct);
[x,y] = mfwdtran (mstruct,lat,lon);
format long g
luas = polyarea(x,y)
By using the "defaultm" and "mfwdtran" function, I can calculate the projected coordinate. Buut, my fellow researcher is feeling doubtful about these 2 Matlab functions. Do you know how to see the script of these two functions?
I already opened the defaultm.m and mfwdtran.m, but I didn't see anything like an m-file from mathworks.com called "deg2utm.m".
Any suggestion will helps.
Thank you

Summing Values based on Area in Matlab

Im trying to write a code in Matlab to calculate an area of influence type question. This is an exert from my data (Weighting, x-coord, y-coord):
M =
15072.00 486.00 -292
13269.00 486.00 -292
12843.00 414.00 -267
10969.00 496.00 -287
9907.00 411.00 -274
9718.00 440.00 -265
9233.00 446.00 -253
9138.00 462.00 -275
8830.00 496.00 -257
8632.00 432.00 -253
R =
-13891.00 452.00 -398
-13471.00 461.00 -356
-12035.00 492.00 -329
-11309.00 413.00 -353
-11079.00 467.00 -375
-10659.00 493.00 -333
-10643.00 495.00 -338
-10121.00 455.00 -346
-9795.00 456.00 -367
-8927.00 485.00 -361
-8765.00 467.00 -351
I want to make a function to calculate the sum of the weightings at any given position based on a circle of influence of 30 for each coordinate.
I have thought of using a for loop to calculate each point independently and summing the result but seems unnecessarily complicated and inefficient.
I also thought of assigning an intensity of color to each circle and overlaying them but I dont know how to change color intensity based on value here is my attempt so far (I would like to have a visual of the result):
function [] = Influence()
M = xlsread('MR.xlsx','A4:C310');
R = xlsread('MR.xlsx','E4:G368');
%these are my values around 300 coordinates
%M are negative values and R positive, I want to see which are dominant in their regions
hold on
scatter(M(:,2),M(:,3),3000,'b','filled')
scatter(R(:,2),R(:,3),3000,'y','filled')
axis([350 650 -450 -200])
hold off
end
%had to use a scalar of 3000 for some reason as it isnt correlated to the graph size
I'd appreciate any ideas/solutions thank you
This is the same but with ca. 2000 data points
How about this:
r_influence = 30; % radius of influence
r = #(p,A) sqrt((p(1)-A(:,2)).^2 + (p(2)-A(:,3)).^2); % distance
wsum = #(p,A) sum(A(find(r(p,A)<=r_influence),1)); % sum where distance less than roi
% compute sum on a grid
xrange = linspace(350,550,201);
yrange = linspace(-200,-450,201);
[XY,YX] = meshgrid(xrange,yrange);
map_M = arrayfun(#(p1,p2) wsum([p1,p2],M),XY,YX);
map_R = arrayfun(#(p1,p2) wsum([p1,p2],R),XY,YX);
figure(1);
clf;
imagesc(xrange,yrange,map_M + map_R);
colorbar;
Gives a picture like this:
Is that what you are looking for?

To calculate the length of a curve on the image

Given the data of the curve and the size of the image, how to calculate the length of the curve ?
curve = [9.93,4;9.87,4.10;9.80,4.20;9.74,4.30;9.68,4.40;9.63,4.50;9.59,4.60;9.55,4.70;9.53,4.80;9.51,4.90;9.50,5;9.50,5.10;9.51,5.20;9.48,5.30;9.55,5.40;9.45,5.47;9.55,5.52;9.45,5.59;9.55,5.65;9.45,5.72;9.55,5.77;9.45,5.84;9.55,5.90];
backgroud = ones(20,20);
imshow(backgroud)
hold on, plot(curve(2,:),curve(1,:),'r');
To expand on the comment, you can simply sum the lengths of the line segments that make up the curve. This could be accomplished using the following code.
curve = [9.93,4;9.87,4.10;9.80,4.20;9.74,4.30;9.68,4.40;9.63,4.50;9.59,4.60;9.55,4.70;9.53,4.80;9.51,4.90;9.50,5;9.50,5.10;9.51,5.20;9.48,5.30;9.55,5.40;9.45,5.47;9.55,5.52;9.45,5.59;9.55,5.65;9.45,5.72;9.55,5.77;9.45,5.84;9.55,5.90];
len = sum(sqrt(sum(diff(curve).^2,2)))
result
len =
2.4757
Edit: As beaker pointed out, the indices are backwards in your answer. Take a look at the values of curve_x1, curve_x2, etc... and you will see that they are just a single value. If you reverse the indices we get the same result. Also, as a sanity check take a look at the plot of the curve, it spans about 2 units in the first dimension and about 0.4 units in the second dimension so a number near 2.5 seems reasonable, a number like around 8 is much too large.
curve_x1 = num2cell(curve(1:end-1,1));
curve_y1 = num2cell(curve(1:end-1,2));
curve_x2 = num2cell(curve(2:end,1));
curve_y2 = num2cell(curve(2:end,2));
instance_length = cellfun(#(x1,y1,x2,y2) sqrt((x2-x1)^2+(y2-y1)^2), curve_x1,curve_y1,curve_x2,curve_y2);
distance = sum(instance_length)

why is the vector coming out of 'trapz' function as NAN?

i am trying to calculate the inverse fourier transform of the vector XRECW. for some reason i get a vector of NANs.
please help!!
t = -2:1/100:2;
x = ((2/5)*sin(5*pi*t))./((1/25)-t.^2);
w = -20*pi:0.01*pi:20*pi;
Hw = (exp(j*pi.*(w./(10*pi)))./(sinc(w./(10*pi)))).*(heaviside(w+5*pi)-heaviside(w-5*pi));%low pass filter
xzohw = 0;
for q=1:20:400
xzohw = xzohw + x(q).*(2./w).*sin(0.1.*w).*exp(-j.*w*0.2*((q-1)/20)+0.5);%calculating fourier transform of xzoh
end
xzohw = abs(xzohw);
xrecw = abs(xzohw.*Hw);%filtering the fourier transform high frequencies
xrect=0;
for q=1:401
xrect(q) = (1/(2*pi)).*trapz(xrecw.*exp(j*w*t(q))); %inverse fourier transform
end
xrect = abs(xrect);
plot(t,xrect)
Here's a direct answer to your question of "why" there is a nan. If you run your code, the Nan comes from dividing by zero in line 7 for computing xzohw. Notice that w contains zero:
>> find(w==0)
ans =
2001
and you can see in line 7 that you divide by the elements of w with the (2./w) factor.
A quick fix (although it is not a guarantee that your code will do what you want) is to avoid including 0 in w by using a step which avoids zero. Since pi is certainly not divisible by 100, you can try taking steps in .01 increments:
w = -20*pi:0.01:20*pi;
Using this, your code produces a plot which might resemble what you're looking for. In order to do better, we might need more details on exactly what you're trying to do, or what these variables represent.
Hope this helps!