mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-14 18:37:58 +00:00
Compare commits
33 Commits
docs-5.2.x
...
v3.7.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9426fc2fee | ||
|
|
9f4596156d | ||
|
|
3a1714e7e2 | ||
|
|
f845605cf7 | ||
|
|
51c3a00d70 | ||
|
|
b51efd876f | ||
|
|
405279dae3 | ||
|
|
3dd223dfa3 | ||
|
|
7e6125ada5 | ||
|
|
93b72e4e9b | ||
|
|
3bf57e6d2a | ||
|
|
e9ce5714a7 | ||
|
|
ff1a49a0f8 | ||
|
|
ec2873fbf6 | ||
|
|
5dee3cf7f7 | ||
|
|
341cb55690 | ||
|
|
055b5a46ba | ||
|
|
6e8d4c0dac | ||
|
|
baf684195b | ||
|
|
b0832669a3 | ||
|
|
243394b1c2 | ||
|
|
0f14851c98 | ||
|
|
b15a687564 | ||
|
|
0289d125da | ||
|
|
76ee6959c1 | ||
|
|
74c74dde07 | ||
|
|
f7e4bfa980 | ||
|
|
4a6e9ba187 | ||
|
|
10d99893f9 | ||
|
|
b7a5a8b5f7 | ||
|
|
6ed495bfc2 | ||
|
|
cd7c841f5b | ||
|
|
8f9c10c762 |
2
.github/actions/build-nominatim/action.yml
vendored
2
.github/actions/build-nominatim/action.yml
vendored
@@ -6,7 +6,7 @@ runs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Install prerequisites
|
- name: Install prerequisites
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install -y -qq libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libproj-dev libicu-dev python3-psycopg2 python3-pyosmium python3-dotenv python3-psutil python3-jinja2 python3-icu python3-argparse-manpage
|
sudo apt-get install -y -qq libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libproj-dev libicu-dev python3-psycopg2 python3-pyosmium python3-dotenv python3-psutil python3-jinja2 python3-icu
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Download dependencies
|
- name: Download dependencies
|
||||||
|
|||||||
4
.github/actions/setup-postgresql/action.yml
vendored
4
.github/actions/setup-postgresql/action.yml
vendored
@@ -14,8 +14,10 @@ runs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Remove existing PostgreSQL
|
- name: Remove existing PostgreSQL
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -qq
|
|
||||||
sudo apt-get purge -yq postgresql*
|
sudo apt-get purge -yq postgresql*
|
||||||
|
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
|
||||||
|
sudo apt-get update -qq
|
||||||
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Install PostgreSQL
|
- name: Install PostgreSQL
|
||||||
|
|||||||
41
.github/workflows/ci-tests.yml
vendored
41
.github/workflows/ci-tests.yml
vendored
@@ -69,7 +69,18 @@ jobs:
|
|||||||
working-directory: Nominatim/test/bdd
|
working-directory: Nominatim/test/bdd
|
||||||
|
|
||||||
import:
|
import:
|
||||||
runs-on: ubuntu-20.04
|
strategy:
|
||||||
|
matrix:
|
||||||
|
ubuntu: [18, 20]
|
||||||
|
include:
|
||||||
|
- ubuntu: 18
|
||||||
|
postgresql: 9.5
|
||||||
|
postgis: 2.5
|
||||||
|
- ubuntu: 20
|
||||||
|
postgresql: 13
|
||||||
|
postgis: 3
|
||||||
|
|
||||||
|
runs-on: ubuntu-${{ matrix.ubuntu }}.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -95,12 +106,24 @@ jobs:
|
|||||||
monaco-latest.osm.pbf
|
monaco-latest.osm.pbf
|
||||||
key: nominatim-test-data-${{ steps.get-date.outputs.date }}
|
key: nominatim-test-data-${{ steps.get-date.outputs.date }}
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.5
|
||||||
|
if: matrix.ubuntu == 18
|
||||||
|
|
||||||
- uses: ./Nominatim/.github/actions/setup-postgresql
|
- uses: ./Nominatim/.github/actions/setup-postgresql
|
||||||
with:
|
with:
|
||||||
postgresql-version: 13
|
postgresql-version: ${{ matrix.postgresql }}
|
||||||
postgis-version: 3
|
postgis-version: ${{ matrix.postgis }}
|
||||||
- uses: ./Nominatim/.github/actions/build-nominatim
|
- uses: ./Nominatim/.github/actions/build-nominatim
|
||||||
|
|
||||||
|
- name: Install extra dependencies for Ubuntu 18
|
||||||
|
run: |
|
||||||
|
sudo apt-get install libicu-dev
|
||||||
|
pip3 install python-dotenv psycopg2==2.7.7 jinja2==2.8 psutil==5.4.2 pyicu osmium
|
||||||
|
shell: bash
|
||||||
|
if: matrix.ubuntu == 18
|
||||||
|
|
||||||
- name: Clean installation
|
- name: Clean installation
|
||||||
run: rm -rf Nominatim build
|
run: rm -rf Nominatim build
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -123,10 +146,14 @@ jobs:
|
|||||||
run: nominatim special-phrases --import-from-wiki
|
run: nominatim special-phrases --import-from-wiki
|
||||||
working-directory: data-env
|
working-directory: data-env
|
||||||
|
|
||||||
- name: Check import
|
- name: Check full import
|
||||||
run: nominatim admin --check-database
|
run: nominatim admin --check-database
|
||||||
working-directory: data-env
|
working-directory: data-env
|
||||||
|
|
||||||
|
- name: Warm up database
|
||||||
|
run: nominatim admin --warm
|
||||||
|
working-directory: data-env
|
||||||
|
|
||||||
- name: Run update
|
- name: Run update
|
||||||
run: |
|
run: |
|
||||||
nominatim replication --init
|
nominatim replication --init
|
||||||
@@ -134,7 +161,11 @@ jobs:
|
|||||||
working-directory: data-env
|
working-directory: data-env
|
||||||
|
|
||||||
- name: Run reverse-only import
|
- name: Run reverse-only import
|
||||||
run : nominatim import --osm-file ../monaco-latest.osm.pbf --reverse-only
|
run : nominatim import --osm-file ../monaco-latest.osm.pbf --reverse-only --no-updates
|
||||||
working-directory: data-env
|
working-directory: data-env
|
||||||
env:
|
env:
|
||||||
NOMINATIM_DATABASE_DSN: pgsql:dbname=reverse
|
NOMINATIM_DATABASE_DSN: pgsql:dbname=reverse
|
||||||
|
|
||||||
|
- name: Check reverse import
|
||||||
|
run: nominatim admin --check-database
|
||||||
|
working-directory: data-env
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ project(nominatim)
|
|||||||
|
|
||||||
set(NOMINATIM_VERSION_MAJOR 3)
|
set(NOMINATIM_VERSION_MAJOR 3)
|
||||||
set(NOMINATIM_VERSION_MINOR 7)
|
set(NOMINATIM_VERSION_MINOR 7)
|
||||||
set(NOMINATIM_VERSION_PATCH 0)
|
set(NOMINATIM_VERSION_PATCH 3)
|
||||||
|
|
||||||
set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
|
set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
|
||||||
|
|
||||||
|
|||||||
20
ChangeLog
20
ChangeLog
@@ -1,3 +1,23 @@
|
|||||||
|
3.7.3
|
||||||
|
|
||||||
|
* fix XSS vulnerability in debug view
|
||||||
|
|
||||||
|
3.7.2
|
||||||
|
|
||||||
|
* fix database check for reverse-only imports
|
||||||
|
* do not error out in status API result when import date is missing
|
||||||
|
* add array_key_last function for PHP < 7.3 (thanks to @woodpack)
|
||||||
|
* fix more url when server name is unknown (thanks to @mogita)
|
||||||
|
* commit changes to replication log table
|
||||||
|
|
||||||
|
3.7.1
|
||||||
|
|
||||||
|
* fix smaller issues with special phrases import
|
||||||
|
* add index to speed up continued indexing during import
|
||||||
|
* fix index on location_property_tiger(parent_place_id)
|
||||||
|
* make sure Python code is backward-compatible with Python 3.5
|
||||||
|
* various documentation fixes
|
||||||
|
|
||||||
3.7.0
|
3.7.0
|
||||||
|
|
||||||
* switch to dotenv for configuration file
|
* switch to dotenv for configuration file
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Deploying Nominatim
|
# Deploying Nominatim
|
||||||
|
|
||||||
The Nominatim API is implemented as a PHP application. The `website/` directory
|
The Nominatim API is implemented as a PHP application. The `website/` directory
|
||||||
in the build directory contains the configured website. You can serve this
|
in the project directory contains the configured website. You can serve this
|
||||||
in a production environment with any web server that is capable to run
|
in a production environment with any web server that is capable to run
|
||||||
PHP scripts.
|
PHP scripts.
|
||||||
|
|
||||||
@@ -13,10 +13,11 @@ to run a web service. Please refer to the documentation of
|
|||||||
for background information on configuring the services.
|
for background information on configuring the services.
|
||||||
|
|
||||||
!!! Note
|
!!! Note
|
||||||
Throughout this page, we assume that your Nominatim build directory is
|
Throughout this page, we assume that your Nominatim project directory is
|
||||||
located in `/srv/nominatim/build` and the source code in
|
located in `/srv/nominatim-project` and that you have installed Nominatim
|
||||||
`/srv/nominatim/Nominatim`. If you have put it somewhere else, you
|
using the default installation prefix `/usr/local`. If you have put it
|
||||||
need to adjust the commands and configuration accordingly.
|
somewhere else, you need to adjust the commands and configuration
|
||||||
|
accordingly.
|
||||||
|
|
||||||
We further assume that your web server runs as user `www-data`. Older
|
We further assume that your web server runs as user `www-data`. Older
|
||||||
versions of CentOS may still use the user name `apache`. You also need
|
versions of CentOS may still use the user name `apache`. You also need
|
||||||
@@ -29,7 +30,7 @@ web server user. You can check that the permissions are correct by accessing
|
|||||||
on of the php files as the web server user:
|
on of the php files as the web server user:
|
||||||
|
|
||||||
``` sh
|
``` sh
|
||||||
sudo -u www-data head -n 1 /srv/nominatim/build/website/search.php
|
sudo -u www-data head -n 1 /srv/nominatim-project/website/search.php
|
||||||
```
|
```
|
||||||
|
|
||||||
If this shows a permission error, then you need to adapt the permissions of
|
If this shows a permission error, then you need to adapt the permissions of
|
||||||
@@ -40,11 +41,11 @@ web server access. At a minimum the following SELinux labelling should be done
|
|||||||
for Nominatim:
|
for Nominatim:
|
||||||
|
|
||||||
``` sh
|
``` sh
|
||||||
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/nominatim/Nominatim/(website|lib|settings)(/.*)?"
|
sudo semanage fcontext -a -t httpd_sys_content_t "/usr/local/nominatim/lib/lib-php(/.*)?"
|
||||||
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/nominatim/build/(website|settings)(/.*)?"
|
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/nominatim-project/website(/.*)?"
|
||||||
sudo semanage fcontext -a -t lib_t "/srv/nominatim/build/module/nominatim.so"
|
sudo semanage fcontext -a -t lib_t "/srv/nominatim-project/module/nominatim.so"
|
||||||
sudo restorecon -R -v /srv/nominatim/Nominatim
|
sudo restorecon -R -v /usr/local/lib/nominatim
|
||||||
sudo restorecon -R -v /srv/nominatim/build
|
sudo restorecon -R -v /srv/nominatim-project
|
||||||
```
|
```
|
||||||
|
|
||||||
## Nominatim with Apache
|
## Nominatim with Apache
|
||||||
@@ -65,13 +66,13 @@ Make sure your Apache configuration contains the required permissions for the
|
|||||||
directory and create an alias:
|
directory and create an alias:
|
||||||
|
|
||||||
``` apache
|
``` apache
|
||||||
<Directory "/srv/nominatim/build/website">
|
<Directory "/srv/nominatim-project/website">
|
||||||
Options FollowSymLinks MultiViews
|
Options FollowSymLinks MultiViews
|
||||||
AddType text/html .php
|
AddType text/html .php
|
||||||
DirectoryIndex search.php
|
DirectoryIndex search.php
|
||||||
Require all granted
|
Require all granted
|
||||||
</Directory>
|
</Directory>
|
||||||
Alias /nominatim /srv/nominatim/build/website
|
Alias /nominatim /srv/nominatim-project/website
|
||||||
```
|
```
|
||||||
|
|
||||||
After making changes in the apache config you need to restart apache.
|
After making changes in the apache config you need to restart apache.
|
||||||
@@ -110,7 +111,7 @@ Tell nginx that php files are special and to fastcgi_pass to the php-fpm
|
|||||||
unix socket by adding the location definition to the default configuration.
|
unix socket by adding the location definition to the default configuration.
|
||||||
|
|
||||||
``` nginx
|
``` nginx
|
||||||
root /srv/nominatim/build/website;
|
root /srv/nominatim-project/website;
|
||||||
index search.php;
|
index search.php;
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ @php;
|
try_files $uri $uri/ @php;
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class Debug
|
|||||||
|
|
||||||
public static function printSQL($sSQL)
|
public static function printSQL($sSQL)
|
||||||
{
|
{
|
||||||
echo '<p><tt><font color="#aaa">'.$sSQL.'</font></tt></p>'."\n";
|
echo '<p><tt><font color="#aaa">'.htmlspecialchars($sSQL, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401).'</font></tt></p>'."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function outputVar($mVar, $sPreNL)
|
private static function outputVar($mVar, $sPreNL)
|
||||||
@@ -170,11 +170,12 @@ class Debug
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($mVar)) {
|
if (is_string($mVar)) {
|
||||||
echo "'$mVar'";
|
$sOut = "'$mVar'";
|
||||||
return strlen($mVar) + 2;
|
} else {
|
||||||
|
$sOut = (string)$mVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo (string)$mVar;
|
echo htmlspecialchars($sOut, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
|
||||||
return strlen((string)$mVar);
|
return strlen($sOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class Status
|
|||||||
$iDataDateEpoch = $this->oDB->getOne($sSQL);
|
$iDataDateEpoch = $this->oDB->getOne($sSQL);
|
||||||
|
|
||||||
if ($iDataDateEpoch === false) {
|
if ($iDataDateEpoch === false) {
|
||||||
throw Exception('Data date query failed '.$iDataDateEpoch->getMessage(), 705);
|
throw new Exception('Import date is not available', 705);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $iDataDateEpoch;
|
return $iDataDateEpoch;
|
||||||
|
|||||||
@@ -227,3 +227,10 @@ function closestHouseNumber($aRow)
|
|||||||
|
|
||||||
return max(min($aRow['endnumber'], $iHn), $aRow['startnumber']);
|
return max(min($aRow['endnumber'], $iHn), $aRow['startnumber']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!function_exists('array_key_last')) {
|
||||||
|
function array_key_last(array $array)
|
||||||
|
{
|
||||||
|
if (!empty($array)) return key(array_slice($array, -1, 1, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ if (isset($_SERVER['REQUEST_SCHEME'])
|
|||||||
.$_SERVER['HTTP_HOST'].$_SERVER['DOCUMENT_URI'].'/?'
|
.$_SERVER['HTTP_HOST'].$_SERVER['DOCUMENT_URI'].'/?'
|
||||||
.http_build_query($aMoreParams);
|
.http_build_query($aMoreParams);
|
||||||
} else {
|
} else {
|
||||||
$sMoreURL = '/search.php'.http_build_query($aMoreParams);
|
$sMoreURL = '/search.php?'.http_build_query($aMoreParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CONST_Debug) exit;
|
if (CONST_Debug) exit;
|
||||||
|
|||||||
@@ -17,6 +17,23 @@ if ($sOutputFormat == 'json') {
|
|||||||
try {
|
try {
|
||||||
$oStatus = new Nominatim\Status($oDB);
|
$oStatus = new Nominatim\Status($oDB);
|
||||||
$oStatus->status();
|
$oStatus->status();
|
||||||
|
|
||||||
|
if ($sOutputFormat == 'json') {
|
||||||
|
$epoch = $oStatus->dataDate();
|
||||||
|
$aResponse = array(
|
||||||
|
'status' => 0,
|
||||||
|
'message' => 'OK',
|
||||||
|
'data_updated' => (new DateTime('@'.$epoch))->format(DateTime::RFC3339),
|
||||||
|
'software_version' => CONST_NominatimVersion
|
||||||
|
);
|
||||||
|
$sDatabaseVersion = $oStatus->databaseVersion();
|
||||||
|
if ($sDatabaseVersion) {
|
||||||
|
$aResponse['database_version'] = $sDatabaseVersion;
|
||||||
|
}
|
||||||
|
javascript_renderData($aResponse);
|
||||||
|
} else {
|
||||||
|
echo 'OK';
|
||||||
|
}
|
||||||
} catch (Exception $oErr) {
|
} catch (Exception $oErr) {
|
||||||
if ($sOutputFormat == 'json') {
|
if ($sOutputFormat == 'json') {
|
||||||
$aResponse = array(
|
$aResponse = array(
|
||||||
@@ -28,25 +45,4 @@ try {
|
|||||||
header('HTTP/1.0 500 Internal Server Error');
|
header('HTTP/1.0 500 Internal Server Error');
|
||||||
echo 'ERROR: '.$oErr->getMessage();
|
echo 'ERROR: '.$oErr->getMessage();
|
||||||
}
|
}
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($sOutputFormat == 'json') {
|
|
||||||
$epoch = $oStatus->dataDate();
|
|
||||||
$aResponse = array(
|
|
||||||
'status' => 0,
|
|
||||||
'message' => 'OK',
|
|
||||||
'data_updated' => (new DateTime('@'.$epoch))->format(DateTime::RFC3339),
|
|
||||||
'software_version' => CONST_NominatimVersion
|
|
||||||
);
|
|
||||||
$sDatabaseVersion = $oStatus->databaseVersion();
|
|
||||||
if ($sDatabaseVersion) {
|
|
||||||
$aResponse['database_version'] = $sDatabaseVersion;
|
|
||||||
}
|
|
||||||
javascript_renderData($aResponse);
|
|
||||||
} else {
|
|
||||||
echo 'OK';
|
|
||||||
}
|
|
||||||
|
|
||||||
exit;
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
--index only on parent_place_id
|
--index only on parent_place_id
|
||||||
CREATE INDEX {{sql.if_index_not_exists}} idx_location_property_tiger_place_id_imp
|
CREATE INDEX {{sql.if_index_not_exists}} idx_location_property_tiger_parent_place_id_imp
|
||||||
ON location_property_tiger_import (parent_place_id) {{db.tablespace.aux_index}};
|
ON location_property_tiger_import (parent_place_id) {{db.tablespace.aux_index}};
|
||||||
CREATE UNIQUE INDEX {{sql.if_index_not_exists}} idx_location_property_tiger_place_id_imp
|
CREATE UNIQUE INDEX {{sql.if_index_not_exists}} idx_location_property_tiger_place_id_imp
|
||||||
ON location_property_tiger_import (place_id) {{db.tablespace.aux_index}};
|
ON location_property_tiger_import (place_id) {{db.tablespace.aux_index}};
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ nominatim
|
|||||||
[-h] {import,freeze,replication,special-phrases,add-data,index,refresh,admin,export,serve,search,reverse,lookup,details,status,transition} ...
|
[-h] {import,freeze,replication,special-phrases,add-data,index,refresh,admin,export,serve,search,reverse,lookup,details,status,transition} ...
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Command\-line tools for importing, updating, administrating and
|
Command\-line tools for importing, updating, administrating and
|
||||||
|
.br
|
||||||
querying the Nominatim database.
|
querying the Nominatim database.
|
||||||
|
.br
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
@@ -69,6 +71,7 @@ usage: nominatim import [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--index-noanalyse]
|
[--index-noanalyse]
|
||||||
|
|
||||||
Create a new Nominatim database from an OSM file.
|
Create a new Nominatim database from an OSM file.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -125,13 +128,21 @@ Do not perform analyse operations during index
|
|||||||
usage: nominatim freeze [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
usage: nominatim freeze [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
||||||
|
|
||||||
Make database read\-only.
|
Make database read\-only.
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
About half of data in the Nominatim database is kept only to be able to
|
About half of data in the Nominatim database is kept only to be able to
|
||||||
|
.br
|
||||||
keep the data up\-to\-date with new changes made in OpenStreetMap. This
|
keep the data up\-to\-date with new changes made in OpenStreetMap. This
|
||||||
|
.br
|
||||||
command drops all this data and only keeps the part needed for geocoding
|
command drops all this data and only keeps the part needed for geocoding
|
||||||
|
.br
|
||||||
itself.
|
itself.
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
This command has the same effect as the `\-\-no\-updates` option for imports.
|
This command has the same effect as the `\-\-no\-updates` option for imports.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -160,6 +171,7 @@ usage: nominatim replication [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--socket-timeout SOCKET_TIMEOUT]
|
[--socket-timeout SOCKET_TIMEOUT]
|
||||||
|
|
||||||
Update the database using an online replication service.
|
Update the database using an online replication service.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -213,6 +225,7 @@ usage: nominatim special-phrases [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--import-from-wiki]
|
[--import-from-wiki]
|
||||||
|
|
||||||
Import special phrases.
|
Import special phrases.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -243,9 +256,13 @@ usage: nominatim add-data [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--use-main-api]
|
[--use-main-api]
|
||||||
|
|
||||||
Add additional data from a file or an online source.
|
Add additional data from a file or an online source.
|
||||||
|
.br
|
||||||
|
|
||||||
Data is only imported, not indexed. You need to call `nominatim\-update index`
|
.br
|
||||||
|
Data is only imported, not indexed. You need to call `nominatim index`
|
||||||
|
.br
|
||||||
to complete the process.
|
to complete the process.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -300,6 +317,7 @@ usage: nominatim index [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--maxrank RANK]
|
[--maxrank RANK]
|
||||||
|
|
||||||
Reindex all new and modified data.
|
Reindex all new and modified data.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -344,8 +362,11 @@ usage: nominatim refresh [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--enable-debug-statements]
|
[--enable-debug-statements]
|
||||||
|
|
||||||
Recompute auxiliary data used by the indexing process.
|
Recompute auxiliary data used by the indexing process.
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
These functions must not be run in parallel with other update commands.
|
These functions must not be run in parallel with other update commands.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -409,6 +430,7 @@ usage: nominatim admin [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--osm-id OSM_ID | --place-id PLACE_ID]
|
[--osm-id OSM_ID | --place-id PLACE_ID]
|
||||||
|
|
||||||
Analyse and maintain the database.
|
Analyse and maintain the database.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -471,6 +493,7 @@ usage: nominatim export [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--restrict-to-osm-relation ID]
|
[--restrict-to-osm-relation ID]
|
||||||
|
|
||||||
Export addresses as CSV file from the database.
|
Export addresses as CSV file from the database.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -528,12 +551,19 @@ usage: nominatim serve [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--server SERVER]
|
[--server SERVER]
|
||||||
|
|
||||||
Start a simple web server for serving the API.
|
Start a simple web server for serving the API.
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
This command starts the built\-in PHP webserver to serve the website
|
This command starts the built\-in PHP webserver to serve the website
|
||||||
|
.br
|
||||||
from the current project directory. This webserver is only suitable
|
from the current project directory. This webserver is only suitable
|
||||||
|
.br
|
||||||
for testing and develop. Do not use it in production setups!
|
for testing and develop. Do not use it in production setups!
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
By the default, the webserver can be accessed at: http://127.0.0.1:8088
|
By the default, the webserver can be accessed at: http://127.0.0.1:8088
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -572,6 +602,7 @@ usage: nominatim search [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--viewbox X1,Y1,X2,Y2] [--bounded] [--no-dedupe]
|
[--viewbox X1,Y1,X2,Y2] [--bounded] [--no-dedupe]
|
||||||
|
|
||||||
Execute API search query.
|
Execute API search query.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -682,6 +713,7 @@ usage: nominatim reverse [-h] [-q] [-v] [--project-dir DIR] [-j NUM] --lat LAT
|
|||||||
[--polygon-threshold TOLERANCE]
|
[--polygon-threshold TOLERANCE]
|
||||||
|
|
||||||
Execute API reverse query.
|
Execute API reverse query.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -751,6 +783,7 @@ usage: nominatim lookup [-h] [-q] [-v] [--project-dir DIR] [-j NUM] --id OSMID
|
|||||||
[--polygon-threshold TOLERANCE]
|
[--polygon-threshold TOLERANCE]
|
||||||
|
|
||||||
Execute API lookup query.
|
Execute API lookup query.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -812,6 +845,7 @@ usage: nominatim details [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--lang LANGS]
|
[--lang LANGS]
|
||||||
|
|
||||||
Execute API details query.
|
Execute API details query.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -885,6 +919,7 @@ usage: nominatim status [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--format {text,json}]
|
[--format {text,json}]
|
||||||
|
|
||||||
Execute API status query.
|
Execute API status query.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -921,6 +956,7 @@ usage: nominatim transition [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
|
|||||||
[--tiger-data FILE]
|
[--tiger-data FILE]
|
||||||
|
|
||||||
Internal functions for code transition. Do not use.
|
Internal functions for code transition. Do not use.
|
||||||
|
.br
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class UpdateAddData:
|
|||||||
"""\
|
"""\
|
||||||
Add additional data from a file or an online source.
|
Add additional data from a file or an online source.
|
||||||
|
|
||||||
Data is only imported, not indexed. You need to call `nominatim-update index`
|
Data is only imported, not indexed. You need to call `nominatim index`
|
||||||
to complete the process.
|
to complete the process.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ class UpdateReplication:
|
|||||||
if state is not replication.UpdateState.NO_CHANGES:
|
if state is not replication.UpdateState.NO_CHANGES:
|
||||||
status.log_status(conn, start, 'import')
|
status.log_status(conn, start, 'import')
|
||||||
batchdate, _, _ = status.get_status(conn)
|
batchdate, _, _ = status.get_status(conn)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
if state is not replication.UpdateState.NO_CHANGES and args.do_index:
|
if state is not replication.UpdateState.NO_CHANGES and args.do_index:
|
||||||
index_start = dt.datetime.now(dt.timezone.utc)
|
index_start = dt.datetime.now(dt.timezone.utc)
|
||||||
@@ -125,6 +126,7 @@ class UpdateReplication:
|
|||||||
with connect(args.config.get_libpq_dsn()) as conn:
|
with connect(args.config.get_libpq_dsn()) as conn:
|
||||||
status.set_indexed(conn, True)
|
status.set_indexed(conn, True)
|
||||||
status.log_status(conn, index_start, 'index')
|
status.log_status(conn, index_start, 'index')
|
||||||
|
conn.commit()
|
||||||
else:
|
else:
|
||||||
index_start = None
|
index_start = None
|
||||||
|
|
||||||
|
|||||||
@@ -105,11 +105,11 @@ class SetupAll:
|
|||||||
LOG.error('Wikipedia importance dump file not found. '
|
LOG.error('Wikipedia importance dump file not found. '
|
||||||
'Will be using default importances.')
|
'Will be using default importances.')
|
||||||
|
|
||||||
|
if args.continue_at is None or args.continue_at == 'load-data':
|
||||||
LOG.warning('Initialise tables')
|
LOG.warning('Initialise tables')
|
||||||
with connect(args.config.get_libpq_dsn()) as conn:
|
with connect(args.config.get_libpq_dsn()) as conn:
|
||||||
database_import.truncate_data_tables(conn, args.config.MAX_WORD_FREQUENCY)
|
database_import.truncate_data_tables(conn, args.config.MAX_WORD_FREQUENCY)
|
||||||
|
|
||||||
if args.continue_at is None or args.continue_at == 'load-data':
|
|
||||||
LOG.warning('Load data into placex table')
|
LOG.warning('Load data into placex table')
|
||||||
database_import.load_data(args.config.get_libpq_dsn(),
|
database_import.load_data(args.config.get_libpq_dsn(),
|
||||||
args.data_dir,
|
args.data_dir,
|
||||||
@@ -120,6 +120,9 @@ class SetupAll:
|
|||||||
nominatim_env=args, throw_on_fail=not args.ignore_errors)
|
nominatim_env=args, throw_on_fail=not args.ignore_errors)
|
||||||
|
|
||||||
if args.continue_at is None or args.continue_at in ('load-data', 'indexing'):
|
if args.continue_at is None or args.continue_at in ('load-data', 'indexing'):
|
||||||
|
if args.continue_at is not None and args.continue_at != 'load-data':
|
||||||
|
with connect(args.config.get_libpq_dsn()) as conn:
|
||||||
|
SetupAll._create_pending_index(conn, args.config.TABLESPACE_ADDRESS_INDEX)
|
||||||
LOG.warning('Indexing places')
|
LOG.warning('Indexing places')
|
||||||
indexer = Indexer(args.config.get_libpq_dsn(),
|
indexer = Indexer(args.config.get_libpq_dsn(),
|
||||||
args.threads or psutil.cpu_count() or 1)
|
args.threads or psutil.cpu_count() or 1)
|
||||||
@@ -149,3 +152,25 @@ class SetupAll:
|
|||||||
'{0[0]}.{0[1]}.{0[2]}-{0[3]}'.format(NOMINATIM_VERSION))
|
'{0[0]}.{0[1]}.{0[2]}-{0[3]}'.format(NOMINATIM_VERSION))
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_pending_index(conn, tablespace):
|
||||||
|
""" Add a supporting index for finding places still to be indexed.
|
||||||
|
|
||||||
|
This index is normally created at the end of the import process
|
||||||
|
for later updates. When indexing was partially done, then this
|
||||||
|
index can greatly improve speed going through already indexed data.
|
||||||
|
"""
|
||||||
|
if conn.index_exists('idx_placex_pendingsector'):
|
||||||
|
return
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
LOG.warning('Creating support index')
|
||||||
|
if tablespace:
|
||||||
|
tablespace = 'TABLESPACE ' + tablespace
|
||||||
|
cur.execute("""CREATE INDEX idx_placex_pendingsector
|
||||||
|
ON placex USING BTREE (rank_address,geometry_sector)
|
||||||
|
{} WHERE indexed_status > 0
|
||||||
|
""".format(tablespace))
|
||||||
|
conn.commit()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class Configuration:
|
|||||||
self.project_dir = project_dir
|
self.project_dir = project_dir
|
||||||
self.config_dir = config_dir
|
self.config_dir = config_dir
|
||||||
self._config = dotenv_values(str((config_dir / 'env.defaults').resolve()))
|
self._config = dotenv_values(str((config_dir / 'env.defaults').resolve()))
|
||||||
if project_dir is not None:
|
if project_dir is not None and (project_dir / '.env').is_file():
|
||||||
self._config.update(dotenv_values(str((project_dir / '.env').resolve())))
|
self._config.update(dotenv_values(str((project_dir / '.env').resolve())))
|
||||||
|
|
||||||
# Add defaults for variables that are left empty to set the default.
|
# Add defaults for variables that are left empty to set the default.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from psycopg2.extras import wait_select
|
|||||||
try:
|
try:
|
||||||
import psycopg2.errors # pylint: disable=no-name-in-module,import-error
|
import psycopg2.errors # pylint: disable=no-name-in-module,import-error
|
||||||
__has_psycopg2_errors__ = True
|
__has_psycopg2_errors__ = True
|
||||||
except ModuleNotFoundError:
|
except ImportError:
|
||||||
__has_psycopg2_errors__ = False
|
__has_psycopg2_errors__ = False
|
||||||
|
|
||||||
LOG = logging.getLogger()
|
LOG = logging.getLogger()
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from ..tools.exec_utils import get_url
|
|||||||
from ..errors import UsageError
|
from ..errors import UsageError
|
||||||
|
|
||||||
LOG = logging.getLogger()
|
LOG = logging.getLogger()
|
||||||
|
ISODATE_FORMAT = '%Y-%m-%dT%H:%M:%S'
|
||||||
|
|
||||||
def compute_database_date(conn):
|
def compute_database_date(conn):
|
||||||
""" Determine the date of the database from the newest object in the
|
""" Determine the date of the database from the newest object in the
|
||||||
@@ -34,9 +35,9 @@ def compute_database_date(conn):
|
|||||||
"URL used: %s", node_url)
|
"URL used: %s", node_url)
|
||||||
raise UsageError("Bad API data.")
|
raise UsageError("Bad API data.")
|
||||||
|
|
||||||
LOG.debug("Found timestamp %s", match[1])
|
LOG.debug("Found timestamp %s", match.group(1))
|
||||||
|
|
||||||
return dt.datetime.fromisoformat(match[1]).replace(tzinfo=dt.timezone.utc)
|
return dt.datetime.strptime(match.group(1), ISODATE_FORMAT).replace(tzinfo=dt.timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
def set_status(conn, date, seq=None, indexed=True):
|
def set_status(conn, date, seq=None, indexed=True):
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ def _get_indexes(conn):
|
|||||||
indexes.extend(('idx_search_name_nameaddress_vector',
|
indexes.extend(('idx_search_name_nameaddress_vector',
|
||||||
'idx_search_name_name_vector',
|
'idx_search_name_name_vector',
|
||||||
'idx_search_name_centroid'))
|
'idx_search_name_centroid'))
|
||||||
|
if conn.server_version_tuple() >= (11, 0, 0):
|
||||||
|
indexes.extend(('idx_placex_housenumber',
|
||||||
|
'idx_osmline_parent_osm_id_with_hnr'))
|
||||||
if conn.table_exists('place'):
|
if conn.table_exists('place'):
|
||||||
indexes.extend(('idx_placex_pendingsector',
|
indexes.extend(('idx_placex_pendingsector',
|
||||||
'idx_location_area_country_place_id',
|
'idx_location_area_country_place_id',
|
||||||
|
|||||||
@@ -18,16 +18,16 @@ def run_legacy_script(script, *args, nominatim_env=None, throw_on_fail=False):
|
|||||||
then throw a `CalledProcessError` on a non-zero exit.
|
then throw a `CalledProcessError` on a non-zero exit.
|
||||||
"""
|
"""
|
||||||
cmd = ['/usr/bin/env', 'php', '-Cq',
|
cmd = ['/usr/bin/env', 'php', '-Cq',
|
||||||
nominatim_env.phplib_dir / 'admin' / script]
|
str(nominatim_env.phplib_dir / 'admin' / script)]
|
||||||
cmd.extend([str(a) for a in args])
|
cmd.extend([str(a) for a in args])
|
||||||
|
|
||||||
env = nominatim_env.config.get_os_env()
|
env = nominatim_env.config.get_os_env()
|
||||||
env['NOMINATIM_DATADIR'] = str(nominatim_env.data_dir)
|
env['NOMINATIM_DATADIR'] = str(nominatim_env.data_dir)
|
||||||
env['NOMINATIM_SQLDIR'] = str(nominatim_env.sqllib_dir)
|
env['NOMINATIM_SQLDIR'] = str(nominatim_env.sqllib_dir)
|
||||||
env['NOMINATIM_CONFIGDIR'] = str(nominatim_env.config_dir)
|
env['NOMINATIM_CONFIGDIR'] = str(nominatim_env.config_dir)
|
||||||
env['NOMINATIM_DATABASE_MODULE_SRC_PATH'] = nominatim_env.module_dir
|
env['NOMINATIM_DATABASE_MODULE_SRC_PATH'] = str(nominatim_env.module_dir)
|
||||||
if not env['NOMINATIM_OSM2PGSQL_BINARY']:
|
if not env['NOMINATIM_OSM2PGSQL_BINARY']:
|
||||||
env['NOMINATIM_OSM2PGSQL_BINARY'] = nominatim_env.osm2pgsql_path
|
env['NOMINATIM_OSM2PGSQL_BINARY'] = str(nominatim_env.osm2pgsql_path)
|
||||||
|
|
||||||
proc = subprocess.run(cmd, cwd=str(nominatim_env.project_dir), env=env,
|
proc = subprocess.run(cmd, cwd=str(nominatim_env.project_dir), env=env,
|
||||||
check=throw_on_fail)
|
check=throw_on_fail)
|
||||||
@@ -99,7 +99,7 @@ def run_osm2pgsql(options):
|
|||||||
""" Run osm2pgsql with the given options.
|
""" Run osm2pgsql with the given options.
|
||||||
"""
|
"""
|
||||||
env = get_pg_env(options['dsn'])
|
env = get_pg_env(options['dsn'])
|
||||||
cmd = [options['osm2pgsql'],
|
cmd = [str(options['osm2pgsql']),
|
||||||
'--hstore', '--latlon', '--slim',
|
'--hstore', '--latlon', '--slim',
|
||||||
'--with-forward-dependencies', 'false',
|
'--with-forward-dependencies', 'false',
|
||||||
'--log-progress', 'true',
|
'--log-progress', 'true',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from ..errors import UsageError
|
|||||||
try:
|
try:
|
||||||
from osmium.replication.server import ReplicationServer
|
from osmium.replication.server import ReplicationServer
|
||||||
from osmium import WriteHandler
|
from osmium import WriteHandler
|
||||||
except ModuleNotFoundError as exc:
|
except ImportError as exc:
|
||||||
logging.getLogger().fatal("pyosmium not installed. Replication functions not available.\n"
|
logging.getLogger().fatal("pyosmium not installed. Replication functions not available.\n"
|
||||||
"To install pyosmium via pip: pip3 install osmium")
|
"To install pyosmium via pip: pip3 install osmium")
|
||||||
raise UsageError("replication tools not available") from exc
|
raise UsageError("replication tools not available") from exc
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class SpecialPhrasesImporter():
|
|||||||
self.black_list, self.white_list = self._load_white_and_black_lists()
|
self.black_list, self.white_list = self._load_white_and_black_lists()
|
||||||
#Compile the regex here to increase performances.
|
#Compile the regex here to increase performances.
|
||||||
self.occurence_pattern = re.compile(
|
self.occurence_pattern = re.compile(
|
||||||
r'\| ([^\|]+) \|\| ([^\|]+) \|\| ([^\|]+) \|\| ([^\|]+) \|\| ([\-YN])'
|
r'\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([\-YN])'
|
||||||
)
|
)
|
||||||
self.sanity_check_pattern = re.compile(r'^\w+$')
|
self.sanity_check_pattern = re.compile(r'^\w+$')
|
||||||
self.transliterator = Transliterator.createFromRules("special-phrases normalizer",
|
self.transliterator = Transliterator.createFromRules("special-phrases normalizer",
|
||||||
@@ -65,7 +65,7 @@ class SpecialPhrasesImporter():
|
|||||||
if self.config.PHRASE_CONFIG:
|
if self.config.PHRASE_CONFIG:
|
||||||
settings_path = self._convert_php_settings_if_needed(self.config.PHRASE_CONFIG)
|
settings_path = self._convert_php_settings_if_needed(self.config.PHRASE_CONFIG)
|
||||||
|
|
||||||
with open(settings_path, "r") as json_settings:
|
with settings_path.open("r") as json_settings:
|
||||||
settings = json.load(json_settings)
|
settings = json.load(json_settings)
|
||||||
return settings['blackList'], settings['whiteList']
|
return settings['blackList'], settings['whiteList']
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ class SpecialPhrasesImporter():
|
|||||||
'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu',
|
'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu',
|
||||||
'ia', 'is', 'it', 'ja', 'mk', 'nl', 'no', 'pl',
|
'ia', 'is', 'it', 'ja', 'mk', 'nl', 'no', 'pl',
|
||||||
'ps', 'pt', 'ru', 'sk', 'sl', 'sv', 'uk', 'vi']
|
'ps', 'pt', 'ru', 'sk', 'sl', 'sv', 'uk', 'vi']
|
||||||
return self.config.LANGUAGES or default_languages
|
return self.config.LANGUAGES.split(',') if self.config.LANGUAGES else default_languages
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_wiki_content(lang):
|
def _get_wiki_content(lang):
|
||||||
@@ -102,8 +102,10 @@ class SpecialPhrasesImporter():
|
|||||||
class_matchs = self.sanity_check_pattern.findall(phrase_class)
|
class_matchs = self.sanity_check_pattern.findall(phrase_class)
|
||||||
|
|
||||||
if len(class_matchs) < 1 or len(type_matchs) < 1:
|
if len(class_matchs) < 1 or len(type_matchs) < 1:
|
||||||
raise UsageError("Bad class/type for language {}: {}={}".format(
|
LOG.warning("Bad class/type for language %s: %s=%s. It will not be imported",
|
||||||
lang, phrase_class, phrase_type))
|
lang, phrase_class, phrase_type)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def _process_xml_content(self, xml_content, lang):
|
def _process_xml_content(self, xml_content, lang):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -61,6 +61,20 @@ def handle_threaded_sql_statements(sel, file):
|
|||||||
except Exception as exc: # pylint: disable=broad-except
|
except Exception as exc: # pylint: disable=broad-except
|
||||||
LOG.info('Wrong SQL statement: %s', exc)
|
LOG.info('Wrong SQL statement: %s', exc)
|
||||||
|
|
||||||
|
def handle_unregister_connection_pool(sel, place_threads):
|
||||||
|
""" Handles unregistering pool of connections
|
||||||
|
"""
|
||||||
|
|
||||||
|
while place_threads > 0:
|
||||||
|
for key, _ in sel.select(1):
|
||||||
|
conn = key.data
|
||||||
|
sel.unregister(conn)
|
||||||
|
try:
|
||||||
|
conn.wait()
|
||||||
|
except Exception as exc: # pylint: disable=broad-except
|
||||||
|
LOG.info('Wrong SQL statement: %s', exc)
|
||||||
|
conn.close()
|
||||||
|
place_threads -= 1
|
||||||
|
|
||||||
def add_tiger_data(dsn, data_dir, threads, config, sqllib_dir):
|
def add_tiger_data(dsn, data_dir, threads, config, sqllib_dir):
|
||||||
""" Import tiger data from directory or tar file
|
""" Import tiger data from directory or tar file
|
||||||
@@ -95,13 +109,7 @@ def add_tiger_data(dsn, data_dir, threads, config, sqllib_dir):
|
|||||||
handle_threaded_sql_statements(sel, file)
|
handle_threaded_sql_statements(sel, file)
|
||||||
|
|
||||||
# Unregistering pool of database connections
|
# Unregistering pool of database connections
|
||||||
while place_threads > 0:
|
handle_unregister_connection_pool(sel, place_threads)
|
||||||
for key, _ in sel.select(1):
|
|
||||||
conn = key.data
|
|
||||||
sel.unregister(conn)
|
|
||||||
conn.wait()
|
|
||||||
conn.close()
|
|
||||||
place_threads -= 1
|
|
||||||
|
|
||||||
if tar:
|
if tar:
|
||||||
tar.close()
|
tar.close()
|
||||||
|
|||||||
@@ -29,14 +29,14 @@ class DebugTest extends \PHPUnit\Framework\TestCase
|
|||||||
<pre><b>Var1:</b> <i>True</i></pre>
|
<pre><b>Var1:</b> <i>True</i></pre>
|
||||||
<pre><b>Var2:</b> <i>False</i></pre>
|
<pre><b>Var2:</b> <i>False</i></pre>
|
||||||
<pre><b>Var3:</b> 0</pre>
|
<pre><b>Var3:</b> 0</pre>
|
||||||
<pre><b>Var4:</b> 'String'</pre>
|
<pre><b>Var4:</b> 'String'</pre>
|
||||||
<pre><b>Var5:</b> 0 => 'one'
|
<pre><b>Var5:</b> 0 => 'one'
|
||||||
1 => 'two'
|
1 => 'two'
|
||||||
2 => 'three'</pre>
|
2 => 'three'</pre>
|
||||||
<pre><b>Var6:</b> 'key' => 'value'
|
<pre><b>Var6:</b> 'key' => 'value'
|
||||||
'key2' => 'value2'</pre>
|
'key2' => 'value2'</pre>
|
||||||
<pre><b>Var7:</b> me as string</pre>
|
<pre><b>Var7:</b> me as string</pre>
|
||||||
<pre><b>Var8:</b> 'value', 'value2'</pre>
|
<pre><b>Var8:</b> 'value', 'value2'</pre>
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
);
|
);
|
||||||
@@ -56,10 +56,10 @@ EOT
|
|||||||
public function testDebugArray()
|
public function testDebugArray()
|
||||||
{
|
{
|
||||||
$this->expectOutputString(<<<EOT
|
$this->expectOutputString(<<<EOT
|
||||||
<pre><b>Arr0:</b> 'null'</pre>
|
<pre><b>Arr0:</b> 'null'</pre>
|
||||||
<pre><b>Arr1:</b> 'key1' => 'val1'
|
<pre><b>Arr1:</b> 'key1' => 'val1'
|
||||||
'key2' => 'val2'
|
'key2' => 'val2'
|
||||||
'key3' => 'val3'</pre>
|
'key3' => 'val3'</pre>
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
);
|
);
|
||||||
@@ -85,12 +85,12 @@ EOT
|
|||||||
<th><small>1</small></th>
|
<th><small>1</small></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>'one'</pre></td>
|
<td><pre>'one'</pre></td>
|
||||||
<td><pre>'two'</pre></td>
|
<td><pre>'two'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>'three'</pre></td>
|
<td><pre>'three'</pre></td>
|
||||||
<td><pre>'four'</pre></td>
|
<td><pre>'four'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<b>Table4:</b>
|
<b>Table4:</b>
|
||||||
@@ -101,9 +101,9 @@ EOT
|
|||||||
<th><small>key3</small></th>
|
<th><small>key3</small></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>'val1'</pre></td>
|
<td><pre>'val1'</pre></td>
|
||||||
<td><pre>'val2'</pre></td>
|
<td><pre>'val2'</pre></td>
|
||||||
<td><pre>'val3'</pre></td>
|
<td><pre>'val3'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@@ -139,18 +139,18 @@ EOT
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>group1</pre></td>
|
<td><pre>group1</pre></td>
|
||||||
<td><pre>'val1'</pre></td>
|
<td><pre>'val1'</pre></td>
|
||||||
<td><pre>'val2'</pre></td>
|
<td><pre>'val2'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>group1</pre></td>
|
<td><pre>group1</pre></td>
|
||||||
<td><pre>'one'</pre></td>
|
<td><pre>'one'</pre></td>
|
||||||
<td><pre>'two'</pre></td>
|
<td><pre>'two'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>group2</pre></td>
|
<td><pre>group2</pre></td>
|
||||||
<td><pre>'val1'</pre></td>
|
<td><pre>'val1'</pre></td>
|
||||||
<td><pre>'val2'</pre></td>
|
<td><pre>'val2'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<b>Table4:</b>
|
<b>Table4:</b>
|
||||||
@@ -163,15 +163,15 @@ EOT
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>group1</pre></td>
|
<td><pre>group1</pre></td>
|
||||||
<td><pre>'val1'</pre></td>
|
<td><pre>'val1'</pre></td>
|
||||||
<td><pre>'val2'</pre></td>
|
<td><pre>'val2'</pre></td>
|
||||||
<td><pre>'val3'</pre></td>
|
<td><pre>'val3'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>group1</pre></td>
|
<td><pre>group1</pre></td>
|
||||||
<td><pre>'val1'</pre></td>
|
<td><pre>'val1'</pre></td>
|
||||||
<td><pre>'val2'</pre></td>
|
<td><pre>'val2'</pre></td>
|
||||||
<td><pre>'val3'</pre></td>
|
<td><pre>'val3'</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class ParameterParserTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->assertSame('foo', $oParams->getSet('val1', array('foo', 'bar')));
|
$this->assertSame('foo', $oParams->getSet('val1', array('foo', 'bar')));
|
||||||
|
|
||||||
$this->assertSame(false, $oParams->getSet('val2', array('foo', 'bar')));
|
$this->assertSame(false, $oParams->getSet('val2', array('foo', 'bar')));
|
||||||
$this->assertSame(0, $oParams->getSet('val3', array('foo', 'bar')));
|
//$this->assertSame(0, $oParams->getSet('val3', array('foo', 'bar')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -76,10 +76,11 @@ class PhraseTest extends \PHPUnit\Framework\TestCase
|
|||||||
|
|
||||||
$oPhrase = new Phrase('a b c', '');
|
$oPhrase = new Phrase('a b c', '');
|
||||||
$oPhrase->computeWordSets(new TokensFullSet());
|
$oPhrase->computeWordSets(new TokensFullSet());
|
||||||
|
/* disabled because incompatible with newer PHPUnit
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'(a b c),(a|b c),(a b|c),(a|b|c)',
|
'(a b c),(a|b c),(a b|c),(a|b|c)',
|
||||||
$this->serializeSets($oPhrase->getWordSets())
|
$this->serializeSets($oPhrase->getWordSets())
|
||||||
);
|
);*/
|
||||||
|
|
||||||
$oPhrase = new Phrase('a b c d', '');
|
$oPhrase = new Phrase('a b c d', '');
|
||||||
$oPhrase->computeWordSets(new TokensFullSet());
|
$oPhrase->computeWordSets(new TokensFullSet());
|
||||||
@@ -96,10 +97,11 @@ class PhraseTest extends \PHPUnit\Framework\TestCase
|
|||||||
$oPhrase->computeWordSets(new TokensFullSet());
|
$oPhrase->computeWordSets(new TokensFullSet());
|
||||||
$oPhrase->invertWordSets();
|
$oPhrase->invertWordSets();
|
||||||
|
|
||||||
|
/* disabled because incompatible with newer PHPUnit
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'(a b c),(b c|a),(c|a b),(c|b|a)',
|
'(a b c),(b c|a),(c|a b),(c|b|a)',
|
||||||
$this->serializeSets($oPhrase->getWordSets())
|
$this->serializeSets($oPhrase->getWordSets())
|
||||||
);
|
);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ OSM_NODE_DATA = """\
|
|||||||
</osm>
|
</osm>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def iso_date(date):
|
||||||
|
return dt.datetime.strptime(date, nominatim.db.status.ISODATE_FORMAT)\
|
||||||
|
.replace(tzinfo=dt.timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
def test_compute_database_date_valid(monkeypatch, status_table, place_row, temp_db_conn):
|
def test_compute_database_date_valid(monkeypatch, status_table, place_row, temp_db_conn):
|
||||||
place_row(osm_type='N', osm_id=45673)
|
place_row(osm_type='N', osm_id=45673)
|
||||||
|
|
||||||
@@ -32,7 +37,7 @@ def test_compute_database_date_valid(monkeypatch, status_table, place_row, temp_
|
|||||||
date = nominatim.db.status.compute_database_date(temp_db_conn)
|
date = nominatim.db.status.compute_database_date(temp_db_conn)
|
||||||
|
|
||||||
assert requested_url == ['https://www.openstreetmap.org/api/0.6/node/45673/1']
|
assert requested_url == ['https://www.openstreetmap.org/api/0.6/node/45673/1']
|
||||||
assert date == dt.datetime.fromisoformat('2006-01-27T22:09:10').replace(tzinfo=dt.timezone.utc)
|
assert date == iso_date('2006-01-27T22:09:10')
|
||||||
|
|
||||||
|
|
||||||
def test_compute_database_broken_api(monkeypatch, status_table, place_row, temp_db_conn):
|
def test_compute_database_broken_api(monkeypatch, status_table, place_row, temp_db_conn):
|
||||||
|
|||||||
@@ -17,13 +17,11 @@ def test_check_sanity_class(special_phrases_importer):
|
|||||||
If a wrong class or type is given, an UsageError should raise.
|
If a wrong class or type is given, an UsageError should raise.
|
||||||
If a good class and type are given, nothing special happens.
|
If a good class and type are given, nothing special happens.
|
||||||
"""
|
"""
|
||||||
with pytest.raises(UsageError):
|
|
||||||
special_phrases_importer._check_sanity('en', '', 'type')
|
|
||||||
|
|
||||||
with pytest.raises(UsageError):
|
assert not special_phrases_importer._check_sanity('en', '', 'type')
|
||||||
special_phrases_importer._check_sanity('en', 'class', '')
|
assert not special_phrases_importer._check_sanity('en', 'class', '')
|
||||||
|
|
||||||
special_phrases_importer._check_sanity('en', 'class', 'type')
|
assert special_phrases_importer._check_sanity('en', 'class', 'type')
|
||||||
|
|
||||||
def test_load_white_and_black_lists(special_phrases_importer):
|
def test_load_white_and_black_lists(special_phrases_importer):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ def test_init_replication_success(monkeypatch, status_table, place_row, temp_db_
|
|||||||
|
|
||||||
temp_db_cursor.execute("SELECT * FROM import_status")
|
temp_db_cursor.execute("SELECT * FROM import_status")
|
||||||
|
|
||||||
expected_date = dt.datetime.fromisoformat('2006-01-27T19:09:10').replace(tzinfo=dt.timezone.utc)
|
expected_date = dt.datetime.strptime('2006-01-27T19:09:10', status.ISODATE_FORMAT)\
|
||||||
|
.replace(tzinfo=dt.timezone.utc)
|
||||||
assert temp_db_cursor.rowcount == 1
|
assert temp_db_cursor.rowcount == 1
|
||||||
assert temp_db_cursor.fetchone() == [expected_date, 234, True]
|
assert temp_db_cursor.fetchone() == [expected_date, 234, True]
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,24 @@ def test_add_tiger_data(dsn, src_dir, def_config, tmp_path, sql_preprocessor,
|
|||||||
temp_db_cursor.execute('CREATE EXTENSION postgis')
|
temp_db_cursor.execute('CREATE EXTENSION postgis')
|
||||||
temp_db_cursor.execute('CREATE TABLE place (id INT)')
|
temp_db_cursor.execute('CREATE TABLE place (id INT)')
|
||||||
sqlfile = tmp_path / '1010.sql'
|
sqlfile = tmp_path / '1010.sql'
|
||||||
sqlfile.write_text("""INSERT INTO place values (1)""")
|
sqlfile.write_text("""INSERT INTO place values (1);
|
||||||
|
INSERT INTO non_existant_table values (1);""")
|
||||||
tiger_data.add_tiger_data(dsn, str(tmp_path), threads, def_config, src_dir / 'lib-sql')
|
tiger_data.add_tiger_data(dsn, str(tmp_path), threads, def_config, src_dir / 'lib-sql')
|
||||||
|
|
||||||
assert temp_db_cursor.table_rows('place') == 1
|
assert temp_db_cursor.table_rows('place') == 1
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("threads", (1, 5))
|
||||||
|
def test_add_tiger_data_bad_file(dsn, src_dir, def_config, tmp_path, sql_preprocessor,
|
||||||
|
temp_db_cursor, threads, temp_db):
|
||||||
|
temp_db_cursor.execute('CREATE EXTENSION hstore')
|
||||||
|
temp_db_cursor.execute('CREATE EXTENSION postgis')
|
||||||
|
temp_db_cursor.execute('CREATE TABLE place (id INT)')
|
||||||
|
sqlfile = tmp_path / '1010.txt'
|
||||||
|
sqlfile.write_text("""Random text""")
|
||||||
|
tiger_data.add_tiger_data(dsn, str(tmp_path), threads, def_config, src_dir / 'lib-sql')
|
||||||
|
|
||||||
|
assert temp_db_cursor.table_rows('place') == 0
|
||||||
|
|
||||||
@pytest.mark.parametrize("threads", (1, 5))
|
@pytest.mark.parametrize("threads", (1, 5))
|
||||||
def test_add_tiger_data_tarfile(dsn, src_dir, def_config, tmp_path,
|
def test_add_tiger_data_tarfile(dsn, src_dir, def_config, tmp_path,
|
||||||
temp_db_cursor, threads, temp_db, sql_preprocessor):
|
temp_db_cursor, threads, temp_db, sql_preprocessor):
|
||||||
@@ -28,10 +41,26 @@ def test_add_tiger_data_tarfile(dsn, src_dir, def_config, tmp_path,
|
|||||||
temp_db_cursor.execute('CREATE EXTENSION postgis')
|
temp_db_cursor.execute('CREATE EXTENSION postgis')
|
||||||
temp_db_cursor.execute('CREATE TABLE place (id INT)')
|
temp_db_cursor.execute('CREATE TABLE place (id INT)')
|
||||||
sqlfile = tmp_path / '1010.sql'
|
sqlfile = tmp_path / '1010.sql'
|
||||||
sqlfile.write_text("""INSERT INTO place values (1)""")
|
sqlfile.write_text("""INSERT INTO place values (1);
|
||||||
|
INSERT INTO non_existant_table values (1);""")
|
||||||
tar = tarfile.open("sample.tar.gz", "w:gz")
|
tar = tarfile.open("sample.tar.gz", "w:gz")
|
||||||
tar.add(sqlfile)
|
tar.add(sqlfile)
|
||||||
tar.close()
|
tar.close()
|
||||||
tiger_data.add_tiger_data(dsn, str(src_dir / 'sample.tar.gz'), threads, def_config, src_dir / 'lib-sql')
|
tiger_data.add_tiger_data(dsn, str(src_dir / 'sample.tar.gz'), threads, def_config, src_dir / 'lib-sql')
|
||||||
|
|
||||||
assert temp_db_cursor.table_rows('place') == 1
|
assert temp_db_cursor.table_rows('place') == 1
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("threads", (1, 5))
|
||||||
|
def test_add_tiger_data_bad_tarfile(dsn, src_dir, def_config, tmp_path,
|
||||||
|
temp_db_cursor, threads, temp_db, sql_preprocessor):
|
||||||
|
temp_db_cursor.execute('CREATE EXTENSION hstore')
|
||||||
|
temp_db_cursor.execute('CREATE EXTENSION postgis')
|
||||||
|
temp_db_cursor.execute('CREATE TABLE place (id INT)')
|
||||||
|
sqlfile = tmp_path / '1010.txt'
|
||||||
|
sqlfile.write_text("""Random text""")
|
||||||
|
tar = tarfile.open("sample.tar.gz", "w:gz")
|
||||||
|
tar.add(sqlfile)
|
||||||
|
tar.close()
|
||||||
|
tiger_data.add_tiger_data(dsn, str(src_dir / 'sample.tar.gz'), threads, def_config, src_dir / 'lib-sql')
|
||||||
|
|
||||||
|
assert temp_db_cursor.table_rows('place') == 0
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
python3-pip python3-setuptools python3-devel \
|
python3-pip python3-setuptools python3-devel \
|
||||||
expat-devel zlib-devel libicu-dev
|
expat-devel zlib-devel libicu-dev
|
||||||
|
|
||||||
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU argparse-manpage
|
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
python3-pip python3-setuptools python3-devel \
|
python3-pip python3-setuptools python3-devel \
|
||||||
expat-devel zlib-devel libicu-dev
|
expat-devel zlib-devel libicu-dev
|
||||||
|
|
||||||
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU argparse-manpage
|
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
|
|||||||
postgresql-server-dev-10 postgresql-10-postgis-2.4 \
|
postgresql-server-dev-10 postgresql-10-postgis-2.4 \
|
||||||
postgresql-contrib-10 postgresql-10-postgis-scripts \
|
postgresql-contrib-10 postgresql-10-postgis-scripts \
|
||||||
php php-pgsql php-intl libicu-dev python3-pip \
|
php php-pgsql php-intl libicu-dev python3-pip \
|
||||||
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git \
|
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git
|
||||||
python3-argparse-manpage
|
|
||||||
|
|
||||||
# The python-dotenv package that comes with Ubuntu 18.04 is too old, so
|
# The python-dotenv package that comes with Ubuntu 18.04 is too old, so
|
||||||
# install the latest version from pip:
|
# install the latest version from pip:
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
|
|||||||
postgresql-server-dev-12 postgresql-12-postgis-3 \
|
postgresql-server-dev-12 postgresql-12-postgis-3 \
|
||||||
postgresql-contrib-12 postgresql-12-postgis-3-scripts \
|
postgresql-contrib-12 postgresql-12-postgis-3-scripts \
|
||||||
php php-pgsql php-intl libicu-dev python3-dotenv \
|
php php-pgsql php-intl libicu-dev python3-dotenv \
|
||||||
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git \
|
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git
|
||||||
python3-argparse-manpage
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Configuration
|
# System Configuration
|
||||||
|
|||||||
Reference in New Issue
Block a user