Izz ad-Din Ruhulessin
Izz ad-Din Ruhulessin

Reputation: 6175

Calculate longitude based on latitude and sunrise time?

I'm calculating the longitude of positions where the current sun altitude currently is ~0.0. This is done by iterating over a range of latitudes, calculating the time of sunrise at (0.0, latitude) and then calculate the longitude by multiplying the time difference (fractional hours) with 15 (the amount of degrees the sun "moves" over the earth surface).

When calculating the time of sunrise from the calculated coordinate tuples, the lowest latitudes show a time difference of a few minutes with the highest latitudes. How can this difference be explained?

In:

points=walk_the_earth()

Out:

[-66.53673944994807, -65.0] 2012-08-21 12:07:04.748893
[-67.13184367865324, -64.5] 2012-08-21 12:07:05.666852
[-67.70314011722803, -64.0] 2012-08-21 12:07:06.541521
...
[-119.24775995314121, 64.0] 2012-08-21 12:08:45.536679
[-119.93103107437491, 64.5] 2012-08-21 12:08:47.770382
[-120.64480075612664, 65.0] 2012-08-21 12:08:50.152224

(Times are in UTC). The code runs under ~second.

What is the cause of this difference?

Code

import math
import xephem

def longitude_from_latitude(lat):
    """
    Calculate the longitude at which Sun altitude is ~0.0.

    Args:
        lat: A float indicating the latitude to calculate longitude
            for.

    Returns:
        float
    """
    now = xephem.julianday.now()
    meridian = xephem.Observer(now.midnight.dublin, 0.0, lat)
    sun = xephem.Sun.fromobserver(meridian)
    transit = sun.transit(-1)
    # Calculate time difference between sun position and local time.
    delta_t = ((now - transit['rs_risetm']) * 24.0) * 15.0
    return delta_t


def walk_the_earth(resolution=0.5, minlat=-65.0, maxlat=65.0):
    """
    Calculate the coordinate at which Sun altitude is ~0.0 for
    a given range of latitudes.

    Args:
        resolution: A float indicating the number of points to
            return for the specified range of latitudes. 1.0 means
            that 1 longitude will be calculated for each real
            latitude, 0.5 means 2, etc.
        minlat: A float indicating the lowest latitude to start
            calculating.
        maxlat: A float indicating the highest latitude to 
            calculate up to.

    Returns:   
        list of longitude, latitude, xephem.Sun tuples.
    """
    now = xephem.julianday.now()
    lat = minlat
    points = []
    while True:
        if lat > maxlat:
            break
        lng = longitude_from_latitude(lat)
        # Create an Observer for longitude and latitude
        obs = xephem.Observer(now.dublin, lng, lat)
        sun = xephem.Sun.fromobserver(obs)
        points.append([lng, lat, sun])
        # sun.transit() calculates the rising, transit and setting times
        # of the sun at Observers location. The -1 argument specifies
        # that we consider sunrise to occur when the upper limb touches
        # the horizon (0 indicates center, 1 indicates lower limb).
        print points[-1], sun.transit(-1)['rs_risetm'].datetime()
        lat += resolution
    return points

Upvotes: 4

Views: 1744

Answers (3)

Jon
Jon

Reputation: 1

The sun's position in the sky is not uniform. Local apparent noon in December may be a few minutes before average local noon, whereas local apparent noon in June may come a few minutes "late." This "wobble" is predicted through the equation of time, which, if I understand this correctly, has a more pronounced effect further from the equator.

Upvotes: -1

Norman Gray
Norman Gray

Reputation: 12514

I think a more direct method would work for you, which would avoid the 15-degrees-per-hour correction. You've got an ephemeris, after all, so you can exploit that.

  1. Pick a latitude and a time
  2. Pick two longitudes, a and b, such that the sun is above the horizon for one (altitude > 0, say a), and below it for the other (altitude < 0, b)
  3. Do a binary search: choose a longitude c half-way between a and b, and calculate the altitude of the sun there.
  4. If that altitude is close enough to zero, stop: c is the answer
  5. If the altitude is less than 0, set b=c; else set a=c.
  6. Go to 3

Do that for each latitude you want.

To check things are working, do the calculation at the equinox, and the longitudes you calculate should be almost exactly equal (make sure you understand why). Do it again at either solstice, and the longitudes should vary quite a lot, and the algorithm will fail as you get to about 67 degrees north or south (can you see why?).

Upvotes: 1

High Performance Mark
High Performance Mark

Reputation: 78316

I checked the sunrise times for the extreme N and S points in your list at the NOAA's solar calculator. Feeding in the lat/long and today's date gave sunrise times which are the same as in the table you have posted, with the proviso that the calculator only gives the sunrise time to the nearest minute.

Nevertheless, if your question was along the lines What is wrong with my code ? the answer is, most likely, Nothing at all.

But if your question was really What am I failing to understand about the variation in sunrise time wrt position and date ? then your question is seriously off-topic for SO.

Upvotes: 1

Related Questions