Add distance to a latitude or longitude - database

Say I have a latitude of 38.802610 and a longitude of -116.419389 and I want to be able to add a distance to that, 20 miles for example.
So far I have came up with a rough idea on how I would do this
Firstly, work out how many miles are in 1° of latitude, say for example it was 30
Then, divide one by it:
1 / 30 = 0.033333
Add it to my original latitude to get my maximum ° of latitude:
38.802610 + 0.033333 = 38.8355943
Subtract it to my original latitude to get my minimum ° of latitude:
38.802610 - 0.033333 = 38.769277
But this is flawed because there seems to be no direct conversion for longitude as from what I've read the calculation varies.
Ultimately, I need to be able to find out the:
maximum latitude (my current latitude + given distance e.g 20 miles)
minimum latitude (my current latitude - given distance e.g 20 miles)
maximum longitude (my current longitude + given distance e.g 20 miles)
minimum longitude (my current longitude - given distance e.g 20 miles)
Any help would be greatly appreciated, thank you.

Linear distances (e.g. 20 miles or 32186.88 m) cannot directly be converted to distances in degrees of latitude or longitude, since the Earth is not flat. However, there are two direct conversion you can try to project one point given a linear distance and azimuth to another point.
Method 1 is to assume a spherical Earth, using Movable Type's "destination point given distance and bearing from start point". The underling equations are described on the website. The difference of latitude is the same in North and South directions, and the difference of longitude is the same in East and West directions, so you can do a minimum of two calculations to determine all four min/max and lat/long combinations.
Method 2 is to assumes a spheroid Earth (also called an ellipsoid of revolution), and calculate a direct geodesic with GeographicLib, which has bindings to several programming languages. The difference of latitude is slightly different in North and South directions, but the same in East and West directions, so you can do a minimum of three calculations. Or just assume the difference in North or South directions is approximately the same and just do two calculations. This method has sub-millimetre accuracy.

Related

MATLAB: Calculate LatLon Distance out of array coordinates

I've got an 1700 x 3 array, with latitude, longitude and metres above sea level. Like this:
51.2551649606487 7.15089717516404 153.110000000000
51.2552453948075 7.15086528446721 150.160000000000
51.2552903318980 7.15086348124900 150.200000000000
I want to calculate the distance between successive Lat Lon Coordinates, using the Haversine formula, since i have no access to the MATLAB mapping toolbox( https://de.mathworks.com/matlabcentral/fileexchange/38812-latlon-distance).
My question is, how i should change the given code, to read all of the 1700 coordinates directly from my array?
I read/checked the following link: MATLAB function to calculate distance between two coordinates (latitude and longitude). But it doesn't tell me how to read all the 1700 coordinates from my array at once.
Thank you in advance for everybody who is willing to help me!
Best regards
If I understand the question correctly, you should be able to split the data into 3 1700 x 1 arrays: latitude, longitude, and elevation. Then apply the haversine formula on those three arrays. (Although the typical haversine function doesn't account for elevation)
coordinates; %1700 x 3 array
latitudes=coordinates(:,1);
longitudes=coordinates(:,2);
elevations=coordinates(:,3);
lat1=0; %coordinates to compare to
long1=0;
earthRadius=6371000;
a=sind((latitudes-lat1)./2).^2 + cosd(latitudes).*cosd(lat1).*sind((longitudes-long1)./2).^2;
c=atan2(sqrt(a),sqrt(1-a));
distances=c*earthRadius;%in meters

how to convert longitude and altitude to a grid with equal(nearly) area on the Earth sphere in Matlab or C/C++?

The range of longitude and latitude of Earth sphere are [-180, 180] and [-90, 90] respectively. I want to get equal area grids by 0.5 deg * 0.5 deg (area around the equator).
As the distortion increased when approaching the polar points. The grid should have the same latitude range but different longitude range.
How should I do?
First, what you ask got, if interpreted literally, is impossible for three reasons. One, the area of the surface of a perfect sphere is about 82506.97413 times the area of a portion 30' (thirty seconds, or half a degree) by 30' at the equator. Since that is not an integer, you cannot partition the surface into a whole number of regions of that size. Two, if you constrain the latitude span to be equal, then the rings at different latitudes must have different numbers of segments, so you cannot make a grid. The edges of segments in different rings cannot coincide. Three, the Earth is not a perfect sphere, and regions of equal area on a sphere will not map to equal areas on the Earth. Imperfections in the Earth would prevent us from knowing the area of each region (and those areas would change as the surface changes).
Supposing that what you actually want is an approximate solution that is not a grid, I suggest you examine the Google search results for “partition sphere into equal areas“. One of the top results is this paper, in which Figure 1.1 appears to show a sphere that has been partitioned into regions of similar, possibly equal, latitude span but different longitude spans. Another result is this page, which is a Matlab package for exploring sphere partitioning.
You are trying to put equal area tiles on the earth's surface with fixed extent like the mirrors on a disco ball.
So if you start at the Equator with a 0.5deg*0.5deg tile, your next tile to the north or south would have a longitude extent of 0.5deg/cos(0.5deg) to have the same area, so slightly above 0.5deg.
With that tile you cannot fill the full circle with an integer number of tiles.
Ending at the pole your tile longitude extent would be 0.5deg/cos(89.5deg) = 59,29..deg which also does not fit exactly into 360degs.
If you decrease the size of your tiles you might have an acceptable small error but yet no real "grid" because coming to the poles there will always be less tiles than at the Equator..
Maybe something like "equal area map projection" might help? http://en.wikipedia.org/wiki/Map_projection#Equal-area
Two possible solutions here (formulas in R):
lat<-seq(-89.75,89.75,by=0.5)
Formula 1, based on the area of a grid point in the equator (111.11km2).
r<-(111*10^3*0.5)*(111*10^3*0.5)*cos(lat*pi/180)
Formula 2, based on the radius of the Earth.
ER<-6371*1000
r2<-(ER^2)*(0.5*pi/180)^2*cos(lat*pi/180)

geohash string length and accuracy

if length of geohash string is more, it is more accurate. But is there any direct relationship like if length is 7 it is providing 100 meter accuracy,
i.e. if two geohash (and either of their bounding box) is having first 7 char matching, both should be near 100 meter etc?
I am using geohash for finding, all near-by location for given geohash, with their distance
Also any directway to calculate distance between two geo-hash? (one way is to decode them to lat/lng, and then calculate distance)
Thanks
Saw a lot of confusion around geohashing so I am posting my understanding so far.
The principle behind geohash is very simple, you can create your own version.
For instance consider following geo-point,
156.34234534,-23.343423345
In the above example, 156 represents degrees, 2 digits after decmal (34) represents
decimal minute and rest, (34.5334) represents seconds.
If you remember school geography circumference of earth at equator is about 40,000kms and,
number of degrees around the earth (latitudes or longitudes) is 360. So at the widest
point each degree of latitude and longitude span equals to about 110kms (40,000/360).
So if you encode the above coordinates as, "156-23" (including negative sign), this will give you (110kmx110km) box.
You can go on and increase the precision,
Fist digit of minute (156.3-23.3) will give you (10kmx10km) box (each minute span equals 1km).
Increase this to include first digit of second you get (100mx100m)box,
each extra digit will add precision to another degree.
Geohashing is just the way to represent the above figure in an encoded form. You can happily use the above format as well!
Was curious about this myself.
If its any good to anyone I put together a spreadsheet here
Not 100% sure its right - feel free to comment if you find a problem.
Judging by graph below, using 6 to 10 digits gives accuracy ~1km to ~1m at 60 degree lat.
Here are the formulas for height and width in degrees of a geohash of length n characters:
First define this function:
parity(n) = 0 if n is even otherwise 1
Then
height = 180 / 2(5n-parity(n))/2 degrees
width = 180 / 2(5n+parity(n)-2)/2 degrees
Note that this is the height and width in degrees only. To convert this to metres requires that you know where on the earth the hash is.
Code for this in java is at http://github.com/davidmoten/geo.
Also any directway to calculate distance between two geo-hash? (one way is to decode them to lat/lng, and then calculate distance)
That is what you should do. Think of the geohash as just another representation of a latitude and longitude as a pair of printed decimal numbers are likewise. If I gave you a pair of lat & lon strings, you would parse them to numbers (in your programming language of choice), and then do the math. It's no different with geohashes -- decode to lat & lon then do the math.
Be very careful with any reasoning you are attempting to do with inferring closeness based on the length of the common prefix between a pair of points. If there is a long common prefix, then they are close, but the converse is not true! -- i.e. two points with no common prefix could be a millimeter apart.
Here is an equation (in pseudocode) that can approximate the optimal Geohash length for a latitude/longitude pair having a certain precision:
geohash_length = FLOOR ( LOG_2(5000000/precision_in_meters) / 2,5 + 1 )
if geohash_length > 12 then geohash_length = 12
if geohash_length < 1 then geohash_length = 1
I've used it to create the optimal Geohash from data received by the gpsddaemon, which also provide precision information via the epx and epy values.

Distance between points by EPSG coordinates

I have a points with coordinates EPSG Projection 3059 - LKS92 / Latvia TM. I need to compute the distance in meters between two points.
It is easy to compute euclidean distance between two points, but I am not sure if the resulting distance is expressed in meters?
PROJCS["LKS92 / Latvia TM",
UNIT["metre",1,
PARAMETER["scale_factor",0.9996],
The unit is 1 meter, but should the scale factor taken into account? Maybe 1 unit in this system is not 1m but 0.9996 meters?
No, the scale factor in a map projection is integrated in the projection calculations. The purpose of the factor is to minimise overall distortion as the easting from the central meridian (24°E) increases. 0.9996 is a common factor when transverse mercator (TM) is involved.
Once projected, the resultant coordinate is in metres (in this case), no further scaling is needed, and you can use a simple Pythagorean hypotenuse calculation to determine a distance.

converting distance into coordinates [duplicate]

This question already has an answer here:
Closed 11 years ago.
How do i convert a given distance (in metres) into geographic coordinates.
What I need is to draw a polygon on the map (a regular polygon, like a circle), however, it's radius is given in meters, how do I calculate the radius in degrees or radians?
I'll probally code it in c
Oh man, geographic coordinates can be a pain in the behind. First of all, I'm assuming that by geographic coordinates, you're talking about geodetic coordinates (lat/lon).
Second of all, you can't find a "radius" in radians or degrees. Why, you ask? Well, one degree of longitude at the equator is WAY longer than one degree of longitude close to the north or south pole. The arc of one degree latitude also changes based on your location on the earth since the earth is not a perfect sphere. It's usually modeled as an ellipsoid.
That being said, here are two ways to map the coordinates of a polygon onto lat-lon coordinates:
1) If you're feeling like a complete badass, you can do the math in lat-lon. Lots of trig, easy to make mistakes... DON'T DO IT. I'm just including this option here to let you know that it is possible.
2) Convert your geodetic coordinates to UTM. Then, you can do whatever you need to do in meters (i.e. find the vertices of a polygon), and then convert the resulting UTM back to geodetic. Personally, I think this is the way to go.
Well, consider that at the equator (0 degrees latitude) one degree of longitude is equal to appximately 60 nautical miles. At either pole (90 degrees latitude) a single degree of longitude equals 0 nautical miles. As I remember the cosine of the latitude times 60 will give you the approximate distance in nautical miles at that latitude of a single degree of longitude.
However, how accurate you would be would have to account for the map projection you're using. For aeronautical maps, they use the Lambert Conformal Conic projection, which means distances are only exactly accurate along the two latitudes that the cone cuts the sphere of the earth. But if an approximation is good enough, you may not need the accuracy.
For conversion, one nautical mile equals 1.852 km. If I did the arithmetic properly (no guarantee, I'm in my 70s), that means that a meter equals (except as you get really close to the poles) 0.0000009 degrees latitude. It also equals 0.0000009 degrees longitude on the equator. If you're not at the equator, divide the 0.0000009 by the cosine of the latitude to get the degrees of longitude.
So, a 1000 meter radius circle at 45 degrees latitude would mean a radius of 0.0009 degrees latitude and 0.0009/0.707 degrees longitude. Approximately of course.
All this is from memory, so take it with a grain of salt. If you really want to get involved, Google geographic equations or some such.
Check out http://trac.osgeo.org/proj/wiki/GeodesicCalculations. Depending on the accuracy you need, this can get pretty complicated, so you're probably best off starting from some existing code.

Resources