]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorSarah Hoffmann <lonvia@denofr.de>
Fri, 16 Mar 2018 22:39:12 +0000 (23:39 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Fri, 16 Mar 2018 22:39:12 +0000 (23:39 +0100)
14 files changed:
CONTRIBUTING.md
VAGRANT.md
Vagrantfile
lib/ParameterParser.php
lib/template/address-json.php
lib/template/address-jsonv2.php [deleted file]
lib/template/search-json.php
lib/template/search-jsonv2.php [deleted file]
sql/partition-functions.src.sql
test/php/Nominatim/ParameterParserTest.php [new file with mode: 0644]
vagrant/Install-on-Centos-7.sh
website/details.php
website/reverse.php
website/search.php

index dc5be190ad7633ec325241f48fd977b65f786f75..242a9d6f55fb27ce2ba68c97d8e6c671fccb29b9 100644 (file)
@@ -41,7 +41,7 @@ Please add the following information to your issue:
 
 ## Workflow for Pull Requests
 
-We love to get pull reuqests from you. We operate the "Fork & Pull" model
+We love to get pull requests from you. We operate the "Fork & Pull" model
 explained at
 
 https://help.github.com/articles/using-pull-requests
@@ -65,7 +65,7 @@ that duplicate work can be avoided.
 ## Coding style
 
 Nominatim historically hasn't followed a particular coding style but we
-are in process of consolodating the style. The following rules apply:
+are in process of consolidating the style. The following rules apply:
 
  * Python code uses the official Python style
  * indention
index de36bc576ec62a97cd792858e62dba21be36011b..2aafb7de43e734ef05d7095211bf6689cd7c88b0 100644 (file)
@@ -1,11 +1,11 @@
 # Install Nominatim in a virtual machine for development and testing
 
-This document describes how you can install Nominatim inside a Ubuntu 14
+This document describes how you can install Nominatim inside a Ubuntu 16
 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. 
 
-The installation can run largely unsupervised. You should expect 1-2h from
+The installation can run largely unsupervised. You should expect 1h from
 start to finish depending on how fast your computer and download speed
 is.
 
@@ -19,7 +19,7 @@ is.
 
         git clone --recursive https://github.com/openstreetmap/Nominatim.git
 
-    If you haven't used `--recursive`, then you can load the submodules using
+    If you forgot `--recursive`, it you can later load the submodules using
     
         git submodule init
         git submodule update
@@ -37,18 +37,14 @@ is.
         vagrant ssh ubuntu
 
 3. Import a small country (Monaco)
-
-    You need to give the virtual machine more memory (2GB) for an import,
-    see `Vagrantfile`. Otherwise 1GB is enough.
     
     See the FAQ how to skip this step and point Nominatim to an existing database.
 
       ```
       # inside the virtual machine:
-      mkdir data
       cd build
-      wget --no-verbose --output-document=../data/monaco.osm.pbf http://download.geofabrik.de/europe/monaco-latest.osm.pbf
-      ./utils/setup.php --osm-file ../data/monaco.osm.pbf --osm2pgsql-cache 1000 --all 2>&1 | tee monaco.$$.log
+      wget --no-verbose --output-document=/tmp/monaco.osm.pbf http://download.geofabrik.de/europe/monaco-latest.osm.pbf
+      ./utils/setup.php --osm-file /tmp/monaco.osm.pbf --osm2pgsql-cache 1000 --all 2>&1 | tee monaco.$$.log
       ```
 
     To repeat an import you'd need to delete the database first
@@ -65,13 +61,32 @@ see Nominatim in action on [locahost:8089](http://localhost:8089/nominatim/).
 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 (preferred) or set
 `@define('CONST_Debug', true);` in `settings/local.php`.
 
+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
@@ -83,27 +98,25 @@ installation to cause false positives in the other tests (see FAQ).
 
 To run the full test suite
 
-    cd ~/Nominatim/tests
-    NOMINATIM_SERVER=http://localhost:8089/nominatim lettuce features
+    cd ~/Nominatim/test/bdd
+    behave -DBUILDDIR=/home/vagrant/build/ db osm2pgsql
 
 To run a single file
 
-    NOMINATIM_SERVER=http://localhost:8089/nominatim lettuce features/api/reverse.feature
+    behave -DBUILDDIR=/home/vagrant/build/ features/api/reverse.feature
+
+Or a single test by line number
+
+    behave -DBUILDDIR=/home/vagrant/build/ features/api/reverse.feature:34
     
-To run specific tests you can add tags just before the `Scenario line`, e.g.
+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
 
-    NOMINATIM_SERVER=http://localhost:8089/nominatim lettuce -t bug-34
-
-
-## Running unit tests
-
-    cd ~/Nominatim/tests/php
-    phpunit ./
+    behave -DBUILDDIR=/home/vagrant/build/ --tags @bug-34
 
 
 
@@ -130,17 +143,18 @@ 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
 of search results. See [Nominatim installation](http://nominatim.org/release-docs/latest/Installation) for details.
 
-##### Why Ubuntu and CentOS, can I test CentOS/CoreOS/FreeBSD?
+##### Why Ubuntu? Can I test CentOS/Fedora/CoreOS/FreeBSD?
 
-There is a Vagrant script for CentOS available. Simply start your box
-with `vagrant up centos` and then log in with `vagrant ssh centos`.
-In general Nominatim will also run in the other environments. The installation steps
+There is a Vagrant script for CentOS available, but the Nominatim directory
+isn't symlinked/mounted to the host which makes development trickier. We used
+it mainly for debugging installation with SELinux.
+
+In general Nominatim will run in the other environments. The installation steps
 are slightly different, e.g. the name of the package manager, Apache2 package
 name, location of files. We chose Ubuntu because that is closest to the
 nominatim.openstreetmap.org production environment.
 
-You can configure/download other Vagrant boxes from [vagrantbox.es](http://www.vagrantbox.es/).
-
+You can configure/download other Vagrant boxes from [https://app.vagrantup.com/boxes/search](https://app.vagrantup.com/boxes/search).
 
 ##### How can I connect to an existing database?
 
@@ -148,7 +162,7 @@ Let's say you have a Postgres database named `nominatim_it` on server `your-serv
 
     pgsql://postgres@your-server.com:5432/nominatim_it
     
-No data import necessary, no restarting necessary.
+No data import necessary or restarting necessary.
 
 If the Postgres installation is behind a firewall, you can try
 
@@ -157,14 +171,15 @@ If the Postgres installation is behind a firewall, you can try
 inside the virtual machine. It will map the port to `localhost:9999` and then
 you edit `settings/local.php` with
 
-    pgsql://postgres@localhost:9999/nominatim_it
+    @define('CONST_Database_DSN', 'pgsql://postgres@localhost:9999/nominatim_it');
 
 To access postgres directly remember to specify the hostname, e.g. `psql --host localhost --port 9999 nominatim_it`
 
 
 ##### My computer is slow and the import takes too long. Can I start the virtual machine "in the cloud"?
 
-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).
+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).
 
 
 
index d369fcd6605118b5afd9ec92003d65e31af8f217..5c9563bd0ef0ced397584b24eb94bd6efa9ded25 100644 (file)
@@ -32,38 +32,21 @@ Vagrant.configure("2") do |config|
       end
   end
 
-   config.vm.define "centos" do |sub|
-      sub.vm.box = "bento/centos-7.2"
+  config.vm.define "centos" do |sub|
+      sub.vm.box = "centos/7"
       sub.vm.provision :shell do |s|
         s.path = "vagrant/Install-on-Centos-7.sh"
         s.privileged = false
-        s.args = [checkout]
+        s.args = "yes"
       end
+      sub.vm.synced_folder ".", "/home/vagrant/Nominatim", disabled: true
+      sub.vm.synced_folder ".", "/vagrant", disabled: true
   end
 
-  # configure shared package cache if possible
-  #if Vagrant.has_plugin?("vagrant-cachier")
-  #  config.cache.enable :apt
-  #  config.cache.scope = :box
-  #end
-
-
   config.vm.provider "virtualbox" do |vb|
     vb.gui = false
-    vb.customize ["modifyvm", :id, "--memory", "2048"]
+    vb.memory = 2048
+    vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate//vagrant","0"]
   end
 
-
-  # config.vm.provider :digital_ocean do |provider, override|
-  #   override.ssh.private_key_path = '~/.ssh/id_rsa'
-  #   override.vm.box = 'digital_ocean'
-  #   override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
-
-  #   provider.token = ''
-  #   # provider.token = 'YOUR TOKEN'
-  #   provider.image = 'ubuntu-14-04-x64'
-  #   provider.region = 'nyc2'
-  #   provider.size = '512mb'
-  # end
-
 end
index 2eed1629b04742ad274c6ac9f5cf8d9bf1ebfbd3..c9a97c25c5f6b0f29f0e9cb3b139b32e8f9d2841 100644 (file)
@@ -23,7 +23,7 @@ class ParameterParser
 
     public function getInt($sName, $bDefault = false)
     {
-        if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0) {
+        if (!isset($this->aParams[$sName])) {
             return $bDefault;
         }
 
@@ -36,7 +36,7 @@ class ParameterParser
 
     public function getFloat($sName, $bDefault = false)
     {
-        if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0) {
+        if (!isset($this->aParams[$sName])) {
             return $bDefault;
         }
 
@@ -74,7 +74,8 @@ class ParameterParser
         $sValue = $this->getString($sName);
 
         if ($sValue) {
-            return explode(',', $sValue);
+            // removes all NULL, FALSE and Empty Strings but leaves 0 (zero) values
+            return array_values(array_filter(explode(',', $sValue), 'strlen'));
         }
 
         return $aDefault;
index cea8774549cef955eb4c91a783cdccbb835f692c..85f6fe8eb7c5fb7cdfe04fb29fd2ef3e4c9fd83a 100644 (file)
@@ -16,7 +16,22 @@ if (!sizeof($aPlace)) {
     }
     if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
     if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
+
+    if ($sOutputFormat == 'jsonv2') {
+        $aFilteredPlaces['place_rank'] = $aPlace['rank_search'];
+
+        $aFilteredPlaces['category'] = $aPlace['class'];
+        $aFilteredPlaces['type'] = $aPlace['type'];
+
+        $aFilteredPlaces['importance'] = $aPlace['importance'];
+
+        $aFilteredPlaces['addresstype'] = strtolower($aPlace['addresstype']);
+
+        $aFilteredPlaces['name'] = $aPlace['placename'];
+    }
+
     $aFilteredPlaces['display_name'] = $aPlace['langaddress'];
+
     if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
     if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
     if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
diff --git a/lib/template/address-jsonv2.php b/lib/template/address-jsonv2.php
deleted file mode 100644 (file)
index 399c978..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-$aFilteredPlaces = array();
-
-if (!sizeof($aPlace)) {
-    if (isset($sError))
-        $aFilteredPlaces['error'] = $sError;
-    else $aFilteredPlaces['error'] = 'Unable to geocode';
-} else {
-    if ($aPlace['place_id']) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
-    $aFilteredPlaces['licence'] = 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright';
-    $sOSMType = formatOSMType($aPlace['osm_type']);
-    if ($sOSMType) {
-        $aFilteredPlaces['osm_type'] = $sOSMType;
-        $aFilteredPlaces['osm_id'] = $aPlace['osm_id'];
-    }
-    if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
-    if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
-
-    $aFilteredPlaces['place_rank'] = $aPlace['rank_search'];
-
-    $aFilteredPlaces['category'] = $aPlace['class'];
-    $aFilteredPlaces['type'] = $aPlace['type'];
-
-    $aFilteredPlaces['importance'] = $aPlace['importance'];
-
-    $aFilteredPlaces['addresstype'] = strtolower($aPlace['addresstype']);
-
-    $aFilteredPlaces['display_name'] = $aPlace['langaddress'];
-    $aFilteredPlaces['name'] = $aPlace['placename'];
-
-    if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
-    if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
-    if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
-
-    if (isset($aPlace['aBoundingBox'])) {
-        $aFilteredPlaces['boundingbox'] = $aPlace['aBoundingBox'];
-    }
-
-    if (isset($aPlace['asgeojson'])) {
-        $aFilteredPlaces['geojson'] = json_decode($aPlace['asgeojson']);
-    }
-
-    if (isset($aPlace['assvg'])) {
-        $aFilteredPlaces['svg'] = $aPlace['assvg'];
-    }
-
-    if (isset($aPlace['astext'])) {
-        $aFilteredPlaces['geotext'] = $aPlace['astext'];
-    }
-
-    if (isset($aPlace['askml'])) {
-        $aFilteredPlaces['geokml'] = $aPlace['askml'];
-    }
-}
-
-javascript_renderData($aFilteredPlaces);
index b997f6d97b1fcb01f7ed12b74f8f3468b5d8377a..774b5be08b3e6bca7db863ab6584542986416cbc 100644 (file)
@@ -1,11 +1,10 @@
 <?php
-header('content-type: application/json; charset=UTF-8');
 
 $aFilteredPlaces = array();
 foreach ($aSearchResults as $iResNum => $aPointDetails) {
     $aPlace = array(
                'place_id'=>$aPointDetails['place_id'],
-               'licence'=>'Data © OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright',
+               'licence'=>'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright',
               );
     
     $sOSMType = formatOSMType($aPointDetails['osm_type']);
@@ -30,7 +29,12 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) {
     $aPlace['lon'] = $aPointDetails['lon'];
     $aPlace['display_name'] = $aPointDetails['name'];
 
-    $aPlace['class'] = $aPointDetails['class'];
+    if ($sOutputFormat == 'jsonv2') {
+        $aPlace['place_rank'] = $aPointDetails['rank_search'];
+        $aPlace['category'] = $aPointDetails['class'];
+    } else {
+        $aPlace['class'] = $aPointDetails['class'];
+    }
     $aPlace['type'] = $aPointDetails['type'];
 
     $aPlace['importance'] = $aPointDetails['importance'];
@@ -39,7 +43,7 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) {
         $aPlace['icon'] = $aPointDetails['icon'];
     }
 
-    if (isset($aPointDetails['address'])) {
+    if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])) {
         $aPlace['address'] = $aPointDetails['address'];
     }
 
diff --git a/lib/template/search-jsonv2.php b/lib/template/search-jsonv2.php
deleted file mode 100644 (file)
index 7610330..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-$aFilteredPlaces = array();
-foreach ($aSearchResults as $iResNum => $aPointDetails) {
-    $aPlace = array(
-               'place_id'=>$aPointDetails['place_id'],
-               'licence'=>'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright',
-              );
-
-    $sOSMType = formatOSMType($aPointDetails['osm_type']);
-    if ($sOSMType) {
-        $aPlace['osm_type'] = $sOSMType;
-        $aPlace['osm_id'] = $aPointDetails['osm_id'];
-    }
-
-    if (isset($aPointDetails['aBoundingBox'])) {
-        $aPlace['boundingbox'] = $aPointDetails['aBoundingBox'];
-
-        if (isset($aPointDetails['aPolyPoints'])) {
-            $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
-        }
-    }
-
-    if (isset($aPointDetails['zoom'])) {
-        $aPlace['zoom'] = $aPointDetails['zoom'];
-    }
-
-    $aPlace['lat'] = $aPointDetails['lat'];
-    $aPlace['lon'] = $aPointDetails['lon'];
-    $aPlace['display_name'] = $aPointDetails['name'];
-    $aPlace['place_rank'] = $aPointDetails['rank_search'];
-
-    $aPlace['category'] = $aPointDetails['class'];
-    $aPlace['type'] = $aPointDetails['type'];
-
-    $aPlace['importance'] = $aPointDetails['importance'];
-
-    if (isset($aPointDetails['icon'])) {
-        $aPlace['icon'] = $aPointDetails['icon'];
-    }
-
-    if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])>0) {
-        $aPlace['address'] = $aPointDetails['address'];
-    }
-
-    if (isset($aPointDetails['asgeojson'])) {
-        $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
-    }
-
-    if (isset($aPointDetails['assvg'])) {
-        $aPlace['svg'] = $aPointDetails['assvg'];
-    }
-
-    if (isset($aPointDetails['astext'])) {
-        $aPlace['geotext'] = $aPointDetails['astext'];
-    }
-
-    if (isset($aPointDetails['askml'])) {
-        $aPlace['geokml'] = $aPointDetails['askml'];
-    }
-
-    if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
-    if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
-
-    $aFilteredPlaces[] = $aPlace;
-}
-
-javascript_renderData($aFilteredPlaces);
index 110dd0cdd1606c843a7244259c5c0c52b204fffd..32b5f0a17f3c7f5396786b1da82e01f2822759bf 100644 (file)
@@ -129,7 +129,7 @@ BEGIN
           ST_Distance(centroid, point) as distance, null as isguess
           FROM search_name_-partition-
           WHERE name_vector @> isin_token
-          AND ST_DWithin(centroid, point, 0.01
+          AND ST_DWithin(centroid, point, 0.015)
           AND search_rank between 26 and 27
       ORDER BY distance ASC limit 1
     LOOP
diff --git a/test/php/Nominatim/ParameterParserTest.php b/test/php/Nominatim/ParameterParserTest.php
new file mode 100644 (file)
index 0000000..4265cff
--- /dev/null
@@ -0,0 +1,217 @@
+<?php
+
+namespace Nominatim;
+
+use Exception;
+
+require_once('../../lib/ParameterParser.php');
+
+
+function userError($sError)
+{
+    throw new Exception($sError);
+}
+
+class ParameterParserTest extends \PHPUnit_Framework_TestCase
+{
+
+
+    public function testGetBool()
+    {
+        $oParams = new ParameterParser([
+                                        'bool1' => '1',
+                                        'bool2' => '0',
+                                        'bool3' => 'true',
+                                        'bool4' => 'false',
+                                        'bool5' => ''
+                                       ]);
+
+        $this->assertSame(false, $oParams->getBool('non-exists'));
+        $this->assertSame(true, $oParams->getBool('non-exists', true));
+        $this->assertSame(true, $oParams->getBool('bool1'));
+        $this->assertSame(false, $oParams->getBool('bool2'));
+        $this->assertSame(true, $oParams->getBool('bool3'));
+        $this->assertSame(true, $oParams->getBool('bool4'));
+        $this->assertSame(false, $oParams->getBool('bool5'));
+    }
+
+
+    public function testGetInt()
+    {
+        $oParams = new ParameterParser([
+                                        'int1' => '5',
+                                        'int2' => '-1',
+                                        'int3' => 0
+                                       ]);
+
+        $this->assertSame(false, $oParams->getInt('non-exists'));
+        $this->assertSame(999, $oParams->getInt('non-exists', 999));
+        $this->assertSame(5, $oParams->getInt('int1'));
+
+        $this->assertSame(-1, $oParams->getInt('int2'));
+        $this->assertSame(0, $oParams->getInt('int3'));
+    }
+
+
+    public function testGetIntWithNonNumber()
+    {
+        $this->setExpectedException(Exception::class, "Integer number expected for parameter 'int4'");
+        (new ParameterParser(['int4' => 'a']))->getInt('int4');
+    }
+
+
+    public function testGetIntWithEmpytString()
+    {
+        $this->setExpectedException(Exception::class, "Integer number expected for parameter 'int5'");
+        (new ParameterParser(['int5' => '']))->getInt('int5');
+    }
+
+
+    public function testGetFloat()
+    {
+
+        $oParams = new ParameterParser([
+                                        'float1' => '1.0',
+                                        'float2' => '-5',
+                                        'float3' => 0
+                                       ]);
+
+        $this->assertSame(false, $oParams->getFloat('non-exists'));
+        $this->assertSame(999, $oParams->getFloat('non-exists', 999));
+        $this->assertSame(1.0, $oParams->getFloat('float1'));
+        $this->assertSame(-5.0, $oParams->getFloat('float2'));
+        $this->assertSame(0.0, $oParams->getFloat('float3'));
+    }
+
+    public function testGetFloatWithEmptyString()
+    {
+        $this->setExpectedException(Exception::class, "Floating-point number expected for parameter 'float4'");
+        (new ParameterParser(['float4' => '']))->getFloat('float4');
+    }
+
+    public function testGetFloatWithTextString()
+    {
+        $this->setExpectedException(Exception::class, "Floating-point number expected for parameter 'float5'");
+        (new ParameterParser(['float5' => 'a']))->getFloat('float5');
+    }
+
+
+    public function testGetFloatWithInvalidNumber()
+    {
+        $this->setExpectedException(Exception::class, "Floating-point number expected for parameter 'float6'");
+        (new ParameterParser(['float6' => '-55.']))->getFloat('float6');
+    }
+
+
+    public function testGetString()
+    {
+        $oParams = new ParameterParser([
+                                        'str1' => 'abc',
+                                        'str2' => '',
+                                        'str3' => '0'
+                                       ]);
+
+        $this->assertSame(false, $oParams->getString('non-exists'));
+        $this->assertSame('default', $oParams->getString('non-exists', 'default'));
+        $this->assertSame('abc', $oParams->getString('str1'));
+        $this->assertSame(false, $oParams->getStringList('str2'));
+        $this->assertSame(false, $oParams->getStringList('str3')); // sadly PHP magic treats 0 as false when returned
+    }
+
+
+    public function testGetSet()
+    {
+        $oParams = new ParameterParser([
+                                        'val1' => 'foo',
+                                        'val2' => '',
+                                        'val3' => 0
+                                       ]);
+
+        $this->assertSame(false, $oParams->getSet('non-exists', ['foo', 'bar']));
+        $this->assertSame('default', $oParams->getSet('non-exists', ['foo', 'bar'], 'default'));
+        $this->assertSame('foo', $oParams->getSet('val1', ['foo', 'bar']));
+
+        $this->assertSame(false, $oParams->getSet('val2', ['foo', 'bar']));
+        $this->assertSame(0, $oParams->getSet('val3', ['foo', 'bar']));
+    }
+
+
+    public function testGetSetWithValueNotInSet()
+    {
+        $this->setExpectedException(Exception::class, "Parameter 'val4' must be one of: foo, bar");
+        (new ParameterParser(['val4' => 'faz']))->getSet('val4', ['foo', 'bar']);
+    }
+
+
+    public function testGetStringList()
+    {
+        $oParams = new ParameterParser([
+                                        'list1' => ',a,b,c,,c,d',
+                                        'list2' => 'a',
+                                        'list3' => '',
+                                        'list4' => '0'
+                                       ]);
+
+        $this->assertSame(false, $oParams->getStringList('non-exists'));
+        $this->assertSame(['a', 'b'], $oParams->getStringList('non-exists', ['a', 'b']));
+        $this->assertSame(['a', 'b', 'c', 'c', 'd'], $oParams->getStringList('list1'));
+        $this->assertSame(['a'], $oParams->getStringList('list2'));
+        $this->assertSame(false, $oParams->getStringList('list3'));
+        $this->assertSame(false, $oParams->getStringList('list4'));
+    }
+
+
+    public function testGetPreferredLanguages()
+    {
+        $oParams = new ParameterParser(['accept-language' => '']);
+        $this->assertSame([
+                           'short_name:default' => 'short_name:default',
+                           'name:default' => 'name:default',
+                           'short_name' => 'short_name',
+                           'name' => 'name',
+                           'brand' => 'brand',
+                           'official_name:default' => 'official_name:default',
+                           'official_name' => 'official_name',
+                           'ref' => 'ref',
+                           'type' => 'type'
+                          ], $oParams->getPreferredLanguages('default'));
+
+        $oParams = new ParameterParser(['accept-language' => 'de,en']);
+        $this->assertSame([
+                           'short_name:de' => 'short_name:de',
+                           'name:de' => 'name:de',
+                           'short_name:en' => 'short_name:en',
+                           'name:en' => 'name:en',
+                           'short_name' => 'short_name',
+                           'name' => 'name',
+                           'brand' => 'brand',
+                           'official_name:de' => 'official_name:de',
+                           'official_name:en' => 'official_name:en',
+                           'official_name' => 'official_name',
+                           'ref' => 'ref',
+                           'type' => 'type'
+                          ], $oParams->getPreferredLanguages('default'));
+
+        $oParams = new ParameterParser(['accept-language' => 'fr-ca,fr;q=0.8,en-ca;q=0.5,en;q=0.3']);
+        $this->assertSame([
+                           'short_name:fr-ca' => 'short_name:fr-ca',
+                           'name:fr-ca' => 'name:fr-ca',
+                           'short_name:fr' => 'short_name:fr',
+                           'name:fr' => 'name:fr',
+                           'short_name:en-ca' => 'short_name:en-ca',
+                           'name:en-ca' => 'name:en-ca',
+                           'short_name:en' => 'short_name:en',
+                           'name:en' => 'name:en',
+                           'short_name' => 'short_name',
+                           'name' => 'name',
+                           'brand' => 'brand',
+                           'official_name:fr-ca' => 'official_name:fr-ca',
+                           'official_name:fr' => 'official_name:fr',
+                           'official_name:en-ca' => 'official_name:en-ca',
+                           'official_name:en' => 'official_name:en',
+                           'official_name' => 'official_name',
+                           'ref' => 'ref',
+                           'type' => 'type',
+                          ], $oParams->getPreferredLanguages('default'));
+    }
+}
index d95f8d5368c656c1c6a371360355e5ca4d216544..50eeaaec96c0365cd4fdf70b90688d8e28c5ac7b 100755 (executable)
@@ -22,7 +22,7 @@
 #DOCS:    :::sh
     sudo yum install -y postgresql-server postgresql-contrib postgresql-devel \
                         postgis postgis-utils \
-                        git cmake make gcc gcc-c++ libtool policycoreutils-python \
+                        wget git cmake make gcc gcc-c++ libtool policycoreutils-python \
                         php-pgsql php php-pear php-pear-DB php-intl libpqxx-devel \
                         proj-epsg bzip2-devel proj-devel libxml2-devel boost-devel \
                         expat-devel zlib-devel
@@ -52,7 +52,8 @@
 # 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
+sudo mkdir -p /srv/nominatim       #DOCS:    sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
+sudo chown vagrant /srv/nominatim  #DOCS:
 #
 # You may find a more suitable location if you wish.
 #
@@ -60,7 +61,7 @@
 # user name and home directory now like this:
 #
     export USERNAME=vagrant        #DOCS:    export USERNAME=nominatim
-    export USERHOME=/home/vagrant  #DOCS:    export USERHOME=/srv/nominatim
+    export USERHOME=/srv/nominatim
 #
 # **Never, ever run the installation as a root user.** You have been warned.
 #
 
 #DOCS:```sh
 sudo tee /etc/httpd/conf.d/nominatim.conf << EOFAPACHECONF
-<Directory "$USERHOME/build/website"> #DOCS:<Directory "$USERHOME/Nominatim/build/website">
+<Directory "$USERHOME/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
+Alias /nominatim $USERHOME/build/website
 EOFAPACHECONF
 #DOCS:```
 
@@ -122,19 +123,9 @@ sudo sed -i 's:#.*::' /etc/httpd/conf.d/nominatim.conf #DOCS:
 # Then reload apache
 #
 
+    sudo systemctl enable httpd
     sudo systemctl restart httpd
 
-#
-# Adding SELinux Security Settings
-# --------------------------------
-#
-# It is a good idea to leave SELinux enabled and enforcing, particularly
-# with a web server accessible from the Internet. At a minimum the
-# following SELinux labeling should be done for Nominatim:
-
-    sudo semanage fcontext -a -t httpd_sys_content_t "$USERHOME/Nominatim/(website|lib|settings)(/.*)?"
-    sudo semanage fcontext -a -t lib_t "$USERHOME/Nominatim/module/nominatim.so"
-    sudo restorecon -R -v $USERHOME/Nominatim
 
 #
 # Installing Nominatim
@@ -163,12 +154,28 @@ 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
+#DOCS:    :::sh
+    cd $USERHOME
     mkdir build
     cd build
     cmake $USERHOME/Nominatim
     make
 
+#
+# Adding SELinux Security Settings
+# --------------------------------
+#
+# It is a good idea to leave SELinux enabled and enforcing, particularly
+# with a web server accessible from the Internet. At a minimum the
+# following SELinux labeling should be done for Nominatim:
+
+    sudo semanage fcontext -a -t httpd_sys_content_t "$USERHOME/Nominatim/(website|lib|settings)(/.*)?"
+    sudo semanage fcontext -a -t httpd_sys_content_t "$USERHOME/build/(website|lib|settings)(/.*)?"
+    sudo semanage fcontext -a -t lib_t "$USERHOME/build/module/nominatim.so"
+    sudo restorecon -R -v $USERHOME/Nominatim
+    sudo restorecon -R -v $USERHOME/build
+
+
 # You need to create a minimal configuration file that tells nominatim
 # the name of your webserver user and the URL of the website:
 
index 4c4ce578a149151d1263b98c3dbe136e57e61495..24e8cd76a2d70217b23ca9c074f24d0bd75c4392 100755 (executable)
@@ -231,7 +231,7 @@ if ($oParams->getBool('keywords')) {
 logEnd($oDB, $hLog, 1);
 
 if ($sOutputFormat=='html') {
-    $sSQL = "SELECT TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' FROM import_status LIMIT 1";
+    $sSQL = "SELECT TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' FROM import_status LIMIT 1";
     $sDataDate = chksql($oDB->getOne($sSQL));
     $sTileURL = CONST_Map_Tile_URL;
     $sTileAttribution = CONST_Map_Tile_Attribution;
index d997088a04b94d5c1e33e633eab06eeed129ebe3..9660f36d8c7231e3d27e5f78f2ecc115ef73e509 100755 (executable)
@@ -73,8 +73,10 @@ if (CONST_Debug) {
 }
 
 if ($sOutputFormat == 'html') {
-    $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
+    $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
     $sTileURL = CONST_Map_Tile_URL;
     $sTileAttribution = CONST_Map_Tile_Attribution;
 }
-include(CONST_BasePath.'/lib/template/address-'.$sOutputFormat.'.php');
+
+$sOutputTemplate = ($sOutputFormat=='jsonv2' ? 'json' : $sOutputFormat);
+include(CONST_BasePath.'/lib/template/address-'.$sOutputTemplate.'.php');
index 9f3ae470c03153edf35bede48eae9353660a33ed..0dddaccec9cf2dc2a2cec98236bea128b16b4dcd 100755 (executable)
@@ -66,7 +66,7 @@ $hLog = logStart($oDB, 'search', $oGeocode->getQueryString(), $aLangPrefOrder);
 $aSearchResults = $oGeocode->lookup();
 
 if ($sOutputFormat=='html') {
-    $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
+    $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
 }
 logEnd($oDB, $hLog, sizeof($aSearchResults));
 
@@ -81,4 +81,5 @@ $sMoreURL = CONST_Website_BaseURL.'search.php?'.http_build_query($aMoreParams);
 
 if (CONST_Debug) exit;
 
-include(CONST_BasePath.'/lib/template/search-'.$sOutputFormat.'.php');
+$sOutputTemplate = ($sOutputFormat=='jsonv2' ? 'json' : $sOutputFormat);
+include(CONST_BasePath.'/lib/template/search-'.$sOutputTemplate.'.php');