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: 353
Last edited:

derez

Expert
Licensed User
The Sunposition regrettably does not seem to report back the correct Sun Azimuth and Elevation.
Others have experienced this too: https://www.b4x.com/android/forum/threads/calculating-solar-azimuth-solved.73665/#post-467905
Is there a bug in the code or does it have to do with the time parameter (I use datetime.now)? I have used:
B4X:
Dim AzimuthAstro() As Double        'Under Globals; Two parameters:  Azimuth and Elevatie

AzimuthAstro=ast.SunPosition(52.10,4.50,DateTime.now)
'Added to Derez's example:
m = m & "Sun Azimuth: " & Round2(AzimuthAstro(0),1) & CRLF
m = m & "Sun Elevation: " & Round2(AzimuthAstro(1),1) & CRLF
I have checked and also found wrong results (in elevation, azimuth looks ok). I'll check.
 

derez

Expert
Licensed 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:

Syd Wright

Well-Known Member
Licensed 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.
 
Last edited:

derez

Expert
Licensed 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
 

Syd Wright

Well-Known Member
Licensed 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.

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.
 

derez

Expert
Licensed 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.
 

Syd Wright

Well-Known Member
Licensed 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).
 
Last edited:

derez

Expert
Licensed 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:

Syd Wright

Well-Known Member
Licensed 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...

For the moment I am using a crude method to calculate the direction (bearing of the Moon), assuming the earth is flat (which is not correct). Here is the code from one of my own libraries:

B4X:
'Calculates the Distance between two Lat/Lon positions (in meters)
Sub DISTANCE1(Latje1 As Double, Lonje1 As Double, Latje2 As Double, Lonje2 As Double) As Double
    Dim XHulp1 As Double        
    Dim YHulp1 As Double
    Dim Zhulp1 As Double
    XHulp1 =(Lonje1-Lonje2) * 111111.111     '40000km/360gr.
    YHulp1 =(Latje1-Latje2) * 111111.111
    Zhulp1 = Sqrt(Power(XHulp1,2) + Power(YHulp1,2))
    Return Zhulp1                            'in meters
End Sub

'Calculates the Bearing between two Lat/Lon positions (in degrees)
Sub BEARING1(Latje1 As Double, Lonje1 As Double, Latje2 As Double, Lonje2 As Double) As Double
    Dim XHulp1 As Double
    Dim YHulp1 As Double
    Dim Hoek1  As Double
    XHulp1 =(Lonje1-Lonje2) * 111111.111     '40000km/360gr.
    YHulp1 =(Latje1-Latje2) * 111111.111
    Hoek1 = ATanD(Abs(XHulp1)/Abs(YHulp1))
    If Hoek1>=360 Then Hoek1 = Hoek1-360
    If XHulp1>0 And YHulp1>0 Then Hoek1 = Hoek1          '1e quadrant
    If XHulp1>0 And YHulp1<0 Then Hoek1 = 180 - Hoek1    '2e quadrant
    If XHulp1<0 And YHulp1<0 Then Hoek1 = 180 + Hoek1    '3e quadrant
    If XHulp1<0 And YHulp1>0 Then Hoek1 = 360 - Hoek1    '4e quadrant
    Return Hoek1                            'In degrees
End Sub

At least it gives some idea where to find the Moon, together with for example:
https://www.timeanddate.com/scripts/sunmap.php?obj=moon&iso=20170205T2015

Thank you very much for all your help!
 
Last edited:

Syd Wright

Well-Known Member
Licensed User
Update: I have added your SunPosition code to one of my libraries and indeed it now works very well!
The difference with the calculations by http://www.suncalc.org/ is only about half a degree, both for Azimuth and Elevation. I wonder who uses the most accurate algorythm :)
 

derez

Expert
Licensed 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
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
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
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
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
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
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.
 
Top