name: 'Build Nominatim'
inputs:
- flavour:
- description: 'Version of Ubuntu to install on'
+ dependencies:
+ description: 'Where to install dependencies from (pip/apt)'
required: false
- default: 'ubuntu-20'
- cmake-args:
- description: 'Additional options to hand to cmake'
- required: false
- default: ''
- lua:
- description: 'Version of Lua to use'
- required: false
- default: '5.3'
+ default: 'pip'
runs:
using: "composite"
sudo rm -rf /opt/hostedtoolcache/go /opt/hostedtoolcache/CodeQL /usr/lib/jvm /usr/local/share/chromium /usr/local/lib/android
df -h
shell: bash
- - name: Install${{ matrix.flavour }} prerequisites
+ - name: Install general prerequisites
+ run: |
+ sudo apt-get install -y -qq libspatialite-dev libsqlite3-mod-spatialite libicu-dev virtualenv python3-dev osm2pgsql
+ shell: bash
+
+ - name: Install prerequisites from apt
run: |
- sudo apt-get install -y -qq libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libproj-dev libicu-dev liblua${LUA_VERSION}-dev lua${LUA_VERSION} lua-dkjson nlohmann-json3-dev libspatialite7 libsqlite3-mod-spatialite
- if [ "$FLAVOUR" == "oldstuff" ]; then
- pip3 install MarkupSafe==2.0.1 python-dotenv jinja2==2.8 psutil==5.4.2 pyicu==2.9 osmium PyYAML==5.1 sqlalchemy==1.4.31 psycopg==3.1.7 datrie asyncpg aiosqlite
- else
- sudo apt-get install -y -qq python3-icu python3-datrie python3-pyosmium python3-jinja2 python3-psutil python3-dotenv python3-yaml
- pip3 install sqlalchemy psycopg aiosqlite
- fi
+ sudo apt-get install -y -qq python3-icu python3-datrie python3-jinja2 python3-psutil python3-dotenv python3-yaml python3-sqlalchemy python3-psycopg python3-asyncpg
shell: bash
- env:
- FLAVOUR: ${{ inputs.flavour }}
- CMAKE_ARGS: ${{ inputs.cmake-args }}
- LUA_VERSION: ${{ inputs.lua }}
+ if: inputs.dependencies == 'apt'
- - name: Configure
- run: mkdir build && cd build && cmake $CMAKE_ARGS ../Nominatim
+ - name: Setup virtual environment (for pip)
+ run: |
+ virtualenv venv
+ ./venv/bin/pip install -U pip
shell: bash
- env:
- CMAKE_ARGS: ${{ inputs.cmake-args }}
+ if: inputs.dependencies == 'pip'
- - name: Build
+ - name: Setup virtual environment (for apt)
run: |
- make -j2 all
- sudo make install
+ virtualenv venv --system-site-packages
+ shell: bash
+ if: inputs.dependencies == 'apt'
+
+ - name: Build nominatim
+ run: ./venv/bin/pip install Nominatim/packaging/nominatim-{api,db}
shell: bash
- working-directory: build
postgresql-version:
description: 'Version of PostgreSQL to install'
required: true
- postgis-version:
- description: 'Version of Postgis to install'
- required: true
runs:
using: "composite"
- name: Install PostgreSQL
run: |
- sudo apt-get install -y -qq --no-install-suggests --no-install-recommends postgresql-client-${PGVER} postgresql-${PGVER}-postgis-${POSTGISVER} postgresql-${PGVER}-postgis-${POSTGISVER}-scripts postgresql-contrib-${PGVER} postgresql-${PGVER}
+ sudo apt-get install -y -qq --no-install-suggests --no-install-recommends postgresql-client-${PGVER} postgresql-${PGVER}-postgis-3 postgresql-${PGVER}-postgis-3-scripts postgresql-contrib-${PGVER} postgresql-${PGVER}
shell: bash
env:
PGVER: ${{ inputs.postgresql-version }}
- POSTGISVER: ${{ inputs.postgis-version }}
- name: Adapt postgresql configuration
run: |
needs: create-archive
strategy:
matrix:
- flavour: [oldstuff, "ubuntu-20", "ubuntu-22"]
+ flavour: ["ubuntu-20", "ubuntu-24"]
include:
- - flavour: oldstuff
- ubuntu: 20
- postgresql: '9.6'
- postgis: '2.5'
- lua: '5.1'
- flavour: ubuntu-20
ubuntu: 20
- postgresql: 13
- postgis: 3
- lua: '5.3'
- - flavour: ubuntu-22
- ubuntu: 22
- postgresql: 15
- postgis: 3
+ postgresql: 12
+ lua: '5.1'
+ dependencies: pip
+ - flavour: ubuntu-24
+ ubuntu: 24
+ postgresql: 17
lua: '5.3'
+ dependencies: apt
runs-on: ubuntu-${{ matrix.ubuntu }}.04
- name: Unpack Nominatim
run: tar xf nominatim-src.tar.bz2
- - uses: actions/setup-python@v5
- with:
- python-version: 3.7
- if: matrix.flavour == 'oldstuff'
-
- uses: ./Nominatim/.github/actions/setup-postgresql
with:
postgresql-version: ${{ matrix.postgresql }}
- postgis-version: ${{ matrix.postgis }}
- uses: ./Nominatim/.github/actions/build-nominatim
with:
- flavour: ${{ matrix.flavour }}
- lua: ${{ matrix.lua }}
+ dependencies: ${{ matrix.dependencies }}
- - name: Install test prerequisites (behave from apt)
- run: sudo apt-get install -y -qq python3-behave
- if: matrix.flavour == 'ubuntu-20'
-
- - name: Install test prerequisites (behave from pip)
- run: pip3 install behave==1.2.6
- if: (matrix.flavour == 'oldstuff') || (matrix.flavour == 'ubuntu-22')
-
- - name: Install test prerequisites (from apt for Ununtu 2x)
- run: sudo apt-get install -y -qq python3-pytest python3-pytest-asyncio uvicorn
- if: matrix.flavour != 'oldstuff'
+ - name: Compile osm2pgsql
+ run: |
+ sudo apt-get install -y -qq libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libproj-dev libicu-dev liblua${LUA_VERSION}-dev lua-dkjson nlohmann-json3-dev
+ mkdir osm2pgsql-build
+ cd osm2pgsql-build
+ git clone https://github.com/osm2pgsql-dev/osm2pgsql
+ mkdir build
+ cd build
+ cmake ../osm2pgsql
+ make
+ sudo make install
+ cd ../..
+ rm -rf osm2pgsql-build
+ if: matrix.ubuntu == '20'
+ env:
+ LUA_VERSION: ${{ matrix.lua }}
- - name: Install newer pytest-asyncio
- run: pip3 install -U pytest-asyncio
- if: matrix.flavour == 'ubuntu-20'
+ - name: Install test prerequisites
+ run: ./venv/bin/pip install behave==1.2.6
- - name: Install test prerequisites (from pip for Ubuntu 18)
- run: pip3 install pytest pytest-asyncio uvicorn
- if: matrix.flavour == 'oldstuff'
+ - name: Install test prerequisites (apt)
+ run: sudo apt-get install -y -qq python3-pytest python3-pytest-asyncio uvicorn python3-falcon python3-aiosqlite python3-pyosmium
+ if: matrix.dependencies == 'apt'
- - name: Install Python webservers
- run: pip3 install falcon starlette asgi_lifespan
+ - name: Install test prerequisites (pip)
+ run: ./venv/bin/pip install pytest-asyncio falcon starlette asgi_lifespan aiosqlite osmium uvicorn
+ if: matrix.dependencies == 'pip'
- name: Install latest flake8
- run: pip3 install -U flake8
- if: matrix.flavour == 'ubuntu-22'
+ run: ./venv/bin/pip install -U flake8
- name: Python linting
- run: python3 -m flake8 src
+ run: ../venv/bin/python -m flake8 src
working-directory: Nominatim
- if: matrix.flavour == 'ubuntu-22'
+
+ - name: Install mypy and typechecking info
+ run: ./venv/bin/pip install -U mypy types-PyYAML types-jinja2 types-psutil types-requests types-ujson types-Pygments typing-extensions
+ if: matrix.dependencies == 'pip'
+
+ - name: Python static typechecking
+ run: ../venv/bin/python -m mypy --strict --python-version 3.8 src
+ working-directory: Nominatim
+ if: matrix.dependencies == 'pip'
- name: Python unit tests
- run: python3 -m pytest test/python
+ run: ../venv/bin/python -m pytest test/python
working-directory: Nominatim
- name: BDD tests
run: |
- export PATH=$GITHUB_WORKSPACE/build/osm2pgsql:$PATH
- python3 -m behave -DREMOVE_TEMPLATE=1 --format=progress3
+ ../../../venv/bin/python -m behave -DREMOVE_TEMPLATE=1 --format=progress3
working-directory: Nominatim/test/bdd
- - name: Install mypy and typechecking info
- run: pip3 install -U mypy osmium uvicorn types-PyYAML types-jinja2 types-psycopg2 types-psutil types-requests types-ujson types-Pygments typing-extensions
- if: matrix.flavour != 'oldstuff'
-
- - name: Python static typechecking
- run: python3 -m mypy --strict src
- working-directory: Nominatim
- if: matrix.flavour != 'oldstuff'
-
install:
runs-on: ubuntu-latest
needs: create-archive
- name: Add nominatim to path
run: |
sudo ln -s /home/nominatim/nominatim-venv/bin/nominatim /usr/local/bin/nominatim
- if: matrix.ubuntu == 24
- name: Need lua binary
run: |
sudo apt-get install -y lua5.4 lua-dkjson
- if: matrix.ubuntu == 24
- name: Print version
run: nominatim --version
run: nominatim admin --warm
working-directory: /home/nominatim/nominatim-project
- - name: Prepare update (Ubuntu)
- run: apt-get install -y python3-pip
- shell: bash
-
- - name: Install osmium (Ubuntu 22)
- run: |
- pip3 install --user osmium
- if: matrix.ubuntu == 22
-
- - name: Install osmium (Ubuntu 24)
+ - name: Install osmium
run: |
/home/nominatim/nominatim-venv/bin/pip install osmium
- if: matrix.ubuntu == 24
- name: Run update
run: |
working-directory: /home/nominatim/nominatim-project
install-no-superuser:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
needs: create-archive
steps:
- uses: ./Nominatim/.github/actions/setup-postgresql
with:
postgresql-version: 16
- postgis-version: 3
- uses: ./Nominatim/.github/actions/build-nominatim
- with:
- flavour: ubuntu-22
- lua: 5.3
- name: Prepare import environment
run: |
- name: Prepare Database
run: |
- nominatim import --prepare-database
+ ./venv/bin/nominatim import --prepare-database
- name: Create import user
run: |
- name: Run import
run: |
- NOMINATIM_DATABASE_DSN="pgsql:host=127.0.0.1;dbname=nominatim;user=osm-import;password=osm-import" nominatim import --continue import-from-file --osm-file test.pbf
+ NOMINATIM_DATABASE_DSN="pgsql:host=127.0.0.1;dbname=nominatim;user=osm-import;password=osm-import" ./venv/bin/nominatim import --continue import-from-file --osm-file test.pbf
- name: Check full import
- run: nominatim admin --check-database
+ run: ./venv/bin/nominatim admin --check-database
migrate:
runs-on: ubuntu-24.04
- uses: ./Nominatim/.github/actions/setup-postgresql
with:
postgresql-version: 17
- postgis-version: 3
- name: Install Python dependencies
run: |
-[submodule "osm2pgsql"]
- path = osm2pgsql
- url = https://github.com/openstreetmap/osm2pgsql.git
- ignore = dirty
+++ /dev/null
-#-----------------------------------------------------------------------------
-#
-# CMake Config
-#
-# Nominatim
-#
-#-----------------------------------------------------------------------------
-
-cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
-
-
-#-----------------------------------------------------------------------------
-#
-# Project version
-#
-#-----------------------------------------------------------------------------
-
-project(nominatim)
-
-set(NOMINATIM_VERSION_MAJOR 4)
-set(NOMINATIM_VERSION_MINOR 5)
-set(NOMINATIM_VERSION_PATCH 0)
-
-set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
-
-add_definitions(-DNOMINATIM_VERSION="${NOMINATIM_VERSION}")
-
-# Setting GIT_HASH
-find_package(Git)
-if (GIT_FOUND)
- execute_process(
- COMMAND "${GIT_EXECUTABLE}" log -1 --format=%h
- WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
- OUTPUT_VARIABLE GIT_HASH
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_QUIET
- )
-endif()
-
-#-----------------------------------------------------------------------------
-# Configuration
-#-----------------------------------------------------------------------------
-
-set(BUILD_IMPORTER on CACHE BOOL "Build everything for importing/updating the database")
-set(BUILD_API on CACHE BOOL "Build everything for the API server")
-set(BUILD_TESTS on CACHE BOOL "Build test suite")
-set(BUILD_OSM2PGSQL on CACHE BOOL "Build osm2pgsql (expert only)")
-set(INSTALL_MUNIN_PLUGINS on CACHE BOOL "Install Munin plugins for supervising Nominatim")
-
-#-----------------------------------------------------------------------------
-# osm2pgsql (imports/updates only)
-#-----------------------------------------------------------------------------
-
-if (BUILD_IMPORTER AND BUILD_OSM2PGSQL)
- if (NOT EXISTS "${CMAKE_SOURCE_DIR}/osm2pgsql/CMakeLists.txt")
- message(FATAL_ERROR "The osm2pgsql directory is empty.\
- Did you forget to check out Nominatim recursively?\
- \nTry updating submodules with: git submodule update --init")
- endif()
- set(BUILD_TESTS_SAVED "${BUILD_TESTS}")
- set(BUILD_TESTS off)
- add_subdirectory(osm2pgsql)
- set(BUILD_TESTS ${BUILD_TESTS_SAVED})
-endif()
-
-
-#-----------------------------------------------------------------------------
-# python (imports/updates only)
-#-----------------------------------------------------------------------------
-
-if (BUILD_IMPORTER OR BUILD_API)
- find_package(PythonInterp 3.7 REQUIRED)
-endif()
-
-#-----------------------------------------------------------------------------
-# import scripts and utilities (importer only)
-#-----------------------------------------------------------------------------
-
-if (BUILD_IMPORTER)
- find_file(COUNTRY_GRID_FILE country_osm_grid.sql.gz
- PATHS ${PROJECT_SOURCE_DIR}/data
- NO_DEFAULT_PATH
- DOC "Location of the country grid file."
- )
-
- if (NOT COUNTRY_GRID_FILE)
- message(FATAL_ERROR "\nYou need to download the country_osm_grid first:\n"
- " wget -O ${PROJECT_SOURCE_DIR}/data/country_osm_grid.sql.gz https://www.nominatim.org/data/country_grid.sql.gz")
- endif()
-
- configure_file(${PROJECT_SOURCE_DIR}/cmake/tool.tmpl
- ${PROJECT_BINARY_DIR}/nominatim)
-endif()
-
-#-----------------------------------------------------------------------------
-# Targets for running a development webserver from the build directory.
-#-----------------------------------------------------------------------------
-
-if (BUILD_API)
- set(WEBSITEFILES
- 403.html
- 509.html
- crossdomain.xml
- favicon.ico
- nominatim.xml
- robots.txt
- taginfo.json
- )
-
- foreach (webfile ${WEBSITEFILES})
- configure_file(${PROJECT_SOURCE_DIR}/website/${webfile}
- ${PROJECT_BINARY_DIR}/website/${webfile})
- endforeach()
-endif()
-
-#-----------------------------------------------------------------------------
-# Tests
-#-----------------------------------------------------------------------------
-
-if (BUILD_TESTS)
- include(CTest)
-
- set(TEST_BDD db osm2pgsql api)
-
- find_program(PYTHON_BEHAVE behave)
- find_program(PYLINT NAMES pylint3 pylint)
- find_program(PYTEST NAMES pytest py.test-3 py.test)
-
- if (PYTHON_BEHAVE)
- message(STATUS "Using Python behave binary ${PYTHON_BEHAVE}")
- foreach (test ${TEST_BDD})
- add_test(NAME bdd_${test}
- COMMAND ${PYTHON_BEHAVE} ${test}
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test/bdd)
- set_tests_properties(bdd_${test}
- PROPERTIES ENVIRONMENT "NOMINATIM_DIR=${PROJECT_BINARY_DIR}")
- endforeach()
- else()
- message(WARNING "behave not found. BDD tests disabled." )
- endif()
-
- if (PYLINT)
- message(STATUS "Using pylint binary ${PYLINT}")
- add_test(NAME pylint
- COMMAND ${PYLINT} nominatim
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- else()
- message(WARNING "pylint not found. Python linting tests disabled.")
- endif()
-
- if (PYTEST)
- message(STATUS "Using pytest binary ${PYTEST}")
- add_test(NAME pytest
- COMMAND ${PYTEST} test/python
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- else()
- message(WARNING "pytest not found. Python tests disabled." )
- endif()
-endif()
-
-#-----------------------------------------------------------------------------
-# Installation
-#-----------------------------------------------------------------------------
-
-
-include(GNUInstallDirs)
-set(NOMINATIM_DATADIR ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME})
-set(NOMINATIM_LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR}/${PROJECT_NAME})
-set(NOMINATIM_CONFIGDIR ${CMAKE_INSTALL_FULL_SYSCONFDIR}/${PROJECT_NAME})
-set(NOMINATIM_MUNINDIR ${CMAKE_INSTALL_FULL_DATADIR}/munin/plugins)
-
-if (BUILD_IMPORTER)
- configure_file(${PROJECT_SOURCE_DIR}/cmake/tool-installed.tmpl installed.bin)
- install(PROGRAMS ${PROJECT_BINARY_DIR}/installed.bin
- DESTINATION ${CMAKE_INSTALL_BINDIR}
- RENAME nominatim)
-
- configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py-no-php.tmpl paths-py.installed)
-
- foreach (submodule nominatim_db nominatim_api)
- install(DIRECTORY src/${submodule}
- DESTINATION ${NOMINATIM_LIBDIR}/lib-python
- FILES_MATCHING PATTERN "*.py"
- PATTERN "paths.py" EXCLUDE
- PATTERN __pycache__ EXCLUDE)
- install(FILES ${PROJECT_BINARY_DIR}/paths-py.installed
- DESTINATION ${NOMINATIM_LIBDIR}/lib-python/${submodule}
- RENAME paths.py)
- endforeach()
-
- install(DIRECTORY lib-sql DESTINATION ${NOMINATIM_LIBDIR})
-
- install(FILES ${COUNTRY_GRID_FILE}
- data/words.sql
- DESTINATION ${NOMINATIM_DATADIR})
-endif()
-
-if (BUILD_OSM2PGSQL)
- if (${CMAKE_VERSION} VERSION_LESS 3.13)
- # Installation of subdirectory targets was only introduced in 3.13.
- # So just copy the osm2pgsql file for older versions.
- install(PROGRAMS ${PROJECT_BINARY_DIR}/osm2pgsql/osm2pgsql
- DESTINATION ${NOMINATIM_LIBDIR})
- else()
- install(TARGETS osm2pgsql RUNTIME DESTINATION ${NOMINATIM_LIBDIR})
- endif()
-endif()
-
-install(FILES settings/env.defaults
- settings/address-levels.json
- settings/phrase-settings.json
- settings/import-admin.lua
- settings/import-street.lua
- settings/import-address.lua
- settings/import-full.lua
- settings/import-extratags.lua
- settings/flex-base.lua
- settings/icu_tokenizer.yaml
- settings/country_settings.yaml
- DESTINATION ${NOMINATIM_CONFIGDIR})
-
-install(DIRECTORY settings/icu-rules
- DESTINATION ${NOMINATIM_CONFIGDIR})
-install(DIRECTORY settings/country-names
- DESTINATION ${NOMINATIM_CONFIGDIR})
-
-if (INSTALL_MUNIN_PLUGINS)
- install(FILES munin/nominatim_importlag
- munin/nominatim_query_speed
- munin/nominatim_requests
- DESTINATION ${NOMINATIM_MUNINDIR})
-endif()
-
-message(WARNING "Building with CMake is deprecated and will be removed in Nominatim 5.0."
- "Use Nominatim pip packages instead.\n"
- "See https://nominatim.org/release-docs/develop/admin/Installation/#downloading-and-building-nominatim")
* [ ] complete `docs/admin/Migration.md`
* [ ] update EOL dates in `SECURITY.md`
* [ ] commit and make sure CI tests pass
+* [ ] update OSMF production repo and release new version -post1 there
* [ ] test migration
* download, build and import previous version
* migrate using master version
* run updates using master version
* [ ] prepare tarball:
- * `git clone --recursive https://github.com/osm-search/Nominatim` (switch to right branch!)
- * `rm -r .git* osm2pgsql/.git*`
+ * `git clone https://github.com/osm-search/Nominatim` (switch to right branch!)
+ * `rm -r .git*`
* copy country data into `data/`
* add version to base directory and package
* [ ] upload tarball to https://nominatim.org
A quick summary of the necessary steps:
-1. Compile Nominatim:
+1. Create a Python virtualenv and install the packages:
- mkdir build
- cd build
- cmake ..
- make
- sudo make install
+ python3 -m venv nominatim-venv
+ ./nominatim-venv/bin/pip install packaging/nominatim-{api,db}
2. Create a project directory, get OSM data and import:
mkdir nominatim-project
cd nominatim-project
- nominatim import --osm-file <your planet file>
+ ../nominatim-venv/bin/nominatim import --osm-file <your planet file>
-3. Point your webserver to the nominatim-project/website directory.
+3. Start the webserver:
+
+ ./nominatim-venv/bin/pip install uvicorn falcon
+ ../nominatim-venv/bin/nominatim serve
License
# Install Nominatim in a virtual machine for development and testing
-This document describes how you can install Nominatim inside a Ubuntu 22
+This document describes how you can install Nominatim inside a Ubuntu 24
virtual machine on your desktop/laptop (host machine). The goal is to give
you a development environment to easily edit code and run the test suite
without affecting the rest of your system.
2. [Vagrant](https://www.vagrantup.com/downloads.html)
-3. Nominatim
-
- git clone --recursive https://github.com/openstreetmap/Nominatim.git
-
- If you forgot `--recursive`, it you can later load the submodules using
-
- git submodule init
- git submodule update
-
+3. Nominatim
+ git clone https://github.com/openstreetmap/Nominatim.git
## Installation
1. Start the virtual machine
- vagrant up ubuntu
+ vagrant up ubuntu24-nginx
2. Log into the virtual machine
- vagrant ssh ubuntu
+ vagrant ssh ubuntu24-nginx
3. Import a small country (Monaco)
-
+
See the FAQ how to skip this step and point Nominatim to an existing database.
```
You edit code on your host machine in any editor you like. There is no need to
restart any software: just refresh your browser window.
-Note that the webserver uses files from the /build directory. If you change
-files in Nominatim/website or Nominatim/utils for example you first need to
-copy them into the /build directory by running the `cmake` step from the
-installation.
-
-PHP errors are written to `/var/log/apache2/error.log`.
-
-With `echo` and `var_dump()` you write into the output (HTML/XML/JSON) when
-you either add `&debug=1` to the URL.
+Use the functions of the `log()` object to create temporary debug output.
+Add `&debug=1` to the URL to see the output.
In the Python BDD test you can use `logger.info()` for temporary debug
statements.
-
-
-## Running unit tests
-
- cd ~/Nominatim/tests/php
- phpunit ./
-
-
-## Running PHP code style tests
-
- cd ~/Nominatim
- phpcs --colors .
-
-
-## Running functional tests
-
-Tests in `test/bdd/db` and `test/bdd/osm2pgsql` have to pass 100%. Other
-tests might require full planet-wide data. Sadly even if you have your own
-planet-wide data there will be enough differences to the openstreetmap.org
-installation to cause false positives in the other tests (see FAQ).
-
-To run the full test suite
-
- cd ~/Nominatim/test/bdd
- behave -DBUILDDIR=/home/vagrant/build/ db osm2pgsql
-
-To run a single file
-
- behave -DBUILDDIR=/home/vagrant/build/ api/lookup/simple.feature
-
-Or a single test by line number
-
- behave -DBUILDDIR=/home/vagrant/build/ api/lookup/simple.feature:34
-
-To run specific groups of tests you can add tags just before the `Scenario line`, e.g.
-
- @bug-34
- Scenario: address lookup for non-existing or invalid node, way, relation
-
-and then
-
- behave -DBUILDDIR=/home/vagrant/build/ --tags @bug-34
-
-
-
-
+For more information on running tests, see
+https://nominatim.org/release-docs/develop/develop/Testing/
## FAQ
##### Will it run on Windows?
-Yes, Vagrant and Virtualbox can be installed on MS Windows just fine. You need a 64bit
-version of Windows.
+Yes, Vagrant and Virtualbox can be installed on MS Windows just fine. You need
+a 64bit version of Windows.
##### Will it run on Apple Silicon?
##### Why Monaco, can I use another country?
-Of course! The Monaco import takes less than 30 minutes and works with 2GB RAM.
+Of course! The Monaco import takes less than 10 minutes and works with 2GB RAM.
##### Will the results be the same as those from nominatim.openstreetmap.org?
-No. Long running Nominatim installations will differ once new import features (or
+No. Long-running Nominatim installations will differ once new import features (or
bug fixes) get added since those usually only get applied to new/changed data.
Also this document skips the optional Wikipedia data import which affects ranking
Yes. It's possible to start the virtual machine on [Amazon AWS (plugin)](https://github.com/mitchellh/vagrant-aws)
or [DigitalOcean (plugin)](https://github.com/smdahlen/vagrant-digitalocean).
-
-
-
-
+++ /dev/null
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# This file is part of Nominatim. (https://nominatim.org)
-#
-# Copyright (C) 2022 by the Nominatim developer community.
-# For a full list of authors see the git log.
-"""
-Path settings for extra data used by Nominatim (installed version).
-"""
-from pathlib import Path
-
-SQLLIB_DIR = (Path('@NOMINATIM_LIBDIR@') / 'lib-sql').resolve()
-DATA_DIR = Path('@NOMINATIM_DATADIR@').resolve()
-CONFIG_DIR = Path('@NOMINATIM_CONFIGDIR@').resolve()
+++ /dev/null
-#!/srv/nominatim.openstreetmap.org/venv/bin/python3
-import sys
-import os
-
-sys.path.insert(1, '@NOMINATIM_LIBDIR@/lib-python')
-
-from nominatim_db import cli
-from nominatim_db import version
-
-version.GIT_COMMIT_HASH = '@GIT_HASH@'
-
-exit(cli.nominatim(module_dir='@NOMINATIM_LIBDIR@/module',
- osm2pgsql_path='@NOMINATIM_LIBDIR@/osm2pgsql'))
+++ /dev/null
-#!/srv/nominatim.openstreetmap.org/venv/bin/python3
-import sys
-import os
-
-sys.path.insert(1, '@CMAKE_SOURCE_DIR@/src')
-
-from nominatim_db import cli
-from nominatim_db import version
-
-version.GIT_COMMIT_HASH = '@GIT_HASH@'
-
-exit(cli.nominatim(module_dir='@CMAKE_BINARY_DIR@/module',
- osm2pgsql_path='@CMAKE_BINARY_DIR@/osm2pgsql/osm2pgsql'))
Otherwise it's best to start the full setup from the beginning.
-
-### nominatim.so version mismatch
-
-When running the import you may get a version mismatch:
-`COPY_END for place failed: ERROR: incompatible library "/srv/Nominatim/nominatim/build/module/nominatim.so": version mismatch`
-
-pg_config seems to use bad includes sometimes when multiple versions
-of PostgreSQL are available in the system. Make sure you remove the
-server development libraries (`postgresql-server-dev-13` on Ubuntu)
-and recompile (`cmake .. && make`).
-
-
-### I see the error "ERROR: permission denied for language c"
-
-`nominatim.so`, written in C, is required to be installed on the database
-server. Some managed database (cloud) services like Amazon RDS do not allow
-this. There is currently no work-around other than installing a database
-on a non-managed machine.
-
-
-### I see the error: "function transliteration(text) does not exist"
-
-Reinstall the nominatim functions with `nominatim refresh --functions`
-and check for any errors, e.g. a missing `nominatim.so` file.
-
### I see the error: "ERROR: mmap (remap) failed"
This may be a simple out-of-memory error. Try reducing the memory used
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "www-data";
```
-### Website reports "Could not load library "nominatim.so"
-
-Example error message
-
-```
- SELECT make_standard_name('3039 E MEADOWLARK LN') [nativecode=ERROR: could not
- load library "/srv/nominatim/Nominatim-3.1.0/build/module/nominatim.so":
- /srv/nominatim/Nominatim-3.1.0/build/module/nominatim.so: cannot open shared
- object file: Permission denied
- CONTEXT: PL/pgSQL function make_standard_name(text) line 5 at assignment]
-```
-
-The PostgreSQL database, i.e. user `postgres`, needs to have access to that file.
-
-The permission need to be read & executable by everybody, but not writeable
-by everybody, e.g.
-
-```
- -rwxr-xr-x 1 nominatim nominatim 297984 build/module/nominatim.so
-```
-
-Try `chmod a+r nominatim.so; chmod a+x nominatim.so`.
-
-When you recently updated your operating system, updated PostgreSQL to
-a new version or moved files (e.g. the build directory) you should
-recreate `nominatim.so`. Try
-
-```
- cd build
- rm -r module/
- cmake $main_Nominatim_path && make
-```
-
### Setup fails with "DB Error: extension not found"
Make sure you have the PostgreSQL extensions "hstore" and "postgis" installed.
### Can I import negative OSM ids into Nominatim?
-See [this question of Stackoverflow](https://help.openstreetmap.org/questions/64662/nominatim-flatnode-with-negative-id).
+No, negative IDs are no longer supported by osm2pgsql. You can use
+large 64-bit IDs that are guaranteed not to clash with OSM IDs. However,
+you will not able to use a flatnode file with them.
### Software
-!!! Warning
- For larger installations you **must have** PostgreSQL 11+ and PostGIS 3+
- otherwise import and queries will be slow to the point of being unusable.
- Query performance has marked improvements with PostgreSQL 13+ and PostGIS 3.2+.
-
For running Nominatim:
- * [PostgreSQL](https://www.postgresql.org) (9.6+ will work, 11+ strongly recommended)
- * [PostGIS](https://postgis.net) (2.2+ will work, 3.0+ strongly recommended)
+ * [PostgreSQL](https://www.postgresql.org) (12+ will work, 13+ strongly recommended)
+ * [PostGIS](https://postgis.net) (3.0+ will work, 3.2+ strongly recommended)
* [osm2pgsql](https://osm2pgsql.org) (1.8+, optional when building with CMake)
* [Python 3](https://www.python.org/) (3.7+)
These will be installed automatically when using pip installation.
-When using legacy CMake-based installation:
-
- * [cmake](https://cmake.org/)
- * [expat](https://libexpat.github.io/)
- * [proj](https://proj.org/)
- * [bzip2](http://www.bzip.org/)
- * [zlib](https://www.zlib.net/)
- * [ICU](http://site.icu-project.org/)
- * [nlohmann/json](https://json.nlohmann.me/)
- * [Boost libraries](https://www.boost.org/), including system and file system
- * PostgreSQL client libraries
- * a recent C++ compiler (gcc 5+ or Clang 3.8+)
-
For running continuous updates:
* [pyosmium](https://osmcode.org/pyosmium/)
### Downloading the latest development version
-If you want to install latest development version from github, make sure to
-also check out the osm2pgsql subproject:
+If you want to install latest development version from github:
```
-git clone --recursive https://github.com/openstreetmap/Nominatim.git
+git clone https://github.com/osm-search/Nominatim.git
```
The development version does not include the country grid. Download it separately:
### Building Nominatim
-#### Building the latest development version with pip
-
Nominatim is easiest to run from its own virtual environment. To create one, run:
sudo apt-get install virtualenv
/srv/nominatim-venv/bin/pip install packaging/nominatim-{db,api}
-#### Building in legacy CMake mode
-
-!!! warning
- Installing Nominatim through CMake is now deprecated. The infrastructure
- will be removed in Nominatim 5.0. Please switch to pip installation.
-
-The code must be built in a separate directory. Create the directory and
-change into it.
-
-```
-mkdir build
-cd build
-```
-
-Nominatim uses cmake and make for building. Assuming that you have created the
-build at the same level as the Nominatim source directory run:
-
-```
-cmake ../Nominatim
-make
-sudo make install
-```
-
-Nominatim installs itself into `/usr/local` per default. To choose a different
-installation directory add `-DCMAKE_INSTALL_PREFIX=<install root>` to the
-cmake command. Make sure that the `bin` directory is available in your path
-in that case, e.g.
-
-```
-export PATH=<install root>/bin:$PATH
-```
Now continue with [importing the database](Import.md).
---
CREATE INDEX IF NOT EXISTS idx_search_name_centroid
ON search_name USING GIST (centroid) {{db.tablespace.search_index}};
-
- {% if postgres.has_index_non_key_column %}
----
- CREATE INDEX IF NOT EXISTS idx_placex_housenumber
- ON placex USING btree (parent_place_id)
- INCLUDE (housenumber) {{db.tablespace.search_index}}
- WHERE housenumber is not null;
----
- CREATE INDEX IF NOT EXISTS idx_osmline_parent_osm_id_with_hnr
- ON location_property_osmline USING btree(parent_place_id)
- INCLUDE (startnumber, endnumber) {{db.tablespace.search_index}}
- WHERE startnumber is not null;
- {% endif %}
-
+---
+ CREATE INDEX IF NOT EXISTS idx_placex_housenumber
+ ON placex USING btree (parent_place_id)
+ INCLUDE (housenumber) {{db.tablespace.search_index}}
+ WHERE housenumber is not null;
+---
+ CREATE INDEX IF NOT EXISTS idx_osmline_parent_osm_id_with_hnr
+ ON location_property_osmline USING btree(parent_place_id)
+ INCLUDE (startnumber, endnumber) {{db.tablespace.search_index}}
+ WHERE startnumber is not null;
{% endif %}
-- Usage: - POI is within building with housenumber
CREATE INDEX idx_placex_geometry_buildings ON placex
- USING {{postgres.spgist_geom}} (geometry) {{db.tablespace.address_index}}
+ USING SPGIST (geometry) {{db.tablespace.address_index}}
WHERE address is not null and rank_search = 30
and ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon');
-- Usage: - linking of similar named places to boundaries
-- - linking of place nodes with same type to boundaries
CREATE INDEX idx_placex_geometry_placenode ON placex
- USING {{postgres.spgist_geom}} (geometry) {{db.tablespace.address_index}}
+ USING SPGIST (geometry) {{db.tablespace.address_index}}
WHERE osm_type = 'N' and rank_search < 26
and class = 'place' and type != 'postcode';
-- Usage: - is node part of a way?
-- - find parent of interpolation spatially
CREATE INDEX idx_placex_geometry_lower_rank_ways ON placex
- USING {{postgres.spgist_geom}} (geometry) {{db.tablespace.address_index}}
+ USING SPGIST (geometry) {{db.tablespace.address_index}}
WHERE osm_type = 'W' and rank_search >= 26;
-- Usage: - linking place nodes by wikidata tag to boundaries
--index only on parent_place_id
CREATE INDEX IF NOT EXISTS idx_location_property_tiger_parent_place_id_imp
ON location_property_tiger_import (parent_place_id)
-{% if postgres.has_index_non_key_column %}
INCLUDE (startnumber, endnumber, step)
-{% endif %}
{{db.tablespace.aux_index}};
CREATE UNIQUE INDEX IF NOT EXISTS idx_location_property_tiger_place_id_imp
ON location_property_tiger_import (place_id) {{db.tablespace.aux_index}};
+++ /dev/null
-Subproject commit cf66989fa2a47aa406f25c0be79e3b4e146284ee
async with engine.begin() as conn:
result = await conn.scalar(sa.text('SHOW server_version_num'))
server_version = int(result)
- if server_version >= 110000:
- await conn.execute(sa.text("SET jit_above_cost TO '-1'"))
- await conn.execute(sa.text(
- "SET max_parallel_workers_per_gather TO '0'"))
+ await conn.execute(sa.text("SET jit_above_cost TO '-1'"))
+ await conn.execute(sa.text(
+ "SET max_parallel_workers_per_gather TO '0'"))
except (PGCORE_ERROR, sa.exc.OperationalError):
server_version = 0
- if server_version >= 110000:
- @sa.event.listens_for(engine.sync_engine, "connect")
- def _on_connect(dbapi_con: Any, _: Any) -> None:
- cursor = dbapi_con.cursor()
- cursor.execute("SET jit_above_cost TO '-1'")
- cursor.execute("SET max_parallel_workers_per_gather TO '0'")
+ @sa.event.listens_for(engine.sync_engine, "connect")
+ def _on_connect(dbapi_con: Any, _: Any) -> None:
+ cursor = dbapi_con.cursor()
+ cursor.execute("SET jit_above_cost TO '-1'")
+ cursor.execute("SET max_parallel_workers_per_gather TO '0'")
self._property_cache['DB:server_version'] = server_version
limit to the configured number of results.
"""
if results:
- results.sort(key=lambda r: r.ranking)
+ results.sort(key=lambda r: (r.ranking, 0 if r.bbox is None else -r.bbox.area))
min_rank = results[0].rank_search
min_ranking = results[0].ranking
results = SearchResults(r for r in results
import jinja2
-from .connection import Connection, server_version_tuple, postgis_version_tuple
+from .connection import Connection
from ..config import Configuration
from ..db.query_pool import QueryPool
""" Set up a dictionary with various optional Postgresql/Postgis features that
depend on the database version.
"""
- pg_version = server_version_tuple(conn)
- postgis_version = postgis_version_tuple(conn)
- pg11plus = pg_version >= (11, 0, 0)
- ps3 = postgis_version >= (3, 0)
- return {
- 'has_index_non_key_column': pg11plus,
- 'spgist_geom': 'SPGIST' if pg11plus and ps3 else 'GIST'
- }
+ return {}
class SQLPreprocessor:
from psycopg.types.json import Jsonb
from psycopg import sql as pysql
-from ..db.connection import connect, Connection, Cursor, server_version_tuple, \
+from ..db.connection import connect, Connection, Cursor, \
drop_tables, table_exists, execute_scalar
from ..config import Configuration
from ..db.sql_preprocessor import SQLPreprocessor
cur.execute(pysql.SQL('SET max_parallel_workers_per_gather TO {}')
.format(pysql.Literal(min(threads, 6),)))
- if server_version_tuple(conn) < (12, 0):
- LOG.info('Computing word frequencies')
- drop_tables(conn, 'word_frequencies', 'addressword_frequencies')
- cur.execute("""CREATE TEMP TABLE word_frequencies AS
- SELECT unnest(name_vector) as id, count(*)
- FROM search_name GROUP BY id""")
- cur.execute('CREATE INDEX ON word_frequencies(id)')
- cur.execute("""CREATE TEMP TABLE addressword_frequencies AS
- SELECT unnest(nameaddress_vector) as id, count(*)
- FROM search_name GROUP BY id""")
- cur.execute('CREATE INDEX ON addressword_frequencies(id)')
- cur.execute("""
- CREATE OR REPLACE FUNCTION word_freq_update(wid INTEGER,
- INOUT info JSONB)
- AS $$
- DECLARE rec RECORD;
- BEGIN
- IF info is null THEN
- info = '{}'::jsonb;
- END IF;
- FOR rec IN SELECT count FROM word_frequencies WHERE id = wid
- LOOP
- info = info || jsonb_build_object('count', rec.count);
- END LOOP;
- FOR rec IN SELECT count FROM addressword_frequencies WHERE id = wid
- LOOP
- info = info || jsonb_build_object('addr_count', rec.count);
- END LOOP;
- IF info = '{}'::jsonb THEN
- info = null;
- END IF;
- END;
- $$ LANGUAGE plpgsql IMMUTABLE;
- """)
- LOG.info('Update word table with recomputed frequencies')
- drop_tables(conn, 'tmp_word')
- cur.execute("""CREATE TABLE tmp_word AS
- SELECT word_id, word_token, type, word,
- word_freq_update(word_id, info) as info
- FROM word
- """)
- drop_tables(conn, 'word_frequencies', 'addressword_frequencies')
- else:
- LOG.info('Computing word frequencies')
- drop_tables(conn, 'word_frequencies')
- cur.execute("""
- CREATE TEMP TABLE word_frequencies AS
- WITH word_freq AS MATERIALIZED (
- SELECT unnest(name_vector) as id, count(*)
- FROM search_name GROUP BY id),
- addr_freq AS MATERIALIZED (
- SELECT unnest(nameaddress_vector) as id, count(*)
- FROM search_name GROUP BY id)
- SELECT coalesce(a.id, w.id) as id,
- (CASE WHEN w.count is null THEN '{}'::JSONB
- ELSE jsonb_build_object('count', w.count) END
- ||
- CASE WHEN a.count is null THEN '{}'::JSONB
- ELSE jsonb_build_object('addr_count', a.count) END) as info
- FROM word_freq w FULL JOIN addr_freq a ON a.id = w.id;
- """)
- cur.execute('CREATE UNIQUE INDEX ON word_frequencies(id) INCLUDE(info)')
- cur.execute('ANALYSE word_frequencies')
- LOG.info('Update word table with recomputed frequencies')
- drop_tables(conn, 'tmp_word')
- cur.execute("""CREATE TABLE tmp_word AS
- SELECT word_id, word_token, type, word,
- (CASE WHEN wf.info is null THEN word.info
- ELSE coalesce(word.info, '{}'::jsonb) || wf.info
- END) as info
- FROM word LEFT JOIN word_frequencies wf
- ON word.word_id = wf.id
- ORDER BY word_id
- """)
- drop_tables(conn, 'word_frequencies')
+ LOG.info('Computing word frequencies')
+ drop_tables(conn, 'word_frequencies')
+ cur.execute("""
+ CREATE TEMP TABLE word_frequencies AS
+ WITH word_freq AS MATERIALIZED (
+ SELECT unnest(name_vector) as id, count(*)
+ FROM search_name GROUP BY id),
+ addr_freq AS MATERIALIZED (
+ SELECT unnest(nameaddress_vector) as id, count(*)
+ FROM search_name GROUP BY id)
+ SELECT coalesce(a.id, w.id) as id,
+ (CASE WHEN w.count is null THEN '{}'::JSONB
+ ELSE jsonb_build_object('count', w.count) END
+ ||
+ CASE WHEN a.count is null THEN '{}'::JSONB
+ ELSE jsonb_build_object('addr_count', a.count) END) as info
+ FROM word_freq w FULL JOIN addr_freq a ON a.id = w.id;
+ """)
+ cur.execute('CREATE UNIQUE INDEX ON word_frequencies(id) INCLUDE(info)')
+ cur.execute('ANALYSE word_frequencies')
+ LOG.info('Update word table with recomputed frequencies')
+ drop_tables(conn, 'tmp_word')
+ cur.execute("""CREATE TABLE tmp_word AS
+ SELECT word_id, word_token, type, word,
+ (CASE WHEN wf.info is null THEN word.info
+ ELSE coalesce(word.info, '{}'::jsonb) || wf.info
+ END) as info
+ FROM word LEFT JOIN word_frequencies wf
+ ON word.word_id = wf.id
+ ORDER BY word_id
+ """)
+ drop_tables(conn, 'word_frequencies')
with conn.cursor() as cur:
cur.execute('SET max_parallel_workers_per_gather TO 0')
from textwrap import dedent
from ..config import Configuration
-from ..db.connection import connect, Connection, server_version_tuple, \
+from ..db.connection import connect, Connection, \
index_exists, table_exists, execute_scalar
from ..db import properties
from ..errors import UsageError
if table_exists(conn, 'search_name'):
indexes.extend(('idx_search_name_nameaddress_vector',
'idx_search_name_name_vector',
- 'idx_search_name_centroid'))
- if server_version_tuple(conn) >= (11, 0, 0):
- indexes.extend(('idx_placex_housenumber',
- 'idx_osmline_parent_osm_id_with_hnr'))
+ 'idx_search_name_centroid',
+ 'idx_placex_housenumber',
+ 'idx_osmline_parent_osm_id_with_hnr'))
# These won't exist if --no-updates import was used
if table_exists(conn, 'place'):
with conn.cursor() as cur:
cur.execute('CREATE EXTENSION IF NOT EXISTS hstore')
cur.execute('CREATE EXTENSION IF NOT EXISTS postgis')
-
- postgis_version = postgis_version_tuple(conn)
- if postgis_version[0] >= 3:
- cur.execute('CREATE EXTENSION IF NOT EXISTS postgis_raster')
+ cur.execute('CREATE EXTENSION IF NOT EXISTS postgis_raster')
conn.commit()
from psycopg import sql as pysql
from ..config import Configuration
-from ..db.connection import Connection, connect, postgis_version_tuple, \
- drop_tables
+from ..db.connection import Connection, connect, drop_tables
from ..db.utils import execute_file
from ..db.sql_preprocessor import SQLPreprocessor
if not datafile.exists():
return 1
- with connect(dsn) as conn:
- postgis_version = postgis_version_tuple(conn)
- if postgis_version[0] < 3:
- LOG.error('PostGIS version is too old for using OSM raster data.')
- return 2
-
execute_file(dsn, datafile, ignore_errors=ignore_errors)
return 0
from ..errors import UsageError
from ..db import status
-from ..db.connection import Connection, connect, server_version_tuple
+from ..db.connection import Connection, connect
from .exec_utils import run_osm2pgsql
try:
# Consume updates with osm2pgsql.
options['append'] = True
- options['disable_jit'] = server_version_tuple(conn) >= (11, 0)
+ options['disable_jit'] = True
run_osm2pgsql(options)
# Handle deletions
NOMINATIM_VERSION = parse_version('4.5.0-0')
-POSTGRESQL_REQUIRED_VERSION = (9, 6)
-POSTGIS_REQUIRED_VERSION = (2, 2)
+POSTGRESQL_REQUIRED_VERSION = (12, 0)
+POSTGIS_REQUIRED_VERSION = (3, 0)
OSM2PGSQL_REQUIRED_VERSION = (1, 8)
# Cmake sets a variable @GIT_HASH@ by executing 'git --log'. It is not run
| 1 | 0.9 |
Then results contain
| geotext |
- | ^POLYGON\(\(9.5225302 47.138066, ?9.5225348 47.1379282, ?9.5227608 47.1379757, ?9.5227337 47.1380692, ?9.5225302 47.138066\)\) |
+ | ^POLYGON\(\([0-9. ]+, ?[0-9. ]+, ?[0-9. ]+, ?[0-9. ]+(, ?[0-9. ]+)?\)\) |
Scenario: For polygons return the centroid as center point
libbz2-dev libpq-dev liblua5.3-dev lua5.3 lua-dkjson \
nlohmann-json3-dev postgresql-14-postgis-3 \
postgresql-contrib-14 postgresql-14-postgis-3-scripts \
- libicu-dev python3-dotenv \
- python3-pip python3-psutil python3-jinja2 \
- python3-sqlalchemy python3-asyncpg \
- python3-icu python3-datrie python3-yaml git
-
-# Some of the Python packages that come with Ubuntu 22.04 are too old,
-# so install the latest version from pip:
-
- pip3 install --user psycopg[binary]
+ libicu-dev virtualenv git
#
# System Configuration
#
if [ "x$1" == "xyes" ]; then #DOCS: :::sh
cd $USERHOME
- git clone --recursive https://github.com/openstreetmap/Nominatim.git
+ git clone https://github.com/osm-search/Nominatim.git
cd Nominatim
else #DOCS:
cd $USERHOME/Nominatim #DOCS:
wget -O data/country_osm_grid.sql.gz https://nominatim.org/data/country_grid.sql.gz
fi #DOCS:
-# The code must be built in a separate directory. Create this directory,
-# then configure and build Nominatim in there:
+# Nominatim needs osm2pgsql >= 1.8. The version that comes with Ubuntu is
+# too old. Download and compile your own:
- mkdir $USERHOME/build
- cd $USERHOME/build
- cmake $USERHOME/Nominatim
+ cd $USERHOME
+ git clone https://github.com/osm2pgsql-dev/osm2pgsql
+ mkdir osm2pgsql-build
+ cd osm2pgsql-build
+ cmake ../osm2pgsql
make
sudo make install
+ cd $USERHOME/Nominatim
+
+# Nominatim should be installed in a separate Python virtual environment.
+# Create the virtual environment:
+
+ virtualenv $USERHOME/nominatim-venv
+
+# We want the faster binary version pf psycopg, so install that:
+
+ $USERHOME/nominatim-venv/bin/pip install psycopg[binary]
+
+# Now install Nominatim using pip:
+
+ cd $USERHOME/Nominatim
+ $USERHOME/nominatim-venv/bin/pip install packaging/nominatim-db
# Nominatim is now ready to use. You can continue with
# [importing a database from OSM data](../admin/Import.md). If you want to set up
# Setting up the Python frontend
# ==============================
#
-# Some of the Python packages in Ubuntu are too old. Therefore run the
-# frontend from a Python virtualenv with current packages.
+# The Python frontend is contained in the nominatim-api package. To run
+# the API as a webservice, you also need falcon with uvicorn to serve the API.
+# It is generally recommended to run falcon/uvicorn on top of gunicorn.
#
-# To set up the virtualenv, run:
+# To install all packages, run:
#DOCS:```sh
-sudo apt-get install -y virtualenv
-virtualenv $USERHOME/nominatim-venv
-$USERHOME/nominatim-venv/bin/pip install SQLAlchemy PyICU psycopg[binary] \
- psycopg2-binary python-dotenv PyYAML falcon uvicorn gunicorn
+$USERHOME/nominatim-venv/bin/pip install falcon uvicorn gunicorn
+cd $USERHOME/Nominatim
+$USERHOME/nominatim-venv/bin/pip install packaging/nominatim-api
#DOCS:```
+
# Next you need to create a systemd job that runs Nominatim on gunicorn.
# First create a systemd job that manages the socket file:
[Service]
Type=simple
-Environment="PYTHONPATH=/usr/local/lib/nominatim/lib-python/"
User=www-data
Group=www-data
WorkingDirectory=$USERHOME/nominatim-project
-ExecStart=$USERHOME/nominatim-venv/bin/gunicorn -b unix:/run/nominatim.sock -w 4 -k uvicorn.workers.UvicornWorker nominatim_api.server.falcon.server:run_wsgi
+ExecStart=$USERHOME/nominatim-venv/bin/gunicorn -b unix:/run/nominatim.sock -w 4 -k uvicorn.workers.UvicornWorker "nominatim_api.server.falcon.server:run_wsgi()"
ExecReload=/bin/kill -s HUP \$MAINPID
-StandardOutput=append:/var/log/gunicorn-nominatim.log
-StandardError=inherit
PrivateTmp=true
TimeoutStopSec=5
KillMode=mixed
#
if [ "x$1" == "xyes" ]; then #DOCS: :::sh
cd $USERHOME
- git clone https://github.com/openstreetmap/Nominatim.git
+ git clone https://github.com/osm-search/Nominatim.git
cd Nominatim
else #DOCS:
cd $USERHOME/Nominatim #DOCS:
virtualenv $USERHOME/nominatim-venv
+# We want the faster binary version pf psycopg, so install that:
+
+ $USERHOME/nominatim-venv/bin/pip install psycopg[binary]
+
# Now install Nominatim using pip:
cd $USERHOME/Nominatim
# To install all packages, run:
#DOCS:```sh
-$USERHOME/nominatim-venv/bin/pip install psycopg[binary] falcon uvicorn gunicorn
+$USERHOME/nominatim-venv/bin/pip install falcon uvicorn gunicorn
cd $USERHOME/Nominatim
$USERHOME/nominatim-venv/bin/pip install packaging/nominatim-api
#DOCS:```
User=www-data
Group=www-data
WorkingDirectory=$USERHOME/nominatim-project
-ExecStart=$USERHOME/nominatim-venv/bin/gunicorn -b unix:/run/nominatim.sock -w 4 -k uvicorn.workers.UvicornWorker nominatim_api.server.falcon.server:run_wsgi
+ExecStart=$USERHOME/nominatim-venv/bin/gunicorn -b unix:/run/nominatim.sock -w 4 -k uvicorn.workers.UvicornWorker "nominatim_api.server.falcon.server:run_wsgi()"
ExecReload=/bin/kill -s HUP \$MAINPID
-StandardOutput=append:/var/log/gunicorn-nominatim.log
-StandardError=inherit
PrivateTmp=true
TimeoutStopSec=5
KillMode=mixed