Search code examples
scalaapache-sparkgeosparkapache-sedona

Wrong computed azimut for geo coordinates using Apache Sedona in Spark


I am running a Spark application, using Apache Sedona.

I am trying to compute the bearing/azimuth between two coordinates, using following script:

import org.apache.sedona.sql.utils.SedonaSQLRegistrator
SedonaSQLRegistrator.registerAll(spark)

spark.sql("SELECT DEGREES(ST_AZIMUTH(ST_POINT(9.942731, 57.042649), ST_POINT(9.940315, 57.04348))) AS azimuth").show

Resulting in 288 degrees:

scala> spark.sql("SELECT DEGREES(ST_AZIMUTH(ST_POINT(9.942731, 57.042649), ST_POINT(9.940315, 57.04348))) AS azimuth").show
+-----------------+
|          azimuth|
+-----------------+
|288.9810116333513|
+-----------------+

Problem is, when I try to verify the bearing using several online tools, like e.g. https://www.sunearthtools.com/tools/distance.php, they all compute the angle to 302 degrees. As all the web tools agree, I guess Sedona computes the angle wrong.

So, I expected the result to be 302 degrees, but got 288.

Can anyone see if I made an error, how to fix it, or if there are a problem with Sedona's computation?

Versions: Scala: 2.11 Spark: 2.4 Sedona: 1.2.1-incubating jts-core: 1.19.0 geotools-wrapper: 1.1.0-25.2


Solution

  • Sedona assumes euclidean geometry (i.e. a flat plane for 2D coordinates). So, it provides the grid azimuth which is the arctangent of the difference of coordinates (some adjustments are also made to not have negative results):

    ST_AZIMUTH(ST_POINT(9.942731, 57.042649), ST_POINT(9.940315, 57.04348)) == ATAN2(57.04348 - 57.042649, 9.940315 - 9.942731)

    The reference website you posted calculates a geodetic azimuth (with a perfect sphere). That functionality is not currently provided in Sedona.

    To answer your questions:

    1. The only error you may have made is the comparison of geodetic and grid azimuths.
    2. You can implement the geodetic calculation from the link you provided. It'll be messy but straightforward. I would probably do it in stages: create columns for the X and Y first and then do the final calculation.
    3. There's no problem with Sedona's calculation that I can see. This is the current method of calculation at the latest commit as of writing this: link

    Additionally, here is a reference with some good illustrations for the difference between geodetic and grid azimuth: https://www.e-education.psu.edu/geog862/node/1816