I love my Coros Vertix 1 and it’s awesome that Coros added support for mapping in an update, for free.
But while the Open Street Map based map material they provide is nice, it just doesn’t come close to the official SwissTopo
map data for Switzerland.
As can be seen, the Coros/OSM material contains very few forests, does not contain all wetland, roads differ a bit in size and
the height contour lines are pretty low resolution (e.g. in the lower left corner), among other things.
When navigating in the wilderness, I want as much detail as possible so I can know where I’m at.
Unfortunately, there’s no other map material available for the Coros watches and scouring the internet I couldn’t find anyone
that got custom maps running on their watch.
So I decided to reverse-engineer the Coros and try and get the SwissTopo maps onto my watch. And write it down to save others the trouble.
If you’re just interested in the map files and not the technical details, you can skip to then end.
Maps for Coros watches can be easily downloaded by region on the Coros download page. When downloading,
one can select the region to export, making it easy to only select Switzerland for our purposes.
We can download a Landscape Map (Containing roads, forests, rivers etc.) or a Topo map (containing contoure lines).
Looking at the downloaded Zip files, they contain various folders and subfolders.
The instruction pdfs are just about installing the maps, but they don’t contain any helpful information on the maps themselves.
The GM folder always has the same contentno matter the region we select, so it isn’t helpful, either.
The OSM folder (For Landscape maps, it’s CM
for Topo maps but otherwise identical) is where it gets interesting. There are many
different files that change depending on which region we select. So they are likely the ones containing the actual map material.
Also note folders OSM/0/35/
and OSM/0/51/
, which are included in every download no matter what region is selected and don’t change.
More on these later.
For now we can focus on the 46
-48
folders. We can see that the filename matches the folder structure a file is in, with Landscape map
files starting with S
and Topo map files starting with C
as the filename, respectively.
The files contained end in .csm
and a quick search tells us that this is used by the 3ds Max
3d animation software, not related to
maps at all, so that can’t be right.
Looking at the content of the files in a hex editor, we see some headers and data that give us a clue as to the format:
Not too much meaningful information here, but the strings GARMIN
and DSKIMG
appear in there. Searching for those turns up the normal
Garmin .img
map format.
So it looks like the maps are actually in Garmin format and Coros just changed the file extension. Though with Garmin we usually get
a gmapsupp.img
file along with some supporting files, not the folder structure we’re seeing above.
Renaming the files to the .img
extension and opening them with GMapTool confirms
that they are indeed Garmin maps:
As we can see, this file (S0470007.img
) covers a map segment N: 47.999997, S: 47.000005, W: 7.000008, E: 8.000000
, or rounded
N: 48, S:47, W: 7, E: 8
. Could it be that the 47
and 7
in the filename refer to the map segments south and west coordinate,
with each map being a 1° degree by 1° degree area?
Looking at the other files, this is indeed the case. The folders 0
and 1
denote the sign of the coordinates, with 0
meaning +
1
meaning -
. Some files end in L
or R
, which just means left or right. In those cases, each file is only a 1° by 0.5° degree section,
which I think is just there to work around maximum file size limits for Garmin .img
files.
This also sheds some light on the two other folders mentioned above, OSM/0/35/
and OSM/0/51/
. S0350139L.csm
maps to coordinates
N: 35°, W: 139°
, an area containing Tokyo, and S0511001L.csm
maps to N: 51°, W: -1°
, which contains London. For some reason,
Coros decided to include those two map segments in every download, essentially wasting space on the device for no good reason that
I could discover. Deleting those folders does not interfere with the functioning of the device in any way.
Now that we know the format the maps are in, we can try and turn the SwissTopo maps into the same format.
The vector map material for the SwissTopo 10m resolution maps can be freely downloaded from the SwissTopo download page.
I downloaded all the sectors as Geopackage (ZIP)
format, because Geopackages can be easily opened with QGis,
a common mapping/GIS tool. All the files together are around 150gb and took around me 3 hours to download.
Since all the sectors are in individual Zip files, we need to extract all of them and combine them into a single Geopackage
using GDal:
Now we have a file target.gpkg
that contains all the Swiss map sectors combined, which we can open in QGis.
You can see the layers I selected, some of them in the SwissTopo data aren’t relevant for our purposes. Unfortunately, buildings and
railways aren’t rendered on the Vertix, so I didn’t include them in the final map (Sure would be nice to see mountain huts. Something
to work on for the future).
One peculiarity of the SwissTopo map is that some features are represented as points instead of areas. These include sparse forest, swamp
and shrubland. I used the DBSCAN
clustering to group those points together and then the n-nearest neighbors concave hull
command to turn
them into proper areas so they are usable in the map. Unfortunately this fails for shrubland (too many points?) but we can live without it.
Once this is done, we can export each layer to a file in the ESRI Shapefile format as a starting point for creating maps.
The most common open-source tool for creating Garming .img
files is mkgmap and I decided to go with that.
Since it only accepts Open Street Map (.osm
) files, we have to convert our ESRI Shapefiles to .osm
somehow. This is not that easy,
as a lot of the scripts have limitations in regards to size of file they can process, the amount of memory they need and what data they
accept, mostly because they were intended for Open Street Map data. Many of the tools also expect unique ids for individual map elements/points,
so we’re just going to number them starting at -1 (negative numbers are arbitrary ids), later changing the sign to positive so other
tools can work with it.
The tools used are ogr2osm and Osmium.
We now have an .osm
file that can be converted to a Garmin .img
using mkgmap. The Open Street Map wiki
has a lot of details on this process and is an invaluable resource for creating Garmin maps. This project certainly wouldn’t
have been possible without it.
The gist of it is that you give mkgmap an .osm
file and a style file that tells it how to convert data to garmin format.
For instance, OBJEKTART=Wald | OBJEKTART=Wald_offen_Symb [0x50 level 2]
in the style file lets mkgmap know that any element in
the .osm
that has OBJEKTART=Wald
(Forest) or OBJEKTART=Wald_offen_Symb
(Sparse Forest) should be rendered as Garmin type code 0x50
and that it should only show up at zoom level 2 or below.
It took me a while to figure out all the type codes that the Coros Vertix successfully renders, but through trial & error
I managed to create a style file that renders nicely.
All that was left was cutting the map into appropriate 1°x1° segments (or 1°x0.5° with L
/R
suffix where the resulting file size was too
big for Garmin .img
) using a small python script I wrote and Osmosis,
and to then convert each segment using mkgmap, with another small python script.
I repeated the same process for the Topo/contour lines maps. This was a bit trickier due to reaching data/memory limits in Shapefiles and ogr2osm,
as well as the contours being too detailed for Garmin .img
file sizes. In the end I settled for including only multiples of 20m height (same as
the original Coros maps), and simplifying the lines a little bit with a deviation of 5m, better than the ~30-50m of the original material.
Copying all this to the watch and, it works!
My map is in the top row and the official one at the bottom. You can see the small islands in the lake in the top right picture
(my version), along with the light-blue shaded area denoting wetland, both of which aren’t in the Coros maps. The rivers also show real contours as
opposed to being mostly just lines in the Coros maps. My map does not show highways as bold/in color as the Coros one, since those are rarely
useful in the mountains and I don’t intend to use my watch for car navigation. I also decided to show more height contours when zoomed out,
as this is useful to get an overview of the surrounding area. Also note that in the bottom left picture, the Coros map does not show
the forest in the hills next to Lake Zurich, even though forests can be very helpful in navigation and those are some major forests.
My Landscape maps are roughly 20% bigger in file size than the corresponding Coros maps and my Topo/contour maps are roughly 50% bigger in
file size. Despite this, my maps seem to load smoother on the device when zooming in/out or dragging the map around. I think this is due
to my maps using a larger block size in the Garmin .img
files, which internally use a FAT32 filesystem.