3

I want to convert lat/long to XY coordinates. I picked up this equation but can't get the desired output:

x = r λ cos(φ0)
y = r φ

The measurements of the two points are:

point1 = (-37.8206195, 144.9837765)
point2 = (-37.8193712, 144.9837765) 

Attempt:

import math

avg = (-37.8206195 + -37.8193712)/2
rad_avg = math.pi / 180

point1 = (-37.8206195, 144.9837765)
point2 = (-37.8193712, 144.9837765) 

dist = rad_avg * math.cos(avg)

print(dist)

Out:

0.01732592680044846

The output should be around 160m

  • 1
    Are you aware of the difference between degrees and radians, and that the Python functions expect radians but latitude and longitude are in degrees? – John Coleman Nov 07 '18 at 00:45
  • @JohnColeman, so you're saying the functions aren't consistent –  Nov 07 '18 at 00:51
  • As @JohnColeman says, [math.cos](https://docs.python.org/3/library/math.html#math.cos) expects angles in radians. Do: `r_avg = avg * math.pi / 180` – Cheche Nov 07 '18 at 00:59
  • The functions are perfectly consistent, but they have to be used with input in the units that they expect, which are not the same units as used in latitude and longitude. – John Coleman Nov 07 '18 at 01:07
  • @Cheche, Thankyou. Do you want to put it in the form of an answer so I can accept it? –  Nov 07 '18 at 01:19
  • @JeremyAlexander Great!, i'll do it – Cheche Nov 07 '18 at 01:21
  • @Cheche or alternatively you can use the `math.radians` function. It does the same calculation but I think it's clearer and less error-prone – Jerfov2 Nov 07 '18 at 03:17
  • @Jerfov2 yeah, that's right. It's in my answer. I agree that's less error prone, but added math calculation just to help others understand what the real calculation is. – Cheche Nov 07 '18 at 03:21

1 Answers1

4

First of all math.cos expects angle argument in radians. To convert from degrees to radians you need to do:

rad_avg = avg * math.pi / 180

Or even:

math.radians(<angle_in_degrees>)

Basically it means you're mapping 180º with pi and taking the portion for your angle.

I assume then that you want to compute distance between both points by converting it first to "xy" coordinates (according to your reference).

You need to get first both points in the same coordinate system. As the link states, for small areas, they can be estimated by:

  • x = r λ cos(φ0)
  • y = r φ

So you need to do:

import math

point1 = (-37.8206195, 144.9837765) # Lat/Long (lambda/phi)
point2 = (-37.8193712, 144.9837765) # Lat/Long (lambda/phi)

r = 6371000 # meters
phi_0 = point1[1]
cos_phi_0 = math.cos(math.radians(phi_0))

def to_xy(point, r, cos_phi_0):
    lam = point[0]
    phi = point[1]
    return (r * math.radians(lam) * cos_phi_0, r * math.radians(phi))

point1_xy = to_xy(point1, r, cos_phi_0)
point2_xy = to_xy(point2, r, cos_phi_0)

Finally, to compute distance in cartesian coordinates you need to use the Pitagoras Theorem d = sqrt(delta_x^2 + delta_y^2)

In your example:

dist = math.sqrt((point1_xy[0] - point2_xy[0])**2 + (point1_xy[1] - point2_xy[1])**2)

Which results: 113.67954606562853. Closer to what you're looking for.

Plus, there's a shortcut to get it right to the distance formula:

  • d = r * sqrt(x² + y²) where x = (λ2 - λ1) * math.cos(φ0) and y = (φ2 - φ1)
Cheche
  • 1,456
  • 10
  • 27
  • I've updated the equation in the question but am getting the wrong answer. Have I got it right? –  Nov 07 '18 at 01:40
  • The point is that your lat/long coordinates are basically angles. Each point consists in two angles: lat and long. Then, any trigonometric function you use `as is` requires radian angles. Then you need to convert both values to radians. – Cheche Nov 07 '18 at 01:49
  • @JeremyAlexander I've added some extra detail on my answer. Let me know if it helps you now. Are you trying to measure a cricket ground size? – Cheche Nov 07 '18 at 03:08
  • Thanks for this. Yeh, it's essentially the size of a cricket oval. So I know roughly one end to the other should be approx 160m. Maybe a bit more. –  Nov 07 '18 at 04:07