B4A Library Astro library

The library provides the times of Sunrise, Sunset, Moon rise and Moon set, according to place and date.
It also provides the phase of the moon (equivalent to the day of the moon month).
The Sunrise and Sunset times vary according to the value of Zenith angle.
The following conventions are in use:
Official – 90.8333 (90° 50’)
Civil - 96°
Nautical - 102°
Astronomical - 108°
The values can be used by their names.
The library use the Official value as default, and it can be changed using the method Zenith.

No demo program as it is very simple to use.
Please report problems.

Edit: Version 1.1 corrected the following as per alfcen comments:
- no_rise or no_set time are returned as "--:--"
- sun rise and set times are within the 24 hours.

Edit: the files are updated to ver. 1.2 with additional methods which provide data about the sun and the moon, all by our astronomy expert alfcen:sign0188:
Edit: Ver 1.21 correction of rounding problem.
Edit: Ver 1.22 bug correction in sun + format change.
Edit: ver 1.23 bug correction in moon phase.
Edit: ver 1.4 added a method to calculate sun's position (azimuth and elevation).
 

Attachments

  • Astro 1.4.zip
    17.5 KB · Views: 739
Last edited:

derez

Expert
Licensed User
Longtime User
Until further notice - do not use SunPosition or Julianday2 - there are bugs there and the page which I took the algorithm from does not exist anymore...

Edit: found the source and the error, will be corrected soon !
Edit: See first post for corrected version, 1.4
See the sun jumps when you enter the new lib.
 
Last edited:

derez

Expert
Licensed User
Longtime User
Thank you. However, your Astro.xml file in the Astro_1.4.zip file is empty (0 bytes).

Another question: I am no expert as regards astronomical calculations, but how can the compass bearing and elevation of the sun be calculated from any location on earth (i.e. by inputting Lat, Lon and date/time)?

Can I simply subtract/add Longitude from the Azimuth calculated with your SunPosition function and ditto subtract/add Latitude from the Elevation (depending on the hemisphere)? I doubt that the latter is correct.
The calculation of the position is not simple at all, you can read about it here http://www.pveducation.org/pvcdrom/suns-position-high-accuracy
 

derez

Expert
Licensed User
Longtime User
Thank you. The xml problem still exists: The ZIP file should hold two files:
- Astro.jar
- Astro.xml

Astro.jar is indeed 15.569 bytes, but Astro.xml is 0 bytes! Kindly correct this. Wimpie3 has also now noticed this.

Updated the files to include ver 1.3 xml file which shows the same data, except for the version name that still shows 1.3

Also, if possible, could you add a function to your library that calculates the Sun's position relative to a Lat/Lon/Time position? If it is accurate to about 1 degree (or better) that would be great..

The method SunPosition does exactly that... to about 1.5 degree.
 

derez

Expert
Licensed User
Longtime User
OK, thank you. Because your previous Astro version 1.3 gave such large elevation errors, I was not sure.

However, your lib still gives strange results: Today at 16.00h Central Europe time, at a latitude of 52.1 degrees and 4.5 degrees East, it reports an Elevation of 51 degrees, whereas suncalc.org reports a far more plausible Altitude of 11.6 degrees (the Sun will set in about 1.5 hours). Also there is about a 10 degrees difference in the Sun's Azimuth. See:
http://www.suncalc.org/#/52.1,4.5,6/2017.02.06/16:00/1

I assume "Altitude" and "Elevation" are the same in your lib and on suncalc.org (?)
Could it be caused by me entering DateTime.now as your Sunposition's 'Time' parameter?
Shouldn't Deltatime be included in here (the offset versus UTC/GMT)? Even when entering GMT the results are totally wrong.

PS: You haven't (yet) changed the version number in your Astro.xml file from "1.3" to "1.4", which also has caused some confusion here about whether I was using your latest version... I hope you agree with me that the ZIP file in thread #1 should hold the correct files, especially for those persons who start to use your lib for the first time.

There is also one more parameter which you might wish to add to your library, namely the Moon's Azimuth and Elevation relative to a Lat/Lon/Time/Date position. I did not find this in version 1.4 (I did find how to calculate the Moon's current Lat/Lon).

I removed the library with the SunPosition from post #1.
The following code is this method in B4A/B4j :
B4X:
Sub SunPosition(  Lat As Double,  Lon As Double,  Timenow As Long ) As Double()
 
        ' Main variables
         Dim  twopi As Double = 2*cPI
        Dim rad  = cPI/180     As Double
        Dim dEarthMeanRadius  =   6371.01    As Double' In km
        Dim dAstronomicalUnit  =  149597890.0 As Double' In km
        Dim dElapsedJulianDays As Double
        Dim dDecimalHours As Double
        Dim dEclipticLongitude As Double
        Dim dEclipticObliquity As Double
        Dim dRightAscension As Double
        Dim dDeclination As Double

        ' Auxiliary variables
        Dim dY As Double
        Dim dX As Double

        ' Calculate difference in days between the current Julian Day
        ' And JD 2451545.0, which Is noon 1 January 2000 Universal Time
     
                ' Calculate time of the day in UT decimal hours
            Dim offsetTicks As Long = DateTime.TimeZoneOffset * DateTime.TicksPerHour
            Dim UTCTimenow As Long = Timenow - offsetTicks
            dDecimalHours = DateTime.GetHour(UTCTimenow ) + DateTime.GetMinute(UTCTimenow )/60 + DateTime.GetSecond(UTCTimenow )/3600.0
            ' Calculate current Julian Day
        Dim    liAux1 As Double = (DateTime.GetMonth(Timenow) - 14) / 12
        Dim    liAux2 As Double = (1461 * (DateTime.GetYear(Timenow) + 4800 + liAux1)) / 4 + _
                                (367*(DateTime.GetMonth(Timenow) _
                                - 2 -12 * liAux1)) / 12- (3 * ((DateTime.GetYear(Timenow) + 4900  _     
                                 + liAux1) / 100)) / 4 + DateTime.GetDayOfMonth(Timenow) - 32075
        Dim    dJulianDate As Double = liAux2 - 0.5 + dDecimalHours / 24.0
            ' Calculate difference between current Julian Day And JD 2451545.0
            dElapsedJulianDays = dJulianDate - 2451545.0
        '    dElapsedJulianDays = Julianday2(UTCTimenow , offsetTicks ) - 2001545.0
        '   dElapsedJulianDays = UTCTimenow  / DateTime.TicksPerDay - 2001545.0  + 2440587.5

        ' Calculate ecliptic coordinates (ecliptic longitude And obliquity of the
        ' ecliptic in radians but without limiting the angle To be less than 2*Pi
        ' (i.e., the result may be greater than 2*Pi)
        '
            Dim  dMeanLongitude As Double
            Dim dMeanAnomaly As Double
            Dim dOmega As Double
            dOmega = 2.1429 - 0.0010394594 * dElapsedJulianDays
            dMeanLongitude = 4.8950630 + 0.017202791698 * dElapsedJulianDays '  Radians
            dMeanAnomaly = 6.2400600 + 0.0172019699 * dElapsedJulianDays
            dEclipticLongitude = dMeanLongitude + 0.03341607 * Sin(( dMeanAnomaly ) _
                    + 0.00034894 * Sin( 2*dMeanAnomaly ) - 0.0001134 - 0.0000203 * Sin(dOmega))
            dEclipticObliquity = 0.4090928 - 6.2140e-9 * dElapsedJulianDays    + 0.0000396 * Cos(dOmega)
     

        ' Calculate celestial coordinates ( right ascension And declination ) in radians
        ' but without limiting the angle To be less than 2*Pi (i.e., the result may be
        ' greater than 2*Pi)
        '
            Dim dSin_EclipticLongitude As Double
            dSin_EclipticLongitude = Sin( dEclipticLongitude )
            dY = Cos( dEclipticObliquity ) * dSin_EclipticLongitude
            dX = Cos( dEclipticLongitude )
            dRightAscension = ATan2( dY,dX )
            If( dRightAscension < 0.0 ) Then dRightAscension = dRightAscension + twopi
            dDeclination = ASin( Sin( dEclipticObliquity ) * dSin_EclipticLongitude )
     

        ' Calculate local coordinates ( azimuth And zenith angle ) in degrees
     
            Dim dGreenwichMeanSiderealTime As Double
            Dim dLocalMeanSiderealTime As Double
            Dim dLatitudeInRadians As Double
            Dim dHourAngle As Double
            Dim dCos_Latitude As Double
            Dim dSin_Latitude As Double
            Dim dCos_HourAngle As Double
            Dim dParallax As Double
            Dim dZenithAngle As Double
            Dim dAzimuth As Double
            dGreenwichMeanSiderealTime = 6.6974243242 + 0.0657098283 * dElapsedJulianDays + dDecimalHours
            dLocalMeanSiderealTime = (dGreenwichMeanSiderealTime * 15 + Lon) * rad
            dHourAngle = dLocalMeanSiderealTime - dRightAscension
            dLatitudeInRadians = Lat * rad
            dCos_Latitude = Cos( dLatitudeInRadians )
            dSin_Latitude = Sin( dLatitudeInRadians )
            dCos_HourAngle= Cos( dHourAngle )
            dZenithAngle = (ACos( dCos_Latitude * dCos_HourAngle *Cos(dDeclination) + Sin( dDeclination ) * dSin_Latitude))
            dY = -Sin( dHourAngle )
            dX = Tan( dDeclination ) * dCos_Latitude - dSin_Latitude * dCos_HourAngle
            dAzimuth = ATan2( dY, dX )
            If ( dAzimuth < 0.0 ) Then     dAzimuth = dAzimuth + twopi
            dAzimuth = dAzimuth / rad
            ' Parallax Correction
            dParallax = (dEarthMeanRadius / dAstronomicalUnit) *Sin(dZenithAngle)
            dZenithAngle = (dZenithAngle + dParallax) / rad
            Dim dbl(2)  As Double
            dbl(0) = dAzimuth
            dbl(1) = 90 - dZenithAngle
            Return dbl

End Sub

This one works. Maybe in the future I'll feel like going back to find what went wrong. I don't have the algorithm for the moon, ask Alfcen if he would like to help - he is the Astronomy expert in this forum.
I've explained in post 1 that the last version is 1.4 although it says 1.3 because I've used the 1.3 xml file which should be the same except for the version number, but that is not relevant anymore now.
 
Last edited:

derez

Expert
Licensed User
Longtime User
Do I understand you correctly that the SunPosition doesn't work via your Astro library, but does work via B4A code?
If so, do you know why? I assume you then did not make your library with B4A...
The library is written in Java but this code is a translation that I used to check with. I took the original method out of the library because it has some error.
 

derez

Expert
Licensed User
Longtime User
Ver 1.4 added to the first post, I solved the problems which were related to offset time. The updated SunPosition require both local time and local offset.
Results are very close to NOAA calculations, please check.
 

Toky Olivier

Active Member
Licensed User
Longtime User
Hi all,
Is it possible to get solar noon or zenith time with this lib or how can I get accurate time of it?
Thank you
 

derez

Expert
Licensed User
Longtime User
Hi all,
Is it possible to get solar noon or zenith time with this lib or how can I get accurate time of it?
Thank you
The library does not provide it directly but if you are willing to invest some time in checking it then do it this way:
I guess that noon time is in the middle of the time span between rise and set.
Check around this time with sunposition method and find the higher sun elevation.
 

Toky Olivier

Active Member
Licensed User
Longtime User
Thank you @derez. I thought the same thing and implemented it like this. I don't know if there is simplier method:

B4X:
Sub GetNoonTime(h() As String) As String
    Dim sf As StringFunctions
    sf.Initialize
    Dim h1 As Int = sf.Left(h(0),h(0).IndexOf(":"))*60+sf.Right(h(0),h(0).IndexOf(":"))
    Dim h2 As Int = sf.Left(h(1),h(1).IndexOf(":"))*60+sf.Right(h(1),h(1).IndexOf(":"))
    Dim h3 As Int = (h1 + h2)/2
    Return NumberFormat(h3/60,2,0) & ":" & NumberFormat(h3 Mod 60,2,0)
End Sub
 

swChef

Active Member
Licensed User
Longtime User
You may be in a country that does not have access. I made a quick attempt to find if there is such a restriction but didn't find information. Sorry.
 

Toky Olivier

Active Member
Licensed User
Longtime User
Thank you very much.
If I use opera mini, I can reach the page. But it is an online solution. I need offline one. Thank you again.
 

swChef

Active Member
Licensed User
Longtime User
If occasional download is possible, you can access and store the result. Daily it doesn't change much, so even once a week may be sufficient depending on task.
 

BugNot

Member
Hi,

This post is old but when the moon is rising (ascending) in the northern hemisphere it is descending in the southern hemisphere; and conversely, when the moon is descending in the northern hemisphere it is then rising (ascending) in the southern hemisphere.

The library ignores this, correct me if im wrong.
 

corwin42

Expert
Licensed User
Longtime User
This post is old but when the moon is rising (ascending) in the northern hemisphere it is descending in the southern hemisphere; and conversely, when the moon is descending in the northern hemisphere it is then rising (ascending) in the southern hemisphere.

The library ignores this, correct me if im wrong.

You are wrong. Moon (and sun) rising and descending is because of the rotation of the earth. It's quite new to me that the earth rotates in the opposite direction in the southern hemisphere.
 

BugNot

Member
corwin42 said:
You are wrong. Moon (and sun) rising and descending is because of the rotation of the earth. It's quite new to me that the earth rotates in the opposite direction in the southern hemisphere.

Yes you are right on this point, the calculations are good, only the phases of the moon are reversed, it's just visual.
Look at this page: wikipedia lunar phase
 

sn_nn

Member
Licensed User
Longtime User
Hi, derez! it's very usefull library!
I have seen in you post a fragment of code for calculating SunPosition. And Celectial coordinates was used inside him.
How i Can get celestial coordinates ( right ascension And declination ) for Sun and for Moon?
 
Top