123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #
- """
- geo.sun (Sun)
- =============
-
- **Author:**
-
- * Dirk Alders <sudo-dirk@mount-mockery.de>
- * Formula from Dr. Roland Brodbeck, Calsky (http://lexikon.astronomie.info/zeitgleichung/neu.html)
- * First implementation by Alexander Klupp 2014-01-14
-
- **Description:**
-
- This module is a submodule of :mod:`geo` and supports functions and classes for sun position.
-
- **Contentlist:**
-
- * :func:`geo.sun.sunset`
- * :func:`geo.sun.sunrise`
-
- **Unittest:**
-
- See also the :download:`unittest <../../geo/_testresults_/unittest.pdf>` documentation.
- """
-
-
- import calendar
- import math
- import time
-
- europe_berlin = {'lat': 52.520008, 'lon': 13.404954}
-
-
- def JulianischesDatum(Jahr, Monat, Tag, Stunde, Minuten, Sekunden):
- if (Monat <= 2):
- Monat = Monat + 12
- Jahr = Jahr - 1
- Gregor = (Jahr / 400) - (Jahr / 100) + (Jahr / 4) # Gregorianischer Kalender
- return 2400000.5 + 365 * Jahr - 679004 + Gregor + math.floor(30.6001 * (Monat + 1)) + Tag + Stunde / 24 + Minuten / 1440 + Sekunden / 86400
-
-
- def InPi(x):
- n = int(x / (2 * math.pi))
- x = x - n * 2 * math.pi
- if (x < 0):
- x += 2 * math.pi
- return x
-
-
- def eps(T):
- # Neigung der Erdachse
- return math.pi / 180 * (23.43929111 + (-46.8150 * T - 0.00059 * T ** 2 + 0.001813 * T ** 3) / 3600)
-
-
- def BerechneZeitgleichung(T):
- RA_Mittel = 18.71506921 + 2400.0513369 * T + (2.5862e-5 - 1.72e-9 * T) * T ** 2
- M = InPi(2 * math.pi * (0.993133 + 99.997361 * T))
- L = InPi(2 * math.pi * (0.7859453 + M / (2 * math.pi) + (6893 * math.sin(M) + 72 * math.sin(2 * M) + 6191.2 * T) / 1296e3))
- e = eps(T)
- RA = math.atan(math.tan(L) * math.cos(e))
- if (RA < 0):
- RA += math.pi
- if (L > math.pi):
- RA += math.pi
- RA = 24 * RA / (2 * math.pi)
- DK = math.asin(math.sin(e) * math.sin(L))
- # Damit 0 <= RA_Mittel < 24
- RA_Mittel = 24.0 * InPi(2 * math.pi * RA_Mittel / 24.0) / (2 * math.pi)
- dRA = RA_Mittel - RA
- if (dRA < -12.0):
- dRA += 24.0
- if (dRA > 12.0):
- dRA -= 24.0
- dRA = dRA * 1.0027379
- return dRA, DK
-
-
- def Sonnenauf_untergang(JD, Zeitzone, coord):
- # Zeitzone = 0 #Weltzeit
- # Zeitzone = 1 #Winterzeit
- # Zeitzone = 2 #Sommerzeit
- # JD = JulianischesDatum
-
- B = math.radians(coord.get('lat')) # geographische Breite Erkelenz
- GeographischeLaenge = coord.get('lon') # geographische Laenge
-
- JD2000 = 2451545
- h = -50.0 / 60.0 * math.pi / 180
- T = (JD - JD2000) / 36525
-
- Zeitgleichung, DK = BerechneZeitgleichung(T)
-
- Zeitdifferenz = 12 * math.acos((math.sin(h) - math.sin(B) * math.sin(DK)) / (math.cos(B) * math.cos(DK))) / math.pi
-
- AufgangOrtszeit = 12 - Zeitdifferenz - Zeitgleichung
- UntergangOrtszeit = 12 + Zeitdifferenz - Zeitgleichung
- AufgangWeltzeit = AufgangOrtszeit - GeographischeLaenge / 15
- UntergangWeltzeit = UntergangOrtszeit - GeographischeLaenge / 15
-
- Aufgang = AufgangWeltzeit + Zeitzone
- if (Aufgang < 0):
- Aufgang += 24
- elif (Aufgang >= 24):
- Aufgang -= 24
-
- AM = round(Aufgang * 60) / 60 # minutengenau runden
-
- Untergang = UntergangWeltzeit + Zeitzone
- if (Untergang < 0):
- Untergang += 24
- elif (Untergang >= 24):
- Untergang -= 24
-
- UM = round(Untergang * 60) / 60 # minutengenau runden
-
- return AM, UM
-
-
- def sunrise(coord=europe_berlin, date=None):
- """
- :param coord: Target coordinate or None (default is central europe).
- :type coord: geo.gps.coordinate
- :param date: The day to calculate with or None (only year, month and day are relevant; default ist today)
- :type date: time.struct_time
- :return: The date and time information for the sunrise
- :rtype: time.struct_time
-
- This Method calculates the time for sunrise for a given date and coordinate.
-
- .. code-block:: python
-
- >>> import geo
-
- >>> ...
- """
- date = date or time.localtime()
-
- year, month, day = date[0:3]
- dst = date[8] # Sommerzeit
-
- AM = Sonnenauf_untergang(JulianischesDatum(year, month, day, 12, 0, 0), dst + 1, coord)[0]
-
- tup_list = list(date)
- tup_list[3] = 0
- tup_list[4] = 0
- tup_list[5] = 0
- tm = time.mktime(time.struct_time(tup_list))
- return time.localtime(tm + AM * 3600)
-
-
- def sunset(coord=europe_berlin, date=None):
- """
- :param coord: Target coordinate or None (default is central europe).
- :type coord: geo.gps.coordinate
- :param date: The day to calculate with or None (only year, month and day are relevant; default ist today)
- :type date: time.struct_time
- :return: The date and time information for the sunset
- :rtype: time.struct_time
-
- This Method calculates the time for sunrise for a given date and coordinate.
-
- .. code-block:: python
-
- >>> import geo
-
- >>> ...
- """
- date = date or time.localtime()
-
- year, month, day = date[0:3]
- dst = date[8] # Sommerzeit
-
- UM = Sonnenauf_untergang(JulianischesDatum(year, month, day, 12, 0, 0), dst + 1, coord)[1]
-
- tup_list = list(date)
- tup_list[3] = 0
- tup_list[4] = 0
- tup_list[5] = 0
- tm = time.mktime(time.struct_time(tup_list))
- return time.localtime(tm + UM * 3600)
|