Mepo is a fast, simple, and hackable OSM map viewer for desktop & mobile Linux devices (like the PinePhone, Librem 5 etc.) and both environment's various user interfaces (Wayland & X inclusive). Its interface presents an SDL interactive application and auxiliary features are built out in scripts. The basic interface is essentially a OSM map that can be panned, zoomed, manipulated, and overlaid via 'pins' which are arbitrary points on the map which can be added by the user to mark locations (see below for a diagram of the general user-interface). Being a good unix citizen, the core application does one thing well, only focusing on displaying the map and visual overlays, and has no extra functionality; however mepo plays well with other applications and is scriptable and very customizable through its JSON API.
For end-users not interested in customizing the behavior of mepo, the
application is bundled with sensible defaults including a default set
of keybindings, touch-compatible configuration, and scripts written in
plain shell which enable features such as POI searches,
routing, and more. Throughout the rest of this guide it will
be assumed the user is making use of the default configuration and has
done no customization. See the install guide for
information on installation and ensure you have both the mepo
binary
and mepo_*
scripts installed before continuing.
The UI features a diagnostic bottombar which indicates a number of
numerical values based on the application state. Shorthand lettering
is used to save visual screenspace. The background color of the
bottombar changes based on tile downloading state. While in offline mode
(tile_cache_network
as 0
), the bar will
be red, while in online mode and idle the bar is white, while downloading
UI tiles the bar turns green, and while downloading background cache /
queued tiles the bar turns blue. See below for a visual labeling overview
of the bottom bar and explanation of each item.
tile_cache_network
is set to 1 or 0 for online or offline respectivelyThe UI features a bar of buttons in the default configuration
indicated as text aligned in a bar at the bottom righthand of
the screen. Under the hood this is actually built out using the
bind_button
JSON API command; so if you
want to add your own custom buttons (tied to userscripts, etc.) this
is doable.
$XDG_CACHE_HOME/mepo/savestate.json
$XDG_CACHE_HOME/mepo/savestate.json
The UI features a bar of buttons in the default configuration indicated
as text aligned in a bar at the top lefthand of the screen similar to the
bottom button bar. The difference between
this bar and the bottom bar is that this button bar only appears
when there is a currently activated pin (this built out using the
bind_button
JSON API command with the
first argument set to 1
). Additionally the items in the top bar utilze
bind_button
's group number functionality
for the 0-9
buttons to show a bar of color for each group transfer
button associated with the group's color (and also the currently active pingroup
will show as highlighted).
Using mepo on mobile linux devices such as the Pinephone, Librem 5, and postmarketOS devices and similar is a primary usecase. Take note of the following shortcuts:
Ordinary desktop usage is supported. Ordinary one finger gestures referenced in the touch & mobile section also apply on the desktop; and in addition numerous hotkeys exist to allow functionality such as panning with vim-style keys and direct hotkeys to launch various scripts.
You can reference the default hotkeys
by studying the default configuration. Take note of the
bind_key
commands to determine the
applications' default keybindings.
Since most auxiliary features such as routing, POI searches, etc. are built out in shellscripts (which utilize zenity for menuing & user input); the central menu provides a central way to launch different scripts on mobile via touch or on the desktop without having to remember numerous hotkeys.
Below is an image of how the central menu may appear:
Here's an explanation of each options available in the central menu. Within parenthesis after the script name is the associated hotkey for desktop users. Also note clicking on each item will show the script source for each:
droppinactivateandcenter
which both drops a pin on the map and centers the map. Meanwhile the function droppin
can be used in isolation to only drop a pin on the map in pingroup 6. This script may be used synchronously or asynchronously; within the default config droppin
is used asynchronously via shellpipe_async
. Note, due to deprecation of MLS; Geoclue may be less reliable or this script may not always work as expected recently - see: https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2959Points of interest within the current viewport (bounding-box) can be searched both via Nominatim or via Overpass using the default included scripts. Each of these methods has its advantages and disadvantages. Generally speaking, for specific name-based searches within a region, you should use Nominatim; while for flexible OSM-tag-based searches you should use Overpass.
As described above, Nominatim excels at name based searches. For
example if you wanted to find a restaurant called "Joe's Pizza" you could
type this directly into the Nominatim POI search script prompt. Or
similarly to find a starbucks, you could just type in "starbucks" in
the Nominatim prompt. Either select the Nm
UI button to launch
a Nominatim POI search or select POI Search: via Nominatim
from
the central menu.
Meanwhile, Overpass is more powerful and suited then Nominatim for
POI searches based on OSM tags; for example if you wanted to find
all coffeshops, (rather then just a specific name of a coffeshop such as
"starbucks" in the previous example) you could search for the general
OSM tag [amenity=cafe]
. This will find all OSM relations matching this
tag within the current bounding box. A number of prepopulated OSM tags
are available within the provided Overpass script; however if you want
to search any custom OSM tag, simply enter it and this will work just
the same. Either select the Op
UI button to launch
a Overpass POI search or select POI Search: via Overpass
from
the central menu.
Routing may be accomplished by two mechanisms:
As for end-user experience: Both of the routing scripts use the
same mechanism for determining from/to location to route and changing
parameters. Before launching either routing script, atleast 2 pins must
be active in the current pingroup which will be routed between (Note,
you can drop arbitrary pins on the map by using the Pins: Drop pin at
crosshair
script in the central menu or by pressing the f
hotkey). Once
the routing script is launched you will be presented with a number of
changable parameters as in the sceenshot below. It is very important to
realize that changed rows must be selected before hitting the 'Route'
button to confirm. Below is a screenshot of the route parameters menu:
Below is an example image of how a rendered route for GraphHopper may appear. Note each 'step' is added to the map as a pin in an ordered pingroup (and thus connected by a line):
You may reposition the map based on a Nominatim query.
Select from the central menu the entry entitled
Relocate map: via Nominatim
. You may also press the button in the
button bar entitled Relocate
to launch this
script as well. You will be presented with menuing to prompt for a
Nominatim query. You may enter a region (e.g. like Vancouver Canada),
a street address (like 20 Jay street), or a point of interest (like
Washington DC capitol). Nominatim will be queried and you may pick from
the resulting list to reposition the map.
You may also reposition the map based on geolocation select
from the central menu the entry entitled
Location Pin: center on user location
. This script uses either
Geoclue2 or GPSd to determine the user's position and both
drops a pin on the map at that location and repositions the map
as well to center on that pin. (Note: since the deprecation of
MLS,
the functionality of this script may be unreliable)
The clipboard may be used to run arbitrary JSON API expressions or relocate the map to an specific geocordinate. Currently in the default configuration clipboard functionality is only accessible via keybindings.
The keybinding y
yanks the current coordinates of the map into the
clipboard in the format of lat, lon
.
Meanwhile, the keybinding Shift-y
can either restore geocoordinates
(such as in the form lat, lon
as yanked with y
); or alternatively may
run JSON API expressions code if not fitting the lat, lon
pattern. Using
Shift-y
you may thus simply recall a previous location yanked with
y
(which is vaguely reminiscent of vim marks). If the pattern in the
clipboard does not look like geocoordinates, what's in the clipboard on
pressing Shift-y
will be run as JSON API code.
The defacto userconfiguration file is located at
$XDG_CACHE_HOME/mepo/config.json
(e.g. ~/.config/mepo/config.json
).
Within this file, you may store JSON API commands to run. Reference the
JSON API guide for more details.
A simple configuration file for mepo to store in ~/.config/mepo/config
to reposition the map to Boston, MA, US and have an arbitrary bookmark
pin named foopin placed on the map, might look like:
[
{
"cmd": "prefset_n",
"args": {"pref": "lat", "value": 42.3608}
},
{
"cmd": "prefset_n",
"args": {"pref": "lon", "value": -71.0573}
},
{
"cmd": "prefset_n",
"args": {"pref": "zoom", "value": 15}
},
{
"cmd": "pin_add",
"args": {
"handle": "foopin",
"pingroup": 3,
"lat": 42.355 ,
"lon": -71.0780
}
}
]
Both from the bottom bar Save
and Load
UI
buttons and in the central
menu scripts for the same, you can save and reload state.
State is saved as JSON API commands to the file
$XDG_CACHE_HOME/mepo/savestate.json
. The save and load functionality
can help you quickly test search queries, manipulate the map, and
subsequently reload a prior state.
In versions of Mepo prior to 1.3.0 autosaving/loading was integrated in the default configuration; after 1.3.0 autosaving/loading has been removed, and rather the user configuration file can be utilized if the user wants to automatically load something. If you want to restore autosave/load functionality as Mepo was configured prior to 1.3.0 had, you can add the following JSON API commands to your user configuration file:
[
{
"cmd": "fileload",
"args": { "filepath": "$XDG_CACHE_HOME/mepo/savestate.json"}
},
{
"cmd": "bind_quit",
"args": {
"exps": [{
"cmd": "filedump",
"args": { "datatypes": "rp", "filepath": "$XDG_CACHE_HOME/mepo/savestate.json" }
}]
}
}
]
Mepo prioritizes offline usage as a first-class usecase. The mepo
application itself presents an SDL2 view of OSM tiles on the map along
with a background thread that interfaces with curl for downloading
tiles. This background downloading thread has the ability to be completely
disabled through a JSON API preference
named tile_cache_network
(when the tile_cache_network
property is 0,
you'll see the bottom bar turn red and O0
indicating Mepo is offline;
otherwise you are online by default). Do note tile_cache_network
does not effect any scripts called.. if you wish to use scripts
utilizing Nominatim or Overpass etc. offline for example for running
your own instances locally, these ENV parameters are customizable (see
the associated mepo_* scripts in your PATH).
Downloading tiles interactively (via UI): By default, dragging
the map will download tiles on the screen as needed assuming you are
online (tile_cache_network
is set to 1
). In addition to this default
behavior; the button bar entry labeled Dl
will download all tiles in the current viewport (current zoom level and
higher) to the filesystem cache. (E.g. so you may zoom out and download
an entire givne region for all zoom levels). Additionally; you may
also select Download: current bounding-box (non-interactive)
from the
central menu for the same functionality. The entry
Download: custom region (interactive)
in the central menu allows you
to download a custom region via Nominatim
search query.
Downloading tiles non-interactively (via commandline): It's a
common use case to need to download an entire block / bounding box of
tiles while online before going offline. For example, say if you want
to use your phone with mepo but are not sure you'll not have internet
access at your destination. To facilitate downloading of tiles, you
may do this from the UI using the Dl
button as described above,
but mepo additionally features a non-interactive tile downloading CLI
accessible through using the -d
flag. This flag should be suffixed
with a list of 6 comma separate parameters (no whitespaces) in the form
of lat_a,lon_a,lat_b,lon_b,zoom_min,zoom_max
. Zoom min and max can
range from 0-16. For example, to download a bounding box:
mepo -d40.74946,-74.04673,40.818358,-73.88211,3,16
This may be a bit more involved then you would like
to get, so as an alternative you can use the provided
mepo_dl.sh
script which provides a prompt-driven dialog which queries
Nominatim to determine the bounding box to
download and then feeds this into mepo -d
. Run this script as:
mepo_dl.sh
The script bundled with mepo named mepo_geojson_import.sh
can be used
to convert standard GeoJSON to the relevant JSON API
pin_add commands. This script may be used in a few different ways.
You can add the GeoJSON converted points to your config by appending the result to your config:
cat my_geojson_file.json | mepo_geojson_import.sh > ~/.config/mepo/config.json
Or this script may be in combination with mepo's -i
flag to turn mepo
into a standalone GeoJSON viewer (note: see more details on using mepo
-i here). For a quick example: alternatively
to using the Mobroute interactive routing script as explained in the
routing section above, you directly can view the output of
mobroute CLI's generated GeoJSON routes
directly on boot in mepo via:
mobroute run route -rp '
{
"route_params": {
"feed_ids": [ 1088 ],
"from": [ 50.85728, 4.351426 ],
"to": [ 50.83214, 4.350534 ],
"transfer_categories": [ "f", "i" ],
"output_formats": [ "geojson" ]
}
}
' | jq '.geojson' | mepo_geojson_import.sh | paste -sd' ' | mepo -i
Mepo features an extensible JSON API which is used both for end-user configuration and arbitrary scripting. See the JSON API page for configuration details; and scripting guide for more information on JSON API usage.
-docmd
: Print markdown documentation for the JSON API to STDOUT.-i
: Read JSON commands from STDIN continually (newline seperated). Can be used for interactive debugging or scripting via: tee | mepo -i
or ./myscript | mepo -i
.-e
: Enable debug mode to log messages to STDERR.-hw
: Force using hardware renderer rather then default auto (HW/SW) renderer.-sw
: Force using software renderer rather then default auto (HW/SW) renderer.-tx#
: Number of textures to load to (GPU) memory for both OSM & pile tile layer cache (defaults to 200).-v
: Print version number.-h
: Print this help text.-dlat_a,lon_a,lat_b,lon_b,zoom_min,zoom_max
: Non-interactively download tiles for given range.