HOW TO: Plot Sunrise/Sunset line on a Map and learn how to use equations

Terminator2 Terminator - a tutorial demonstrating one way to create a sunrise/sunset equation display

Terminator :sunny: by SteveJG

      Sunrise/sunset line displayed on the MIT map component.


Display using the Aerial map type tiles on a 10" tablet.
Display using the default map tiles Roads.

This is an advanced tutorial made to shows ways to work with the Math Blocks and Map component to calculate a complex path and display it on a Map. The tutorial explains how an app was made to display the sunrise/sunset line (often called the Terminator) in real time on OpenStreetMap tiles. That's all it does. The tutorial shows the code required to build an app called Terminator and explains how the code works.

The position of the Terminator path on the map is within about +/- 10 minutes of actual setting/rising time for a specific location. The Terminator position compares fairly well a time determined by more
precise sunrise/set determination methods. If you discover a more robust calculation method to display the sunrise/sunset track, please let me know. I'm not an astronomer and based this app on materials /astronomical equations suggested in the Internet. Improvements are welcome.

Background
Almost 20 years ago I wrote a Windows program to plot the Sun's Terminator path (the Sun follows on the surface of the Earth) on a map using Object Pascal (Delphi) that displayed on a landsat image
(Landsat imagery courtesy of **USGS/NASA Landsat?. Various versions of the Mercator like map image are available at https://visibleearth.nasa.gov/images/73776/august-blue-marble-next-generation-w-topography-and-bathymetry
.

Terminator
Year 2000 Windows Terminator Plot

A developer recently asked in the Community how to plot the sunrise/sunset line with App Inventor. The Project conversion seemed simple enough. I dusted off the old Pascal code and started to port the code to AI2 using a Canvas.

It is possible to refactor the code to plot the sunrise/sunset line. I found it less complicated to return to the original astronomical equations and draw the Terminator on the Canvas or MIT Map component.
Re-coding, rather than 'convert' or refactor existing Pascal code, is less work and allowed easily coding the app to display on a dynamic map. I made App Inventor versions of Terminator that work with Canvas and Map. I only describe the Map component solution here. The Canvas version of Terminator is significantly more complex; World coordinates need to be converted to Canvas screen coordinates. The code demonstrating how to do the conversion on the Canvas needs cleaning up. I may post the code at a later date.

Building the Terminator app
The app is clever, calculating the position of the sunrise/sunset line using key information that exists in your Android device settings. The app uses simplified astronomical formula obtained from the Internet.

The Designer Interface

The Designer is simple. The app uses only a few native components (no extensions):

A significant issue designing an app like this is converting the mathematical equations required to App Inventor 2 Blocks. Learn how to use the Math Block External Inputs and Inline Inputs.
Here is an example showing two ways to write mathematical equations using Blocks: inlineExternal

The upper Blocks use Inline Input (the default), the lower Blocks use External Input. Both perform the calculation cos(b) * sin(distanceDegrees). Converting the Blocks to Inline Input often makes the blocks easier to read. The option helps you compare your hand written equation you are attempting to convert with the blocks you create. Select Inline Input or External Input by left clicking on a Block that performs and operation, then select the Block display format you want to switch to. How to do this simple equation seems obvious; where these tools become valuable is when you daisy chain Blocks and have a significantly more complex equation to resolve into AI2 Math Blocks.

Help with the Math Blocks is the documentation http://ai2.appinventor.mit.edu/reference/blocks/math.html .

The LocationSensor provides your geocoordinates to display your location on the map and centers the map display at your location at a default zoom of 4. The initial map tile zoom is set in the Map component. You can use a Block in your Screen1.Initialize event handler. I use centerFromString

to center the map on the USER'S location. MIT provides and recommends
panTo

Why? Using the PanTo block often glitches in this example, the CenterFromString code does not. Feel free to try the Pan Block, it might behave on your hardware.

The Blocks
All the code Blocks are shown at the end of this document. This is an advanced tutorial. A minimal explanation of the code and math required is provided.

The basic astronomical equations needed to calculate the position of the Terminator are discussed in this link:
https://en.wikipedia.org/wiki/Sunrise_equation . Gather all the mathematical formula required to calculate the path of the Terminator and read how the Terminator line can be calculated. A synopsis
follows:

How to display the path of the sun line

  • Calculate the declination of the Sun. This is a simple calculation if the day number of the year is known. Android makes calculating the day of the year easy. The Android system utilities provide a function that knows the days since the beginning of the most recent December 31st.
    The app you build uses that information with the Clock component.

dayOfYear
The day (February 2) is day number 33 in this example; the decimal part represents the current time.

You cam alternatively and independently calculate the day number the 'hard' way by using Blocks to determine the day of the year. The equations for the fractional year are
https://www.esrl.noaa.gov/gmd/grad/solcalc/solareqns.PDF (see the solareqens.PDF in the link ) which suggests the following":

γ = 2pi/365 x (day_of_year - 1 + (ℎ𝑜𝑢𝑟 - 12)/24 ).
For leap years use 366 instead of 365.

Determine d (the day number) with either the built-in Android routines or your Block code version of those routines. Next use approximations (simplifications) of more complex equations (on which this example is based) to provide a reasonably accurate Terminator path.

The following are astronomical approximations derived from more complex equations posted at
https://www.aa.quae.nl/en/antwoorden/zonpositie.html#v526

terminatorDeclination

Translate the Greek letter variables to something everyone can understand. Here is a key to the Greek letters in the equations: https://www.medcalc.org/manual/greek_alphabet.php

M = -3.6 +0.9856 * d where d is day number, M is the solar mean anomaly
( or more correctly, (-3.6 + 0/98560 x d) mod 360 )

v = M + 1.9 sin M where v is Greek letter Nu in the simplified formula

lambda = v + 102.9

declination = 22.8 * sin(lambda) + 0.6 sin3(lambda)

Greek delta is easier to understand if written " declination = (22.8) * ( sin(lambda)) + (0.6 * sin(lambda) * sin(lambda) * sin(lambda) "

Convert the equations to App Inventor 2 Math Blocks.
The most difficult part of creating the app is understanding the math in the algorithm. The calculateSunDeclination Procedure calculates declination using the above equations. The global M is determined using information provided by the Android operating system. Alternative Blocks to calculate 'M' for devices with Android operating systems lower than 5 are provided (disabled Blocks in the code snipped below). If you have an Android 4.2.2 device, substitute the colored block code with the example alternative set global M code. Unfortunately using the alternative blocks results in lower precision in the calculation of M. You can regain that precision by creating code to account for the
present local hour. I do not show how to do this with Blocks.


Procedure to calculateSunDeclination in Blocks

Continue calculating. You are not yet finished. The above Procedure determines the sun's declination but you need to do more math to obtain additional parameters.

How do you know your calculations are providing the correct results? Check for accuracy 1) by inspection of the results; 2) by comparing the declination with a spreadsheet you can download at
NOAA_Solar_Calculations_day, then compare the sunrise and sunset times for your location using https://www.esrl.noaa.gov/gmd/grad/solcalc/ or calculate using the following equations
http://www.jgiesen.de/astro/suncalc/calculations.htm or view a Terminator display on-line https://in-the-sky.org/twilightmap.php and compare the display to the app's display.

Math and Astronomical Notes:

  • the Earth rotates at an angular velocity of 15 deg/hour.
  • t = UTC hour
  • latitude is b = declination [that you just calculated]
  • longitude is l = 180 -15 * t If t is not between -180 and + 180 then
    add 360 or subtract 360 from the longitude
  • L = eastlongitude and B =northlatitude at a distanceG

Use the following astronomical equations from the link to calculate the latitude and longitude information required:
terminatorLatLon

and convert the equations that use Greek letters to something easier to understand and convert to Block code. Write the formula out:

B = arcsin(cos(b)sin(distanceG)) [where distanceG is Greek Psi]
x = -cos(l)sin(b)sin(distanceG) - sin(l)cos(distanceG)
y = -sin(l)sin(b)sin(distanceG) + cos(l)cos(distanceG)
L= arctan(y,x)

B is the latitude
L is the longitude

B and L respectively are the map coordinates calculated at any one time.

As one changes Psi from 0 to 360 degrees, these equations trace out the terminator position.

For distance from 0 to 360 calculate the above for changes in Psi.

Uh oh, App Inventor 2 does not have an arctan(y,x) function. App Inventor's Math Blocs has an arctan(y/x) function. The arctan function(y/x) is used in the Blocks instead of arctan(y,x).

Now try these Blocks. The for each number from iteration calculates the Terminator coordinates every 1/2 degree of Latitude starting at 0 incrementing each 0.5 degree.

Congratulations. You created a list of coordinates. When the locations defined by these coordinates are plotted on a map, the locations, when connected, provide a solid line representing the Terminator on the surface of the earth. The List of coordinates generated has this structure:

[[0.92725, -149.62555], [1.85447, -149.2509], [2.7816, -148.87586],[3.70861, -148.50022], [4.63547, -148.1238], [5.56212, -147.74639],[6.48854, -147.36779], ... [-0.92725, -150.37445], [0, -150.0]]
containing 360 sets (or pairs) of coordinates. The actual coordinates change with time.

How do I plot the coordinates
The Terminator coordinates calculated are provided as a List of latitude,longitude pairs) . Use a LineString with the coordinates to provide a 'trace' of the Terminator line. Plot the terminator ground trace line by setting LineString.Points to the terminatorList.

To display display a solid filled representation of the sunny versus night side of the earth, you need a Polygon on the Map. Show a display of illuminated versus non-illuminated Earth by setting Polygon1.Points to the terminatorList. Polygon1.FillColor provides a semi-transparent coloring of the portion of the map that is receiving sunshine.

You need these Blocks:
terminatorDrawingOnMap

The chaos begins.

At map tile zooms less than about tile zoom 5, a colored map centered on your location coordinates (provided by the LocationSensor) displays. At lower zooms (showing larger areas), you probably get some unwanted map display chaos that might look like this:


on your display. Obviously the instructions to the OSM server are confused. I suspect the map display chaos is a bug in the Map component or related to how Map displays the sinusoidal curve of the Terminator and issues with OpenStreetMap's api. I tried to ameliorate the chaos. I sorted the coordinate List, added points to close off the curve, etc. Nothing worked to eliminate the problem. I quit trying. 90 percent of the time, I get my desired results. The display problem is probably a bug in the Mapping components or in Leaflet (how OpenStreetMap ultimately displays map elements).

Will the Terminator calculation produce a correct graphic for you? This example works for a location in the northern hemisphere and west of the prime meridian. The example should also work for a location to the east (but untested). I suspect locations in the southern hemisphere may require adjustment. Appropriate negative signs somewhere in the equations might be needed outside the western northern hemisphere. Probably the algorithm to plot the Terminator is fine with the existing equations everywhere.

How to use the app

Install the apk on your device, then enable the app. The app uses your device's gps hardware. Be aware it takes up to a minute for the gps to become aware of where it is located. The map tiles come from the OSM server and may take a few seconds to display depending on that server's load and your WIFI or network connection speed.

The position of the Terminator updates each minute (the Clock2 event handler redraws the Terminator every 60000 ms ) automatically.

The Map opens as an OpenStreetMap Aerial map (2). Make a long press anywhere on the map display to toggle the map display between Roads (1) and Aerial (2). An Aerial Map type display might not available at all tile zoom values. Aerial is not available at all in some geographic areas at about tile zooms 18+ and the map option is not available on Android
4.2.2 and lower. What Aerial display is available depends on what data OSM has available for your region.

Default map settings are set in code. Modify the code and interface to provide more flexibility in your version of Terminator.

Requirements

  • the apps needs a WIFI or network connection to connect to the OSM tile servers.
  • you need to test the app using a real Android device (not the emulator) because the apps requires a LocationSensor and few emulators 'simulate' the gps hardware.

Issues

  • An 4.2.2 Android does not display Aerial [ to 'fix this' for that version of Android only and set Map1.MapType to 2 in the configure procedure]
  • An 4.2.2 Android does not like enhanced declination calculation. [Use the grayed out M calculation blocks . The enabled blocks work with all other versions of Android]
  • Android 5.1 is ok with Aerial map tiles and the declination calculation that uses operating system calls.
  • Android 8.1 is fine with all.
  • Sometimes the map mis-displays, this unfortunately cannot be avoided as far as I can tell.

The Terminator code was tested on Android 4.2.2 and 5.1 cell phones and an 8.1 tablet.

To Do
A javascript version might execute faster and handle the equations better.
A math extension might simplify the code.

Note that the Terminator - Solar Calculator is intended for recreational use only. The Terminator app uses mathematical approximations. Terminator can only provide approximate sunrise and sunset data.

All the Blocks

TerminatorMapDisplayFinal.aia (23.3 KB)

Best regards,
SteveJG

15 Likes

Massive :+1:

3 Likes

Thanks @SteveJG. This app makes me realize how lucky i was to pay attention in trig class... Thanks! It is so cool!

Thank you very much @SteveJG :smiling_face_with_three_hearts: :heart_eyes:

Wow!!! Great learning :+1:

Is there an iOS app for this?

Welcome Michael.

The aia that is part of the tutorial (TerminatorMapDisplayFinal.aia) works on Androids. The aia probably also works with App Inventor for ios. You should be able to compile it for ios and it may/probably will work OK Let us know what you discover. I do not have an ios device so I personally do not know how the code will perform on an ios.

--Steve