]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge pull request #1555 from mtmail/setup-escape-shell-args
authorSarah Hoffmann <lonvia@denofr.de>
Wed, 6 Nov 2019 21:47:00 +0000 (22:47 +0100)
committerGitHub <noreply@github.com>
Wed, 6 Nov 2019 21:47:00 +0000 (22:47 +0100)
setup: escape arguments when executing shell commands (psql, createdb)

26 files changed:
CMakeLists.txt
ChangeLog
data-sources/wikipedia-wikidata/README.md
docs/CMakeLists.txt
docs/admin/Migration.md
docs/api/Search.md
docs/develop/Documentation.md
docs/develop/Postcodes.md [new file with mode: 0644]
docs/mkdocs.yml
docs/styles.css [new file with mode: 0644]
lib/DB.php
lib/ParameterParser.php
lib/setup/SetupClass.php
lib/template/details-index-html.php [new file with mode: 0644]
osm2pgsql
settings/address-levels.json
sql/functions.sql
sql/indices.src.sql
sql/indices_search.src.sql
test/php/Nominatim/ParameterParserTest.php
utils/specialphrases.php
vagrant/Install-on-Centos-7.sh
website/css/details.css
website/details.php
website/js/nominatim-ui.js
website/search.php

index 163b04943c68f8b39cf368ae94647ec2f1de761c..88b0405187e6192780d42e9dc64363c83364fd7e 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 3)
+set(NOMINATIM_VERSION_MINOR 4)
 set(NOMINATIM_VERSION_PATCH 0)
 
 set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
index 1927b5901cc950e3d89cadc19ec644151645c90f..db8f9bba86dfb41f33ceca3e77f141fd4dbb14b4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+3.4.0
+
+ * increase required version for PostgreSQL(9.3), PostGIS(2.2) and PHP(7.0)
+ * better error reporting for out-of-memory errors
+ * exclude postcode ranges separated by colon from centre point calculation
+ * update osm2pgsql, better handling of imports without flatnode file
+ * switch to more efficient algorithm for word set computation
+ * use only boundries for country and state parts of addresses
+ * improve updates of addresses with housenumbers and interpolations
+ * remove country from place_addressline table and use country_code instead
+ * optimise indexes on search_name partition tables
+ * improve searching of attached streets for large objects like airports
+ * drop support for python 2
+ * new scripts for importing Wikidata for importance
+ * create and drop indexes concurrently to not clash with auto vacuum
+ * various documentation improvements
+
+
 3.3.0
 
  * zoom 17 in reverse now zooms in on minor streets
index 7ac1974e76279ea485b07ed3ac8e71060dae68f4..78a9a37444b66b98f851d9371d161f71ac9fdabe 100644 (file)
@@ -32,7 +32,7 @@ To download, convert, and import the data, then process summary statistics and c
 Wikidata
 ---
 
-This script downloads and processes Wikidata to enrich the previously created Wekipedia tables for use in Nominatim.
+This script downloads and processes Wikidata to enrich the previously created Wikipedia tables for use in Nominatim.
 
 #### Import & Process Wikidata
 
index fb35cc1d5e75b0182058cdfb5876bfba8521ec48..bdba63db189ec3f9205f808d1fcc935e7a45b44b 100644 (file)
@@ -13,6 +13,7 @@ ADD_CUSTOM_TARGET(doc
    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_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/styles.css ${CMAKE_CURRENT_BINARY_DIR}/styles.css
    COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/data-sources/overview.md ${CMAKE_CURRENT_BINARY_DIR}/data-sources/overview.md
    COMMAND ${CMAKE_COMMAND} -E create_symlink ${PROJECT_SOURCE_DIR}/data-sources/us-tiger/README.md ${CMAKE_CURRENT_BINARY_DIR}/data-sources/US-Tiger.md
    COMMAND ${CMAKE_COMMAND} -E create_symlink ${PROJECT_SOURCE_DIR}/data-sources/gb-postcodes/README.md ${CMAKE_CURRENT_BINARY_DIR}/data-sources/GB-Postcodes.md
index c5a05d9afec79b93f5c81439847071c1da92c852..f3668357fd1ffa36b5f595710f4e53d781bb1526 100644 (file)
@@ -6,7 +6,7 @@ to newer versions of Nominatim.
 SQL statements should be executed from the PostgreSQL commandline. Execute
 `psql nominatim` to enter command line mode.
 
-## 3.3.0 -> master
+## 3.3.0 -> 3.4.0
 
 ### Reorganisation of location_area_country table
 
index df39bba800a51e40ff3ff804cab2750d870e9f42..ace6cc8de7df34571c334bd0d396f611703c17d3 100644 (file)
@@ -112,7 +112,8 @@ Limit the number of returned results. (Default: 10, Maximum: 50)
 * `viewbox=<x1>,<y1>,<x2>,<y2>`
 
 The preferred area to find search results. Any two corner points of the box
-are accepted in any order as long as they span a real box.
+are accepted in any order as long as they span a real box. `x` is longitude,
+`y` is latitude.
 
 
 * `bounded=[0|1]`
index 6e792c25caa7db74103a9c5a5ec2b4afc51e0835..df8d2b1a84f05a8dab945f3b100d9935deea5b1a 100644 (file)
@@ -1,36 +1,36 @@
 # Documentation Pages
 
-The [Nominatim documentation](https://nominatim.org/release-docs/develop/) is built using the [MkDocs](https://www.mkdocs.org/) static site generation framework. The master branch is automatically deployed every night on under [https://nominatim.org/release-docs/develop/]()
+The [Nominatim documentation](https://nominatim.org/release-docs/develop/) is built using the [MkDocs](https://www.mkdocs.org/) static site generation framework. The master branch is automatically deployed every night on under [https://nominatim.org/release-docs/develop/](https://nominatim.org/release-docs/develop/)
 
-To preview local changes:
+To preview local changes, first install MkDocs
 
-1. Install MkDocs
+```
+pip3 install --user mkdocs
+```
 
-   ```
-   pip3 install --user mkdocs 
-   ```
 
+Then go to the build directory and run
 
-2. In build directory run
+```
+make doc
+INFO - Cleaning site directory
+INFO - Building documentation to directory: /home/vagrant/build/site-html
+```
 
-   ```
-   make doc
-   INFO - Cleaning site directory
-   INFO - Building documentation to directory: /home/vagrant/build/site-html 
-   ```
+This runs `mkdocs build` plus extra transformation of some files and adds
+symlinks (see `CMakeLists.txt` for the exact steps).
 
-   This runs `mkdocs build` plus extra transformion of some files and adds symlinks (see `CMakeLists.txt` for the exact steps).
+Now you can start webserver for local testing
 
+```
+build> mkdocs serve
+[server:296] Serving on http://127.0.0.1:8000
+[handlers:62] Start watching changes
+```
 
-3. Start webserver for local testing
+If you develop inside a Vagrant virtual machine:
 
-   ```
-   mkdocs serve
-   [server:296] Serving on http://127.0.0.1:8000
-   [handlers:62] Start watching changes
-   ```
-
-   If you develop inside a Vagrant virtual machine:
-   * add port forwarding to your Vagrantfile, e.g. `config.vm.network "forwarded_port", guest: 8000, host: 8000`
-   * use `mkdocs serve --dev-addr 0.0.0.0:8000` because the default localhost
-      IP does not get forwarded.
+ * add port forwarding to your Vagrantfile,
+   e.g. `config.vm.network "forwarded_port", guest: 8000, host: 8000`
+ * use `mkdocs serve --dev-addr 0.0.0.0:8000` because the default localhost
+   IP does not get forwarded.
diff --git a/docs/develop/Postcodes.md b/docs/develop/Postcodes.md
new file mode 100644 (file)
index 0000000..c52f0b8
--- /dev/null
@@ -0,0 +1,43 @@
+# Postcodes in Nominatim
+
+The blog post [Nominatim and Postcodes](https://www.openstreetmap.org/user/lonvia/diary/43143)
+describes the handling implemented since Nominatim 3.1.
+
+Postcode centroids (aka 'calculated postcodes') are generated by looking at all
+postcodes of a country, grouping them and calculating the geometric centroid.
+There is currently no logic to deal with extreme outliers (typos or other
+mistakes in OSM data). There is also no check if a postcodes adheres to a
+country's format, e.g. if Swiss postcodes are 4 digits.
+
+
+## Regular updating calculated postcodes
+
+The script to rerun the calculation is
+`build/utils/update.php --calculate-postcodes`
+and runs once per night on nominatim.openstreetmap.org.
+
+
+## Finding places that share a specific postcode
+
+In the Nominatim database run
+
+```sql
+SELECT osm_type, osm_id, class, type,
+       st_x(centroid) as lon, st_y(centroid) at lat
+FROM placex
+WHERE country_code='fr'
+  AND upper(trim (both ' ' from address->'postcode')) = '33210';
+```
+
+Alternatively on [Overpass](https://overpass-turbo.eu/) run the following query
+
+```
+[out:json][timeout:250];
+area["name"="France"]->.boundaryarea;
+(
+nwr(area.boundaryarea)["addr:postcode"="33210"];
+);
+out body;
+>;
+out skel qt;
+```
index d87fda7a7e9d42c4b227d0cfdb67c44b6b646dc3..5cf63f83414e2319622a8a80e772692b16d18cca 100644 (file)
@@ -22,6 +22,7 @@ pages:
         - 'Overview' : 'develop/overview.md'
         - 'OSM Data Import' : 'develop/Import.md'
         - 'Place Ranking' : 'develop/Ranking.md'
+        - 'Postcodes' : 'develop/Postcodes.md'
         - 'Documentation' : 'develop/Documentation.md'
     - 'External Data Sources':
         - 'Overview' : 'data-sources/overview.md'
@@ -34,8 +35,7 @@ pages:
         - '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
+    - codehilite
     - toc:
         permalink: 
-extra_css: [extra.css]
+extra_css: [extra.css, styles.css]
diff --git a/docs/styles.css b/docs/styles.css
new file mode 100644 (file)
index 0000000..8ba0a1d
--- /dev/null
@@ -0,0 +1,69 @@
+.codehilite .hll { background-color: #ffffcc }
+.codehilite  { background: #f0f0f0; }
+.codehilite .c { color: #60a0b0; font-style: italic } /* Comment */
+.codehilite .err { /* border: 1px solid #FF0000 */ } /* Error */
+.codehilite .k { color: #007020; font-weight: bold } /* Keyword */
+.codehilite .o { color: #666666 } /* Operator */
+.codehilite .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
+.codehilite .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
+.codehilite .cp { color: #007020 } /* Comment.Preproc */
+.codehilite .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
+.codehilite .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
+.codehilite .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
+.codehilite .gd { color: #A00000 } /* Generic.Deleted */
+.codehilite .ge { font-style: italic } /* Generic.Emph */
+.codehilite .gr { color: #FF0000 } /* Generic.Error */
+.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.codehilite .gi { color: #00A000 } /* Generic.Inserted */
+.codehilite .go { color: #888888 } /* Generic.Output */
+.codehilite .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.codehilite .gs { font-weight: bold } /* Generic.Strong */
+.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.codehilite .gt { color: #0044DD } /* Generic.Traceback */
+.codehilite .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.codehilite .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.codehilite .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.codehilite .kp { color: #007020 } /* Keyword.Pseudo */
+.codehilite .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.codehilite .kt { color: #902000 } /* Keyword.Type */
+.codehilite .m { color: #40a070 } /* Literal.Number */
+.codehilite .s { color: #4070a0 } /* Literal.String */
+.codehilite .na { color: #4070a0 } /* Name.Attribute */
+.codehilite .nb { color: #007020 } /* Name.Builtin */
+.codehilite .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.codehilite .no { color: #60add5 } /* Name.Constant */
+.codehilite .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.codehilite .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.codehilite .ne { color: #007020 } /* Name.Exception */
+.codehilite .nf { color: #06287e } /* Name.Function */
+.codehilite .nl { color: #002070; font-weight: bold } /* Name.Label */
+.codehilite .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.codehilite .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.codehilite .nv { color: #bb60d5 } /* Name.Variable */
+.codehilite .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
+.codehilite .mb { color: #40a070 } /* Literal.Number.Bin */
+.codehilite .mf { color: #40a070 } /* Literal.Number.Float */
+.codehilite .mh { color: #40a070 } /* Literal.Number.Hex */
+.codehilite .mi { color: #40a070 } /* Literal.Number.Integer */
+.codehilite .mo { color: #40a070 } /* Literal.Number.Oct */
+.codehilite .sa { color: #4070a0 } /* Literal.String.Affix */
+.codehilite .sb { color: #4070a0 } /* Literal.String.Backtick */
+.codehilite .sc { color: #4070a0 } /* Literal.String.Char */
+.codehilite .dl { color: #4070a0 } /* Literal.String.Delimiter */
+.codehilite .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.codehilite .s2 { color: #4070a0 } /* Literal.String.Double */
+.codehilite .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.codehilite .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.codehilite .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.codehilite .sx { color: #c65d09 } /* Literal.String.Other */
+.codehilite .sr { color: #235388 } /* Literal.String.Regex */
+.codehilite .s1 { color: #4070a0 } /* Literal.String.Single */
+.codehilite .ss { color: #517918 } /* Literal.String.Symbol */
+.codehilite .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.codehilite .fm { color: #06287e } /* Name.Function.Magic */
+.codehilite .vc { color: #bb60d5 } /* Name.Variable.Class */
+.codehilite .vg { color: #bb60d5 } /* Name.Variable.Global */
+.codehilite .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.codehilite .vm { color: #bb60d5 } /* Name.Variable.Magic */
+.codehilite .il { color: #40a070 } /* Literal.Number.Integer.Long */
index ddc0932c871e123214e3d373b7a33e9abcaa193a..e4aa4349dbf7dc4a55fd43417a0ff62448aadc36 100644 (file)
@@ -135,7 +135,7 @@ class DB
         try {
             $stmt = $this->getQueryStatement($sSQL, $aInputVars, $sErrMessage);
 
-            while ($val = $stmt->fetchColumn(0)) { // returns first column or false
+            while (($val = $stmt->fetchColumn(0)) !== false) { // returns first column or false
                 $aVals[] = $val;
             }
         } catch (\PDOException $e) {
index ad281d70b634260bfcac15d4656c425d4299e4f1..cb03c6cc7c25c77f3b73f3b2347628a328734f83 100644 (file)
@@ -104,16 +104,16 @@ class ParameterParser
         }
 
         foreach ($aLanguages as $sLanguage => $fLanguagePref) {
-            $aLangPrefOrder['short_name:'.$sLanguage] = 'short_name:'.$sLanguage;
             $aLangPrefOrder['name:'.$sLanguage] = 'name:'.$sLanguage;
         }
-        $aLangPrefOrder['short_name'] = 'short_name';
         $aLangPrefOrder['name'] = 'name';
         $aLangPrefOrder['brand'] = 'brand';
         foreach ($aLanguages as $sLanguage => $fLanguagePref) {
             $aLangPrefOrder['official_name:'.$sLanguage] = 'official_name:'.$sLanguage;
+            $aLangPrefOrder['short_name:'.$sLanguage] = 'short_name:'.$sLanguage;
         }
         $aLangPrefOrder['official_name'] = 'official_name';
+        $aLangPrefOrder['short_name'] = 'short_name';
         $aLangPrefOrder['ref'] = 'ref';
         $aLangPrefOrder['type'] = 'type';
         return $aLangPrefOrder;
index b8070e4a2d326255497a979d6ee2b1e5ccac0e0d..818aeeb7d1b5cdb083d025cd9c3790b77e4c292d 100755 (executable)
@@ -139,7 +139,7 @@ class SetupFunctions
             exit(1);
         }
         $this->pgsqlRunScriptFile(CONST_BasePath.'/data/country_name.sql');
-        $this->pgsqlRunScriptFile(CONST_BasePath.'/data/country_osm_grid.sql.gz');
+        $this->pgsqlRunScriptFile(CONST_ExtraDataPath.'/country_osm_grid.sql.gz');
         $this->pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_table.sql');
         $this->pgsqlRunScriptFile(CONST_BasePath.'/data/us_postcode_table.sql');
 
@@ -470,6 +470,10 @@ class SetupFunctions
     {
         info('Import Tiger data');
 
+        $aFilenames = glob(CONST_Tiger_Data_Path.'/*.sql');
+        info('Found '.count($aFilenames).' SQL files in path '.CONST_Tiger_Data_Path);
+        if (empty($aFilenames)) return;
+
         $sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_start.sql');
         $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
         $sTemplate = $this->replaceTablespace(
@@ -494,7 +498,7 @@ class SetupFunctions
             pg_ping($aDBInstances[$i]);
         }
 
-        foreach (glob(CONST_Tiger_Data_Path.'/*.sql') as $sFile) {
+        foreach ($aFilenames as $sFile) {
             echo $sFile.': ';
             $hFile = fopen($sFile, 'r');
             $sSQL = fgets($hFile, 100000);
@@ -729,9 +733,7 @@ class SetupFunctions
         }
         foreach ($aDropTables as $sDrop) {
             if ($this->bVerbose) echo "Dropping table $sDrop\n";
-            $this->oDB->exec("DROP TABLE $sDrop CASCADE");
-            // ignore warnings/errors as they might be caused by a table having
-            // been deleted already by CASCADE
+            $this->oDB->exec("DROP TABLE IF EXISTS $sDrop CASCADE");
         }
 
         if (!is_null(CONST_Osm2pgsql_Flatnode_File) && CONST_Osm2pgsql_Flatnode_File) {
diff --git a/lib/template/details-index-html.php b/lib/template/details-index-html.php
new file mode 100644 (file)
index 0000000..640a212
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+    header("content-type: text/html; charset=UTF-8");
+?>
+<?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
+    <link href="css/common.css" rel="stylesheet" type="text/css" />
+    <link href="css/details.css" rel="stylesheet" type="text/css" />
+</head>
+
+
+<body id="details-index-page">
+    <div class="container">
+        <div class="row">
+            <div class="col-md-12">
+
+                <h1>Show details for place</h1>
+
+                <div class="search-form">
+                    <h4>Search by place id</h4>
+
+                    <form class="form-inline" action="details.php">
+                        <input type="edit" class="form-control input-sm" pattern="^[0-9]+$" name="place_id" placeholder="12345" />
+                        <input type="submit" class="btn btn-primary btn-sm" value="Show" />
+                    </form>
+                </div>
+
+                <div class="search-form">
+                    <h4>Search by OSM type and OSM id</h4>
+
+                    <form id="form-by-type-and-id" class="form-inline" action="details.php">
+                        <input type="edit" class="form-control input-sm" pattern="^[NWR][0-9]+$" placeholder="N123 or W123 or R123" />
+                        <input type="hidden" name="osmtype" />
+                        <input type="hidden" name="osmid" />
+                        <input type="submit" class="btn btn-primary btn-sm" value="Show" />
+                    </form>
+                </div>
+
+                <div class="search-form">
+                    <h4>Search by openstreetmap.org URL</h4>
+
+                    <form id="form-by-osm-url" class="form-inline" action="details.php">
+                        <input type="edit" class="form-control input-sm" pattern=".*openstreetmap.*" placeholder="https://www.openstreetmap.org/relation/123" />
+                        <input type="hidden" name="osmtype" />
+                        <input type="hidden" name="osmid" />
+                        <input type="submit" class="btn btn-primary btn-sm" value="Show" />
+                    </form>
+                </div>
+
+            </div>
+        </div>
+    </div>
+
+
+    <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
+</body>
+</html>
index 90e17f0e8c793487ca39cbf95501cd9c5daa33e2..8d9087f1111f4a062158e8e6b10bfbceed90899b 160000 (submodule)
--- a/osm2pgsql
+++ b/osm2pgsql
@@ -1 +1 @@
-Subproject commit 90e17f0e8c793487ca39cbf95501cd9c5daa33e2
+Subproject commit 8d9087f1111f4a062158e8e6b10bfbceed90899b
index a7264181de205a7504a9d3ae04de56ee1ede1ae4..8429a3cbd8c7f649ae7f0b7ae2227475cae7540b 100644 (file)
@@ -25,6 +25,8 @@
           "islet" : [20, 0],
           "mountain_pass" : [20, 0],
           "neighbourhood" : 22,
+          "quarter" : 22,
+          "city_block" : 22,
           "houses" : [28, 0]
       },
       "boundary" : {
index f696e23132804314cc848f330a445eb40c6e2039..f3bff89c66e63a018ce03e482447f8f2a1b246dc 100644 (file)
@@ -2386,7 +2386,7 @@ BEGIN
 
   -- postcode table
   IF for_place_id IS NULL THEN
-    SELECT parent_place_id, country_code, rank_address, postcode, 'place', 'postcode'
+    SELECT parent_place_id, country_code, rank_search, postcode, 'place', 'postcode'
       FROM location_postcode
       WHERE place_id = in_place_id
       INTO for_place_id, searchcountrycode, searchrankaddress, searchpostcode,
index b661cf4a6d3fe4aa66de5810afb18ff43d7c2317..a5aae32b4c8a08d2e9090b9e3ed4e5a2caa7bffe 100644 (file)
@@ -1,27 +1,27 @@
 -- Indices used only during search and update.
 -- These indices are created only after the indexing process is done.
 
-CREATE INDEX idx_word_word_id on word USING BTREE (word_id) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_word_word_id on word USING BTREE (word_id) {ts:search-index};
 
-CREATE INDEX idx_place_addressline_address_place_id on place_addressline USING BTREE (address_place_id) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_place_addressline_address_place_id on place_addressline USING BTREE (address_place_id) {ts:search-index};
 
-DROP INDEX IF EXISTS idx_placex_rank_search;
-CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search) {ts:search-index};
-CREATE INDEX idx_placex_rank_address ON placex USING BTREE (rank_address) {ts:search-index};
-CREATE INDEX idx_placex_pendingsector ON placex USING BTREE (rank_search,geometry_sector) {ts:address-index} where indexed_status > 0;
-CREATE INDEX idx_placex_parent_place_id ON placex USING BTREE (parent_place_id) {ts:search-index} where parent_place_id IS NOT NULL;
+DROP INDEX CONCURRENTLY IF EXISTS idx_placex_rank_search;
+CREATE INDEX CONCURRENTLY idx_placex_rank_search ON placex USING BTREE (rank_search) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_placex_rank_address ON placex USING BTREE (rank_address) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_placex_pendingsector ON placex USING BTREE (rank_search,geometry_sector) {ts:address-index} where indexed_status > 0;
+CREATE INDEX CONCURRENTLY idx_placex_parent_place_id ON placex USING BTREE (parent_place_id) {ts:search-index} where parent_place_id IS NOT NULL;
 
-CREATE INDEX idx_placex_geometry_reverse_lookupPoint
+CREATE INDEX CONCURRENTLY idx_placex_geometry_reverse_lookupPoint
   ON placex USING gist (geometry) {ts:search-index}
   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
+CREATE INDEX CONCURRENTLY idx_placex_geometry_reverse_lookupPolygon
   ON placex USING gist (geometry) {ts:search-index}
   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
+CREATE INDEX CONCURRENTLY idx_placex_geometry_reverse_placeNode
   ON placex USING gist (geometry) {ts:search-index}
   WHERE osm_type = 'N' AND rank_search between 5 and 25
     AND class = 'place' AND type != 'postcode'
@@ -29,14 +29,14 @@ CREATE INDEX idx_placex_geometry_reverse_placeNode
 
 GRANT SELECT ON table country_osm_grid to "{www-user}";
 
-CREATE INDEX idx_location_area_country_place_id ON location_area_country USING BTREE (place_id) {ts:address-index};
+CREATE INDEX CONCURRENTLY idx_location_area_country_place_id ON location_area_country USING BTREE (place_id) {ts:address-index};
 
-CREATE INDEX idx_osmline_parent_place_id ON location_property_osmline USING BTREE (parent_place_id) {ts:search-index};
-CREATE INDEX idx_osmline_parent_osm_id ON location_property_osmline USING BTREE (osm_id) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_osmline_parent_place_id ON location_property_osmline USING BTREE (parent_place_id) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_osmline_parent_osm_id ON location_property_osmline USING BTREE (osm_id) {ts:search-index};
 
-DROP INDEX IF EXISTS place_id_idx;
-CREATE UNIQUE INDEX idx_place_osm_unique on place using btree(osm_id,osm_type,class,type) {ts:address-index};
+DROP INDEX CONCURRENTLY IF EXISTS place_id_idx;
+CREATE UNIQUE INDEX CONCURRENTLY idx_place_osm_unique on place using btree(osm_id,osm_type,class,type) {ts:address-index};
 
 
-CREATE UNIQUE INDEX idx_postcode_id ON location_postcode USING BTREE (place_id) {ts:search-index};
-CREATE INDEX idx_postcode_postcode ON location_postcode USING BTREE (postcode) {ts:search-index};
+CREATE UNIQUE INDEX CONCURRENTLY idx_postcode_id ON location_postcode USING BTREE (place_id) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_postcode_postcode ON location_postcode USING BTREE (postcode) {ts:search-index};
index d1363fc6e1ea7e55c55a1049532201c69b7939f2..70cd8799e2425c8b1be8cf96e7db08511f2ee6e7 100644 (file)
@@ -1,6 +1,6 @@
 -- Indices used for /search API.
 -- These indices are created only after the indexing process is done.
 
-CREATE INDEX idx_search_name_nameaddress_vector ON search_name USING GIN (nameaddress_vector) WITH (fastupdate = off) {ts:search-index};
-CREATE INDEX idx_search_name_name_vector ON search_name USING GIN (name_vector) WITH (fastupdate = off) {ts:search-index};
-CREATE INDEX idx_search_name_centroid ON search_name USING GIST (centroid) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_search_name_nameaddress_vector ON search_name USING GIN (nameaddress_vector) WITH (fastupdate = off) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_search_name_name_vector ON search_name USING GIN (name_vector) WITH (fastupdate = off) {ts:search-index};
+CREATE INDEX CONCURRENTLY idx_search_name_centroid ON search_name USING GIST (centroid) {ts:search-index};
index ee2f5e1897d8652cf3d7bef9c2a034b1aaba6a72..75f6b276ae19fd5bcd143f399016fff36742a97e 100644 (file)
@@ -175,73 +175,73 @@ class ParameterParserTest extends \PHPUnit\Framework\TestCase
     {
         $oParams = new ParameterParser(array('accept-language' => ''));
         $this->assertSame(array(
-                           'short_name:default' => 'short_name:default',
                            'name:default' => 'name:default',
-                           'short_name' => 'short_name',
                            'name' => 'name',
                            'brand' => 'brand',
                            'official_name:default' => 'official_name:default',
+                           'short_name:default' => 'short_name:default',
                            'official_name' => 'official_name',
+                           'short_name' => 'short_name',
                            'ref' => 'ref',
                            'type' => 'type'
                           ), $oParams->getPreferredLanguages('default'));
 
         $oParams = new ParameterParser(array('accept-language' => 'de,en'));
         $this->assertSame(array(
-                           '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',
+                           'short_name:de' => 'short_name:de',
                            'official_name:en' => 'official_name:en',
+                           'short_name:en' => 'short_name:en',
                            'official_name' => 'official_name',
+                           'short_name' => 'short_name',
                            'ref' => 'ref',
                            'type' => 'type'
                           ), $oParams->getPreferredLanguages('default'));
 
         $oParams = new ParameterParser(array('accept-language' => 'fr-ca,fr;q=0.8,en-ca;q=0.5,en;q=0.3'));
         $this->assertSame(array(
-                           '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',
+                           'short_name:fr-ca' => 'short_name:fr-ca',
                            'official_name:fr' => 'official_name:fr',
+                           'short_name:fr' => 'short_name:fr',
                            'official_name:en-ca' => 'official_name:en-ca',
+                           'short_name:en-ca' => 'short_name:en-ca',
                            'official_name:en' => 'official_name:en',
+                           'short_name:en' => 'short_name:en',
                            'official_name' => 'official_name',
+                           'short_name' => 'short_name',
                            'ref' => 'ref',
                            'type' => 'type',
                           ), $oParams->getPreferredLanguages('default'));
 
         $oParams = new ParameterParser(array('accept-language' => 'ja_rm,zh_pinyin'));
         $this->assertSame(array(
-                           'short_name:ja_rm' => 'short_name:ja_rm',
                            'name:ja_rm' => 'name:ja_rm',
-                           'short_name:zh_pinyin' => 'short_name:zh_pinyin',
                            'name:zh_pinyin' => 'name:zh_pinyin',
-                           'short_name:ja' => 'short_name:ja',
                            'name:ja' => 'name:ja',
-                           'short_name:zh' => 'short_name:zh',
                            'name:zh' => 'name:zh',
-                           'short_name' => 'short_name',
                            'name' => 'name',
                            'brand' => 'brand',
                            'official_name:ja_rm' => 'official_name:ja_rm',
+                           'short_name:ja_rm' => 'short_name:ja_rm',
                            'official_name:zh_pinyin' => 'official_name:zh_pinyin',
+                           'short_name:zh_pinyin' => 'short_name:zh_pinyin',
                            'official_name:ja' => 'official_name:ja',
+                           'short_name:ja' => 'short_name:ja',
                            'official_name:zh' => 'official_name:zh',
+                           'short_name:zh' => 'short_name:zh',
                            'official_name' => 'official_name',
+                           'short_name' => 'short_name',
                            'ref' => 'ref',
                            'type' => 'type',
                           ), $oParams->getPreferredLanguages('default'));
index cb237be6d74cd7478e1842c37bdc327ecfe50997..9e6c9d76c757a38c70ba4a722207881c13368e98 100644 (file)
@@ -27,77 +27,127 @@ if ($aCMDResult['wiki-import']) {
     foreach (explode(',', $sLanguageIn) as $sLanguage) {
         $sURL = 'https://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Special_Phrases/'.strtoupper($sLanguage);
         $sWikiPageXML = file_get_contents($sURL);
-        if (preg_match_all('#\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([\\-YN])#', $sWikiPageXML, $aMatches, PREG_SET_ORDER)) {
-            foreach ($aMatches as $aMatch) {
-                $sLabel = trim($aMatch[1]);
-                if ($oNormalizer !== null) {
-                    $sTrans = pg_escape_string($oNormalizer->transliterate($sLabel));
-                } else {
-                    $sTrans = null;
-                }
-                $sClass = trim($aMatch[2]);
-                $sType = trim($aMatch[3]);
-                // hack around a bug where building=yes was imported with
-                // quotes into the wiki
-                $sType = preg_replace('/&quot;/', '', $sType);
-                // sanity check, in case somebody added garbage in the wiki
-                if (preg_match('/^\\w+$/', $sClass) < 1
-                    || preg_match('/^\\w+$/', $sType) < 1
-                ) {
-                    trigger_error("Bad class/type for language $sLanguage: $sClass=$sType");
-                    exit;
-                }
-                // blacklisting: disallow certain class/type combinations
-                if (isset($aTagsBlacklist[$sClass]) && in_array($sType, $aTagsBlacklist[$sClass])) {
-                    // fwrite(STDERR, "Blacklisted: ".$sClass."/".$sType."\n");
-                    continue;
-                }
-                // whitelisting: if class is in whitelist, allow only tags in the list
-                if (isset($aTagsWhitelist[$sClass]) && !in_array($sType, $aTagsWhitelist[$sClass])) {
-                    // fwrite(STDERR, "Non-Whitelisted: ".$sClass."/".$sType."\n");
-                    continue;
-                }
-                $aPairs[$sClass.'|'.$sType] = array($sClass, $sType);
-
-                switch (trim($aMatch[4])) {
-                    case 'near':
-                        echo "select getorcreate_amenityoperator(make_standard_name('".pg_escape_string($sLabel)."'), '$sTrans', '$sClass', '$sType', 'near');\n";
-                        break;
-                    case 'in':
-                        echo "select getorcreate_amenityoperator(make_standard_name('".pg_escape_string($sLabel)."'), '$sTrans', '$sClass', '$sType', 'in');\n";
-                        break;
-                    default:
-                        echo "select getorcreate_amenity(make_standard_name('".pg_escape_string($sLabel)."'), '$sTrans', '$sClass', '$sType');\n";
-                        break;
-                }
+
+        if (!preg_match_all(
+            '#\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([\\-YN])#',
+            $sWikiPageXML,
+            $aMatches,
+            PREG_SET_ORDER
+        )) {
+            continue;
+        }
+
+        foreach ($aMatches as $aMatch) {
+            $sLabel = trim($aMatch[1]);
+            if ($oNormalizer !== null) {
+                $sTrans = pg_escape_string($oNormalizer->transliterate($sLabel));
+            } else {
+                $sTrans = null;
+            }
+            $sClass = trim($aMatch[2]);
+            $sType = trim($aMatch[3]);
+            // hack around a bug where building=yes was imported with
+            // quotes into the wiki
+            $sType = preg_replace('/(&quot;|")/', '', $sType);
+            // sanity check, in case somebody added garbage in the wiki
+            if (preg_match('/^\\w+$/', $sClass) < 1
+                || preg_match('/^\\w+$/', $sType) < 1
+            ) {
+                trigger_error("Bad class/type for language $sLanguage: $sClass=$sType");
+                exit;
+            }
+            // blacklisting: disallow certain class/type combinations
+            if (isset($aTagsBlacklist[$sClass]) && in_array($sType, $aTagsBlacklist[$sClass])) {
+                // fwrite(STDERR, "Blacklisted: ".$sClass."/".$sType."\n");
+                continue;
+            }
+            // whitelisting: if class is in whitelist, allow only tags in the list
+            if (isset($aTagsWhitelist[$sClass]) && !in_array($sType, $aTagsWhitelist[$sClass])) {
+                // fwrite(STDERR, "Non-Whitelisted: ".$sClass."/".$sType."\n");
+                continue;
+            }
+            $aPairs[$sClass.'|'.$sType] = array($sClass, $sType);
+
+            switch (trim($aMatch[4])) {
+                case 'near':
+                    printf(
+                        "SELECT getorcreate_amenityoperator(make_standard_name('%s'), '%s', '%s', '%s', 'near');\n",
+                        pg_escape_string($sLabel),
+                        $sTrans,
+                        $sClass,
+                        $sType
+                    );
+                    break;
+                case 'in':
+                    printf(
+                        "SELECT getorcreate_amenityoperator(make_standard_name('%s'), '%s', '%s', '%s', 'in');\n",
+                        pg_escape_string($sLabel),
+                        $sTrans,
+                        $sClass,
+                        $sType
+                    );
+                    break;
+                default:
+                    printf(
+                        "SELECT getorcreate_amenity(make_standard_name('%s'), '%s', '%s', '%s');\n",
+                        pg_escape_string($sLabel),
+                        $sTrans,
+                        $sClass,
+                        $sType
+                    );
+                    break;
             }
         }
     }
 
-    echo 'create index idx_placex_classtype on placex (class, type);';
+    echo 'CREATE INDEX idx_placex_classtype ON placex (class, type);';
 
     foreach ($aPairs as $aPair) {
-        echo 'create table place_classtype_'.pg_escape_string($aPair[0]).'_'.pg_escape_string($aPair[1]);
-        if (CONST_Tablespace_Aux_Data)
-            echo ' tablespace '.CONST_Tablespace_Aux_Data;
-        echo ' as select place_id as place_id,st_centroid(geometry) as centroid from placex where ';
-        echo "class = '".pg_escape_string($aPair[0])."' and type = '".pg_escape_string($aPair[1])."'";
-        echo ";\n";
-
-        echo 'CREATE INDEX idx_place_classtype_'.pg_escape_string($aPair[0]).'_'.pg_escape_string($aPair[1]).'_centroid ';
-        echo 'ON place_classtype_'.pg_escape_string($aPair[0]).'_'.pg_escape_string($aPair[1]).' USING GIST (centroid)';
-        if (CONST_Tablespace_Aux_Index)
-            echo ' tablespace '.CONST_Tablespace_Aux_Index;
-        echo ";\n";
-
-        echo 'CREATE INDEX idx_place_classtype_'.pg_escape_string($aPair[0]).'_'.pg_escape_string($aPair[1]).'_place_id ';
-        echo 'ON place_classtype_'.pg_escape_string($aPair[0]).'_'.pg_escape_string($aPair[1]).' USING btree(place_id)';
-        if (CONST_Tablespace_Aux_Index)
-            echo ' tablespace '.CONST_Tablespace_Aux_Index;
-        echo ";\n";
-
-        echo 'GRANT SELECT ON place_classtype_'.pg_escape_string($aPair[0]).'_'.pg_escape_string($aPair[1]).' TO "'.CONST_Database_Web_User."\";\n";
+        $sql_tablespace = CONST_Tablespace_Aux_Data ? ' TABLESPACE '.CONST_Tablespace_Aux_Data : '';
+
+        printf(
+            'CREATE TABLE place_classtype_%s_%s'
+            . $sql_tablespace
+            . ' AS'
+            . ' SELECT place_id AS place_id,st_centroid(geometry) AS centroid FROM placex'
+            . " WHERE class = '%s' AND type = '%s'"
+            . ";\n",
+            pg_escape_string($aPair[0]),
+            pg_escape_string($aPair[1]),
+            pg_escape_string($aPair[0]),
+            pg_escape_string($aPair[1])
+        );
+
+        printf(
+            'CREATE INDEX idx_place_classtype_%s_%s_centroid'
+            . ' ON place_classtype_%s_%s USING GIST (centroid)'
+            . $sql_tablespace
+            . ";\n",
+            pg_escape_string($aPair[0]),
+            pg_escape_string($aPair[1]),
+            pg_escape_string($aPair[0]),
+            pg_escape_string($aPair[1])
+        );
+
+        printf(
+            'CREATE INDEX idx_place_classtype_%s_%s_place_id'
+            . ' ON place_classtype_%s_%s USING btree(place_id)'
+            . $sql_tablespace
+            . ";\n",
+            pg_escape_string($aPair[0]),
+            pg_escape_string($aPair[1]),
+            pg_escape_string($aPair[0]),
+            pg_escape_string($aPair[1])
+        );
+
+        printf(
+            'GRANT SELECT ON place_classtype_%s_%s TO "%s"'
+            . ";\n",
+            pg_escape_string($aPair[0]),
+            pg_escape_string($aPair[1]),
+            CONST_Database_Web_User
+        );
     }
 
-    echo 'drop index idx_placex_classtype;';
+    echo 'DROP INDEX idx_placex_classtype;';
 }
index 19b7ff84802cedd9f4ea1588ec53ade24a8647af..b456fb74fd1fb6dfc12f752abb2a5e70fadac387 100755 (executable)
 
     sudo yum install -y epel-release
 
+# More repositories for postgresql 11 (CentOS default 'postgresql' is 9.2), postgis
+# and llvm-toolset (https://github.com/theory/pg-semver/issues/35)
+
+    sudo yum install -y https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
+    sudo yum install -y centos-release-scl-rh
+
 # Now you can install all packages needed for Nominatim:
 
 #DOCS:    :::sh
-    sudo yum install -y postgresql-server postgresql-contrib postgresql-devel \
-                        postgis postgis-utils \
+
+    sudo yum install -y postgresql11-server postgresql11-contrib postgresql11-devel \
+                        postgis25_11 postgis25_11-utils \
                         wget git cmake make gcc gcc-c++ libtool policycoreutils-python \
+                        devtoolset-7 llvm-toolset-7 \
                         php-pgsql php php-intl libpqxx-devel \
                         proj-epsg bzip2-devel proj-devel libxml2-devel boost-devel \
                         expat-devel zlib-devel
@@ -77,8 +85,11 @@ sudo chown vagrant /srv/nominatim  #DOCS:
 # CentOS does not automatically create a database cluster. Therefore, start
 # with initializing the database, then enable the server to start at boot:
 
-    sudo postgresql-setup initdb
-    sudo systemctl enable postgresql
+    echo 'PATH=$PATH:/usr/pgsql-11/bin' > .bash_profile
+    source .bash_profile
+
+    sudo /usr/pgsql-11/bin/postgresql-11-setup initdb
+    sudo systemctl enable postgresql-11
 
 #
 # Next tune the postgresql configuration, which is located in 
@@ -88,7 +99,7 @@ sudo chown vagrant /srv/nominatim  #DOCS:
 #
 # Now start the postgresql service after updating this config file.
 
-    sudo systemctl restart postgresql
+    sudo systemctl restart postgresql-11
 
 #
 # Finally, we need to add two postgres users: one for the user that does
@@ -150,7 +161,7 @@ fi                                 #DOCS:
 # 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
+    wget --no-verbose -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,
index 171de42acaa6ca3694b5619d53510894583133db..8f21c310aaa9b265b0b76e1960fef4ec342a18e0 100644 (file)
@@ -52,6 +52,17 @@ tr.all-columns td {
   margin: 10px 0;
 }
 
+#details-index-page .search-form {
+  padding: 20px 10px;
+  margin: 2em 0;
+}
+#details-index-page .search-form h4 {
+  margin-top: 0;
+}
+#details-index-page .search-form .form-control{
+  width: 30em;
+}
+
 footer {
   text-align: center;  
   padding: 2em 0;
index cb371e6b09d2cd8d3e21d463731dce8dea552820..44d4956b4d2845e166dcd8dfac32d8d815a5c9f0 100644 (file)
@@ -30,6 +30,11 @@ $oDB->connect();
 
 $sLanguagePrefArraySQL = $oDB->getArraySQL($oDB->getDBQuotedList($aLangPrefOrder));
 
+if ($sOutputFormat == 'html' && !$sPlaceId && !$sOsmType) {
+    include(CONST_BasePath.'/lib/template/details-index-html.php');
+    exit;
+}
+
 if ($sOsmType && $iOsmId > 0) {
     $sSQL = 'SELECT place_id FROM placex WHERE osm_type = :type AND osm_id = :id';
     // osm_type and osm_id are not unique enough
index e96ebd25c836c3469a2c5cfe36860b390943c8bb..32e7cbda8fc3321b1fd4a6b0389b91bb900a764d 100644 (file)
@@ -273,6 +273,30 @@ jQuery(document).ready(function(){
 });
 
 
+jQuery(document).ready(function(){
+
+    if ( !$('#details-index-page').length ){ return; }
+
+    $('#form-by-type-and-id,#form-by-osm-url').on('submit', function(e){
+        e.preventDefault();
+
+        var val = $(this).find('input[type=edit]').val();
+        var matches = val.match(/^\s*([NWR])(\d+)\s*$/i);
+
+        if (!matches) {
+            matches = val.match(/\/(relation|way|node)\/(\d+)\s*$/);
+        }
+
+        if (matches) {
+            $(this).find('input[name=osmtype]').val(matches[1].charAt(0).toUpperCase());
+            $(this).find('input[name=osmid]').val(matches[2]);
+            $(this).get(0).submit();
+        } else {
+            alert('invalid input');
+        }
+    });
+});
+
 jQuery(document).ready(function(){
 
     if ( !$('#details-page').length ){ return; }
index 26c10122924dc9329ea288d06a40687d75a33dfc..557056566c1065f30146c6c7b448af88fb90efaa 100644 (file)
@@ -50,6 +50,7 @@ $oGeocode->setQueryFromParams($oParams);
 
 if (!$oGeocode->getQueryString()
     && isset($_SERVER['PATH_INFO'])
+    && strlen($_SERVER['PATH_INFO']) > 0
     && $_SERVER['PATH_INFO'][0] == '/'
 ) {
     $sQuery = substr(rawurldecode($_SERVER['PATH_INFO']), 1);