FOSS driving directions in Nextcloud

peacecop kalmer:
Jun 24, 2020 · 7 min read

As I wanted to find a free and open source (FOSS) alternative to Google Maps, I did a research, tested Graphhopper and OSRM and finally got to work OSRM. If you want to run a FOSS map that offers driving directions on your own server feel free to follow my instructions.

First, you need Nextcloud. Or if you have an alternative to Nextcloud that can read JSON from OSRM output you can use that. I use Nextcloud so my instructions base on that.

First, they say that we need all of that:

sudo apt install build-essential git cmake pkg-config libbz2-dev libstxxl-dev libstxxl1v5 libxml2-dev libzip-dev libboost-all-dev lua5.2 liblua5.2-dev libtbb-dev libluabind-dev

Then, clone, build and install:

kalmer@tomekit-ubuntu-server:/projektid$ git clone https://github.com/Project-OSRM/osrm-backend.git
Cloning into ‘osrm-backend’…
remote: Enumerating objects: 80297, done.
remote: Total 80297 (delta 0), reused 0 (delta 0), pack-reused 80297
Receiving objects: 100% (80297/80297), 30.59 MiB | 1.11 MiB/s, done.
Resolving deltas: 100% (57891/57891), done.
kalmer@tomekit-ubuntu-server:/projektid$ cd osrm-backend/
kalmer@tomekit-ubuntu-server:/projektid/osrm-backend$ mkdir build
kalmer@tomekit-ubuntu-server:/projektid/osrm-backend$ cd build
kalmer@tomekit-ubuntu-server:/projektid/osrm-backend/build$ cmake ..
kalmer@tomekit-ubuntu-server:/projektid/osrm-backend/build$ sudo make install

The installation process lasts long.

Then, you need a map that you can download from OpenStreetMap Data Extracts. As I need mostly routes in Estonia, I downloaded estonia-latest.osm.pbf. I did put it directly in the folder osrm-backend.

Then, you need to do some things on that map:

kalmer@tomekit-ubuntu-server:/projektid/osrm-backend/build$ cd ..
kalmer@tomekit-ubuntu-server:/projektid/osrm-backend$ osrm-extract estonia-latest.osm.pbf

So far, the whole thing has eaten about one gigabyte of physical storage.

There are two more things to do before we can start the program:

kalmer@tomekit-ubuntu-server:/projektid/osrm-backend$ osrm-partition estonia-latest.osrm
[info] Computing recursive bisection
[info] Loaded compressed node based graph: 406384 edges, 943307 nodes
[info] running partition: 128 1.2 0.25 10 1000 # max_cell_size balance boundary cuts small_component_size
[info] Found 775653 SCC (1 large, 775652 small)
[info] SCC run took: 0.068297s
[info] Full bisection done in 2.02963s
[info] Loaded node based graph to edge based graph mapping
[info] Loaded edge based graph for mapping partition ids: 1483588 edges, 393645 nodes
[info] Fixed 29 unconnected nodes
[info] Edge-based-graph annotation:
[info] level 1 #cells 1985 bit size 11
[info] level 2 #cells 139 bit size 8
[info] level 3 #cells 11 bit size 4
[info] level 4 #cells 1 bit size 1
[info] Renumbered data in 0.584086 seconds
[info] MultiLevelPartition constructed in 0.053047 seconds
[info] CellStorage constructed in 0.071956 seconds
[info] MLD data writing took 0.042443 seconds
[info] Cells statistics per level
[info] Level 1 #cells 1984 #boundary nodes 34601, sources: avg. 11, destinations: avg. 16, entries: 455138 (3641104 bytes)
[info] Level 2 #cells 139 #boundary nodes 4783, sources: avg. 22, destinations: avg. 32, entries: 122726 (981808 bytes)
[info] Level 3 #cells 11 #boundary nodes 619, sources: avg. 37, destinations: avg. 53, entries: 26384 (211072 bytes)
[info] Level 4 #cells 1 #boundary nodes 0, sources: avg. 0, destinations: avg. 0, entries: 0 (0 bytes)
[info] Bisection took 3.59743 seconds.
[info] RAM: peak bytes used: 197586944

The second thing to do:

kalmer@tomekit-ubuntu-server:/projektid/osrm-backend$ osrm-customize estonia-latest.osrm
[info] Loaded edge based graph: 1483588 edges, 393645 nodes
[info] Loading partition data took 0.39564 seconds
[info] Cells customization took 1.15302 seconds
[info] Cells statistics per level
[info] Level 1 #cells 1984 #boundary nodes 34601, sources: avg. 11, destinations: avg. 16, entries: 455138 (3641104 bytes)
[info] Level 2 #cells 139 #boundary nodes 4783, sources: avg. 22, destinations: avg. 32, entries: 122726 (981808 bytes)
[info] Level 3 #cells 11 #boundary nodes 619, sources: avg. 37, destinations: avg. 53, entries: 26384 (211072 bytes)
[info] Level 4 #cells 1 #boundary nodes 0, sources: avg. 0, destinations: avg. 0, entries: 0 (0 bytes)
[info] Unreachable nodes statistics per level
[info] Unreachable nodes statistics per level
[info] Unreachable nodes statistics per level
[info] Unreachable nodes statistics per level
[warn] Level 1 unreachable boundary nodes per cell: 0.00252016 sources, 0.00403226 destinations
[warn] Level 2 unreachable boundary nodes per cell: 0.0215827 sources, 0.0215827 destinations
[warn] Level 3 unreachable boundary nodes per cell: 0.181818 sources, 0.181818 destinations
[info] MLD customization writing took 0.040721 seconds
[info] Graph writing took 0.045656 seconds
[info] RAM: peak bytes used: 122253312

Now you can let it fly:

kalmer@tomekit-ubuntu-server:/projektid/osrm-backend$ osrm-routed --algorithm=MLD estonia-latest.osrm
[info] starting up engines, v5.22.0
[info] Threads: 8
[info] IP address: 0.0.0.0
[info] IP port: 5000
[info] http 1.1 compression handled by zlib version 1.2.11
[info] Listening on: 0.0.0.0:5000
[info] running and waiting for requests

As you see, the port used is 5000. You must remember this for configuring your web server. Of course, you could access OSRM directly but then, you must make sure that port is open. I decided to use Nginx as a proxy. So I made a new configuration file for OSRM:

sudo emacs osrm.tennis24.ee 

Inside that file, I put the following lines:

server {
server_name osrm.tennis24.ee;
location /route/v1 {
proxy_pass http://192.168.1.65:5000;
}
location / {
try_files $uri $uri/ =404;
}
}

Here, osrm.tennis24.ee is my domain. For that, I had to make a record in Zone Editor and wait an hour to make it work:

osrm.tennis24.ee. 3600 INA 80.235.6.91

The location /route/v1 must be exactly as I’ve written as otherwise, Nextcloud’s Maps can’t connect to OSRM server. It tends to add /car, /bicycle or /foot to the end of that URL.

192.168.1.65 is the inside address of my server. Here, you see the port 5000, too.

Then, enable the Nginx configuration file:

sudo ln -s /etc/nginx/sites-available/osrm.tennis24.ee /etc/nginx/sites-enabled/osrm.tennis24.ee

It’s time to restart Nginx:

sudo systemctl restart nginx
apps in menu in Nextcloud
apps in menu in Nextcloud
For installing Maps, go to apps in Nextcloud!
You can search for “maps” and install it.
“Settings” from menu
“Settings” from menu
“Maps” must be set up before use.
additional settings from menu
additional settings from menu
Choose “Additional settings”!
Fill in the URL fields for OSRM server!
opening “Maps”
opening “Maps”
Opening “Maps” goes via main menu.

After installing Maps, you may get a complaint about scanning images. You can solve it by going into your Nextcloud folder on the server and scan the repository for image files:

sudo chmod u+x occ
sudo -u www-data ./occ maps:scan-photos

After that, you can perform address search after using enter as that runs from a third-party site, however you can’t calculate any routes as OSRM assumes you using HTTPS. So make your Nextcloud run on HTTPS:

sudo certbot — nginx -d osrm.tennis24.ee

Now, Maps can only offer directions for car driving. If you want to add more functionality like directions for walking or cycling, you need to create additional folders anywhere on your server each for either type. Then repeat the following for both folders:

  1. Copy the .pbf-map into the created folder!
  2. Run osrm-extract with specific profile (-p ../osrm-backend/profiles/bicycle.lua or -p ../osrm-backend/profiles/foot.lua )!
  3. Run osrm-partition on osrm-file!
  4. Run osrm-customize on osrm-file!
  5. Run osrm-routed --algorithm=MLD on osrm-file with -p 5001 or any other free port!

Finally, you should change the location-directives for Nginx:

location /route/v1/car {
proxy_pass http://192.168.1.65:5000;
}
location /route/v1/bicycle {
proxy_pass http://192.168.1.65:5001;
}
location /route/v1/foot {
proxy_pass http://192.168.1.65:5002;
}

This all works if you start osrm-routed manually every time after you restart your server machine. In order to make it start automatically, you can use supervisor. Here, I have an example for just calculating the path for driving a car:

[program:osrm-car]
autorestart=true
autostart=true
command=/usr/local/bin/osrm-routed -p 5000 --algorithm=MLD /projektid/osrm-backend/estonia-latest.osrm
stderr_logfile=/var/log/osrm-car-errors.log
stdout_logfile=/var/log/osrm-car-output.log

You should have such a block for each type of traffic instructions. I’ve marked bold the parts that differ between blocks.

If you click the button “Export current route to GPX” then a GPX-file will be created in “Maps”-folder.

We can search for locations or planning routes. Once the location is written, pressing enter confirms it or opens an autocompletion list. Locations can also be written using GPS-coordinates: first either the number for the north or south following by the number for the east or west separated by a comma. On the map, we can use a special menu that appears clicking the non-default pointer button to set start, end or intermediate points. We can choose between car, bike and foot routes assumed that they are installed as described previously. We can also export the route but at least now, there’s a bug: if we have many route points then the export fails as the file name becomes too long. I reported the issue to the developers.

Incorrect marker location
Incorrect marker location
Blue is the marker set by “Maps”, green is the marker where it’s supposed to be.
The distance between the locations is 746.7 meters by foot.

Using coordinates, the result might be very incorrect. For instance, if you enter the coordinates 59.39736,24.29106 then the marker will be set to Merenuka, somewhere in the forest close to a road. Actually, that point is like a kilometer away. Nextcloud Maps queries https://nominatim.openstreetmap.org/search/59.39736%2C24.29106?format=json&addressdetails=1&extratags=1&namedetails=1&limit=8. The result is:

[{"place_id":140845919,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"way","osm_id":222473368,"boundingbox":["59.3995823","59.4025795","24.2840268","24.2956984"],"lat":"59.4012388","lon":"24.2897721","display_name":"Merenuka, Keila-Joa alevik, Keila-Joa, Lääne-Harju vald, Harju maakond, 76719, Estonia","class":"highway","type":"service","importance":0.001,"address":{"road":"Merenuka","city_district":"Keila-Joa alevik","village":"Keila-Joa","municipality":"Lääne-Harju vald","county":"Harju maakond","postcode":"76719","country":"Estonia","country_code":"ee"},"extratags":{"service":"driveway"},"namedetails":{"name":"Merenuka"}}]

Isn’t it weird that the resulting coordinates are totally different:

"lat":"59.4012388","lon":"24.2897721"

If you perform a search with the same coordinates on Duckduckgo then the query will be https://duckduckgo.com/local.js?q=59.39736%2C24.29106&vqd=3-103348761171173820949112319336023907177-298853212309544924666489924946875453471&tg=maps_places&rt=D&mkexp=b&wiki_info=1&is_requery=1&bbox_tl=59.41958356937411%2C24.27851299999999&bbox_br=59.388251332414484%2C24.312831899999978&strict_bbox=0. The result will be:

{"response_type":"map","queryEncoded":"59.39736,24.29106","features":[{"text":"76701 Keila vald","place_name":"76701 Keila vald","bbox":[24.278513,59.4165649,24.3128319,59.39127],"center":[24.29106,59.39736],"context":[{"text":"Estonia","id":"country.1"},{"text":"Estonia","id":"region.1"},{"text":"76701 Keila vald","id":"place.1"}]}],"query":"59.39736,24.29106","type":"FeatureCollection"}

As you see, the coordinates won’t be altered. So why do Nextcloud Maps developers prefer Nominatim.openstreetmap.com that seems to respond to any query incorrectly? I reported the issue for Nominatim. I also reported the issue for Nextcloud Maps.

Arvutiteadus

arvutiteadus

peacecop kalmer:

Written by

I teach math, computer science and tennis, create software, arrange tennis events, process multimedia, run orienteering, collect tree juices and fruits.

Arvutiteadus

arvutiteadus

peacecop kalmer:

Written by

I teach math, computer science and tennis, create software, arrange tennis events, process multimedia, run orienteering, collect tree juices and fruits.

Arvutiteadus

arvutiteadus

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store