Kia Maidenhead Grids ... calculate Amateur Radio location Grids automatically using GPS

kia Maidenhead Grids App Inventor tutorial to calculate Amateur Radio location Grids automatically using GPS. Build the kiaGrids app.

Maidenhead locator grids are a geocoordinate location system used by radio amateurs to communicate their approximate location to other radio amateurs. The six character locator is sometimes used in contests, sometimes in SkyWarn communications. The Maidenhead locator define a location using four to six alphanumeric characters (instead of latitude and longitude coordinates).

This Intermediate level tutorial shows how to build an Android Maidenhead grid calculator called kia Maidenhead Grids (kiaGrids).

This example identifies EM13na.

The app Maidenhead Grid updates automatically as the device changes its location to another grid. The example app must be tested on an Android device having a GPS receiver. The app can also manually calculate the grid of any coordinates you provide.

Grid calculation is automatic with GPS when you select Get GPS Location to enable the LocationSensor. Manual grid calculation is available using the Text box input. Use the Change Enter Coordinates button to do a grid calculation based on any coordinates. Enter the latitude and longitude in the textboxes (labeled 1 and 2), enter the coordinates (overwrite the default 0,0 values). Follow up by pressing the Calculate Entered Grid button (labeled 3) to do the calculation.


Entering 0,0 results in a Grid JJ00aa .

The Calculation - What is a grid locator and how to calculate a Maidenhead Grid from Geocoordinates

Wikipedia has a good description of how the basics of the Maidenhead Grid system works. The grid system was defined as in the illustration using alpha numeric character locator designators . Here is a graphic showing grid EM highlighted in red.

Grid image modified from Wikipedia.

“To simplify manual encoding, the base for the first pair of letters—traditionally called a field—was chosen to be 18, thus dividing the globe into 18 zones of longitude of 20° each, and 18 zones of latitude 10° each. These zones are encoded with the letters "A" through "R".

The world is divided into 324 (18²) Maidenhead fields.
The first pair of numbers, called a square and placed after the first pair of letters, uses a base number of 10, and is encoded using the digits "0" to "9". This is where the alternative name "grid squares" comes from. Each of these squares represents 1° of latitude by 2° of longitude.
For additional precision, each square can optionally be sub-divided further, into subsquares. These are encoded into a second pair of letters, often (but not always) presented in lowercase, and again, to make manual calculations from degrees and minutes easier, 24 was chosen as the base number, giving these subsquares dimensions of 2.5' of latitude by 5' of longitude. The letters used are "A" through "X".
The resulting Maidenhead subsquare locator string is hence composed of two letters, two digits, and two more letters." My station grid is EM13na. to give an example

Two points within the same Maidenhead subsquare are always less than 12 km apart, which means a Maidenhead locator can give significant precision from just six easily transmissible characters.”

The app in this tutorial calculates a Maidenhead grid from latitude and longitude information using the algorithm in the app’s Procedure called determineMHGrid. Latitude (myLat) and Longitude (myLon) are in decimal degrees. The pseudocode in Table 1 shows how the App Inventor 2 blocks use the algorithm to calculate the grid terms described above. The app determines which grid the Android is currently located in with GPS or an inputted pair of geocoordinates.

Table 1. Grid Calculation Pseudo-code Algorithm used in the Procedure determineMHGrid .

Calculate the first two terms: (e.g. EM)
theLat = originates from the contents of Textbox1 + 90 or the LocationSensor (which places the latitude into Textbox1).
thelon= originates from contents of Textbox2 + 180 or the LocationSensor (which places the longitude into Textbox2).
theLat = (mylat / 10 ) + 0.00001
theLng = (myLng / 20 + 0.00001
locator = floor(theLon)
H1 = floor((theLon)
replace the numeric value with a character
H1 = the item at index of floor(locator) + 1 in AlphaList
locator2 = floor(theLat)
H2 = floor(locator2)
replace the numeric value with a character
H2 = the item at index of floor(locator2) + 1 in AlphaList

Calculate the second two terms: (e.g. 13)
theLat = 10 * theLat – floor(theLat)
theLon = 10 * theyLng – floor(theLng)
H3 = floor(theLng)
H4= floor(theLat)

Calculate the next two terms: (e.g. NA)
theLat = 24 * theLat – floor(theLat)
theLon = 24 * theLon – floor(theLon)
locator = floor(theLon)
locator2 = floor(theLat)
replace the numeric value with a character
H5 = the item at index of floor(locator) + 1 in AlphaList
H6 = the item at index of floor(locator2) + 1 in AlphaList

Display the grid (e.g. EM13na)
H7 = join Label1 through H6 using the Text join, this is the Maidenhead six character grid locator.

AlphaList is a List of the first 24 characters of the alphabet. The function floor( ) effectively truncates the decimal part of the value in the brackets. Index is the position of a character in AlphaList. H1 - H7 are local variables.

The AlphaList is the following string of 24 characters: A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X

The Designer Screen

Object layout is not critical. This image shows the layout for the app. Several Vertical and Horizontal Layouts, Labels used as ‘spacers’ and other techniques are used to create the app screen. Note the non-visible components required to complete the app.

The Required Blocks
The blocks in the app are native Blocks (no extensions are used). There is a generous use of Math blocks in the determineMHGrid Procedure.

The determineMHGrid Procedure is described in Table 1 in pseudo-code. Here are the blocks to make the Procedure:

Screen1.Initialize sets the default conditions.

The LocationSensor is coded to fire every 20 seconds to attempt a satellite fix change. More frequently is not recommended 1)battery drain 2) on average, most devices require about 20 seconds to get a satellite fix. Note the actual time is set to 20100 ms to help avoid possible collisions with the Clock2 events. Set Clock2 to fire every 1.6 seconds perhaps. The TTS speech rate can be slowed slightly (0.9) from the default 1.0 to make the announcement more understandable if you set the rate.

The LocationSensor block stores geocoordinates directly in the Text boxes rather than in variables. Variables could have been used to store the geocoordinate, however, Text boxes works better to toggle the app between the manual and automatic modes.

Button1 (Calculate Entered Grid) contains the code to ‘manually’ calculate a grid from geocoordinates input directly into Textbox1 and Textbox2 (Latitude and Longitude input).

Button2 (Get GPS Location) requests the permission FineLocation, sets the ProviderName to gps, locks the permission (to avoid the app using the
Provider Google introduced with Android 11 that lets the Android decide whether to us WIFi or cell data instead of the GPS hardware), and sets the LocationSensor.TimeInterval to slightly more than 20 seconds.

Button3 (Enter Coordinates) makes the manual grid coordinates controls visible to allow calculation of a grid without using the device's location.

The Clocks and Check Boxes

Checkbox1 turns the TTS (TextToSpeech) on or off selecting a vocal grid announcement with text or a text alone indication of the grid locator.

Clock1 has a simple kludge code to prevent the app from going to sleep and to StayAwake in the foreground. The kludge has consequences. AI2 apps cannot run in the background without an extension. Rather than continuously touching the screen to turn on the Android screen you have an option that rapidly drains the device’s battery but allows Maidenhead Grids to run continuously. The 10 seconds text shown above does not display because the text color is set to none. The text is a reminder the clock interval is set to about 16 seconds (16000 ms). The interval input here depends on how quickly your device normally goes into sleep mode. The Clock.Timer event prevents the Android screen from going dark as it constantly posts the invisible message using the Notifier2 component.

App Inventor apps, as this is written, cannot run in the background without an extension. When the phone ‘sleeps,’ the app stops working. For users requiring the app to remain open constantly, the app uses a kludge to keep the phone on. Clock1 fires every 16 seconds as presently coded in it's Properties. This interval you chose is dependent on how quickly the phone goes into sleep mode and might have to be modified to suit the device the app is used on. The Clock posts a Notifier (made invisible - set the Notifier background and text color properties to none or 16777215). Setting these properties to none makes the Notifier and text transparent and ‘invisible.’ The downside is excessive battery use. I recommend you plug in your Android device (using a vehicle’s power receptacle perhaps) when StayAwake is set checked.

When first run, the app may take up to 60 seconds or more to achieve a satellite fix with the gps.

The aia File
The MaidenheadGrids aia file is the full app.
kiaGridsMaidenhead.aia (19.9 KB)

Important Facts
The tutorial and the Maidenhead Grids app are copyrighted. Please do not slightly modify this tutorial and claim it as your own or post Maidenhead Grids on Google Play or on any Web page. Have fun with the app for personal use. Use the algorithms and ideas in your own app and enjoy coding.

A similar Maidenhead grid app (without GPS capability) is described in the August 2015 QST magazine.(Program Android Amateur Radio Apps with MIT App Inventor 2 by Steve Gradijan, WB5KIA; QST Magazine, August 2015)

This tutorial, images within the tutorial and Maidenhead Grids are Copyright © 2015 -2023 by SJG.

How to calculate Maidenhead Grids with javascriipt.