I recentely found out about OpenStreetMap Nominatim and its reverse geocoding feature. And same as OSM it can be installed on a local server. I followed the installation steps documented in online manual and everything runs very smoothly.
#!/bin/bash
# steps for 18.04 LTS with latest updates
# run as root
export USERNAME=nominatim
export USERHOME=/srv/nominatim
export NOMATIM_VERSION=3.4.1
export NOMINATIM_SOURCE_DIR=$USERHOME/Nominatim-${NOMATIM_VERSION}
export BUILD_LOCAL=$USERHOME/build/settings/local.php
export BUILD_UTILS=$USERHOME/build/utils
export PG_CONF=/etc/postgresql/10/main
# installation
apt update
apt dist-upgrade -y
apt-get install -y build-essential cmake g++ libboost-dev libboost-system-dev \
libboost-filesystem-dev libexpat1-dev zlib1g-dev libxml2-dev \
libbz2-dev libpq-dev libproj-dev \
postgresql-server-dev-10 postgresql-10-postgis-2.4 \
postgresql-contrib-10 postgresql-10-postgis-scripts \
apache2 php php-pgsql libapache2-mod-php \
php-intl git python3-pip
apt-get clean
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# user
useradd -d ${USERHOME} -s /bin/bash -m ${USERNAME}
# apache
tee /etc/apache2/conf-available/nominatim.conf << EOFAPACHECONF
<Directory "/srv/nominatim/build/website">
Options FollowSymLinks MultiViews
AddType text/html .php
DirectoryIndex search.php
Require all granted
</Directory>
Alias /nominatim /srv/nominatim/build/website
EOFAPACHECONF
a2enconf nominatim
systemctl restart apache2
# nomatim
sudo -u $USERNAME -H sh -c "cd $USERHOME && wget https://nominatim.org/release/Nominatim-${NOMATIM_VERSION}.tar.bz2 && tar xf Nominatim-${NOMATIM_VERSION}.tar.bz2 && mkdir build && cd build && cmake $USERHOME/${NOMINATIM_SOURCE_DIR} && make"
tee $BUILD_LOCAL << EOFLOCAL
<?php
@define('CONST_Website_BaseURL', '/nominatim/');
@define('CONST_Osm2pgsql_Flatnode_File', '${USERHOME}/flatnode.file');
EOFLOCAL
# postgre
sudo -u postgres createuser -s $USERNAME
sudo -u postgres createuser www-data
cp postgresql_preimport.conf postgresql_postimport.conf ${PG_CONF}
mv ${PG_CONF}/postgresql.conf ${PG_CONF}/postgresql.conf.orig
ln -s ${PG_CONF}/postgresql_preimport.conf ${PG_CONF}/postgresql.conf
systemctl restart postgresql
# wikipedia data
#cd $NOMINATIM_SOURCE_DIR/data
#wget https://www.nominatim.org/data/wikipedia_article.sql.bin
#wget https://www.nominatim.org/data/wikipedia_redirect.sql.bin
#wget https://www.nominatim.org/data/gb_postcode_data.sql.gz
#wget https://www.nominatim.org/data/us_postcode_data.sql.gz
# streetmap data
export MAP_DATA_DIR=$USERHOME/mapdata
mkdir $MAP_DATA_DIR
cd $MAP_DATA_DIR
wget https://download.geofabrik.de/europe/austria-latest.osm.pbf
# fix permissions after getting all data
chmod -R a+x $USERHOME
chown -R ${USERNAME}:${USERNAME} $USERHOME
# install map data
sudo -u $USERNAME -H sh -c "$BUILD_UTILS/setup.php --osm-file $MAP_DATA_DIR/austria-latest.osm.pbf --all" 2>&1 | tee $USERHOME/setup-austria.log
# update process
sudo -u $USERNAME -H sh -c "pip3 install --user osmium"
echo " // update process" >> $BUILD_LOCAL
echo " @define('CONST_Pyosmium_Binary', '/srv/nominatim/.local/bin/pyosmium-get-changes');" >> $BUILD_LOCAL
echo " @define('CONST_Replication_Url', 'https://download.geofabrik.de/europe/austria-updates');" >> $BUILD_LOCAL
echo " @define('CONST_Replication_Update_Interval', '86400');" >> $BUILD_LOCAL
echo " @define('CONST_Replication_Recheck_Interval', '900');" >> $BUILD_LOCAL
sudo -u $USERNAME -H sh -c "$BUILD_UTILS/update.php --init-updates"
# enable fsync of postgre
rm ${PG_CONF}/postgresql.conf
ln -s ${PG_CONF}/postgresql_postimport.conf ${PG_CONF}/postgresql.conf
service postgresql restart
The mentioned files are also included here:
After installing it i was able to call the reverse geocoding API like this (replace the ip with the one of your server):
curl -X GET 'http://192.168.0.247/nominatim/reverse.php?lat=48&lon=15&osm_type=N&format=json&zoom=3'
{"place_id":3655636,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":16239,"lat":"47.2000338","lon":"13.199959","display_name":"Österreich","address":{"country":"Österreich","country_code":"at"},"boundingbox":["46.3722761","49.0205305","9.5307487","17.160776"]}