Is it possible to calculate the azimuth from a single latitude and longitude and the destination's distance x and y from the mentioned coordinate?
Basically I have a single coordinate in WGS84
, and I need to specify the next coordinate given the x
, y
distance in meters from this point.
I tried something like the following but it has a huge offset when distance increases:
def get_next_coordinate(initial_coordinate, dx_meters, dy_meters, is_up=False, is_right=True):
lat, long = initial_coordinate
# earth radius in km
earth = 6378.137
# 1 meter in degree
coef = (1 / ((2 * math.pi / 360) * earth)) / 1000
up_dir = 1 if is_up else -1
right_dir = 1 if is_right else -1
dx = (dx_meters * right_dir) * coef
dy = (dy_meters * up_dir) * coef
new_lat = lat + dy
new_long = long + dx / math.cos(lat * (math.pi/180))
return new_lat, new_long
So, I thought I give geographiclib
a try. it seems geograpghiclib.geodesicline.GeodesicLine
has a SetDistance
method that does exactly this; given a coordinate and a distance, it calculates the next coordinate. However it requires the azimuth for it to work.
Is it possible to somehow calculate the azimuth from what I have here? what are my options here?
More explanation:
To be more precise, I'm trying to calculate a latitude, longitude
for any given pixel location in a map (which is an image). I have the latitude and longitude at map(0,0)
and I also have pixel scales, so I know how much space a pixel takes.
Using these two pieces of information, I can count pixels in x,y (height and width) and get the relative distances in meters.
My final step would be to calculate the coordinates at the given point.
Best Answer
After couple of days of searching and testing I finally managed to get this to work.
The first question was whether it was possible to calculate azimuth using an image's x,y pixel coordinate.
The answer is Yes.
Following the answer here, you can calculate the azimuth/bearing in a 2D image.
This is how the code looks in python:
Also, there is this gist, where it calculates the direction of a line, in the same manner, suggested here.
Apart from this, I found out that calculating the bearing in my case can be done in a relatively simple way.
Since The azimuth is the heading measured clockwise from north, and our image is already aligned toward north, the point to the right will have 90 degree (clockwise) angle and the point below will have 180 degree angle.
We can hardcode these or calculate them like the method I just mentioned. this is a simple figure I came up with to show this.
Before I continue, I want to talk about the pixel scale calculation. without a precise pixel scale calculation everything is in vein. Searching for how to calculate the pixel scale ends up in lots of results that dont work! like the one explained here :
The thing is, if you use the snippet above, you'll get huge deviations based on where in the world you use it to calculate the pixel scale.
Basically when it comes to Mercator projection, it produces a different horizontal scale at different latitudes and thus pixel scale differs based on the latitudes.
What seems to get a very decent approximation is
Now, somehow in order to get this, and calculate the next latitude/longitude, I need to have the latitude of that location! it seems like a circle now!
In order to break this cycle, we can use google tile coordinates. we know that at different zooms, we have different number of tiles that constitute our map.
These tiles are all
256x256
in size, so if we know a single tile at our specified zoom level in our map, we can calculate any other tile coordinates in our map (as they are 256x256, its a simple math)So if we can get the tile coordinate at our map(0,0) pixel coordinate, we be fine. there are many ways to do this, but one simple way would be to calculate tile coordinate from a given latitude, longitude. This can be done like this:
Now that we have the tile coordinate, we can check at which tile our desired pixel resides, then we get that tile's gps coordinate, now we can use it's latitude to calculate the pixel scale, and then calculate the offset inside that tile, to get the exact gps location of specified pixel coordinate.
also now that we can have any tile number, by using the tile to the right and the tile below the target tile, we can calculate exact pixel scale for x, and y axis respectively(shown below).
This is my quick and dirty code that I have been playing wit,but before that, for better visualization this might help:
![enter image description here](https://i.stack.imgur.com/nZ2r8.jpg)
test:
output: