converting degrees minutes seconds to decimal degrees adds too much precision - coordinates

I'm converting coordinates from degrees minutes seconds to decimal degrees. However, in the process of converting, the resulting coordinates are much more precise than they should be.
How can I correctly incorporate the lack of precision?
For example, some coordinates lacking seconds:
143 DEG 10 MIN W, 28 DEG 25 MIN N
To convert, I would do the following:
143.1667 <- 143 + 10/60
28.41667 <- 28 + 25/60
But really, the longitude could be anywhere from:
143.1667 <- 143 + 10/60 + 0/3600
to
143.1831 <- 143 + 10/60 + 59/3600
It seems like I should be rounding these coordinates so that they do not convey artificial precision...

You can round it just like this:
double roundedValue = Math.floor(unroundedValue * 10) / 10;
// 123.456 --> 123.4
If you use "100" instead of "10", you will get a a precision of two digits.

Related

affine transformation and `imtransform`

I am trying to follow this MATLAB example.
Please see Step 2, the example used a 128 * 27 matrix M2, and use affine transform to scale and rotate M2, the scale factor is 2.5. However, I expect the size of the result should be 67.5 * 128 (since 27 * 2.5 = 67.5, I do not think it works, but I have no idea how to handle double in this case), the actual result done by MATLAB is 66 * 128.
How to derive the 66 in this case?
I tried to change the scale factor to 2, and the result is 53 * 128, and I expect it to be 54 * 128 since 27 * 2 = 54.
load mri
M1 = D(:,64,:,:);
M2 = reshape(M1,[128 27]);
T0 = maketform('affine',[0 -2.5; 1 0; 0 0]);
res = imtransform(M2,T0,'cubic')
size(res) // 66 * 128
A matrix with 27 elements has coordinates going from 0 through 26 (these are the coordinates used by imtransform). After scaling by 2.5, these coordinates go from 0 through 26*2.5 = 65. To hold x-coordinates from 0 through 65 you need 66 elements.

Matlab repeating x-axis for interpolation

I have to interpolate wind directions. The data is given for every 1000 [ft]. for example:
%winddata input in feet en degrees
x=0:1000:10000;
grad=[340 350 360 1 10 20 30 35 34 36 38];
The interpolation works great, i use the function interp1. (please see code below.) However, the step from 360 degrees to 1 degrees is a problem. I want Matlab to interpolate from 360 to 1 degree directly (clockwise), instead of anticlockwise with the values degreasing from 360-359-358-...3-2-1. That doesnt make sense when you interpolate wind directions.
How can i command Matlab to repeate the x-axis and values every 360 degrees?
clear all;clc;
h=2000;
%winddata input in feet en degrees!
x=0:1000:10000;
degrees=[340 350 360 1 10 20 30 35 34 36 38];
%conversion to SI:
x=0.3048*x;
u=0:1:max(x);
yinterp1 = interp1(x,degrees,u,'linear');
figure(3)
plot(degrees,x,'bo',yinterp1,u,'-r')
xlabel('wind direction [degrees]')
ylabel('height [m]')
title 'windspeed lineair interpolated with function interp'
The problem is that Matlab, as smart as it is, doesn't realise that you're working with degrees, so therefore it sees no reason that 360 = 0. Therefore I believe your problem isn't with finding a way to repeat the plot every 360 degrees, but rather with the data you are feeding in to your interp1 function, as currently you are telling it there is a straight line between the points (0, 950) and (360, 750).
The easiest, but ugliest, method would be to just add 360 to your lower values, so your degrees vector read:
degrees = [340 350 360 361 370 380 390 395 394 396 398];
and then subtract 360 from your degrees and yinterp1 vectors:
clear all;clc;
h=2000;
%winddata input in feet en degrees!
x=0:1000:10000;
degrees=[340 350 360 361 370 380 390 395 394 396 398];
%conversion to SI:
x=0.3048*x;
u=0:1:max(x);
yinterp1 = interp1(x,degrees,u,'linear');
figure(3)
plot(degrees-360,x,'bo',yinterp1-360,u,'-r')
xlabel('wind direction [degrees]')
ylabel('height [m]')
title 'windspeed lineair interpolated with function interp'
xlim([-180 180]);
The obvious problem with this is it isn't able to be applied for all cases, but if you just need a one off, then it works well.
For a more generic solution you could have it so you manually enter a point below which values have 360 added to them:
clear all;clc;
h=2000;
% --------------------- Manual cutoff for rectification -------------------
limitDegrees = 180;
% -------------------------------------------------------------------------
%winddata input in feet en degrees!
x=0:1000:10000;
degrees=[340 350 360 1 10 20 30 35 34 36 38];
%conversion to SI:
x=0.3048*x;
u=0:1:max(x);
indecesTooSmall = find(degrees <= limitDegrees);
oneVec = zeros(size(degrees));
oneVec(indecesTooSmall) = 1;
vecToAdd = 360*ones(size(degrees));
vecToAdd = vecToAdd .* oneVec;
newDegrees = degrees + vecToAdd;
yinterp1 = interp1(x,newDegrees,u,'linear');
figure(3)
plot(newDegrees-360,x,'bo',yinterp1-360,u,'-r')
xlabel('wind direction [degrees]')
ylabel('height [m]')
title 'windspeed lineair interpolated with function interp'
xlim([-180 180]);
Both of the above solutions give the following:
EDIT: Substantially easier solution, just use rad2deg(unwrap(deg2rad(degrees))), or try to find an unwrap which works for degrees.

Matlab 3D polar plot

I am struggling with the concepts behind plotting a surface polar plot.
I am trying to plot the values measured by a sensor at a combination of different angles over a hemisphere.
I have an array containing the following information:
A(:,1) = azimuth values from 0 to 360º
A(:,2) = zenith values from 0 to 90º
A(:,3) = values measured at the combination of angles of A(:,1) and A(:,2)
For example, here is a snippet:
0 15 0.489502132167206
0 30 0.452957556748497
0 45 0.468147850273115
0 60 0.471115818950192
0 65 0.352532182508945
30 15 0.424997863795610
30 30 0.477814980942155
30 45 0.383999653859467
30 60 0.509625464595446
30 75 0.440940431784788
60 15 0.445028058361392
60 30 0.522388502880219
60 45 0.428092266657885
60 60 0.429315072676194
60 75 0.358172892912138
90 15 0.493704001125912
90 30 0.508762762699997
90 45 0.450598496609200
90 58 0.468523071441297
120 15 0.501619699042408
120 30 0.561755273071577
120 45 0.489660355057938
120 60 0.475478615354648
120 75 0.482572226928475
150 15 0.423716506205776
150 30 0.426735372570756
150 45 0.448548968227972
150 60 0.478055144126694
150 75 0.437389584937356
To clarify, here is a piece of code that shows the measurement points on a polar plot.
th = A(:,1)*pi/180
polar(th,A(:,2))
view([180 90])
This gives me the following plot:
I would like now to plot the same thing, but instead of the points, use the values of these points stored in A(:,3). Then, I would like to interpolate the data to get a colored surface.
After some research, I found that I need to interpolate my values over a grid, then translate to Cartesian coordinates. From there I do not know how to proceed. Could someone point me in the right direction?
I have trouble getting the concept of the interpolation, but this is what I have attempted:
x1 = linspace(0,2*pi,100)
x2 = linspace(0,90,100)
[XX,YY] = meshgrid(x1,x2)
[x,y] = pol2cart(th,A(:,2))
gr=griddata(x,y,A(:,3),XX,YY,'linear')
With this piece of code, your example data points are converted into cartesian coords, and then plotted as "lines". The two tips of a line are one data point and the origin.
az = bsxfun(#times, A(:,1), pi/180);
el = bsxfun(#times, A(:,2), pi/180);
r = A(:,3);
[x,y,z] = sph2cart(az,el,r);
cx = 0; % center of the sphere
cy = 0;
cz = 0;
X = [repmat(cx,1,length(x));x'];
Y = [repmat(cy,1,length(y));y'];
Z = [repmat(cz,1,length(z));z'];
Still thinking how to interpolate the data so you can draw a sphere. See my comments to your question.

Which coordinate format is this?

How to split these coordinates to degrees, minutes and seconds?
E0732931.00 and N30 2025.20
Is it 73 degrees, 29 mins and 31 seconds. To convert it to decimal degree, i have to
73+39/60+31/3600?
N30 2025.20 is 30 degs, 20 minutes, 25 seconds? What is the value after the decimal?
2nd i want to ask that is there any coordinate system which uses 100 seconds in a minute, i.e.
decimal degrees = 73+39/60+31/(60*100) ???
Your asumption are correct.
Further:
What is the value after the decimal?
the fraction of seconds: so 25.20 seconds
is there any coordinate system which uses 100 seconds in a minute, i.e.
No! There are other systems like DM which uses Degrees and decimal minutes: e.g 23 deg 17.1234 minutes

Converting numbers between Number Bases

I'm working on a program that converts between number bases. For example Octal is 8, decimal is 10. Letters A to Z could be considered as base 26.
I want to convert a number like "A" into 0, Z into 25, "AA" into 27 and "BA" into 53.
Before I start coding I'm doing it on paper so I understand the process. To start out I'm trying to convert 533 to base 26.
What algorithm is best for doing this?
You need to assign a "digit" to each letter, like:
A = 0 N = 13
B = 1 O = 14
C = 2 P = 15
D = 3 Q = 16
E = 4 R = 17
F = 5 S = 18
G = 6 T = 19
H = 7 U = 20
I = 8 V = 21
J = 9 W = 22
K = 10 X = 23
L = 11 Y = 24
M = 12 Z = 25
Then, your {20,13} becomes UN.
Converting back is UN -> {20,13} -> (20 * 26 + 13) -> 52.
By way of further example, let's try the number 10163, just plucked out of the air at random.
Divide that by 26 until you get a number less than 26 (i.e., twice), and you get 15 with a fractional part of 0.03402366.
Multiply that by 26 and you get 0 with a fractional part of 0.88461516.
Multiply that by 26 and you get 23 (actually 22.99999416 on my calculator but, since the initial division was only two steps, we stop here - the very slight inaccuracy is due to the fact that the floating point numbers are being rounded).
So the "digits" are {15,0,23} which is the "number" PAX. Wow, what a coincidence?
To convert PAX back into decimal, its
P * 262 + A * 261 + X * 260
or
(15 * 676) + (0 * 26) + 23
= 10140 + 0 + 23
= 10163
Let's take a step back for a second, and look at decimal.
What does a number like "147" mean? Or rather, what do the characters '1', '4' and '7', when arranged like that, indicate?
There are ten digits in decimal, and after that, we add another digit to the left of the first, and so on as our number increases. So after "9" = 9*1, we get "10" = 1*10 + 0*1. So "147" is 1*10^2 + 4*10 + 7*1 = 147. Similarly, we can go backwards - 147/10^2 = 1, which maps to the character '1'. (147 % 10^2) / 10 = 4, which maps to the character '4'. And 147 % 10 = 7, which maps to the character '7'.
This works works for any base N - if we get the number 0, that maps to the first character in our set. The number 1 maps to the second character, and so on until the number N-1 maps to the last character in our set of digits.
You convert 20 and 13 to the symbols that represent 20 and 13 in your base 26 notation. It sounds like you are using the letters of the alphabet so, that would be UN (where A is 0 and Z is 25).
What language are you writing this in? If you're doing this in Perl you can use the CPAN module Math::Fleximal that I wrote many years ago while I was bored. If you're using a language with infinite precision integers, then life becomes much easier. All you have to do is take characters, convert them into an array of integers, then do the calculation to turn that into a number.