]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorSarah Hoffmann <lonvia@denofr.de>
Tue, 18 Sep 2018 20:32:30 +0000 (22:32 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Tue, 18 Sep 2018 20:32:30 +0000 (22:32 +0200)
37 files changed:
AUTHORS
CMakeLists.txt
ChangeLog
README.md
Vagrantfile
docs/CMakeLists.txt
docs/admin/Faq.md
docs/admin/Import-and-Update.md
docs/admin/Installation.md
docs/admin/Migration.md
docs/api/Details.md
docs/extra.css [new file with mode: 0644]
docs/mkdocs.yml
lib/SearchDescription.php
lib/cmd.php
sql/tables.sql
test/php/Nominatim/DebugTest.php
test/php/Nominatim/LibTest.php
test/php/Nominatim/ParameterParserTest.php
test/php/Nominatim/PhraseTest.php
test/php/Nominatim/SearchContextTest.php
test/php/Nominatim/StatusTest.php
test/php/Nominatim/TokenListTest.php
test/php/bootstrap.php
test/php/phpunit.xml [moved from phpunit.xml with 81% similarity]
utils/blocks.php
utils/country_languages.php
utils/export.php
utils/importWikipedia.php
utils/imports.php
utils/query.php
utils/server_compare.php
utils/setup.php
utils/specialphrases.php
utils/update.php
utils/warm.php
vagrant/Install-on-Ubuntu-18.sh [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
index a94d288eed4f50dc01651f8d0d37fcf202ca00a2..fc28bf2e7fea28d8e32a4e484de14371cc4de1b8 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,16 +3,13 @@ Nominatim was written by:
   Brian Quinion
   Sarah Hoffmann
   Marc Tobias Metten
+
   markigail
+  gemo1011
   IrlJidel
   Frederik Ramm
-  Michael Spreng
-  Daniele Forsi
-  mfn
-  Grant Slater
-  Andree Klattenhoff
-  appelflap
-  b3nn0
-  Spin0us
-  Kurt Roeckx
-  Rodolphe QuiĆ©deville
+
+and many more.
+
+For a full list of contributors see
+https://github.com/openstreetmap/Nominatim/graphs/contributors
index 347f4d488b5a9c506985aab71a1be9feebfe02b2..0c6d4094ed7eaadd78d42b7898e33793d7e72450 100644 (file)
@@ -19,7 +19,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 project(nominatim)
 
 set(NOMINATIM_VERSION_MAJOR 3)
-set(NOMINATIM_VERSION_MINOR 1)
+set(NOMINATIM_VERSION_MINOR 2)
 set(NOMINATIM_VERSION_PATCH 0)
 
 set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
@@ -77,6 +77,16 @@ find_package(BZip2 REQUIRED)
 find_package(LibXml2 REQUIRED)
 include_directories(${LIBXML2_INCLUDE_DIR})
 
+# Setting PHP binary variable as to command line (prevailing) or auto detect
+if (NOT PHP_BIN)
+     find_program (PHP_BIN php)
+endif()
+# sanity check if PHP binary exists
+if (NOT EXISTS ${PHP_BIN})
+    message(FATAL_ERROR "PHP binary not found. Install php or provide location with -DPHP_BIN=/path/php ")
+endif()
+message (STATUS "Using PHP binary " ${PHP_BIN})
+
 #-----------------------------------------------------------------------------
 #
 # Setup settings and paths
index 3bd80bd5a2391a310787c2ac986960b03a20a010..31c5f2263926ec3eb89927110a2830537ee9599d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+3.2.0
+
+ * complete rewrite of reverse search algorithm
+ * add new geojson and geocodejson output formats
+ * add simple export script to exprot addresses to CSV
+ * remove is_in terms from address computation
+ * remove unused search_name_country tables
+ * various smaller fixes to query parsing
+ * convert Tokens and token types to class types
+ * correctly handle update when boundary object type is changed
+ * improve debug output for /search endpoint
+ * update to latest osm2pgsql and leaflet.js
+ * overhaul of /details endpoint:
+     * new class parameter when using osmtype/osmid parameters
+     * permalink to instance-independent osmtype/osmid parameter format
+     * new json output format
+ * update CentOS vagrant machine to use SELinux
+ * add vagrant scripts for Ubuntu 18.04
+ * fix build process for BSD
+ * enable running the database on a different host than the setup scripts
+ * allow to configure use of custom PHP binaries (PHP_BIN)
+ * extensive coding style improvements to PHP code
+ * more PHP unit tests for new classes
+ * increase coverage for API tests
+ * add documentation for API
+
 3.1.0
 
  * rework postcode handling and introduce location_postcode table
index 406f7c858a065a11ffa56c6d806680a94f471fce..dd900e3e91f434df9792174473eb9d2306f91538 100644 (file)
--- a/README.md
+++ b/README.md
@@ -47,11 +47,17 @@ License
 
 The source code is available under a GPLv2 license.
 
-Contact and Bug reports
-======================
+
+Contributing
+============
+
+Contributions are welcome. For details see [CONTRIBUTING.md](contribution guide).
+
+Both bug reports and pull requests are welcome.
+
+
+Mailing list
+============
 
 For questions you can join the geocoding mailinglist, see
 https://lists.openstreetmap.org/listinfo/geocoding
-
-Bugs may be reported on the github project site:
-https://github.com/openstreetmap/Nominatim
index 5c9563bd0ef0ced397584b24eb94bd6efa9ded25..bd610e7e756fda910b69da6838cc6a398907c80f 100644 (file)
@@ -15,6 +15,15 @@ Vagrant.configure("2") do |config|
   end
 
   config.vm.define "ubuntu", primary: true do |sub|
+      sub.vm.box = "bento/ubuntu-18.04"
+      sub.vm.provision :shell do |s|
+        s.path = "vagrant/Install-on-Ubuntu-18.sh"
+        s.privileged = false
+        s.args = [checkout]
+      end
+  end
+
+  config.vm.define "ubuntu16" do |sub|
       sub.vm.box = "bento/ubuntu-16.04"
       sub.vm.provision :shell do |s|
         s.path = "vagrant/Install-on-Ubuntu-16.sh"
index f335060f692402b9ed1d0ccb3df6a43f35cbd68d..cbe91b91d355e90416b0aa30be7d096cec010b25 100644 (file)
@@ -11,8 +11,10 @@ ADD_CUSTOM_TARGET(doc
    COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/develop ${CMAKE_CURRENT_BINARY_DIR}/develop
    COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/api ${CMAKE_CURRENT_BINARY_DIR}/api
    COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/index.md ${CMAKE_CURRENT_BINARY_DIR}/index.md
+   COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/extra.css ${CMAKE_CURRENT_BINARY_DIR}/extra.css
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bash2md.sh ${PROJECT_SOURCE_DIR}/vagrant/Install-on-Centos-7.sh ${CMAKE_CURRENT_BINARY_DIR}/appendix/Install-on-Centos-7.md
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bash2md.sh ${PROJECT_SOURCE_DIR}/vagrant/Install-on-Ubuntu-16.sh ${CMAKE_CURRENT_BINARY_DIR}/appendix/Install-on-Ubuntu-16.md
+   COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bash2md.sh ${PROJECT_SOURCE_DIR}/vagrant/Install-on-Ubuntu-18.sh ${CMAKE_CURRENT_BINARY_DIR}/appendix/Install-on-Ubuntu-18.md
    COMMAND mkdocs build -d ${CMAKE_CURRENT_BINARY_DIR}/../site-html -f ${CMAKE_CURRENT_BINARY_DIR}/../mkdocs.yml
 )
 
index f3ad670a6e836344c5fe61985d96e0255730337b..46da7e21ba0b8384e9d3ff8c38804124a9cf6f3e 100644 (file)
@@ -1,33 +1,6 @@
-# Running Your Own Instance
-
-### Can I import multiple countries and keep them up to date?
-
-You should use the extracts and updates from https://download.geofabrik.de.
-For the initial import, download the countries you need and merge them.
-See [OSM Help](https://help.openstreetmap.org/questions/48843/merging-two-or-more-geographical-areas-to-import-two-or-more-osm-files-in-nominatim)
-for examples how to do that. Use the resulting single osm file when
-running `setup.php`.
-
-For updates you need to download the change files for each country
-once per day and apply them **separately** using
-
-    ./utils/update.php --import-diff <filename> --index
-    
-See [this issue](https://github.com/openstreetmap/Nominatim/issues/60#issuecomment-18679446)
-for a script that runs the updates using osmosis.
-
-### Can I import negative OSM ids into Nominatim?
-
-See [https://help.openstreetmap.org/questions/64662/nominatim-flatnode-with-negative-id]()
-
-### Missing XML or text declaration
-
-The website might show: `XML Parsing Error: XML or text declaration not at start of entity Location.`
-
-Make sure there are no spaces at the beginning of your `settings/local.php` file.
+# Troubleshooting Nominatim Installations
 
-
-# Installation
+## Installation Issues
 
 ### Can a stopped/killed import process be resumed?
 
@@ -145,9 +118,9 @@ Example error message
    CONTEXT: PL/pgSQL function make_standard_name(text) line 5 at assignment]
 ```
 
-The user the webserver, e.g. Apache, runs under needs to have access to that file. Same for the user the Postgres runs as. You can find the user like [this](https://serverfault.com/questions/125865/finding-out-what-user-apache-is-running-as), for default Ubuntu operating system for example it's `www-data`.
+The Postgresql database, i.e. user postgres, needs to have access to that file.
 
-The permission need to be read&executable by everybody, e.g.
+The permission need to be read & executable by everybody, e.g.
 
 ```
    -rwxr-xr-x 1 nominatim nominatim 297984 build/module/nominatim.so
@@ -155,6 +128,9 @@ The permission need to be read&executable by everybody, e.g.
 
 Try `chmod a+r nominatim.so; chmod a+x nominatim.so`.
 
+When running SELinux, make sure that the
+[context is set up correctly](../appendix/Install-on-Centos-7/#adding-selinux-security-settings).
+
 ### Setup.php fails with "DB Error: extension not found"
 
 Make sure you have the Postgres extensions hstore and postgis installed.
@@ -177,3 +153,33 @@ That's fine. For each import the flatnodes file get overwritten.
 See [https://help.openstreetmap.org/questions/52419/nominatim-flatnode-storage]()
 for more information.
 
+
+## Running your own instance
+
+### Can I import multiple countries and keep them up to date?
+
+You should use the extracts and updates from https://download.geofabrik.de.
+For the initial import, download the countries you need and merge them.
+See [OSM Help](https://help.openstreetmap.org/questions/48843/merging-two-or-more-geographical-areas-to-import-two-or-more-osm-files-in-nominatim)
+for examples how to do that. Use the resulting single osm file when
+running `setup.php`.
+
+For updates you need to download the change files for each country
+once per day and apply them **separately** using
+
+    ./utils/update.php --import-diff <filename> --index
+    
+See [this issue](https://github.com/openstreetmap/Nominatim/issues/60#issuecomment-18679446)
+for a script that runs the updates using osmosis.
+
+### Can I import negative OSM ids into Nominatim?
+
+See [this question of Stackoverflow](https://help.openstreetmap.org/questions/64662/nominatim-flatnode-with-negative-id).
+
+### Missing XML or text declaration
+
+The website might show: `XML Parsing Error: XML or text declaration not at start of entity Location.`
+
+Make sure there are no spaces at the beginning of your `settings/local.php` file.
+
+
index 25954ba075b800f68fe829bd1e805625dfe04837..731ff8faee6bda0fb480b53e62fdceb7052b6bf9 100644 (file)
@@ -1,9 +1,11 @@
+# Importing and Updating the Database
+
 The following instructions explain how to create a Nominatim database
 from an OSM planet file and how to keep the database up to date. It
 is assumed that you have already successfully installed the Nominatim
 software itself, if not return to the [installation page](Installation.md).
 
-# Configuration setup in settings/local.php
+## Configuration setup in settings/local.php
 
 The Nominatim server can be customized via the file `settings/local.php`
 in the build directory. Note that this is a PHP file, so it must always
@@ -16,7 +18,7 @@ without any leading spaces.
 There are lots of configuration settings you can tweak. Have a look
 at `settings/default.php` for a full list. Most should have a sensible default.
 
-### Flatnode files
+#### Flatnode files
 
 If you plan to import a large dataset (e.g. Europe, North America, planet),
 you should also enable flatnode storage of node locations. With this
@@ -29,9 +31,9 @@ Add to your `settings/local.php`:
 Replace the second part with a suitable path on your system and make sure
 the directory exists. There should be at least 40GB of free space.
 
-# Downloading additional data
+## Downloading additional data
 
-## Wikipedia rankings
+### Wikipedia rankings
 
 Wikipedia can be used as an optional auxiliary data source to help indicate
 the importance of osm features. Nominatim will work without this information
@@ -49,7 +51,7 @@ size of nominatim. They also increase the install time by an hour or so.
 the initial import of the data if you want the rankings applied to the
 loaded data.
 
-## UK postcodes
+### UK postcodes
 
 Nominatim can use postcodes from an external source to improve searches that involve a UK postcode. This data can be optionally downloaded: 
 
@@ -57,7 +59,7 @@ Nominatim can use postcodes from an external source to improve searches that inv
     wget https://www.nominatim.org/data/gb_postcode_data.sql.gz
 
 
-# Initial import of the data
+## Initial import of the data
 
 **Important:** first try the import with a small excerpt, for example from
 [Geofabrik](https://download.geofabrik.de).
@@ -97,7 +99,7 @@ you also need to enable these key phrases like this:
 Note that this command downloads the phrases from the wiki link above.
 
 
-# Installing Tiger housenumber data for the US
+## Installing Tiger housenumber data for the US
 
 Nominatim is able to use the official TIGER address set to complement the
 OSM house number data in the US. You can add TIGER data to your own Nominatim
@@ -146,13 +148,13 @@ SQL files, Nominatim needs for the import:
 Be warned that this can take quite a long time. After this process is finished,
 the same preprocessed files as above are available in `data/tiger`.
 
-# Updates
+## Updates
 
 There are many different possibilities to update your Nominatim database.
 The following section describes how to keep it up-to-date with Pyosmium.
 For a list of other methods see the output of `./utils/update.php --help`.
 
-### Installing the newest version of Pyosmium
+#### Installing the newest version of Pyosmium
 
 It is recommended to install Pyosmium via pip. Run (as the same user who
 will later run the updates):
@@ -161,7 +163,7 @@ will later run the updates):
 pip install --user osmium
 ```
 
-Nominatim needs a tool called `pyosmium-get-updates` that comes with
+Nominatim needs a tool called `pyosmium-get-updates`, which comes with
 Pyosmium. You need to tell Nominatim where to find it. Add the
 following line to your `settings/local.php`:
 
@@ -170,7 +172,7 @@ following line to your `settings/local.php`:
 The path above is fine if you used the `--user` parameter with pip.
 Replace `user` with your user name.
 
-### Setting up the update process
+#### Setting up the update process
 
 Next the update needs to be initialised. By default Nominatim is configured
 to update using the global minutely diffs.
@@ -196,7 +198,7 @@ what you expect.
 The --init-updates command needs to be rerun whenever the replication service
 is changed.
 
-### Updating Nominatim
+#### Updating Nominatim
 
 The following command will keep your database constantly up to date:
 
index 67c4fe3c6687639423ef3ed465619ee1516347c8..592c6cc19e0b85209da671a0cdfb8d5e0d1f308e 100644 (file)
@@ -1,7 +1,10 @@
+# Basic Installation
+
 This page contains generic installation instructions for Nominatim and its
 prerequisites. There are also step-by-step instructions available for
 the following operating systems:
 
+  * [Ubuntu 18.04](../appendix/Install-on-Ubuntu-18.md)
   * [Ubuntu 16.04](../appendix/Install-on-Ubuntu-16.md)
   * [CentOS 7.2](../appendix/Install-on-Centos-7.md)
 
@@ -15,9 +18,9 @@ and can't offer support.
   * [Docker on Kubernetes](https://github.com/peter-evans/nominatim-k8s)
   * [Ansible](https://github.com/synthesio/infra-ansible-nominatim)
 
-# Prerequisites
+## Prerequisites
 
-## Software
+### Software
 
 For compiling:
 
@@ -49,22 +52,22 @@ For running continuous updates:
 
   * [pyosmium](http://osmcode.org/pyosmium/)
 
-## Hardware
+### Hardware
 
 A minimum of 2GB of RAM is required or installation will fail. For a full
 planet import 32GB of RAM or more strongly are recommended.
 
-For a full planet install you will need about 600GB of hard disk space (as of
-January 2017, take into account that the OSM database is growing fast). SSD disks
+For a full planet install you will need at least 700GB of hard disk space
+(take into account that the OSM database is growing fast). SSD disks
 will help considerably to speed up import and queries.
 
 On a 6-core machine with 32GB RAM and SSDs the import of a full planet takes
 a bit more than 2 days. Without SSDs 7-8 days are more realistic.
 
 
-# Setup of the server
+## Setup of the server
 
-## PostgreSQL tuning
+### PostgreSQL tuning
 
 You might want to tune your PostgreSQL installation so that the later steps
 make best use of your hardware. You should tune the following parameters in
@@ -91,13 +94,13 @@ Don't forget to reenable them after the initial import or you risk database
 corruption. Autovacuum must not be switched off because it ensures that the
 tables are frequently analysed.
 
-## Webserver setup
+### Webserver setup
 
 The `website/` directory in the build directory contains the configured
 website. Include the directory into your webbrowser to serve php files
 from there.
 
-### Configure for use with Apache
+#### Configure for use with Apache
 
 Make sure your Apache configuration contains the required permissions for the
 directory and create an alias:
@@ -116,7 +119,7 @@ build directory.
 After making changes in the apache config you need to restart apache.
 The website should now be available on http://localhost/nominatim.
 
-### Configure for use with Nginx
+#### Configure for use with Nginx
 
 Use php-fpm as a deamon for serving PHP cgi. Install php-fpm together with nginx.
 
index 2f03c200a1acfc21b17815f0f81afd86a99cd288..2cc0b80b3cddcb867d1ad9a2c9d4a0be9f537eb3 100644 (file)
@@ -1,5 +1,4 @@
-Database Migrations
-===================
+# Database Migrations
 
 This page describes database migrations necessary to update existing databases
 to newer versions of Nominatim.
@@ -7,7 +6,46 @@ to newer versions of Nominatim.
 SQL statements should be executed from the postgres commandline. Execute
 `psql nominiatim` to enter command line mode.
 
-# 3.0.0 -> 3.1.0
+## 3.1.0 -> 3.2.0
+
+### New reverse algorithm
+
+The reverse algorithm has changed and requires new indexes. Run the following
+SQL statements to create the indexes:
+
+```
+CREATE INDEX idx_placex_geometry_reverse_lookupPoint
+  ON placex USING gist (geometry)
+  WHERE (name is not null or housenumber is not null or rank_address between 26 and 27)
+    AND class not in ('railway','tunnel','bridge','man_made')
+    AND rank_address >= 26 AND indexed_status = 0 AND linked_place_id is null;
+CREATE INDEX idx_placex_geometry_reverse_lookupPolygon
+  ON placex USING gist (geometry)
+  WHERE St_GeometryType(geometry) in ('ST_Polygon', 'ST_MultiPolygon')
+    AND rank_address between 4 and 25 AND type != 'postcode'
+    AND name is not null AND indexed_status = 0 AND linked_place_id is null;
+CREATE INDEX idx_placex_geometry_reverse_placeNode
+  ON placex USING gist (geometry)
+  WHERE osm_type = 'N' AND rank_search between 5 and 25
+    AND class = 'place' AND type != 'postcode'
+    AND name is not null AND indexed_status = 0 AND linked_place_id is null;
+```
+
+You also need to grant the website user access to the `country_osm_grid` table:
+
+```
+GRANT SELECT ON table country_osm_grid to "www-user";
+```
+
+Replace the `www-user` with the user name of your website server if necessary.
+
+Finally, you can drop the now unused indexes:
+
+```
+DROP INDEX idx_placex_reverse_geometry;
+```
+
+## 3.0.0 -> 3.1.0
 
 ### Postcode Table
 
@@ -26,6 +64,17 @@ CREATE INDEX idx_postcode_geometry ON location_postcode USING GIST (geometry);
 CREATE UNIQUE INDEX idx_postcode_id ON location_postcode USING BTREE (place_id);
 CREATE INDEX idx_postcode_postcode ON location_postcode USING BTREE (postcode);
 GRANT SELECT ON location_postcode TO "www-data";
+drop type if exists nearfeaturecentr cascade;
+create type nearfeaturecentr as (
+  place_id BIGINT,
+  keywords int[],
+  rank_address smallint,
+  rank_search smallint,
+  distance float,
+  isguess boolean,
+  postcode TEXT,
+  centroid GEOMETRY
+);
 ```
 
 Add postcode column to `location_area` tables with SQL statement:
index 357b6a4b92ef6e3088d07c08777b11525c2db633..027138a9b73615869f4723bb3eb3a35ae9dcec34 100644 (file)
@@ -10,12 +10,18 @@ Lookup details about a single place by id. The default output is HTML for debugg
 The details API supports the following two request formats:
 
 ```
-  https://nominatim.openstreetmap.org/details?osmtype=[N|W|R]&osmid=<value>
+  https://nominatim.openstreetmap.org/details?osmtype=[N|W|R]&osmid=<value>&class=<value>
 ```
 
-Both parameters are required, the type is one of node(N), way(W) or relation(R).
-
-Or
+`osmtype` and `osmid` are required parameter. The type is one of node (N), way (W)
+or relation (R). The id must be a number. The `class` parameter is optional and
+allows to distinguish between entries, when the corresponding OSM object has more
+than one main tag. For example, when a place is tagged with `tourism=hotel` and
+`amenity=restaurant`, there will be two place entries in Nominatim, one for a
+restaurant, one for a hotel. You need to specify `class=tourism` or `class=amentity`
+to get exactly the one you want. If there are multiple places in the database
+but the `class` parameter is left out, then one of the places will be chosen
+at random and displayed.
 
 ```
   https://nominatim.openstreetmap.org/details?placeid=<value>
@@ -82,11 +88,11 @@ comma-separated list of language codes.
 
 ##### HTML
 
-[https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=38210407]()
+[https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=38210407](https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=38210407)
 
 ##### JSON
 
-[https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=38210407&format=json]()
+[https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=38210407&format=json](https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=38210407&format=json)
 
 
 ```json
diff --git a/docs/extra.css b/docs/extra.css
new file mode 100644 (file)
index 0000000..a8c3a1c
--- /dev/null
@@ -0,0 +1,3 @@
+.toctree-l3 {
+    display: none!important
+}
index 87d6536378a90d8f6a5a240c84d8b756153e164c..b620decf19bbed792e0aa9b15f4c450d5e7a4d69 100644 (file)
@@ -10,6 +10,7 @@ pages:
         - 'Search': 'api/Search.md'
         - 'Reverse': 'api/Reverse.md'
         - 'Address Lookup': 'api/Lookup.md'
+        - 'Details' : 'api/Details.md'
         - 'Place Output Formats': 'api/Output.md'
         - 'FAQ': 'api/Faq.md'
     - 'Administration Guide':
@@ -22,6 +23,10 @@ pages:
     - 'Appendix':
         - 'Installation on CentOS 7' : 'appendix/Install-on-Centos-7.md'
         - 'Installation on Ubuntu 16' : 'appendix/Install-on-Ubuntu-16.md'
+        - 'Installation on Ubuntu 18' : 'appendix/Install-on-Ubuntu-18.md'
 markdown_extensions:
     - codehilite:
         use_pygments: False
+    - toc:
+        permalink: ļƒ
+extra_css: [extra.css]
index 079cb8a6e65d1c72d8dd8693e40d740569206d45..35424b529244c9071a89d808a2419e3dba00f0ab 100644 (file)
@@ -287,7 +287,7 @@ class SearchDescription
             if (!empty($this->aName) || !($bFirstPhrase || $sPhraseType == '')) {
                 if (($sPhraseType == '' || !$bFirstPhrase) && !$bHasPartial) {
                     $oSearch = clone $this;
-                    $oSearch->iSearchRank++;
+                    $oSearch->iSearchRank += 2;
                     $oSearch->aAddress[$iWordID] = $iWordID;
                     $aNewSearches[] = $oSearch;
                 } else {
index 9efe5653b735ca45dd12a62da471d824436dc4ee..44923618723636b86aec3c17f9f3ae4df3742e83 100644 (file)
@@ -185,6 +185,10 @@ function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreError
         fail('unable to start pgsql');
     }
 
+    if (!$bVerbose) {
+        fwrite($ahPipes[0], 'set client_min_messages to WARNING;');
+    }
+
     while (strlen($sScript)) {
         $iWritten = fwrite($ahPipes[0], $sScript);
         if ($iWritten <= 0) break;
index 4a22a814feab17140a2af2b0f994fa9bfb0b1935..949dc6ffe1c8c26dc7e6bb48727b61c4a9443a42 100644 (file)
@@ -10,7 +10,7 @@ drop table if exists import_osmosis_log;
 CREATE TABLE import_osmosis_log (
   batchend timestamp,
   batchseq integer,
-  batchsize integer,
+  batchsize bigint,
   starttime timestamp,
   endtime timestamp,
   event text
index 6e0c25f3a22a150b4b4838c5ffeaba03713f09e5..7ef1dba336836be7f6f6626a75f36943e6edb472 100644 (file)
@@ -2,19 +2,23 @@
 
 namespace Nominatim;
 
-use Exception;
+require_once(CONST_BasePath.'/lib/DebugHtml.php');
 
-require_once('../../lib/DebugHtml.php');
-
-class DebugTest extends \PHPUnit_Framework_TestCase
+class DebugTest extends \PHPUnit\Framework\TestCase
 {
+
     protected function setUp()
     {
-        $this->oWithDebuginfo = $this->getMock(Geocode::class, array('debugInfo'));
+        $this->oWithDebuginfo = $this->getMockBuilder(\GeococdeMock::class)
+                                    ->setMethods(array('debugInfo'))
+                                    ->getMock();
         $this->oWithDebuginfo->method('debugInfo')
                   ->willReturn(array('key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3'));
 
-        $this->oWithToString = $this->getMock(Geocode::class, array('__toString'));
+
+        $this->oWithToString = $this->getMockBuilder(\SomeMock::class)
+                                    ->setMethods(array('__toString'))
+                                    ->getMock();
         $this->oWithToString->method('__toString')->willReturn('me as string');
     }
 
index 55ae1aaa055eaf93dfb4693bdf9c9b33edf77381..d2237b602657939b44aadc158792c66701469403 100644 (file)
@@ -2,10 +2,9 @@
 
 namespace Nominatim;
 
-require_once '../../lib/lib.php';
-require_once '../../lib/ClassTypes.php';
+require_once(CONST_BasePath.'/lib/ClassTypes.php');
 
-class LibTest extends \PHPUnit_Framework_TestCase
+class LibTest extends \PHPUnit\Framework\TestCase
 {
     public function testGetClassTypesWithImportance()
     {
index 0cbc60c545c5494b74d05493073ecbdc1b8d5008..9f51a629f09d99856a9d4bbf6b7748dfa9a27542 100644 (file)
@@ -2,17 +2,15 @@
 
 namespace Nominatim;
 
-use Exception;
-
-require_once('../../lib/ParameterParser.php');
+require_once(CONST_BasePath.'/lib/ParameterParser.php');
 
 
 function userError($sError)
 {
-    throw new Exception($sError);
+    throw new \Exception($sError);
 }
 
-class ParameterParserTest extends \PHPUnit_Framework_TestCase
+class ParameterParserTest extends \PHPUnit\Framework\TestCase
 {
 
 
@@ -55,14 +53,18 @@ class ParameterParserTest extends \PHPUnit_Framework_TestCase
 
     public function testGetIntWithNonNumber()
     {
-        $this->setExpectedException(Exception::class, "Integer number expected for parameter 'int4'");
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage("Integer number expected for parameter 'int4'");
+
         (new ParameterParser(array('int4' => 'a')))->getInt('int4');
     }
 
 
     public function testGetIntWithEmpytString()
     {
-        $this->setExpectedException(Exception::class, "Integer number expected for parameter 'int5'");
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage("Integer number expected for parameter 'int5'");
+
         (new ParameterParser(array('int5' => '')))->getInt('int5');
     }
 
@@ -85,20 +87,26 @@ class ParameterParserTest extends \PHPUnit_Framework_TestCase
 
     public function testGetFloatWithEmptyString()
     {
-        $this->setExpectedException(Exception::class, "Floating-point number expected for parameter 'float4'");
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage("Floating-point number expected for parameter 'float4'");
+
         (new ParameterParser(array('float4' => '')))->getFloat('float4');
     }
 
     public function testGetFloatWithTextString()
     {
-        $this->setExpectedException(Exception::class, "Floating-point number expected for parameter 'float5'");
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage("Floating-point number expected for parameter 'float5'");
+
         (new ParameterParser(array('float5' => 'a')))->getFloat('float5');
     }
 
 
     public function testGetFloatWithInvalidNumber()
     {
-        $this->setExpectedException(Exception::class, "Floating-point number expected for parameter 'float6'");
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage("Floating-point number expected for parameter 'float6'");
+
         (new ParameterParser(array('float6' => '-55.')))->getFloat('float6');
     }
 
@@ -138,7 +146,9 @@ class ParameterParserTest extends \PHPUnit_Framework_TestCase
 
     public function testGetSetWithValueNotInSet()
     {
-        $this->setExpectedException(Exception::class, "Parameter 'val4' must be one of: foo, bar");
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage("Parameter 'val4' must be one of: foo, bar");
+
         (new ParameterParser(array('val4' => 'faz')))->getSet('val4', array('foo', 'bar'));
     }
 
index b5e6c1bf6e666b0f3a6c631648f3bc24865566e6..cd74271543c7979300ea6026dd3109bb2c03a944 100644 (file)
@@ -2,9 +2,9 @@
 
 namespace Nominatim;
 
-require_once '../../lib/Phrase.php';
+require_once(CONST_BasePath.'/lib/Phrase.php');
 
-class PhraseTest extends \PHPUnit_Framework_TestCase
+class PhraseTest extends \PHPUnit\Framework\TestCase
 {
 
 
index db0b2dee1de20c4338f6cbd9d3ba1f6c42ec254a..166e6433d141d259007cbc5b7e17686149d49faf 100644 (file)
@@ -2,11 +2,9 @@
 
 namespace Nominatim;
 
-@define('CONST_BasePath', '../../');
+require_once(CONST_BasePath.'/lib/SearchContext.php');
 
-require_once '../../lib/SearchContext.php';
-
-class SearchContextTest extends \PHPUnit_Framework_TestCase
+class SearchContextTest extends \PHPUnit\Framework\TestCase
 {
     private $oCtx;
 
index 06823720c48e582a3c70f219822bce5303594a8d..4f21706ecaf9274ce74740d750025152dc2c133a 100644 (file)
@@ -2,18 +2,17 @@
 
 namespace Nominatim;
 
-require_once('../../lib/Status.php');
-require_once('DB.php');
+require_once(CONST_BasePath.'/lib/Status.php');
 
-use Exception;
 
-class StatusTest extends \PHPUnit_Framework_TestCase
+class StatusTest extends \PHPUnit\Framework\TestCase
 {
 
-
     public function testNoDatabaseGiven()
     {
-        $this->setExpectedException(Exception::class, 'No database', 700);
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('No database');
+        $this->expectExceptionCode(700);
 
         $oDB = null;
         $oStatus = new Status($oDB);
@@ -22,7 +21,9 @@ class StatusTest extends \PHPUnit_Framework_TestCase
 
     public function testNoDatabaseConnectionFail()
     {
-        $this->setExpectedException(Exception::class, 'No database', 700);
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('No database');
+        $this->expectExceptionCode(700);
 
         // causes 'Non-static method should not be called statically, assuming $this from incompatible context'
         // failure on travis
@@ -40,10 +41,14 @@ class StatusTest extends \PHPUnit_Framework_TestCase
 
     public function testModuleFail()
     {
-        $this->setExpectedException(Exception::class, 'Module call failed', 702);
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('Module call failed');
+        $this->expectExceptionCode(702);
 
         // stub has getOne method but doesn't return anything
-        $oDbStub = $this->getMock(\DB::class, array('getOne'));
+        $oDbStub = $this->getMockBuilder(\DB::class)
+                        ->setMethods(array('getOne'))
+                        ->getMock();
 
         $oStatus = new Status($oDbStub);
         $this->assertNull($oStatus->status());
@@ -52,9 +57,13 @@ class StatusTest extends \PHPUnit_Framework_TestCase
 
     public function testWordIdQueryFail()
     {
-        $this->setExpectedException(Exception::class, 'No value', 704);
+        $this->expectException(\Exception::class);
+        $this->expectExceptionMessage('No value');
+        $this->expectExceptionCode(704);
 
-        $oDbStub = $this->getMock(\DB::class, array('getOne'));
+        $oDbStub = $this->getMockBuilder(\DB::class)
+                        ->setMethods(array('getOne'))
+                        ->getMock();
 
         // return no word_id
         $oDbStub->method('getOne')
@@ -70,7 +79,9 @@ class StatusTest extends \PHPUnit_Framework_TestCase
 
     public function testOK()
     {
-        $oDbStub = $this->getMock(\DB::class, array('getOne'));
+        $oDbStub = $this->getMockBuilder(\DB::class)
+                        ->setMethods(array('getOne'))
+                        ->getMock();
 
         $oDbStub->method('getOne')
                 ->will($this->returnCallback(function ($sql) {
@@ -84,7 +95,9 @@ class StatusTest extends \PHPUnit_Framework_TestCase
 
     public function testDataDate()
     {
-        $oDbStub = $this->getMock(\DB::class, array('getOne'));
+        $oDbStub = $this->getMockBuilder(\DB::class)
+                        ->setMethods(array('getOne'))
+                        ->getMock();
      
         $oDbStub->method('getOne')
                 ->willReturn(1519430221);
index 38f13e184db8ea73ad8261b18b205d32d3b37085..fa1331e87b17d187fc0ebbd29b15e9c3b9567703 100644 (file)
@@ -2,17 +2,18 @@
 
 namespace Nominatim;
 
-@define('CONST_BasePath', '../../');
+require_once(CONST_BasePath.'/lib/db.php');
+require_once(CONST_BasePath.'/lib/cmd.php');
+require_once(CONST_BasePath.'/lib/TokenList.php');
 
-require_once '../../lib/db.php';
-require_once '../../lib/cmd.php';
-require_once '../../lib/TokenList.php';
 
-class TokenTest extends \PHPUnit_Framework_TestCase
+class TokenTest extends \PHPUnit\Framework\TestCase
 {
     protected function setUp()
     {
-        $this->oNormalizer = $this->getMock(\MockNormalizer::class, array('transliterate'));
+        $this->oNormalizer = $this->getMockBuilder(\MockNormalizer::class)
+                                  ->setMethods(array('transliterate'))
+                                  ->getMock();
         $this->oNormalizer->method('transliterate')
                           ->will($this->returnCallback(function ($text) {
                               return strtolower($text);
@@ -55,7 +56,9 @@ class TokenTest extends \PHPUnit_Framework_TestCase
     {
         $this->expectOutputRegex('/<p><tt>/');
 
-        $oDbStub = $this->getMock(\DB::class, array('getAll'));
+        $oDbStub = $this->getMockBuilder(\DB::class)
+                        ->setMethods(array('getAll'))
+                        ->getMock();
         $oDbStub->method('getAll')
                 ->will($this->returnCallback(function ($sql) {
                     $aResults = array();
index b3d9bbc7f3711e882119cd6b3af051245d859d04..0d4759622ff06f0ec8d6e4d09e2a673e4eb06a38 100644 (file)
@@ -1 +1,2 @@
 <?php
+    @define('CONST_BasePath', '../..');
similarity index 81%
rename from phpunit.xml
rename to test/php/phpunit.xml
index addce5ce37154a96df2e505c800bd1bbe193e9f3..1fc95795c1d0b86b3704488e10956f493f0b1d26 100644 (file)
@@ -8,13 +8,14 @@
     processIsolation="false"
     stopOnFailure="false"
     syntaxCheck="true"
-    bootstrap="test/php/bootstrap.php"
+    bootstrap="./bootstrap.php"
+    beStrictAboutTestsThatDoNotTestAnything="true"
     >
     <php>
     </php>
     <testsuites>
         <testsuite name="Nominatim PHP Test Suite">
-            <directory>./test/php/Nominatim</directory>
+            <directory>./Nominatim</directory>
         </testsuite>
     </testsuites>
     <filter>
index 602df0bc09822e763c0e59bc845ce3793391a7c4..761ab9e4f004c11097093da1b16891dba8f1b6d5 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
index 19ad25b82570833816540f7b257614f201482267..b1a7ab1185336419f3659de49afeaf7a318cf3ae 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
index 13f062d4f637bad6d959a55e3e630d4814fd85a9..aafb3759ab2ee399611b5c53dfe6260a4dfb869b 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
     // Script to extract structured city and street data
     // from a running nominatim instance as CSV data
index b767adb36ff2774ea8b208adcc670c5866de65fa..6e42975481cbbd35b8fafb92ddbe7b4f9652a045 100755 (executable)
@@ -309,7 +309,7 @@ if (isset($aCMDResult['parse-wikipedia'])) {
     $oDB =& getDB();
     $sSQL = 'select page_title from content where page_namespace = 0 and page_id %10 = ';
     $sSQL .= $aCMDResult['parse-wikipedia'];
-    $sSQL .= ' and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\'))'
+    $sSQL .= ' and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\'))';
     $aArticleNames = $oDB->getCol($sSQL);
     /* $aArticleNames = $oDB->getCol($sSQL = 'select page_title from content where page_namespace = 0
         and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\'
index 07bc9c4512176da12e67c323854adbb22d41792b..9d1085f041e78ed5953c0ee6abc050f0273cf1e1 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
index 53ce176cf3aea6168adadb7b717b893833196404..e3e2e7b8737eaac707fb6a60a525e01055b56f58 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
index 39016d072a17522b741bbb84bffb2c51fc048d37..0a27c484914fddb169b11dfe47184848d754bbc9 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 $sFile = 'sample.log.txt'; // Apache log file
index 95eda0f4a085726ef12a51b4f43d3e126ce0f33a..b9c0166c5ad213aaff4e0d0fe20529c8794f5964 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
@@ -440,7 +440,6 @@ if ($aCMDResult['load-data'] || $aCMDResult['all']) {
             // PGSQL_EMPTY_QUERY, PGSQL_COMMAND_OK, PGSQL_TUPLES_OK,
             // PGSQL_COPY_OUT, PGSQL_COPY_IN, PGSQL_BAD_RESPONSE,
             // PGSQL_NONFATAL_ERROR and PGSQL_FATAL_ERROR
-            echo 'Query result ' . $i . ' is: ' . $resultStatus . "\n";
             if ($resultStatus != PGSQL_COMMAND_OK && $resultStatus != PGSQL_TUPLES_OK) {
                 $resultError = pg_result_error($hPGresult);
                 echo '-- error text ' . $i . ': ' . $resultError . "\n";
index 8378b37339a1b1f64c7594d5b513a1888ce27d73..7d22df50027ecc534d311d0d10ebc4d4423549a0 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
index 4897872b5fee5998dbc64ba1e1229e76c11e1025..ad57101009f9dd7e996a2eeb536817c754b738c9 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
@@ -100,7 +100,7 @@ if ($aResult['init-updates']) {
         fail('pyosmium-get-changes not found or not usable');
     }
     if (!$aResult['no-update-functions']) {
-        $sSetup = CONST_InstallPath.'/utils/setup.php';
+        $sSetup ='@PHP_BIN@ '. CONST_InstallPath.'/utils/setup.php';
         $iRet = -1;
         passthru($sSetup.' --create-functions --enable-diff-updates', $iRet);
         if ($iRet != 0) {
index 0ac13c469d6918c936f97a219f0711fa11c2f453..653bcf100c2fc63a6a009324947d2b226055336d 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/php -Cq
+#!@PHP_BIN@ -Cq
 <?php
 
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
diff --git a/vagrant/Install-on-Ubuntu-18.sh b/vagrant/Install-on-Ubuntu-18.sh
new file mode 100755 (executable)
index 0000000..062d7ce
--- /dev/null
@@ -0,0 +1,171 @@
+#!/bin/bash
+#
+# hacks for broken vagrant box      #DOCS:
+sudo rm -f /var/lib/dpkg/lock       #DOCS:
+sudo update-locale LANG=en_US.UTF-8 #DOCS:
+export APT_LISTCHANGES_FRONTEND=none #DOCS:
+export DEBIAN_FRONTEND=noninteractive #DOCS:
+
+#
+# *Note:* these installation instructions are also available in executable
+#         form for use with vagrant under vagrant/Install-on-Ubuntu-18.sh.
+#
+# Installing the Required Software
+# ================================
+#
+# These instructions expect that you have a freshly installed Ubuntu 18.04.
+#
+# Make sure all packages are are up-to-date by running:
+#
+
+#DOCS:    :::sh
+    sudo apt-get -o DPkg::options::="--force-confdef" -o DPkg::options::="--force-confold" --force-yes -fuy install grub-pc #DOCS:
+    sudo apt-get update -qq
+
+# Now you can install all packages needed for Nominatim:
+
+    sudo 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 \
+                            apache2 php php-pgsql libapache2-mod-php php-pear php-db \
+                            php-intl git
+
+# If you want to run the test suite, you need to install the following
+# additional packages:
+
+    sudo apt-get install -y python3-setuptools python3-dev python3-pip \
+                            python3-psycopg2 python3-tidylib phpunit php-cgi
+
+    pip3 install --user behave nose
+    sudo pear install PHP_CodeSniffer
+
+#
+# System Configuration
+# ====================
+#
+# The following steps are meant to configure a fresh Ubuntu installation
+# for use with Nominatim. You may skip some of the steps if you have your
+# OS already configured.
+#
+# Creating Dedicated User Accounts
+# --------------------------------
+#
+# Nominatim will run as a global service on your machine. It is therefore
+# best to install it under its own separate user account. In the following
+# we assume this user is called nominatim and the installation will be in
+# /srv/nominatim. To create the user and directory run:
+#
+#     sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
+#
+# You may find a more suitable location if you wish.
+#
+# To be able to copy and paste instructions from this manual, export
+# user name and home directory now like this:
+#
+    export USERNAME=vagrant        #DOCS:    export USERNAME=nominatim
+    export USERHOME=/home/vagrant  #DOCS:    export USERHOME=/srv/nominatim
+#
+# **Never, ever run the installation as a root user.** You have been warned.
+#
+# Make sure that system servers can read from the home directory:
+
+    chmod a+x $USERHOME
+
+# Setting up PostgreSQL
+# ---------------------
+#
+# Tune the postgresql configuration, which is located in 
+# `/etc/postgresql/9.5/main/postgresql.conf`. See section *Postgres Tuning* in
+# [the installation page](../admin/Installation.md#postgresql-tuning)
+# for the parameters to change.
+#
+# Restart the postgresql service after updating this config file.
+
+    sudo systemctl restart postgresql
+
+#
+# Finally, we need to add two postgres users: one for the user that does
+# the import and another for the webserver which should access the database
+# for reading only:
+#
+
+    sudo -u postgres createuser -s $USERNAME
+    sudo -u postgres createuser www-data
+
+#
+# Setting up the Apache Webserver
+# -------------------------------
+#
+# You need to create an alias to the website directory in your apache
+# configuration. Add a separate nominatim configuration to your webserver:
+
+#DOCS:```sh
+sudo tee /etc/apache2/conf-available/nominatim.conf << EOFAPACHECONF
+<Directory "$USERHOME/build/website"> #DOCS:<Directory "$USERHOME/Nominatim/build/website">
+  Options FollowSymLinks MultiViews
+  AddType text/html   .php
+  DirectoryIndex search.php
+  Require all granted
+</Directory>
+
+Alias /nominatim $USERHOME/build/website  #DOCS:Alias /nominatim $USERHOME/Nominatim/build/website
+EOFAPACHECONF
+#DOCS:```
+
+sudo sed -i 's:#.*::' /etc/apache2/conf-available/nominatim.conf #DOCS:
+
+#
+# Then enable the configuration and restart apache
+#
+
+    sudo a2enconf nominatim
+    sudo systemctl restart apache2
+
+#
+# Installing Nominatim
+# ====================
+#
+# Building and Configuration
+# --------------------------
+#
+# Get the source code from Github and change into the source directory
+#
+if [ "x$1" == "xyes" ]; then  #DOCS:    :::sh
+    cd $USERHOME
+    git clone --recursive git://github.com/openstreetmap/Nominatim.git
+    cd Nominatim
+else                               #DOCS:
+    cd $USERHOME/Nominatim         #DOCS:
+fi                                 #DOCS:
+
+# When installing the latest source from github, you also need to
+# download the country grid:
+
+if [ ! -f data/country_osm_grid.sql.gz ]; then       #DOCS:    :::sh
+    wget -O data/country_osm_grid.sql.gz https://www.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:
+
+    cd $USERHOME                   #DOCS:    :::sh
+    mkdir build
+    cd build
+    cmake $USERHOME/Nominatim
+    make
+
+# You need to create a minimal configuration file that tells nominatim
+# where it is located on the webserver:
+
+#DOCS:```sh
+tee settings/local.php << EOF
+<?php
+ @define('CONST_Website_BaseURL', '/nominatim/');
+EOF
+#DOCS:```
+
+
+# Nominatim is now ready to use. Continue with
+# [importing a database from OSM data](../admin/Import-and-Update.md).