SOTA Layer for OsmAnd


I am seeking opinions as to whether anyone is interested in a SOTA layer file for OsmAnd.

OsmAnd is a full-featured mapping program for Android. It uses the free OSM data to draw maps on your screen, and also provide search and navigation functions. The OSM data is downloaded to your Android device and rendered locally, i.e. once you have the data you don’t need an internet connection to draw maps or navigate.

I have been curious about how to make my own POI layer file for OsmAnd to overlay on top of everything else. The documentation is a bit sparse, but I finally got something working.

Step 1) Make an OSM XML file containing POI information. It looks a bit like this:

<?xml version='1.0' encoding='UTF-8'?> Step 2) Process this file with OsmAnd Map Creator (using the Build POI Index option only) and create an .obf file. Step 3) Copy the .obf file to the OsmAnd directory on your phone.

If you download the summits.csv file (containing all summit information) the first step can be done with a small Python script I wrote. The second step can be manual or automated.

Is anyone using OsmAnd who would like a layer file? I will deal with the first six requests (please tell me Association and Region). If there are a huge number then I’ll have to automate it. If there is a small number I’ll just keep it to myself.

Feel free to ask any questions.



1 Like

Hello Andrew

My solution is simple, needs no programming: OruxMaps can display map overlays in KMZ format. From the SOTAmaps website I download summit lists in KMZ format and can use them immediately in OruxMaps. Summits appear as waypoints. All summit details are visible in the waypoint properties.

73, Markus HB9BRJ

1 Like

I didn’t know that. It took me longer to figure out how to export the KML data from SOTAmaps website than to transfer it to my phone. Hit the “draw KML overlay”, select the downloaded file and pazooooow… the summits appear on the map.

I used Oruxmaps extensively in Germany and France last week to do general navigation never mind summit location. This makes it just so much more useful. Markus, thanks for this as it lets me use SOTAmaps for planning and Oruxmaps for navigation.

I don’t have (or want) OruxMaps, but it’s good to know this is possible.

I like OsmAnd, and I am happy to have SOTA summits on it now.



You could of course generate a personalized layer, for example using QGIS as outlined in this posting:

Locus maps will also happily import kml. The fact that I have a SOTA list permanently installed on my maps can make my wife nervous any time we are actually trying to get somewhere in case I spot a nearby summit!

From what I read GPX might suit OsmAnd better. No problem exporting from QGIS or indeed using

I use osmand, can you please send me sota layer for italy?


73 de IZ3GME Marco

Ok. I put some samples on my github, including Italy. I haven’t tested it, so let me know if it’s broken. Thanks.

I think OsmAnd only imports GPX and displays them as waypoints, which is no good.

The OsmAnd “favourites” are stored internally as GPX, so it should be possible to add summits to that file, but I didn’t try it yet. It might clutter the favourites file, or be too tedious to merge in with existing favourites.

The Python script is on my github too, if anyone wants to play.



You also need to find the correct place to put the file.

There are two similarly-named folders on my phone. The right one is SD card/Android/data/

You can see the location in OsmAnd by choosing Settings, then General Settings, then look for “Data storage folder”


What’s wrong with GPX? I have uploaded onto my smarthphone’s Osmand HA SOTA summits as waypoints.
Here is a schreenshot.
I am happy with it.
73 viktor HA5LV

Nothing wrong with that, but my POI layer shows the SOTA ref, summit name, and number of points. It also has a note of the number of activations and the last activation. The summits are searchable and routable (and, as you probably know, OsmAnd will plan a walking route if there are hiking paths in the OSM database)



OK Andrew you convinced me.
I’ll try to make OBF as you mentioned earlier.
Thanks for the hint, and your effort. GL for SOTA.
73 Viktor HA5LV

Actually, you convinced me too!

I am going to prepare a GPX version of the summitslist.csv and compare the functionality.



Ok, I wrote a quick Python script to make a GPX file from summitslist.csv

I used the same concatenation of fields for the name, and put the activations in a note. I also graduated the colours, from blue (1pt) to red (10pts).

I don’t know if it’s better, but it works. It has the advantage that I don’t need OsmAnd Map Creator.

Here’s what it looks like:

Ok, you can find the code at my github.

It’s called

There are two extra files in the examples folder, one is HA_favourites.gpx and the other is I_favourites.gpx (for IZ3GME).

You have to rename it to favourites.gpx and put it in your OsmAnd files folder.



You can also try this , and the files generated on the

Thanks. I took a look, but I prefer to add more fields into the name. Right now I make the ‘name’ field from the SOTA ref + summit name + [points], so it’s immediately visible on the map.

The ‘note’ field contains the total number of activations and the last activation (callsign + date).

I like your idea of including the SOTA summit page url. I might do that.



Andrew did a good job!
I have improved a little his
Now it skips lines of summitslists.csv with format errors and outdated summits
You can convert more than one area at once.
call it like: FL/VO,HB,DL/BW
Import the favorites.gpx as tracks into osmand!
Thanks to Andrew!

here is the code:

#!/usr/bin/env python3

#Python program to extract country-specific SOTA peaks from "summitslist.csv"
#and write out a GPX file, "favourites.gpx".  This can be copied directly
#to the OsmAnd file directory on an Android phone.  OsmAnd will import and
#merge the peaks with existing favourites so that SOTA peaks can be viewed
#on the OsmAnd screen. Import it as Track

#import selected summits: FL/VO,HB,DM/BW

#0: SummitCode
#1: AssociationName
#2: RegionName
#3: SummitName
#4: AltM
#5: AltFt
#6: GridRef1
#7: GridRef2
#8: Longitude
#9: Latitude
#10: Points
#11: BonusPoints
#12: ValidFrom
#13: ValidTo
#14: ActivationCount
#15: ActivationDate
#16: ActivationCall

import argparse
import sys
from datetime import date

parser = argparse.ArgumentParser()
                    help='SOTA region to extract, e.g. G/ or G/CE')

args = parser.parse_args()

if args.region is None:
    print("Region must be specified.")

keys = args.region.split(',')       # First part of SOTA ref. to match (can be as long as you like)

print("Extracting '%s'."%keys)

id = 2     # Internal counter

#Colours for each point level.  Gradient from green to red.
colours = {'1':'00FF00', '2':'65FF00', '4':'CCFF00', '6':'FFCC00', '8':'FF6600', '10':'FF0000'}
e = open ('errors.txt','w',encoding='utf-8')
with open('favourites.gpx', 'w', encoding='utf-8') as o:

    o.write('<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n')
    o.write('<gpx version="1.1" creator="" xmlns=""\n')

    with open("summitslist.csv", encoding='utf-8') as f:
        line=f.readline() #skip header
        for line in f:
            for key in keys: #select all keys
                if line[:len(key)]== key: 
                    fields = line.split(',')
                    # Name is "SOTA ref. Name [Points]"
                    name = fields[0] + ' ' + fields[3] + ' [' + fields[10] + ']'
                    if len(fields)!=18: #error in datafields: ignore
                        error=' # of fields:'+ str(len(fields))+' line:'+ str(id)+' contents: '+line
                        if int(fields[13].split('/')[2])> #only activated summits
                            id += 1
                            activations = fields[14] + ' activation' + ('.' if int(fields[14])==1 else 's.')
                            if int(fields[14]) > 0:
                                activations += '\nLast ' + fields[16] + ' (' + fields[15] + ').'
                            # Activations go in 'desc', with URL.
                            o.write('  <wpt lat="%s" lon="%s">\n'%( fields[9],fields[8]))
                            o.write('    <ele>%s</ele>\n'%(fields[4]))
                            o.write('    <name>%s</name>\n'%(name))
                            o.write('    <desc>%s\n</desc>\n'%(activations,fields[0]))
                            o.write('    <type>SOTA %s</type>\n'%category)   # SOTA + Association + Region
                            o.write('    <extensions>\n')
                            o.write('        <color>#%s</color>\n'%colours[fields[10]])
                            o.write('    </extensions>\n')
                            o.write('  </wpt>\n')  
print("%s POIs extracted."%abs(id))