Latitude and longitude decimal range from degrees

Hello friends!

One of the use cases for Julia that I’m finding for work is for geographical purposes. However geography wasn’t my specialization in school. :sweat_smile:

One of the things I’m wanting to do is collect data within countries/regions/provinces/counties/etc, which are defined by some latitude and longitude degree range.

Thing is when looking at geographical data with something like GeoDataFrames.jl, lat and long aren’t stored as degrees but as large decimal points.

So say we look at Texas, which is massive, and it’s spans something like 25° 50’ N to 36° 30′ N (Latitude) and 93° 31′ W to 106° 439′ W (Longitude).

If I can transform the above degree ranges into decimal ranges, I can filter my geographical dataframe for points, polygons, whatever if their lat and long is within those ranges.

Is there something in ArchGDAL.jl to do this?

maybe worth taking a look at

What do you mean by this?

This? 93° 31′ W == 93.5166666667° W
or something else?

More or less yes, because generally for anything GIS related (something I do at work) you don’t have 93° 31′ W or 93.5166666667° W in the data you want to put on a map. It’s usually just 93.5166666667 is a longitude data point in your data.

Don’t know if it helps but GMT.jl accepts also the limits/regions in “dd::mm:ss”. e.g.

using GMT

coast(region=("-108:43.9", "-91:31", "24:50", "37:30"), borders=(1,:red), shore=true, show=true)

Red line is the Texas border.

Interesting! I guess I would need to decide if

  • Giorgi & Francisco
  • Seneviratne, or
  • IPCC AR6

Fits my use cases best for the first one. The second I’d have to look at a bit more.

Ah, thank you for reminding of GMT.jl! I was trying to recall what package I found previously to map geograhpical data.

Isn’t this achieved by a simple function:

deg2dec(d, m, s) = d + m/60 + s/3600

# example:
deg2dec(25, 50, 0)   # 25.833333333333332

If that correctly lines up with how latitudes and longitudes are represented, yes.

Apologies if this seemed like a silly question.

I think it does.

Blockquote

deg2dec(d, m, s) = d + m/60 + s/3600

# example:
deg2dec(25, 50, 0)   # 25.833333333333332

You got to be careful if the values are NEGATIVE
For example: -23degrees 12minutes 46sec

1 Like

Good point.
Can be edited to:

deg2dec(d, m, s) = (d!=0) ? sign(d)*(abs(d) + m/60 + s/3600) : m/60 + s/3600

PS:
sign(0) == 0 which is a bit annoying

1 Like

The formula above does not properly handle all cases near zero.

An algorithm is described in Matlab’s dms2degrees() function description.

A first attempt below to write such function:

function deg2dec(d, m, s)
    t = (d, m, s)
    (t[findfirst(!=(0), t)] < 0) ? SGN = -1 : SGN = 1
    ((t[2] < 0 && t[1] != 0) || (t[3] < 0 && any(!=(0), t[1:2]))) && throw(ArgumentError("Invalid input"))
    return SGN * (abs(d) + abs(m)/60 + abs(s)/3600)
end
julia> using AstroAngles

julia> dms"1°2′3″N"
0.018049613347708025  # radians

julia> dms"1°2′3″N"deg
1.0341666666666667  # degrees

Also provides string parsing/formatting, and assemble/split into components, see AstroAngles.jl.

4 Likes

@aplavin, I looked briefly at your code and the various cases handled by the Matlab function indicated above don’t seem to be treated?

Consider a small area of ​​interest defined across the equator with zero latitude (and/or across Greenwich with zero longitude). A location can then be defined with negative minutes or negative seconds, but the signs cannot be arbitrary.

Can you give a specific example?

You can consider this example:

deg2dec(0, -30, 17.12345)       # -0.5047565138888889

using AstroAngles
dms2deg(0, -30, 17.12345)       # -0.49524348611111113

Sounds like a straight up bug in that package.

In the OP case, though, won’t deg, min and sec always be of the same sign, and a simple sum will give the correct magnitude in decimal degrees.

The sign can be taken straight from E (+ve) or W (-ve), N (+ve) or S (-ve).

Is that too simplistic?

As the OP data is far from zero latitude or longitude, the simple sum formula is fine.