mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-16 15:47:58 +00:00
Compare commits
1 Commits
v3.3.0
...
add-logend
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e7ea9662e |
@@ -11,8 +11,6 @@ git:
|
|||||||
env:
|
env:
|
||||||
- TEST_SUITE=tests
|
- TEST_SUITE=tests
|
||||||
- TEST_SUITE=monaco
|
- TEST_SUITE=monaco
|
||||||
before_install:
|
|
||||||
- phpenv global 7.1
|
|
||||||
install:
|
install:
|
||||||
- vagrant/install-on-travis-ci.sh
|
- vagrant/install-on-travis-ci.sh
|
||||||
before_script:
|
before_script:
|
||||||
@@ -21,7 +19,7 @@ script:
|
|||||||
- cd $TRAVIS_BUILD_DIR/
|
- cd $TRAVIS_BUILD_DIR/
|
||||||
- if [[ $TEST_SUITE == "tests" ]]; then phpcs --report-width=120 . ; fi
|
- if [[ $TEST_SUITE == "tests" ]]; then phpcs --report-width=120 . ; fi
|
||||||
- cd $TRAVIS_BUILD_DIR/test/php
|
- cd $TRAVIS_BUILD_DIR/test/php
|
||||||
- if [[ $TEST_SUITE == "tests" ]]; then /usr/bin/phpunit ./ ; fi
|
- if [[ $TEST_SUITE == "tests" ]]; then phpunit ./ ; fi
|
||||||
- cd $TRAVIS_BUILD_DIR/test/bdd
|
- cd $TRAVIS_BUILD_DIR/test/bdd
|
||||||
- # behave --format=progress3 api
|
- # behave --format=progress3 api
|
||||||
- if [[ $TEST_SUITE == "tests" ]]; then behave -DREMOVE_TEMPLATE=1 --format=progress3 db ; fi
|
- if [[ $TEST_SUITE == "tests" ]]; then behave -DREMOVE_TEMPLATE=1 --format=progress3 db ; fi
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
|||||||
project(nominatim)
|
project(nominatim)
|
||||||
|
|
||||||
set(NOMINATIM_VERSION_MAJOR 3)
|
set(NOMINATIM_VERSION_MAJOR 3)
|
||||||
set(NOMINATIM_VERSION_MINOR 3)
|
set(NOMINATIM_VERSION_MINOR 2)
|
||||||
set(NOMINATIM_VERSION_PATCH 0)
|
set(NOMINATIM_VERSION_PATCH 0)
|
||||||
|
|
||||||
set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
|
set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
|
||||||
|
|||||||
24
ChangeLog
24
ChangeLog
@@ -1,27 +1,3 @@
|
|||||||
3.3.0
|
|
||||||
|
|
||||||
* zoom 17 in reverse now zooms in on minor streets
|
|
||||||
* fix use of postcode relations in address
|
|
||||||
* support for housenumber 0 on interpolations
|
|
||||||
* replace database abstraction DB with PDO and switch to using exceptions
|
|
||||||
* exclude line features at rank 30 from reverse geocoding
|
|
||||||
* remove self-reference and country from place_addressline
|
|
||||||
* make json output more readable (less escaping)
|
|
||||||
* update conversion scripts for postcodes
|
|
||||||
* scripts in utils/ are no longer executable (always use scripts in build dir)
|
|
||||||
* remove Natural Earth country fallback (OSM is complete enough)
|
|
||||||
* make rank assignments configurable
|
|
||||||
* allow accept languages with underscore
|
|
||||||
* new reverse-only import mode (without search index table)
|
|
||||||
* rely on boundaries only for states and countries
|
|
||||||
* update osm2pgsql, now using a configurable style
|
|
||||||
* provide multiple import styles
|
|
||||||
* improve search when house number and postcodes are dropped
|
|
||||||
* overhaul of setup code
|
|
||||||
* add support for PHPUnit 6
|
|
||||||
* update test database
|
|
||||||
* various documentation improvements
|
|
||||||
|
|
||||||
3.2.0
|
3.2.0
|
||||||
|
|
||||||
* complete rewrite of reverse search algorithm
|
* complete rewrite of reverse search algorithm
|
||||||
|
|||||||
@@ -59,5 +59,5 @@ Both bug reports and pull requests are welcome.
|
|||||||
Mailing list
|
Mailing list
|
||||||
============
|
============
|
||||||
|
|
||||||
For questions you can join the geocoding mailing list, see
|
For questions you can join the geocoding mailinglist, see
|
||||||
https://lists.openstreetmap.org/listinfo/geocoding
|
https://lists.openstreetmap.org/listinfo/geocoding
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ If the Postgres installation is behind a firewall, you can try
|
|||||||
inside the virtual machine. It will map the port to `localhost:9999` and then
|
inside the virtual machine. It will map the port to `localhost:9999` and then
|
||||||
you edit `settings/local.php` with
|
you edit `settings/local.php` with
|
||||||
|
|
||||||
@define('CONST_Database_DSN', 'pgsql:host=localhost;port=9999;user=postgres;dbname=nominatim_it');
|
@define('CONST_Database_DSN', 'pgsql://postgres@localhost:9999/nominatim_it');
|
||||||
|
|
||||||
To access postgres directly remember to specify the hostname, e.g. `psql --host localhost --port 9999 nominatim_it`
|
To access postgres directly remember to specify the hostname, e.g. `psql --host localhost --port 9999 nominatim_it`
|
||||||
|
|
||||||
|
|||||||
@@ -25,32 +25,41 @@ If you forgot to download the file, or have a new version, you can import it sep
|
|||||||
|
|
||||||
2. `unzip codepo_gb.zip`
|
2. `unzip codepo_gb.zip`
|
||||||
|
|
||||||
Unpacked you'll see a directory of CSV files.
|
Unpacked you'll see a directory of CSV files.
|
||||||
|
|
||||||
$ more codepo_gb/Data/CSV/n.csv
|
```
|
||||||
"N1 0AA",10,530626,183961,"E92000001","E19000003","E18000007","","E09000019","E05000368"
|
$ more codepo_gb/Data/CSV/n.csv
|
||||||
"N1 0AB",10,530559,183978,"E92000001","E19000003","E18000007","","E09000019","E05000368"
|
"N1 0AA",10,530626,183961,"E92000001","E19000003","E18000007","","E09000019","E05000368"
|
||||||
|
"N1 0AB",10,530559,183978,"E92000001","E19000003","E18000007","","E09000019","E05000368"
|
||||||
|
```
|
||||||
|
|
||||||
The coordinates are "Northings" and "Eastings" in [OSGB 1936](http://epsg.io/1314) projection. They can be projected to WGS84 like this
|
The coordinates are "Northings" and "Eastings" in [OSGB 1936](http://epsg.io/1314) projection. They can be projected to WGS84 like this
|
||||||
|
|
||||||
SELECT ST_AsText(ST_Transform(ST_SetSRID('POINT(530626 183961)'::geometry,27700), 4326));
|
```
|
||||||
POINT(-0.117872733220225 51.5394424719303)
|
SELECT ST_AsText(ST_Transform(ST_SetSRID('POINT(530626 183961)'::geometry,27700), 4326));
|
||||||
|
POINT(-0.117872733220225 51.5394424719303)
|
||||||
[-0.117872733220225 51.5394424719303 on OSM map](https://www.openstreetmap.org/?mlon=-0.117872733220225&mlat=51.5394424719303&zoom=16)
|
```
|
||||||
|
[-0.117872733220225 51.5394424719303 on OSM map](https://www.openstreetmap.org/?mlon=-0.117872733220225&mlat=51.5394424719303&zoom=16)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3. Create database, import CSV files, add geometry column, dump into file
|
3. Create database, import CSV files, add geometry column, dump into file
|
||||||
|
|
||||||
DBNAME=create_gb_postcode_file
|
```
|
||||||
createdb $DBNAME
|
DBNAME=create_gb_postcode_file
|
||||||
echo 'CREATE EXTENSION postgis' | psql $DBNAME
|
|
||||||
|
createdb $DBNAME
|
||||||
cat data/gb_postcode_table.sql | psql $DBNAME
|
echo 'CREATE EXTENSION postgis' | psql $DBNAME
|
||||||
cat codepo_gb/Data/CSV/*.csv | ./data-sources/gb-postcodes/convert_codepoint.php | psql $DBNAME
|
|
||||||
cat codepo_gb/Doc/licence.txt | iconv -f iso-8859-1 -t utf-8 | dos2unix | sed 's/^/-- /g' > gb_postcode_data.sql
|
cat data/gb_postcode_table.sql | psql $DBNAME
|
||||||
pg_dump -a -t gb_postcode $DBNAME | grep -v '^--' >> gb_postcode_data.sql
|
|
||||||
|
cat codepo_gb/Data/CSV/*.csv | ./data-sources/gb-postcodes/convert_codepoint.php | psql $DBNAME
|
||||||
gzip -9 -f gb_postcode_data.sql
|
|
||||||
ls -lah gb_postcode_data.*
|
cat codepo_gb/Doc/licence.txt | iconv -f iso-8859-1 -t utf-8 | dos2unix | sed 's/^/-- /g' > gb_postcode_data.sql
|
||||||
# dropdb $DBNAME
|
pg_dump -a -t gb_postcode $DBNAME | grep -v '^--' >> gb_postcode_data.sql
|
||||||
|
|
||||||
|
gzip -9 -f gb_postcode_data.sql
|
||||||
|
ls -lah gb_postcode_data.*
|
||||||
|
|
||||||
|
# dropdb $DBNAME
|
||||||
|
```
|
||||||
|
|||||||
@@ -81,14 +81,6 @@ If you are using a flatnode file, then it may also be that the underlying
|
|||||||
filesystem does not fully support 'mmap'. A notable candidate is virtualbox's
|
filesystem does not fully support 'mmap'. A notable candidate is virtualbox's
|
||||||
vboxfs.
|
vboxfs.
|
||||||
|
|
||||||
### nominatim UPDATE failed: ERROR: buffer 179261 is not owned by resource owner Portal
|
|
||||||
|
|
||||||
Several users [reported this](https://github.com/openstreetmap/Nominatim/issues/1168) during the initial import of the database. It's
|
|
||||||
something Postgresql internal Nominatim doesn't control. And Postgresql forums
|
|
||||||
suggest it's threading related but definitely some kind of crash of a process.
|
|
||||||
Users reported either rebooting the server, different hardware or just trying
|
|
||||||
the import again worked.
|
|
||||||
|
|
||||||
### The website shows: "Could not get word tokens"
|
### The website shows: "Could not get word tokens"
|
||||||
|
|
||||||
The server cannot access your database. Add `&debug=1` to your URL
|
The server cannot access your database. Add `&debug=1` to your URL
|
||||||
@@ -112,8 +104,11 @@ However, you can solve this the quick and dirty way by commenting out that line
|
|||||||
|
|
||||||
### "must be an array or an object that implements Countable" warning in /usr/share/pear/DB.php
|
### "must be an array or an object that implements Countable" warning in /usr/share/pear/DB.php
|
||||||
|
|
||||||
The warning started with PHP 7.2. Make sure you have at least [version 1.9.3 of PEAR DB](https://github.com/pear/DB/releases)
|
As reported starting PHP 7.2. This external DB library is no longer maintained and will be replaced in future Nominatim versions. In the meantime you'd have to manually change the line near 774 from
|
||||||
installed.
|
`if (!count($dsn)) {` to `if (!$dsn && !count($dsn))`. [More details](https://github.com/openstreetmap/Nominatim/issues/1184)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Website reports "DB Error: insufficient permissions"
|
### Website reports "DB Error: insufficient permissions"
|
||||||
|
|
||||||
|
|||||||
@@ -7,19 +7,7 @@ SQL statements should be executed from the postgres commandline. Execute
|
|||||||
`psql nominatim` to enter command line mode.
|
`psql nominatim` to enter command line mode.
|
||||||
|
|
||||||
|
|
||||||
## 3.2.0 -> 3.3.0
|
## 3.2.0 -> master
|
||||||
|
|
||||||
### New database connection string (DSN) format
|
|
||||||
|
|
||||||
Previously database connection setting (`CONST_Database_DSN` in `settings/*.php`) had the format
|
|
||||||
|
|
||||||
* (simple) `pgsql://@/nominatim`
|
|
||||||
* (complex) `pgsql://johndoe:secret@machine1.domain.com:1234/db1`
|
|
||||||
|
|
||||||
The new format is
|
|
||||||
|
|
||||||
* (simple) `pgsql:dbname=nominatim`
|
|
||||||
* (complex) `pgsql:dbname=db1;host=machine1.domain.com;port=1234;user=johndoe;password=secret`
|
|
||||||
|
|
||||||
### Natural Earth country boundaries no longer needed as fallback
|
### Natural Earth country boundaries no longer needed as fallback
|
||||||
|
|
||||||
|
|||||||
@@ -80,8 +80,7 @@ In terms of address details the zoom levels are as follows:
|
|||||||
8 | county
|
8 | county
|
||||||
10 | city
|
10 | city
|
||||||
14 | suburb
|
14 | suburb
|
||||||
16 | major streets
|
16 | street
|
||||||
17 | major and minor streets
|
|
||||||
18 | building
|
18 | building
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class AddressDetails
|
|||||||
$mLangPref = 'ARRAY['.join(',', array_map('getDBQuoted', $mLangPref)).']';
|
$mLangPref = 'ARRAY['.join(',', array_map('getDBQuoted', $mLangPref)).']';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($sHousenumber)) {
|
if (!$sHousenumber) {
|
||||||
$sHousenumber = -1;
|
$sHousenumber = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,12 +26,12 @@ class AddressDetails
|
|||||||
$sSQL .= ' FROM get_addressdata('.$iPlaceID.','.$sHousenumber.')';
|
$sSQL .= ' FROM get_addressdata('.$iPlaceID.','.$sHousenumber.')';
|
||||||
$sSQL .= ' ORDER BY rank_address DESC, isaddress DESC';
|
$sSQL .= ' ORDER BY rank_address DESC, isaddress DESC';
|
||||||
|
|
||||||
$this->aAddressLines = $oDB->getAll($sSQL);
|
$this->aAddressLines = chksql($oDB->getAll($sSQL));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function isAddress($aLine)
|
private static function isAddress($aLine)
|
||||||
{
|
{
|
||||||
return $aLine['isaddress'] || $aLine['type'] == 'country_code';
|
return $aLine['isaddress'] == 't' || $aLine['type'] == 'country_code';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAddressDetails($bAll = false)
|
public function getAddressDetails($bAll = false)
|
||||||
@@ -49,7 +49,7 @@ class AddressDetails
|
|||||||
$sPrevResult = '';
|
$sPrevResult = '';
|
||||||
|
|
||||||
foreach ($this->aAddressLines as $aLine) {
|
foreach ($this->aAddressLines as $aLine) {
|
||||||
if ($aLine['isaddress'] && $sPrevResult != $aLine['localname']) {
|
if ($aLine['isaddress'] == 't' && $sPrevResult != $aLine['localname']) {
|
||||||
$sPrevResult = $aLine['localname'];
|
$sPrevResult = $aLine['localname'];
|
||||||
$aParts[] = $sPrevResult;
|
$aParts[] = $sPrevResult;
|
||||||
}
|
}
|
||||||
|
|||||||
298
lib/DB.php
298
lib/DB.php
@@ -1,298 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Nominatim;
|
|
||||||
|
|
||||||
require_once(CONST_BasePath.'/lib/DatabaseError.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses PDO to access the database specified in the CONST_Database_DSN
|
|
||||||
* setting.
|
|
||||||
*/
|
|
||||||
class DB
|
|
||||||
{
|
|
||||||
protected $connection;
|
|
||||||
|
|
||||||
public function __construct($sDSN = CONST_Database_DSN)
|
|
||||||
{
|
|
||||||
$this->sDSN = $sDSN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function connect($bNew = false, $bPersistent = true)
|
|
||||||
{
|
|
||||||
if (isset($this->connection) && !$bNew) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
$aConnOptions = array(
|
|
||||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
|
||||||
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
|
|
||||||
\PDO::ATTR_PERSISTENT => $bPersistent
|
|
||||||
);
|
|
||||||
|
|
||||||
// https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
|
|
||||||
try {
|
|
||||||
$conn = new \PDO($this->sDSN, null, null, $aConnOptions);
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
$sMsg = 'Failed to establish database connection:' . $e->getMessage();
|
|
||||||
throw new \Nominatim\DatabaseError($sMsg, 500, null, $e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$conn->exec("SET DateStyle TO 'sql,european'");
|
|
||||||
$conn->exec("SET client_encoding TO 'utf-8'");
|
|
||||||
$iMaxExecution = ini_get('max_execution_time');
|
|
||||||
if ($iMaxExecution > 0) $conn->setAttribute(\PDO::ATTR_TIMEOUT, $iMaxExecution); // seconds
|
|
||||||
|
|
||||||
$this->connection = $conn;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the number of rows that were modified or deleted by the SQL
|
|
||||||
// statement. If no rows were affected returns 0.
|
|
||||||
public function exec($sSQL, $aInputVars = null, $sErrMessage = 'Database query failed')
|
|
||||||
{
|
|
||||||
$val = null;
|
|
||||||
try {
|
|
||||||
if (isset($aInputVars)) {
|
|
||||||
$stmt = $this->connection->prepare($sSQL);
|
|
||||||
$stmt->execute($aInputVars);
|
|
||||||
} else {
|
|
||||||
$val = $this->connection->exec($sSQL);
|
|
||||||
}
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new \Nominatim\DatabaseError($sErrMessage, 500, null, $e, $sSQL);
|
|
||||||
}
|
|
||||||
return $val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes query. Returns first row as array.
|
|
||||||
* Returns false if no result found.
|
|
||||||
*
|
|
||||||
* @param string $sSQL
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function getRow($sSQL, $aInputVars = null, $sErrMessage = 'Database query failed')
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$stmt = $this->getQueryStatement($sSQL, $aInputVars, $sErrMessage);
|
|
||||||
$row = $stmt->fetch();
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new \Nominatim\DatabaseError($sErrMessage, 500, null, $e, $sSQL);
|
|
||||||
}
|
|
||||||
return $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes query. Returns first value of first result.
|
|
||||||
* Returns false if no results found.
|
|
||||||
*
|
|
||||||
* @param string $sSQL
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function getOne($sSQL, $aInputVars = null, $sErrMessage = 'Database query failed')
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$stmt = $this->getQueryStatement($sSQL, $aInputVars, $sErrMessage);
|
|
||||||
$row = $stmt->fetch(\PDO::FETCH_NUM);
|
|
||||||
if ($row === false) return false;
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new \Nominatim\DatabaseError($sErrMessage, 500, null, $e, $sSQL);
|
|
||||||
}
|
|
||||||
return $row[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes query. Returns array of results (arrays).
|
|
||||||
* Returns empty array if no results found.
|
|
||||||
*
|
|
||||||
* @param string $sSQL
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function getAll($sSQL, $aInputVars = null, $sErrMessage = 'Database query failed')
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$stmt = $this->getQueryStatement($sSQL, $aInputVars, $sErrMessage);
|
|
||||||
$rows = $stmt->fetchAll();
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new \Nominatim\DatabaseError($sErrMessage, 500, null, $e, $sSQL);
|
|
||||||
}
|
|
||||||
return $rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes query. Returns array of the first value of each result.
|
|
||||||
* Returns empty array if no results found.
|
|
||||||
*
|
|
||||||
* @param string $sSQL
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function getCol($sSQL, $aInputVars = null, $sErrMessage = 'Database query failed')
|
|
||||||
{
|
|
||||||
$aVals = array();
|
|
||||||
try {
|
|
||||||
$stmt = $this->getQueryStatement($sSQL, $aInputVars, $sErrMessage);
|
|
||||||
|
|
||||||
while ($val = $stmt->fetchColumn(0)) { // returns first column or false
|
|
||||||
$aVals[] = $val;
|
|
||||||
}
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new \Nominatim\DatabaseError($sErrMessage, 500, null, $e, $sSQL);
|
|
||||||
}
|
|
||||||
return $aVals;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes query. Returns associate array mapping first value to second value of each result.
|
|
||||||
* Returns empty array if no results found.
|
|
||||||
*
|
|
||||||
* @param string $sSQL
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function getAssoc($sSQL, $aInputVars = null, $sErrMessage = 'Database query failed')
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$stmt = $this->getQueryStatement($sSQL, $aInputVars, $sErrMessage);
|
|
||||||
|
|
||||||
$aList = array();
|
|
||||||
while ($aRow = $stmt->fetch(\PDO::FETCH_NUM)) {
|
|
||||||
$aList[$aRow[0]] = $aRow[1];
|
|
||||||
}
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new \Nominatim\DatabaseError($sErrMessage, 500, null, $e, $sSQL);
|
|
||||||
}
|
|
||||||
return $aList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes query. Returns a PDO statement to iterate over.
|
|
||||||
*
|
|
||||||
* @param string $sSQL
|
|
||||||
*
|
|
||||||
* @return PDOStatement
|
|
||||||
*/
|
|
||||||
public function getQueryStatement($sSQL, $aInputVars = null, $sErrMessage = 'Database query failed')
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (isset($aInputVars)) {
|
|
||||||
$stmt = $this->connection->prepare($sSQL);
|
|
||||||
$stmt->execute($aInputVars);
|
|
||||||
} else {
|
|
||||||
$stmt = $this->connection->query($sSQL);
|
|
||||||
}
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new \Nominatim\DatabaseError($sErrMessage, 500, null, $e, $sSQL);
|
|
||||||
}
|
|
||||||
return $stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* St. John's Way => 'St. John\'s Way'
|
|
||||||
*
|
|
||||||
* @param string $sVal Text to be quoted.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getDBQuoted($sVal)
|
|
||||||
{
|
|
||||||
return $this->connection->quote($sVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like getDBQuoted, but takes an array.
|
|
||||||
*
|
|
||||||
* @param array $aVals List of text to be quoted.
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function getDBQuotedList($aVals)
|
|
||||||
{
|
|
||||||
return array_map(function ($sVal) {
|
|
||||||
return $this->getDBQuoted($sVal);
|
|
||||||
}, $aVals);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [1,2,'b'] => 'ARRAY[1,2,'b']''
|
|
||||||
*
|
|
||||||
* @param array $aVals List of text to be quoted.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getArraySQL($a)
|
|
||||||
{
|
|
||||||
return 'ARRAY['.join(',', $a).']';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a table exists in the database. Returns true if it does.
|
|
||||||
*
|
|
||||||
* @param string $sTableName
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function tableExists($sTableName)
|
|
||||||
{
|
|
||||||
$sSQL = 'SELECT count(*) FROM pg_tables WHERE tablename = :tablename';
|
|
||||||
return ($this->getOne($sSQL, array(':tablename' => $sTableName)) == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Since the DSN includes the database name, checks if the connection works.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function databaseExists()
|
|
||||||
{
|
|
||||||
$bExists = true;
|
|
||||||
try {
|
|
||||||
$this->connect(true);
|
|
||||||
} catch (\Nominatim\DatabaseError $e) {
|
|
||||||
$bExists = false;
|
|
||||||
}
|
|
||||||
return $bExists;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* e.g. 9.6, 10, 11.2
|
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function getPostgresVersion()
|
|
||||||
{
|
|
||||||
$sVersionString = $this->getOne('SHOW server_version_num');
|
|
||||||
preg_match('#([0-9]?[0-9])([0-9][0-9])[0-9][0-9]#', $sVersionString, $aMatches);
|
|
||||||
return (float) ($aMatches[1].'.'.$aMatches[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* e.g. 2, 2.2
|
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function getPostgisVersion()
|
|
||||||
{
|
|
||||||
$sVersionString = $this->getOne('select postgis_lib_version()');
|
|
||||||
preg_match('#^([0-9]+)[.]([0-9]+)[.]#', $sVersionString, $aMatches);
|
|
||||||
return (float) ($aMatches[1].'.'.$aMatches[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function parseDSN($sDSN)
|
|
||||||
{
|
|
||||||
// https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
|
|
||||||
$aInfo = array();
|
|
||||||
if (preg_match('/^pgsql:(.+)/', $sDSN, $aMatches)) {
|
|
||||||
foreach (explode(';', $aMatches[1]) as $sKeyVal) {
|
|
||||||
list($sKey, $sVal) = explode('=', $sKeyVal, 2);
|
|
||||||
if ($sKey == 'host') $sKey = 'hostspec';
|
|
||||||
if ($sKey == 'dbname') $sKey = 'database';
|
|
||||||
if ($sKey == 'user') $sKey = 'username';
|
|
||||||
$aInfo[$sKey] = $sVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $aInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,12 +5,10 @@ namespace Nominatim;
|
|||||||
class DatabaseError extends \Exception
|
class DatabaseError extends \Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct($message, $code = 500, Exception $previous = null, $oPDOErr, $sSql = null)
|
public function __construct($message, $code = 500, Exception $previous = null, $oSql)
|
||||||
{
|
{
|
||||||
parent::__construct($message, $code, $previous);
|
parent::__construct($message, $code, $previous);
|
||||||
// https://secure.php.net/manual/en/class.pdoexception.php
|
$this->oSql = $oSql;
|
||||||
$this->oPDOErr = $oPDOErr;
|
|
||||||
$this->sSql = $sSql;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __toString()
|
public function __toString()
|
||||||
@@ -20,15 +18,15 @@ class DatabaseError extends \Exception
|
|||||||
|
|
||||||
public function getSqlError()
|
public function getSqlError()
|
||||||
{
|
{
|
||||||
return $this->oPDOErr->getMessage();
|
return $this->oSql->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSqlDebugDump()
|
public function getSqlDebugDump()
|
||||||
{
|
{
|
||||||
if (CONST_Debug) {
|
if (CONST_Debug) {
|
||||||
return var_export($this->oPDOErr, true);
|
return var_export($this->oSql, true);
|
||||||
} else {
|
} else {
|
||||||
return $this->sSql;
|
return $this->oSql->getUserInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -527,8 +527,8 @@ class Geocode
|
|||||||
$sNormQuery = $this->normTerm($this->sQuery);
|
$sNormQuery = $this->normTerm($this->sQuery);
|
||||||
Debug::printVar('Normalized query', $sNormQuery);
|
Debug::printVar('Normalized query', $sNormQuery);
|
||||||
|
|
||||||
$sLanguagePrefArraySQL = $this->oDB->getArraySQL(
|
$sLanguagePrefArraySQL = getArraySQL(
|
||||||
$this->oDB->getDBQuotedList($this->aLangPrefOrder)
|
array_map('getDBQuoted', $this->aLangPrefOrder)
|
||||||
);
|
);
|
||||||
|
|
||||||
$sQuery = $this->sQuery;
|
$sQuery = $this->sQuery;
|
||||||
@@ -581,9 +581,8 @@ class Geocode
|
|||||||
|
|
||||||
if ($sSpecialTerm && !$aSearches[0]->hasOperator()) {
|
if ($sSpecialTerm && !$aSearches[0]->hasOperator()) {
|
||||||
$sSpecialTerm = pg_escape_string($sSpecialTerm);
|
$sSpecialTerm = pg_escape_string($sSpecialTerm);
|
||||||
$sToken = $this->oDB->getOne(
|
$sToken = chksql(
|
||||||
'SELECT make_standard_name(:term)',
|
$this->oDB->getOne("SELECT make_standard_name('$sSpecialTerm')"),
|
||||||
array(':term' => $sSpecialTerm),
|
|
||||||
'Cannot decode query. Wrong encoding?'
|
'Cannot decode query. Wrong encoding?'
|
||||||
);
|
);
|
||||||
$sSQL = 'SELECT class, type FROM word ';
|
$sSQL = 'SELECT class, type FROM word ';
|
||||||
@@ -591,7 +590,7 @@ class Geocode
|
|||||||
$sSQL .= ' AND class is not null AND class not in (\'place\')';
|
$sSQL .= ' AND class is not null AND class not in (\'place\')';
|
||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$aSearchWords = $this->oDB->getAll($sSQL);
|
$aSearchWords = chksql($this->oDB->getAll($sSQL));
|
||||||
$aNewSearches = array();
|
$aNewSearches = array();
|
||||||
foreach ($aSearches as $oSearch) {
|
foreach ($aSearches as $oSearch) {
|
||||||
foreach ($aSearchWords as $aSearchTerm) {
|
foreach ($aSearchWords as $aSearchTerm) {
|
||||||
@@ -629,9 +628,8 @@ class Geocode
|
|||||||
$aTokens = array();
|
$aTokens = array();
|
||||||
$aPhrases = array();
|
$aPhrases = array();
|
||||||
foreach ($aInPhrases as $iPhrase => $sPhrase) {
|
foreach ($aInPhrases as $iPhrase => $sPhrase) {
|
||||||
$sPhrase = $this->oDB->getOne(
|
$sPhrase = chksql(
|
||||||
'SELECT make_standard_name(:phrase)',
|
$this->oDB->getOne('SELECT make_standard_name('.getDBQuoted($sPhrase).')'),
|
||||||
array(':phrase' => $sPhrase),
|
|
||||||
'Cannot normalize query string (is it a UTF-8 string?)'
|
'Cannot normalize query string (is it a UTF-8 string?)'
|
||||||
);
|
);
|
||||||
if (trim($sPhrase)) {
|
if (trim($sPhrase)) {
|
||||||
@@ -649,7 +647,7 @@ class Geocode
|
|||||||
if (!empty($aTokens)) {
|
if (!empty($aTokens)) {
|
||||||
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code, operator, search_name_count';
|
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code, operator, search_name_count';
|
||||||
$sSQL .= ' FROM word ';
|
$sSQL .= ' FROM word ';
|
||||||
$sSQL .= ' WHERE word_token in ('.join(',', $this->oDB->getDBQuotedList($aTokens)).')';
|
$sSQL .= ' WHERE word_token in ('.join(',', array_map('getDBQuoted', $aTokens)).')';
|
||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
@@ -832,7 +830,7 @@ class Geocode
|
|||||||
if ($aFilterSql) {
|
if ($aFilterSql) {
|
||||||
$sSQL = join(' UNION ', $aFilterSql);
|
$sSQL = join(' UNION ', $aFilterSql);
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$aFilteredIDs = $this->oDB->getCol($sSQL);
|
$aFilteredIDs = chksql($this->oDB->getCol($sSQL));
|
||||||
}
|
}
|
||||||
|
|
||||||
$tempIDs = array();
|
$tempIDs = array();
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class PlaceLookup
|
|||||||
{
|
{
|
||||||
$aLangs = $oParams->getPreferredLanguages();
|
$aLangs = $oParams->getPreferredLanguages();
|
||||||
$this->aLangPrefOrderSql =
|
$this->aLangPrefOrderSql =
|
||||||
'ARRAY['.join(',', $this->oDB->getDBQuotedList($aLangs)).']';
|
'ARRAY['.join(',', array_map('getDBQuoted', $aLangs)).']';
|
||||||
|
|
||||||
$this->bExtraTags = $oParams->getBool('extratags', false);
|
$this->bExtraTags = $oParams->getBool('extratags', false);
|
||||||
$this->bNameDetails = $oParams->getBool('namedetails', false);
|
$this->bNameDetails = $oParams->getBool('namedetails', false);
|
||||||
@@ -132,9 +132,8 @@ class PlaceLookup
|
|||||||
|
|
||||||
public function setLanguagePreference($aLangPrefOrder)
|
public function setLanguagePreference($aLangPrefOrder)
|
||||||
{
|
{
|
||||||
$this->aLangPrefOrderSql = $this->oDB->getArraySQL(
|
$this->aLangPrefOrderSql =
|
||||||
$this->oDB->getDBQuotedList($aLangPrefOrder)
|
'ARRAY['.join(',', array_map('getDBQuoted', $aLangPrefOrder)).']';
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addressImportanceSql($sGeometry, $sPlaceId)
|
private function addressImportanceSql($sGeometry, $sPlaceId)
|
||||||
@@ -163,8 +162,8 @@ class PlaceLookup
|
|||||||
|
|
||||||
public function lookupOSMID($sType, $iID)
|
public function lookupOSMID($sType, $iID)
|
||||||
{
|
{
|
||||||
$sSQL = 'select place_id from placex where osm_type = :type and osm_id = :id';
|
$sSQL = "select place_id from placex where osm_type = '".$sType."' and osm_id = ".$iID;
|
||||||
$iPlaceID = $this->oDB->getOne($sSQL, array(':type' => $sType, ':id' => $iID));
|
$iPlaceID = chksql($this->oDB->getOne($sSQL));
|
||||||
|
|
||||||
if (!$iPlaceID) {
|
if (!$iPlaceID) {
|
||||||
return null;
|
return null;
|
||||||
@@ -425,10 +424,9 @@ class PlaceLookup
|
|||||||
|
|
||||||
$sSQL = join(' UNION ', $aSubSelects);
|
$sSQL = join(' UNION ', $aSubSelects);
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$aPlaces = $this->oDB->getAll($sSQL, null, 'Could not lookup place');
|
$aPlaces = chksql($this->oDB->getAll($sSQL), 'Could not lookup place');
|
||||||
|
|
||||||
foreach ($aPlaces as &$aPlace) {
|
foreach ($aPlaces as &$aPlace) {
|
||||||
$aPlace['importance'] = (float) $aPlace['importance'];
|
|
||||||
if ($this->bAddressDetails) {
|
if ($this->bAddressDetails) {
|
||||||
// to get addressdetails for tiger data, the housenumber is needed
|
// to get addressdetails for tiger data, the housenumber is needed
|
||||||
$aPlace['address'] = new AddressDetails(
|
$aPlace['address'] = new AddressDetails(
|
||||||
@@ -515,9 +513,9 @@ class PlaceLookup
|
|||||||
$sSQL .= $sFrom;
|
$sSQL .= $sFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
$aPointPolygon = $this->oDB->getRow($sSQL, null, 'Could not get outline');
|
$aPointPolygon = chksql($this->oDB->getRow($sSQL), 'Could not get outline');
|
||||||
|
|
||||||
if ($aPointPolygon && $aPointPolygon['place_id']) {
|
if ($aPointPolygon['place_id']) {
|
||||||
if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null) {
|
if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null) {
|
||||||
$aOutlineResult['lat'] = $aPointPolygon['centrelat'];
|
$aOutlineResult['lat'] = $aPointPolygon['centrelat'];
|
||||||
$aOutlineResult['lon'] = $aPointPolygon['centrelon'];
|
$aOutlineResult['lon'] = $aPointPolygon['centrelon'];
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ class ReverseGeocode
|
|||||||
13 => 18,
|
13 => 18,
|
||||||
14 => 22, // Suburb
|
14 => 22, // Suburb
|
||||||
15 => 22,
|
15 => 22,
|
||||||
16 => 26, // major street
|
16 => 26, // Street, TODO: major street?
|
||||||
17 => 27, // minor street
|
17 => 26,
|
||||||
18 => 30, // or >, Building
|
18 => 30, // or >, Building
|
||||||
19 => 30, // or >, Building
|
19 => 30, // or >, Building
|
||||||
);
|
);
|
||||||
@@ -63,9 +63,8 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' and indexed_status = 0 and startnumber is not NULL ';
|
$sSQL .= ' and indexed_status = 0 and startnumber is not NULL ';
|
||||||
$sSQL .= ' ORDER BY distance ASC limit 1';
|
$sSQL .= ' ORDER BY distance ASC limit 1';
|
||||||
|
|
||||||
return $this->oDB->getRow(
|
return chksql(
|
||||||
$sSQL,
|
$this->oDB->getRow($sSQL),
|
||||||
null,
|
|
||||||
'Could not determine closest housenumber on an osm interpolation line.'
|
'Could not determine closest housenumber on an osm interpolation line.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -93,9 +92,8 @@ class ReverseGeocode
|
|||||||
$sSQL = 'SELECT country_code FROM country_osm_grid';
|
$sSQL = 'SELECT country_code FROM country_osm_grid';
|
||||||
$sSQL .= ' WHERE ST_CONTAINS(geometry, '.$sPointSQL.') LIMIT 1';
|
$sSQL .= ' WHERE ST_CONTAINS(geometry, '.$sPointSQL.') LIMIT 1';
|
||||||
|
|
||||||
$sCountryCode = $this->oDB->getOne(
|
$sCountryCode = chksql(
|
||||||
$sSQL,
|
$this->oDB->getOne($sSQL),
|
||||||
null,
|
|
||||||
'Could not determine country polygon containing the point.'
|
'Could not determine country polygon containing the point.'
|
||||||
);
|
);
|
||||||
if ($sCountryCode) {
|
if ($sCountryCode) {
|
||||||
@@ -117,7 +115,10 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' LIMIT 1';
|
$sSQL .= ' LIMIT 1';
|
||||||
|
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aPlace = $this->oDB->getRow($sSQL, null, 'Could not determine place node.');
|
$aPlace = chksql(
|
||||||
|
$this->oDB->getRow($sSQL),
|
||||||
|
'Could not determine place node.'
|
||||||
|
);
|
||||||
if ($aPlace) {
|
if ($aPlace) {
|
||||||
return new Result($aPlace['place_id']);
|
return new Result($aPlace['place_id']);
|
||||||
}
|
}
|
||||||
@@ -133,7 +134,10 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' ORDER BY distance ASC';
|
$sSQL .= ' ORDER BY distance ASC';
|
||||||
|
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aPlace = $this->oDB->getRow($sSQL, null, 'Could not determine place node.');
|
$aPlace = chksql(
|
||||||
|
$this->oDB->getRow($sSQL),
|
||||||
|
'Could not determine place node.'
|
||||||
|
);
|
||||||
if ($aPlace) {
|
if ($aPlace) {
|
||||||
return new Result($aPlace['place_id']);
|
return new Result($aPlace['place_id']);
|
||||||
}
|
}
|
||||||
@@ -174,8 +178,10 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' WHERE ST_CONTAINS(geometry, '.$sPointSQL.' )';
|
$sSQL .= ' WHERE ST_CONTAINS(geometry, '.$sPointSQL.' )';
|
||||||
$sSQL .= ' ORDER BY rank_address DESC LIMIT 1';
|
$sSQL .= ' ORDER BY rank_address DESC LIMIT 1';
|
||||||
|
|
||||||
$aPoly = $this->oDB->getRow($sSQL, null, 'Could not determine polygon containing the point.');
|
$aPoly = chksql(
|
||||||
|
$this->oDB->getRow($sSQL),
|
||||||
|
'Could not determine polygon containing the point.'
|
||||||
|
);
|
||||||
if ($aPoly) {
|
if ($aPoly) {
|
||||||
// if a polygon is found, search for placenodes begins ...
|
// if a polygon is found, search for placenodes begins ...
|
||||||
$iParentPlaceID = $aPoly['parent_place_id'];
|
$iParentPlaceID = $aPoly['parent_place_id'];
|
||||||
@@ -207,7 +213,10 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' LIMIT 1';
|
$sSQL .= ' LIMIT 1';
|
||||||
|
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aPlacNode = $this->oDB->getRow($sSQL, null, 'Could not determine place node.');
|
$aPlacNode = chksql(
|
||||||
|
$this->oDB->getRow($sSQL),
|
||||||
|
'Could not determine place node.'
|
||||||
|
);
|
||||||
if ($aPlacNode) {
|
if ($aPlacNode) {
|
||||||
return $aPlacNode;
|
return $aPlacNode;
|
||||||
}
|
}
|
||||||
@@ -246,7 +255,12 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' placex';
|
$sSQL .= ' placex';
|
||||||
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')';
|
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')';
|
||||||
$sSQL .= ' AND';
|
$sSQL .= ' AND';
|
||||||
$sSQL .= ' rank_address between 26 and '.$iMaxRank;
|
// only streets
|
||||||
|
if ($iMaxRank == 26) {
|
||||||
|
$sSQL .= ' rank_address = 26';
|
||||||
|
} else {
|
||||||
|
$sSQL .= ' rank_address between 26 and '.$iMaxRank;
|
||||||
|
}
|
||||||
$sSQL .= ' and (name is not null or housenumber is not null';
|
$sSQL .= ' and (name is not null or housenumber is not null';
|
||||||
$sSQL .= ' or rank_address between 26 and 27)';
|
$sSQL .= ' or rank_address between 26 and 27)';
|
||||||
$sSQL .= ' and (rank_address between 26 and 27';
|
$sSQL .= ' and (rank_address between 26 and 27';
|
||||||
@@ -257,7 +271,10 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' OR ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.'))';
|
$sSQL .= ' OR ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.'))';
|
||||||
$sSQL .= ' ORDER BY distance ASC limit 1';
|
$sSQL .= ' ORDER BY distance ASC limit 1';
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aPlace = $this->oDB->getRow($sSQL, null, 'Could not determine closest place.');
|
$aPlace = chksql(
|
||||||
|
$this->oDB->getRow($sSQL),
|
||||||
|
'Could not determine closest place.'
|
||||||
|
);
|
||||||
|
|
||||||
if (CONST_Debug) var_dump($aPlace);
|
if (CONST_Debug) var_dump($aPlace);
|
||||||
if ($aPlace) {
|
if ($aPlace) {
|
||||||
@@ -299,14 +316,17 @@ class ReverseGeocode
|
|||||||
// radius ?
|
// radius ?
|
||||||
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, 0.001)';
|
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, 0.001)';
|
||||||
$sSQL .= ' AND parent_place_id = '.$iPlaceID;
|
$sSQL .= ' AND parent_place_id = '.$iPlaceID;
|
||||||
$sSQL .= ' and rank_address > 28';
|
$sSQL .= ' and rank_address != 28';
|
||||||
$sSQL .= ' and ST_GeometryType(geometry) != \'ST_LineString\'';
|
$sSQL .= ' and ST_GeometryType(geometry) != \'ST_LineString\'';
|
||||||
$sSQL .= ' and (name is not null or housenumber is not null)';
|
$sSQL .= ' and (name is not null or housenumber is not null)';
|
||||||
$sSQL .= ' and class not in (\'boundary\')';
|
$sSQL .= ' and class not in (\'boundary\')';
|
||||||
$sSQL .= ' and indexed_status = 0 and linked_place_id is null';
|
$sSQL .= ' and indexed_status = 0 and linked_place_id is null';
|
||||||
$sSQL .= ' ORDER BY distance ASC limit 1';
|
$sSQL .= ' ORDER BY distance ASC limit 1';
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aStreet = $this->oDB->getRow($sSQL, null, 'Could not determine closest place.');
|
$aStreet = chksql(
|
||||||
|
$this->oDB->getRow($sSQL),
|
||||||
|
'Could not determine closest place.'
|
||||||
|
);
|
||||||
if ($aStreet) {
|
if ($aStreet) {
|
||||||
if (CONST_Debug) var_dump($aStreet);
|
if (CONST_Debug) var_dump($aStreet);
|
||||||
$oResult = new Result($aStreet['place_id']);
|
$oResult = new Result($aStreet['place_id']);
|
||||||
@@ -327,7 +347,10 @@ class ReverseGeocode
|
|||||||
$sSQL .= ' AND ST_DWithin('.$sPointSQL.', linegeo, 0.001)';
|
$sSQL .= ' AND ST_DWithin('.$sPointSQL.', linegeo, 0.001)';
|
||||||
$sSQL .= ' ORDER BY distance ASC limit 1';
|
$sSQL .= ' ORDER BY distance ASC limit 1';
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aPlaceTiger = $this->oDB->getRow($sSQL, null, 'Could not determine closest Tiger place.');
|
$aPlaceTiger = chksql(
|
||||||
|
$this->oDB->getRow($sSQL),
|
||||||
|
'Could not determine closest Tiger place.'
|
||||||
|
);
|
||||||
if ($aPlaceTiger) {
|
if ($aPlaceTiger) {
|
||||||
if (CONST_Debug) var_dump('found Tiger housenumber', $aPlaceTiger);
|
if (CONST_Debug) var_dump('found Tiger housenumber', $aPlaceTiger);
|
||||||
$oResult = new Result($aPlaceTiger['place_id'], Result::TABLE_TIGER);
|
$oResult = new Result($aPlaceTiger['place_id'], Result::TABLE_TIGER);
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ class SearchContext
|
|||||||
* The viewbox may be bounded which means that no search results
|
* The viewbox may be bounded which means that no search results
|
||||||
* must be outside the viewbox.
|
* must be outside the viewbox.
|
||||||
*
|
*
|
||||||
* @param object $oDB Nominatim::DB instance to use for computing the box.
|
* @param object $oDB DB connection to use for computing the box.
|
||||||
* @param string[] $aRoutePoints List of x,y coordinates along a route.
|
* @param string[] $aRoutePoints List of x,y coordinates along a route.
|
||||||
* @param float $fRouteWidth Buffer around the route to use.
|
* @param float $fRouteWidth Buffer around the route to use.
|
||||||
* @param bool $bBounded True if the viewbox bounded.
|
* @param bool $bBounded True if the viewbox bounded.
|
||||||
@@ -146,11 +146,11 @@ class SearchContext
|
|||||||
$this->sqlViewboxCentre .= ")'::geometry,4326)";
|
$this->sqlViewboxCentre .= ")'::geometry,4326)";
|
||||||
|
|
||||||
$sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/69).')';
|
$sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/69).')';
|
||||||
$sGeom = $oDB->getOne('select '.$sSQL, null, 'Could not get small viewbox');
|
$sGeom = chksql($oDB->getOne('select '.$sSQL), 'Could not get small viewbox');
|
||||||
$this->sqlViewboxSmall = "'".$sGeom."'::geometry";
|
$this->sqlViewboxSmall = "'".$sGeom."'::geometry";
|
||||||
|
|
||||||
$sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/30).')';
|
$sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/30).')';
|
||||||
$sGeom = $oDB->getOne('select '.$sSQL, null, 'Could not get large viewbox');
|
$sGeom = chksql($oDB->getOne('select '.$sSQL), 'Could not get large viewbox');
|
||||||
$this->sqlViewboxLarge = "'".$sGeom."'::geometry";
|
$this->sqlViewboxLarge = "'".$sGeom."'::geometry";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ class SearchDescription
|
|||||||
/**
|
/**
|
||||||
* Query database for places that match this search.
|
* Query database for places that match this search.
|
||||||
*
|
*
|
||||||
* @param object $oDB Nominatim::DB instance to use.
|
* @param object $oDB Database connection to use.
|
||||||
* @param integer $iMinRank Minimum address rank to restrict search to.
|
* @param integer $iMinRank Minimum address rank to restrict search to.
|
||||||
* @param integer $iMaxRank Maximum address rank to restrict search to.
|
* @param integer $iMaxRank Maximum address rank to restrict search to.
|
||||||
* @param integer $iLimit Maximum number of results.
|
* @param integer $iLimit Maximum number of results.
|
||||||
@@ -479,7 +479,7 @@ class SearchDescription
|
|||||||
$sSQL .= ' WHERE place_id in ('.$sPlaceIds.')';
|
$sSQL .= ' WHERE place_id in ('.$sPlaceIds.')';
|
||||||
$sSQL .= " AND postcode != '".$this->sPostcode."'";
|
$sSQL .= " AND postcode != '".$this->sPostcode."'";
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$aFilteredPlaceIDs = $oDB->getCol($sSQL);
|
$aFilteredPlaceIDs = chksql($oDB->getCol($sSQL));
|
||||||
if ($aFilteredPlaceIDs) {
|
if ($aFilteredPlaceIDs) {
|
||||||
foreach ($aFilteredPlaceIDs as $iPlaceId) {
|
foreach ($aFilteredPlaceIDs as $iPlaceId) {
|
||||||
$aResults[$iPlaceId]->iResultRank++;
|
$aResults[$iPlaceId]->iResultRank++;
|
||||||
@@ -504,10 +504,8 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
$iPlaceId = $oDB->getOne($sSQL);
|
|
||||||
|
|
||||||
$aResults = array();
|
$aResults = array();
|
||||||
if ($iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$aResults[$iPlaceId] = new Result($iPlaceId);
|
$aResults[$iPlaceId] = new Result($iPlaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,7 +521,8 @@ class SearchDescription
|
|||||||
$aDBResults = array();
|
$aDBResults = array();
|
||||||
$sPoiTable = $this->poiTable();
|
$sPoiTable = $this->poiTable();
|
||||||
|
|
||||||
if ($oDB->tableExists($sPoiTable)) {
|
$sSQL = 'SELECT count(*) FROM pg_tables WHERE tablename = \''.$sPoiTable."'";
|
||||||
|
if (chksql($oDB->getOne($sSQL))) {
|
||||||
$sSQL = 'SELECT place_id FROM '.$sPoiTable.' ct';
|
$sSQL = 'SELECT place_id FROM '.$sPoiTable.' ct';
|
||||||
if ($this->oContext->sqlCountryList) {
|
if ($this->oContext->sqlCountryList) {
|
||||||
$sSQL .= ' JOIN placex USING (place_id)';
|
$sSQL .= ' JOIN placex USING (place_id)';
|
||||||
@@ -543,14 +542,14 @@ class SearchDescription
|
|||||||
} elseif ($this->oContext->hasNearPoint()) {
|
} elseif ($this->oContext->hasNearPoint()) {
|
||||||
$sSQL .= ' ORDER BY '.$this->oContext->distanceSQL('ct.centroid').' ASC';
|
$sSQL .= ' ORDER BY '.$this->oContext->distanceSQL('ct.centroid').' ASC';
|
||||||
}
|
}
|
||||||
$sSQL .= " LIMIT $iLimit";
|
$sSQL .= " limit $iLimit";
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$aDBResults = $oDB->getCol($sSQL);
|
$aDBResults = chksql($oDB->getCol($sSQL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->oContext->hasNearPoint()) {
|
if ($this->oContext->hasNearPoint()) {
|
||||||
$sSQL = 'SELECT place_id FROM placex WHERE ';
|
$sSQL = 'SELECT place_id FROM placex WHERE ';
|
||||||
$sSQL .= 'class = :class and type = :type';
|
$sSQL .= 'class=\''.$this->sClass."' and type='".$this->sType."'";
|
||||||
$sSQL .= ' AND '.$this->oContext->withinSQL('geometry');
|
$sSQL .= ' AND '.$this->oContext->withinSQL('geometry');
|
||||||
$sSQL .= ' AND linked_place_id is null';
|
$sSQL .= ' AND linked_place_id is null';
|
||||||
if ($this->oContext->sqlCountryList) {
|
if ($this->oContext->sqlCountryList) {
|
||||||
@@ -559,10 +558,7 @@ class SearchDescription
|
|||||||
$sSQL .= ' ORDER BY '.$this->oContext->distanceSQL('centroid').' ASC';
|
$sSQL .= ' ORDER BY '.$this->oContext->distanceSQL('centroid').' ASC';
|
||||||
$sSQL .= " LIMIT $iLimit";
|
$sSQL .= " LIMIT $iLimit";
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$aDBResults = $oDB->getCol(
|
$aDBResults = chksql($oDB->getCol($sSQL));
|
||||||
$sSQL,
|
|
||||||
array(':class' => $this->sClass, ':type' => $this->sType)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$aResults = array();
|
$aResults = array();
|
||||||
@@ -581,23 +577,20 @@ class SearchDescription
|
|||||||
$sSQL .= ', search_name s ';
|
$sSQL .= ', search_name s ';
|
||||||
$sSQL .= 'WHERE s.place_id = p.parent_place_id ';
|
$sSQL .= 'WHERE s.place_id = p.parent_place_id ';
|
||||||
$sSQL .= 'AND array_cat(s.nameaddress_vector, s.name_vector)';
|
$sSQL .= 'AND array_cat(s.nameaddress_vector, s.name_vector)';
|
||||||
$sSQL .= ' @> '.$oDB->getArraySQL($this->aAddress).' AND ';
|
$sSQL .= ' @> '.getArraySQL($this->aAddress).' AND ';
|
||||||
} else {
|
} else {
|
||||||
$sSQL .= 'WHERE ';
|
$sSQL .= 'WHERE ';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sSQL .= "p.postcode = '".reset($this->aName)."'";
|
$sSQL .= "p.postcode = '".reset($this->aName)."'";
|
||||||
$sSQL .= $this->countryCodeSQL(' AND p.country_code');
|
$sSQL .= $this->countryCodeSQL(' AND p.country_code');
|
||||||
if ($this->oContext->bViewboxBounded) {
|
|
||||||
$sSQL .= ' AND ST_Intersects('.$this->oContext->sqlViewboxSmall.', geometry)';
|
|
||||||
}
|
|
||||||
$sSQL .= $this->oContext->excludeSQL(' AND p.place_id');
|
$sSQL .= $this->oContext->excludeSQL(' AND p.place_id');
|
||||||
$sSQL .= " LIMIT $iLimit";
|
$sSQL .= " LIMIT $iLimit";
|
||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
$aResults = array();
|
$aResults = array();
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$aResults[$iPlaceId] = new Result($iPlaceId, Result::TABLE_POSTCODE);
|
$aResults[$iPlaceId] = new Result($iPlaceId, Result::TABLE_POSTCODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,14 +633,14 @@ class SearchDescription
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($this->aName)) {
|
if (!empty($this->aName)) {
|
||||||
$aTerms[] = 'name_vector @> '.$oDB->getArraySQL($this->aName);
|
$aTerms[] = 'name_vector @> '.getArraySQL($this->aName);
|
||||||
}
|
}
|
||||||
if (!empty($this->aAddress)) {
|
if (!empty($this->aAddress)) {
|
||||||
// For infrequent name terms disable index usage for address
|
// For infrequent name terms disable index usage for address
|
||||||
if ($this->bRareName) {
|
if ($this->bRareName) {
|
||||||
$aTerms[] = 'array_cat(nameaddress_vector,ARRAY[]::integer[]) @> '.$oDB->getArraySQL($this->aAddress);
|
$aTerms[] = 'array_cat(nameaddress_vector,ARRAY[]::integer[]) @> '.getArraySQL($this->aAddress);
|
||||||
} else {
|
} else {
|
||||||
$aTerms[] = 'nameaddress_vector @> '.$oDB->getArraySQL($this->aAddress);
|
$aTerms[] = 'nameaddress_vector @> '.getArraySQL($this->aAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -702,7 +695,7 @@ class SearchDescription
|
|||||||
if (!empty($this->aFullNameAddress)) {
|
if (!empty($this->aFullNameAddress)) {
|
||||||
$sExactMatchSQL = ' ( ';
|
$sExactMatchSQL = ' ( ';
|
||||||
$sExactMatchSQL .= ' SELECT count(*) FROM ( ';
|
$sExactMatchSQL .= ' SELECT count(*) FROM ( ';
|
||||||
$sExactMatchSQL .= ' SELECT unnest('.$oDB->getArraySQL($this->aFullNameAddress).')';
|
$sExactMatchSQL .= ' SELECT unnest('.getArraySQL($this->aFullNameAddress).')';
|
||||||
$sExactMatchSQL .= ' INTERSECT ';
|
$sExactMatchSQL .= ' INTERSECT ';
|
||||||
$sExactMatchSQL .= ' SELECT unnest(nameaddress_vector)';
|
$sExactMatchSQL .= ' SELECT unnest(nameaddress_vector)';
|
||||||
$sExactMatchSQL .= ' ) s';
|
$sExactMatchSQL .= ' ) s';
|
||||||
@@ -727,7 +720,10 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
$aDBResults = $oDB->getAll($sSQL, null, 'Could not get places for search terms.');
|
$aDBResults = chksql(
|
||||||
|
$oDB->getAll($sSQL),
|
||||||
|
'Could not get places for search terms.'
|
||||||
|
);
|
||||||
|
|
||||||
foreach ($aDBResults as $aResult) {
|
foreach ($aDBResults as $aResult) {
|
||||||
$oResult = new Result($aResult['place_id']);
|
$oResult = new Result($aResult['place_id']);
|
||||||
@@ -757,7 +753,7 @@ class SearchDescription
|
|||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
// XXX should inherit the exactMatches from its parent
|
// XXX should inherit the exactMatches from its parent
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$aResults[$iPlaceId] = new Result($iPlaceId);
|
$aResults[$iPlaceId] = new Result($iPlaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,7 +779,7 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$oResult = new Result($iPlaceId, Result::TABLE_OSMLINE);
|
$oResult = new Result($iPlaceId, Result::TABLE_OSMLINE);
|
||||||
$oResult->iHouseNumber = $iHousenumber;
|
$oResult->iHouseNumber = $iHousenumber;
|
||||||
$aResults[$iPlaceId] = $oResult;
|
$aResults[$iPlaceId] = $oResult;
|
||||||
@@ -799,7 +795,7 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$aResults[$iPlaceId] = new Result($iPlaceId, Result::TABLE_AUX);
|
$aResults[$iPlaceId] = new Result($iPlaceId, Result::TABLE_AUX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -820,7 +816,7 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$oResult = new Result($iPlaceId, Result::TABLE_TIGER);
|
$oResult = new Result($iPlaceId, Result::TABLE_TIGER);
|
||||||
$oResult->iHouseNumber = $iHousenumber;
|
$oResult->iHouseNumber = $iHousenumber;
|
||||||
$aResults[$iPlaceId] = $oResult;
|
$aResults[$iPlaceId] = $oResult;
|
||||||
@@ -854,7 +850,7 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$aResults[$iPlaceId] = new Result($iPlaceId);
|
$aResults[$iPlaceId] = new Result($iPlaceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -862,11 +858,12 @@ class SearchDescription
|
|||||||
// NEAR and IN are handled the same
|
// NEAR and IN are handled the same
|
||||||
if ($this->iOperator == Operator::TYPE || $this->iOperator == Operator::NEAR) {
|
if ($this->iOperator == Operator::TYPE || $this->iOperator == Operator::NEAR) {
|
||||||
$sClassTable = $this->poiTable();
|
$sClassTable = $this->poiTable();
|
||||||
$bCacheTable = $oDB->tableExists($sClassTable);
|
$sSQL = "SELECT count(*) FROM pg_tables WHERE tablename = '$sClassTable'";
|
||||||
|
$bCacheTable = (bool) chksql($oDB->getOne($sSQL));
|
||||||
|
|
||||||
$sSQL = "SELECT min(rank_search) FROM placex WHERE place_id in ($sPlaceIDs)";
|
$sSQL = "SELECT min(rank_search) FROM placex WHERE place_id in ($sPlaceIDs)";
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$iMaxRank = (int) $oDB->getOne($sSQL);
|
$iMaxRank = (int)chksql($oDB->getOne($sSQL));
|
||||||
|
|
||||||
// For state / country level searches the normal radius search doesn't work very well
|
// For state / country level searches the normal radius search doesn't work very well
|
||||||
$sPlaceGeom = false;
|
$sPlaceGeom = false;
|
||||||
@@ -879,7 +876,7 @@ class SearchDescription
|
|||||||
$sSQL .= ' ORDER BY rank_search ASC ';
|
$sSQL .= ' ORDER BY rank_search ASC ';
|
||||||
$sSQL .= ' LIMIT 1';
|
$sSQL .= ' LIMIT 1';
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$sPlaceGeom = $oDB->getOne($sSQL);
|
$sPlaceGeom = chksql($oDB->getOne($sSQL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sPlaceGeom) {
|
if ($sPlaceGeom) {
|
||||||
@@ -889,7 +886,7 @@ class SearchDescription
|
|||||||
$sSQL = 'SELECT place_id FROM placex';
|
$sSQL = 'SELECT place_id FROM placex';
|
||||||
$sSQL .= " WHERE place_id in ($sPlaceIDs) and rank_search < $iMaxRank";
|
$sSQL .= " WHERE place_id in ($sPlaceIDs) and rank_search < $iMaxRank";
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
$aPlaceIDs = $oDB->getCol($sSQL);
|
$aPlaceIDs = chksql($oDB->getCol($sSQL));
|
||||||
$sPlaceIDs = join(',', $aPlaceIDs);
|
$sPlaceIDs = join(',', $aPlaceIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,7 +932,7 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$aResults[$iPlaceId] = new Result($iPlaceId);
|
$aResults[$iPlaceId] = new Result($iPlaceId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -967,7 +964,7 @@ class SearchDescription
|
|||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
foreach ($oDB->getCol($sSQL) as $iPlaceId) {
|
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
|
||||||
$aResults[$iPlaceId] = new Result($iPlaceId);
|
$aResults[$iPlaceId] = new Result($iPlaceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace Nominatim;
|
namespace Nominatim;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use PEAR;
|
||||||
|
|
||||||
class Status
|
class Status
|
||||||
{
|
{
|
||||||
@@ -15,18 +16,12 @@ class Status
|
|||||||
|
|
||||||
public function status()
|
public function status()
|
||||||
{
|
{
|
||||||
if (!$this->oDB) {
|
if (!$this->oDB || PEAR::isError($this->oDB)) {
|
||||||
throw new Exception('No database', 700);
|
throw new Exception('No database', 700);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
$this->oDB->connect();
|
|
||||||
} catch (\Nominatim\DatabaseError $e) {
|
|
||||||
throw new Exception('Database connection failed', 700);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sStandardWord = $this->oDB->getOne("SELECT make_standard_name('a')");
|
$sStandardWord = $this->oDB->getOne("SELECT make_standard_name('a')");
|
||||||
if ($sStandardWord === false) {
|
if (PEAR::isError($sStandardWord)) {
|
||||||
throw new Exception('Module failed', 701);
|
throw new Exception('Module failed', 701);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +32,7 @@ class Status
|
|||||||
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code, ';
|
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code, ';
|
||||||
$sSQL .= "operator, search_name_count FROM word WHERE word_token IN (' a')";
|
$sSQL .= "operator, search_name_count FROM word WHERE word_token IN (' a')";
|
||||||
$iWordID = $this->oDB->getOne($sSQL);
|
$iWordID = $this->oDB->getOne($sSQL);
|
||||||
if ($iWordID === false) {
|
if (PEAR::isError($iWordID)) {
|
||||||
throw new Exception('Query failed', 703);
|
throw new Exception('Query failed', 703);
|
||||||
}
|
}
|
||||||
if (!$iWordID) {
|
if (!$iWordID) {
|
||||||
@@ -50,7 +45,7 @@ class Status
|
|||||||
$sSQL = 'SELECT EXTRACT(EPOCH FROM lastimportdate) FROM import_status LIMIT 1';
|
$sSQL = 'SELECT EXTRACT(EPOCH FROM lastimportdate) FROM import_status LIMIT 1';
|
||||||
$iDataDateEpoch = $this->oDB->getOne($sSQL);
|
$iDataDateEpoch = $this->oDB->getOne($sSQL);
|
||||||
|
|
||||||
if ($iDataDateEpoch === false) {
|
if (PEAR::isError($iDataDateEpoch)) {
|
||||||
throw Exception('Data date query failed '.$iDataDateEpoch->getMessage(), 705);
|
throw Exception('Data date query failed '.$iDataDateEpoch->getMessage(), 705);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class TokenList
|
|||||||
/**
|
/**
|
||||||
* Add token information from the word table in the database.
|
* Add token information from the word table in the database.
|
||||||
*
|
*
|
||||||
* @param object $oDB Nominatim::DB instance.
|
* @param object $oDB Database connection.
|
||||||
* @param string[] $aTokens List of tokens to look up in the database.
|
* @param string[] $aTokens List of tokens to look up in the database.
|
||||||
* @param string[] $aCountryCodes List of country restrictions.
|
* @param string[] $aCountryCodes List of country restrictions.
|
||||||
* @param string $sNormQuery Normalized query string.
|
* @param string $sNormQuery Normalized query string.
|
||||||
@@ -85,11 +85,11 @@ class TokenList
|
|||||||
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code,';
|
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code,';
|
||||||
$sSQL .= ' operator, coalesce(search_name_count, 0) as count';
|
$sSQL .= ' operator, coalesce(search_name_count, 0) as count';
|
||||||
$sSQL .= ' FROM word WHERE word_token in (';
|
$sSQL .= ' FROM word WHERE word_token in (';
|
||||||
$sSQL .= join(',', $oDB->getDBQuotedList($aTokens)).')';
|
$sSQL .= join(',', array_map('getDBQuoted', $aTokens)).')';
|
||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|
||||||
$aDBWords = $oDB->getAll($sSQL, null, 'Could not get word tokens.');
|
$aDBWords = chksql($oDB->getAll($sSQL), 'Could not get word tokens.');
|
||||||
|
|
||||||
foreach ($aDBWords as $aWord) {
|
foreach ($aDBWords as $aWord) {
|
||||||
$oToken = null;
|
$oToken = null;
|
||||||
|
|||||||
11
lib/cmd.php
11
lib/cmd.php
@@ -120,6 +120,15 @@ function showUsage($aSpec, $bExit = false, $sError = false)
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function chksql($oSql, $sMsg = false)
|
||||||
|
{
|
||||||
|
if (PEAR::isError($oSql)) {
|
||||||
|
fail($sMsg || $oSql->getMessage(), $oSql->userinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oSql;
|
||||||
|
}
|
||||||
|
|
||||||
function info($sMsg)
|
function info($sMsg)
|
||||||
{
|
{
|
||||||
echo date('Y-m-d H:i:s == ').$sMsg."\n";
|
echo date('Y-m-d H:i:s == ').$sMsg."\n";
|
||||||
@@ -146,7 +155,7 @@ function repeatWarnings()
|
|||||||
function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreErrors = false)
|
function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreErrors = false)
|
||||||
{
|
{
|
||||||
// Convert database DSN to psql parameters
|
// Convert database DSN to psql parameters
|
||||||
$aDSNInfo = \Nominatim\DB::parseDSN(CONST_Database_DSN);
|
$aDSNInfo = DB::parseDSN(CONST_Database_DSN);
|
||||||
if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
|
if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
|
||||||
$sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
|
$sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
|
||||||
if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
|
if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
|
||||||
|
|||||||
43
lib/db.php
Normal file
43
lib/db.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once('DB.php');
|
||||||
|
|
||||||
|
|
||||||
|
function &getDB($bNew = false, $bPersistent = false)
|
||||||
|
{
|
||||||
|
// Get the database object
|
||||||
|
$oDB = chksql(
|
||||||
|
DB::connect(CONST_Database_DSN.($bNew?'?new_link=true':''), $bPersistent),
|
||||||
|
'Failed to establish database connection'
|
||||||
|
);
|
||||||
|
$oDB->setFetchMode(DB_FETCHMODE_ASSOC);
|
||||||
|
$oDB->query("SET DateStyle TO 'sql,european'");
|
||||||
|
$oDB->query("SET client_encoding TO 'utf-8'");
|
||||||
|
$iMaxExecution = ini_get('max_execution_time') * 1000;
|
||||||
|
if ($iMaxExecution > 0) $oDB->query("SET statement_timeout TO $iMaxExecution");
|
||||||
|
return $oDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDBQuoted($s)
|
||||||
|
{
|
||||||
|
return "'".pg_escape_string($s)."'";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArraySQL($a)
|
||||||
|
{
|
||||||
|
return 'ARRAY['.join(',', $a).']';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPostgresVersion(&$oDB)
|
||||||
|
{
|
||||||
|
$sVersionString = $oDB->getOne('SHOW server_version_num');
|
||||||
|
preg_match('#([0-9]?[0-9])([0-9][0-9])[0-9][0-9]#', $sVersionString, $aMatches);
|
||||||
|
return (float) ($aMatches[1].'.'.$aMatches[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPostgisVersion(&$oDB)
|
||||||
|
{
|
||||||
|
$sVersionString = $oDB->getOne('select postgis_lib_version()');
|
||||||
|
preg_match('#^([0-9]+)[.]([0-9]+)[.]#', $sVersionString, $aMatches);
|
||||||
|
return (float) ($aMatches[1].'.'.$aMatches[2]);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
require_once('init.php');
|
require_once('init.php');
|
||||||
require_once('ParameterParser.php');
|
require_once('ParameterParser.php');
|
||||||
|
require_once('DatabaseError.php');
|
||||||
require_once(CONST_Debug ? 'DebugHtml.php' : 'DebugNone.php');
|
require_once(CONST_Debug ? 'DebugHtml.php' : 'DebugNone.php');
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@@ -10,6 +11,15 @@ require_once(CONST_Debug ? 'DebugHtml.php' : 'DebugNone.php');
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
function chksql($oSql, $sMsg = 'Database request failed')
|
||||||
|
{
|
||||||
|
if (!PEAR::isError($oSql)) return $oSql;
|
||||||
|
|
||||||
|
throw new Nominatim\DatabaseError($sMsg, 500, null, $oSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function userError($sMsg)
|
function userError($sMsg)
|
||||||
{
|
{
|
||||||
throw new Exception($sMsg, 400);
|
throw new Exception($sMsg, 400);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once(CONST_BasePath.'/lib/lib.php');
|
require_once(CONST_BasePath.'/lib/lib.php');
|
||||||
require_once(CONST_BasePath.'/lib/DB.php');
|
require_once(CONST_BasePath.'/lib/db.php');
|
||||||
|
|
||||||
if (get_magic_quotes_gpc()) {
|
if (get_magic_quotes_gpc()) {
|
||||||
echo "Please disable magic quotes in your php.ini configuration\n";
|
echo "Please disable magic quotes in your php.ini configuration\n";
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ function fail($sError, $sUserError = false)
|
|||||||
{
|
{
|
||||||
if (!$sUserError) $sUserError = $sError;
|
if (!$sUserError) $sUserError = $sError;
|
||||||
error_log('ERROR: '.$sError);
|
error_log('ERROR: '.$sError);
|
||||||
var_dump($sUserError)."\n";
|
echo $sUserError."\n";
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
lib/log.php
22
lib/log.php
@@ -36,18 +36,8 @@ function logStart(&$oDB, $sType = '', $sQuery = '', $aLanguageList = array())
|
|||||||
$sUserAgent = $_SERVER['HTTP_USER_AGENT'];
|
$sUserAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||||
else $sUserAgent = '';
|
else $sUserAgent = '';
|
||||||
$sSQL = 'insert into new_query_log (type,starttime,query,ipaddress,useragent,language,format,searchterm)';
|
$sSQL = 'insert into new_query_log (type,starttime,query,ipaddress,useragent,language,format,searchterm)';
|
||||||
$sSQL .= ' values ('.
|
$sSQL .= ' values ('.getDBQuoted($sType).','.getDBQuoted($hLog[0]).','.getDBQuoted($hLog[2]);
|
||||||
$sSQL .= join(',', $oDB->getDBQuotedList(array(
|
$sSQL .= ','.getDBQuoted($hLog[1]).','.getDBQuoted($sUserAgent).','.getDBQuoted(join(',', $aLanguageList)).','.getDBQuoted($sOutputFormat).','.getDBQuoted($hLog[3]).')';
|
||||||
$sType,
|
|
||||||
$hLog[0],
|
|
||||||
$hLog[2],
|
|
||||||
$hLog[1],
|
|
||||||
$sUserAgent,
|
|
||||||
join(',', $aLanguageList),
|
|
||||||
$sOutputFormat,
|
|
||||||
$hLog[3]
|
|
||||||
)));
|
|
||||||
$sSQL .= ')';
|
|
||||||
$oDB->query($sSQL);
|
$oDB->query($sSQL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,10 +53,10 @@ function logEnd(&$oDB, $hLog, $iNumResults)
|
|||||||
if (!$aEndTime[1]) $aEndTime[1] = '0';
|
if (!$aEndTime[1]) $aEndTime[1] = '0';
|
||||||
$sEndTime = date('Y-m-d H:i:s', $aEndTime[0]).'.'.$aEndTime[1];
|
$sEndTime = date('Y-m-d H:i:s', $aEndTime[0]).'.'.$aEndTime[1];
|
||||||
|
|
||||||
$sSQL = 'update new_query_log set endtime = '.$oDB->getDBQuoted($sEndTime).', results = '.$iNumResults;
|
$sSQL = 'update new_query_log set endtime = '.getDBQuoted($sEndTime).', results = '.$iNumResults;
|
||||||
$sSQL .= ' where starttime = '.$oDB->getDBQuoted($hLog[0]);
|
$sSQL .= ' where starttime = '.getDBQuoted($hLog[0]);
|
||||||
$sSQL .= ' and ipaddress = '.$oDB->getDBQuoted($hLog[1]);
|
$sSQL .= ' and ipaddress = '.getDBQuoted($hLog[1]);
|
||||||
$sSQL .= ' and query = '.$oDB->getDBQuoted($hLog[2]);
|
$sSQL .= ' and query = '.getDBQuoted($hLog[2]);
|
||||||
$oDB->query($sSQL);
|
$oDB->query($sSQL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,21 +53,21 @@ class AddressLevelParser
|
|||||||
*/
|
*/
|
||||||
public function createTable($oDB, $sTable)
|
public function createTable($oDB, $sTable)
|
||||||
{
|
{
|
||||||
$oDB->exec('DROP TABLE IF EXISTS '.$sTable);
|
chksql($oDB->query('DROP TABLE IF EXISTS '.$sTable));
|
||||||
$sSql = 'CREATE TABLE '.$sTable;
|
$sSql = 'CREATE TABLE '.$sTable;
|
||||||
$sSql .= '(country_code varchar(2), class TEXT, type TEXT,';
|
$sSql .= '(country_code varchar(2), class TEXT, type TEXT,';
|
||||||
$sSql .= ' rank_search SMALLINT, rank_address SMALLINT)';
|
$sSql .= ' rank_search SMALLINT, rank_address SMALLINT)';
|
||||||
$oDB->exec($sSql);
|
chksql($oDB->query($sSql));
|
||||||
|
|
||||||
$sSql = 'CREATE UNIQUE INDEX ON '.$sTable.' (country_code, class, type)';
|
$sSql = 'CREATE UNIQUE INDEX ON '.$sTable.'(country_code, class, type)';
|
||||||
$oDB->exec($sSql);
|
chksql($oDB->query($sSql));
|
||||||
|
|
||||||
$sSql = 'INSERT INTO '.$sTable.' VALUES ';
|
$sSql = 'INSERT INTO '.$sTable.' VALUES ';
|
||||||
foreach ($this->aLevels as $aLevel) {
|
foreach ($this->aLevels as $aLevel) {
|
||||||
$aCountries = array();
|
$aCountries = array();
|
||||||
if (isset($aLevel['countries'])) {
|
if (isset($aLevel['countries'])) {
|
||||||
foreach ($aLevel['countries'] as $sCountry) {
|
foreach ($aLevel['countries'] as $sCountry) {
|
||||||
$aCountries[$sCountry] = $oDB->getDBQuoted($sCountry);
|
$aCountries[$sCountry] = getDBQuoted($sCountry);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$aCountries['NULL'] = 'NULL';
|
$aCountries['NULL'] = 'NULL';
|
||||||
@@ -75,8 +75,8 @@ class AddressLevelParser
|
|||||||
foreach ($aLevel['tags'] as $sKey => $aValues) {
|
foreach ($aLevel['tags'] as $sKey => $aValues) {
|
||||||
foreach ($aValues as $sValue => $mRanks) {
|
foreach ($aValues as $sValue => $mRanks) {
|
||||||
$aFields = array(
|
$aFields = array(
|
||||||
$oDB->getDBQuoted($sKey),
|
getDBQuoted($sKey),
|
||||||
$sValue ? $oDB->getDBQuoted($sValue) : 'NULL'
|
$sValue ? getDBQuoted($sValue) : 'NULL'
|
||||||
);
|
);
|
||||||
if (is_array($mRanks)) {
|
if (is_array($mRanks)) {
|
||||||
$aFields[] = (string) $mRanks[0];
|
$aFields[] = (string) $mRanks[0];
|
||||||
@@ -93,6 +93,6 @@ class AddressLevelParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oDB->exec(rtrim($sSql, ','));
|
chksql($oDB->query(rtrim($sSql, ',')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class SetupFunctions
|
|||||||
info('module path: ' . $this->sModulePath);
|
info('module path: ' . $this->sModulePath);
|
||||||
|
|
||||||
// parse database string
|
// parse database string
|
||||||
$this->aDSNInfo = \Nominatim\DB::parseDSN(CONST_Database_DSN);
|
$this->aDSNInfo = array_filter(\DB::parseDSN(CONST_Database_DSN));
|
||||||
if (!isset($this->aDSNInfo['port'])) {
|
if (!isset($this->aDSNInfo['port'])) {
|
||||||
$this->aDSNInfo['port'] = 5432;
|
$this->aDSNInfo['port'] = 5432;
|
||||||
}
|
}
|
||||||
@@ -74,9 +74,8 @@ class SetupFunctions
|
|||||||
public function createDB()
|
public function createDB()
|
||||||
{
|
{
|
||||||
info('Create DB');
|
info('Create DB');
|
||||||
$oDB = new \Nominatim\DB;
|
$sDB = \DB::connect(CONST_Database_DSN, false);
|
||||||
|
if (!\PEAR::isError($sDB)) {
|
||||||
if ($oDB->databaseExists()) {
|
|
||||||
fail('database already exists ('.CONST_Database_DSN.')');
|
fail('database already exists ('.CONST_Database_DSN.')');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,15 +94,14 @@ class SetupFunctions
|
|||||||
|
|
||||||
public function connect()
|
public function connect()
|
||||||
{
|
{
|
||||||
$this->oDB = new \Nominatim\DB();
|
$this->oDB =& getDB();
|
||||||
$this->oDB->connect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setupDB()
|
public function setupDB()
|
||||||
{
|
{
|
||||||
info('Setup DB');
|
info('Setup DB');
|
||||||
|
|
||||||
$fPostgresVersion = $this->oDB->getPostgresVersion();
|
$fPostgresVersion = getPostgresVersion($this->oDB);
|
||||||
echo 'Postgres version found: '.$fPostgresVersion."\n";
|
echo 'Postgres version found: '.$fPostgresVersion."\n";
|
||||||
|
|
||||||
if ($fPostgresVersion < 9.01) {
|
if ($fPostgresVersion < 9.01) {
|
||||||
@@ -116,7 +114,7 @@ class SetupFunctions
|
|||||||
// For extratags and namedetails the hstore_to_json converter is
|
// For extratags and namedetails the hstore_to_json converter is
|
||||||
// needed which is only available from Postgresql 9.3+. For older
|
// needed which is only available from Postgresql 9.3+. For older
|
||||||
// versions add a dummy function that returns nothing.
|
// versions add a dummy function that returns nothing.
|
||||||
$iNumFunc = $this->oDB->getOne("select count(*) from pg_proc where proname = 'hstore_to_json'");
|
$iNumFunc = chksql($this->oDB->getOne("select count(*) from pg_proc where proname = 'hstore_to_json'"));
|
||||||
|
|
||||||
if ($iNumFunc == 0) {
|
if ($iNumFunc == 0) {
|
||||||
$this->pgsqlRunScript("create function hstore_to_json(dummy hstore) returns text AS 'select null::text' language sql immutable");
|
$this->pgsqlRunScript("create function hstore_to_json(dummy hstore) returns text AS 'select null::text' language sql immutable");
|
||||||
@@ -124,7 +122,7 @@ class SetupFunctions
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$fPostgisVersion = $this->oDB->getPostgisVersion();
|
$fPostgisVersion = getPostgisVersion($this->oDB);
|
||||||
echo 'Postgis version found: '.$fPostgisVersion."\n";
|
echo 'Postgis version found: '.$fPostgisVersion."\n";
|
||||||
|
|
||||||
if ($fPostgisVersion < 2.1) {
|
if ($fPostgisVersion < 2.1) {
|
||||||
@@ -136,7 +134,7 @@ class SetupFunctions
|
|||||||
$this->pgsqlRunScript('ALTER FUNCTION ST_Distance_Spheroid(geometry, geometry, spheroid) RENAME TO ST_DistanceSpheroid');
|
$this->pgsqlRunScript('ALTER FUNCTION ST_Distance_Spheroid(geometry, geometry, spheroid) RENAME TO ST_DistanceSpheroid');
|
||||||
}
|
}
|
||||||
|
|
||||||
$i = $this->oDB->getOne("select count(*) from pg_user where usename = '".CONST_Database_Web_User."'");
|
$i = chksql($this->oDB->getOne("select count(*) from pg_user where usename = '".CONST_Database_Web_User."'"));
|
||||||
if ($i == 0) {
|
if ($i == 0) {
|
||||||
echo "\nERROR: Web user '".CONST_Database_Web_User."' does not exist. Create it with:\n";
|
echo "\nERROR: Web user '".CONST_Database_Web_User."' does not exist. Create it with:\n";
|
||||||
echo "\n createuser ".CONST_Database_Web_User."\n\n";
|
echo "\n createuser ".CONST_Database_Web_User."\n\n";
|
||||||
@@ -144,7 +142,9 @@ class SetupFunctions
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try accessing the C module, so we know early if something is wrong
|
// Try accessing the C module, so we know early if something is wrong
|
||||||
checkModulePresence(); // raises exception on failure
|
if (!checkModulePresence()) {
|
||||||
|
fail('error loading nominatim.so module');
|
||||||
|
}
|
||||||
|
|
||||||
if (!file_exists(CONST_ExtraDataPath.'/country_osm_grid.sql.gz')) {
|
if (!file_exists(CONST_ExtraDataPath.'/country_osm_grid.sql.gz')) {
|
||||||
echo 'Error: you need to download the country_osm_grid first:';
|
echo 'Error: you need to download the country_osm_grid first:';
|
||||||
@@ -216,7 +216,7 @@ class SetupFunctions
|
|||||||
|
|
||||||
$this->runWithPgEnv($osm2pgsql);
|
$this->runWithPgEnv($osm2pgsql);
|
||||||
|
|
||||||
if (!$this->sIgnoreErrors && !$this->oDB->getRow('select * from place limit 1')) {
|
if (!$this->sIgnoreErrors && !chksql($this->oDB->getRow('select * from place limit 1'))) {
|
||||||
fail('No Data');
|
fail('No Data');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,9 +225,11 @@ class SetupFunctions
|
|||||||
{
|
{
|
||||||
info('Create Functions');
|
info('Create Functions');
|
||||||
|
|
||||||
// Try accessing the C module, so we know early if something is wrong
|
// Try accessing the C module, so we know eif something is wrong
|
||||||
checkModulePresence(); // raises exception on failure
|
// update.php calls this function
|
||||||
|
if (!checkModulePresence()) {
|
||||||
|
fail('error loading nominatim.so module');
|
||||||
|
}
|
||||||
$this->createSqlFunctions();
|
$this->createSqlFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,8 +378,7 @@ class SetupFunctions
|
|||||||
echo '.';
|
echo '.';
|
||||||
|
|
||||||
$sSQL = 'select distinct partition from country_name';
|
$sSQL = 'select distinct partition from country_name';
|
||||||
$aPartitions = $this->oDB->getCol($sSQL);
|
$aPartitions = chksql($this->oDB->getCol($sSQL));
|
||||||
|
|
||||||
if (!$this->bNoPartitions) $aPartitions[] = 0;
|
if (!$this->bNoPartitions) $aPartitions[] = 0;
|
||||||
foreach ($aPartitions as $sPartition) {
|
foreach ($aPartitions as $sPartition) {
|
||||||
$this->pgExec('TRUNCATE location_road_'.$sPartition);
|
$this->pgExec('TRUNCATE location_road_'.$sPartition);
|
||||||
@@ -398,48 +399,34 @@ class SetupFunctions
|
|||||||
|
|
||||||
info('Load Data');
|
info('Load Data');
|
||||||
$sColumns = 'osm_type, osm_id, class, type, name, admin_level, address, extratags, geometry';
|
$sColumns = 'osm_type, osm_id, class, type, name, admin_level, address, extratags, geometry';
|
||||||
|
|
||||||
$aDBInstances = array();
|
$aDBInstances = array();
|
||||||
$iLoadThreads = max(1, $this->iInstances - 1);
|
$iLoadThreads = max(1, $this->iInstances - 1);
|
||||||
for ($i = 0; $i < $iLoadThreads; $i++) {
|
for ($i = 0; $i < $iLoadThreads; $i++) {
|
||||||
// https://secure.php.net/manual/en/function.pg-connect.php
|
$aDBInstances[$i] =& getDB(true);
|
||||||
$DSN = CONST_Database_DSN;
|
|
||||||
$DSN = preg_replace('/^pgsql:/', '', $DSN);
|
|
||||||
$DSN = preg_replace('/;/', ' ', $DSN);
|
|
||||||
$aDBInstances[$i] = pg_connect($DSN, PGSQL_CONNECT_FORCE_NEW);
|
|
||||||
pg_ping($aDBInstances[$i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($i = 0; $i < $iLoadThreads; $i++) {
|
|
||||||
$sSQL = "INSERT INTO placex ($sColumns) SELECT $sColumns FROM place WHERE osm_id % $iLoadThreads = $i";
|
$sSQL = "INSERT INTO placex ($sColumns) SELECT $sColumns FROM place WHERE osm_id % $iLoadThreads = $i";
|
||||||
$sSQL .= " and not (class='place' and type='houses' and osm_type='W'";
|
$sSQL .= " and not (class='place' and type='houses' and osm_type='W'";
|
||||||
$sSQL .= " and ST_GeometryType(geometry) = 'ST_LineString')";
|
$sSQL .= " and ST_GeometryType(geometry) = 'ST_LineString')";
|
||||||
$sSQL .= ' and ST_IsValid(geometry)';
|
$sSQL .= ' and ST_IsValid(geometry)';
|
||||||
if ($this->bVerbose) echo "$sSQL\n";
|
if ($this->bVerbose) echo "$sSQL\n";
|
||||||
if (!pg_send_query($aDBInstances[$i], $sSQL)) {
|
if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) {
|
||||||
fail(pg_last_error($aDBInstances[$i]));
|
fail(pg_last_error($aDBInstances[$i]->connection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// last thread for interpolation lines
|
// last thread for interpolation lines
|
||||||
// https://secure.php.net/manual/en/function.pg-connect.php
|
$aDBInstances[$iLoadThreads] =& getDB(true);
|
||||||
$DSN = CONST_Database_DSN;
|
|
||||||
$DSN = preg_replace('/^pgsql:/', '', $DSN);
|
|
||||||
$DSN = preg_replace('/;/', ' ', $DSN);
|
|
||||||
$aDBInstances[$iLoadThreads] = pg_connect($DSN, PGSQL_CONNECT_FORCE_NEW);
|
|
||||||
pg_ping($aDBInstances[$iLoadThreads]);
|
|
||||||
$sSQL = 'insert into location_property_osmline';
|
$sSQL = 'insert into location_property_osmline';
|
||||||
$sSQL .= ' (osm_id, address, linegeo)';
|
$sSQL .= ' (osm_id, address, linegeo)';
|
||||||
$sSQL .= ' SELECT osm_id, address, geometry from place where ';
|
$sSQL .= ' SELECT osm_id, address, geometry from place where ';
|
||||||
$sSQL .= "class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString'";
|
$sSQL .= "class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString'";
|
||||||
if ($this->bVerbose) echo "$sSQL\n";
|
if ($this->bVerbose) echo "$sSQL\n";
|
||||||
if (!pg_send_query($aDBInstances[$iLoadThreads], $sSQL)) {
|
if (!pg_send_query($aDBInstances[$iLoadThreads]->connection, $sSQL)) {
|
||||||
fail(pg_last_error($aDBInstances[$iLoadThreads]));
|
fail(pg_last_error($aDBInstances[$iLoadThreads]->connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
$bFailed = false;
|
$bFailed = false;
|
||||||
for ($i = 0; $i <= $iLoadThreads; $i++) {
|
for ($i = 0; $i <= $iLoadThreads; $i++) {
|
||||||
while (($hPGresult = pg_get_result($aDBInstances[$i])) !== false) {
|
while (($hPGresult = pg_get_result($aDBInstances[$i]->connection)) !== false) {
|
||||||
$resultStatus = pg_result_status($hPGresult);
|
$resultStatus = pg_result_status($hPGresult);
|
||||||
// PGSQL_EMPTY_QUERY, PGSQL_COMMAND_OK, PGSQL_TUPLES_OK,
|
// PGSQL_EMPTY_QUERY, PGSQL_COMMAND_OK, PGSQL_TUPLES_OK,
|
||||||
// PGSQL_COPY_OUT, PGSQL_COPY_IN, PGSQL_BAD_RESPONSE,
|
// PGSQL_COPY_OUT, PGSQL_COPY_IN, PGSQL_BAD_RESPONSE,
|
||||||
@@ -455,22 +442,17 @@ class SetupFunctions
|
|||||||
if ($bFailed) {
|
if ($bFailed) {
|
||||||
fail('SQL errors loading placex and/or location_property_osmline tables');
|
fail('SQL errors loading placex and/or location_property_osmline tables');
|
||||||
}
|
}
|
||||||
|
|
||||||
for ($i = 0; $i < $this->iInstances; $i++) {
|
|
||||||
pg_close($aDBInstances[$i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\n";
|
echo "\n";
|
||||||
info('Reanalysing database');
|
info('Reanalysing database');
|
||||||
$this->pgsqlRunScript('ANALYSE');
|
$this->pgsqlRunScript('ANALYSE');
|
||||||
|
|
||||||
$sDatabaseDate = getDatabaseDate($this->oDB);
|
$sDatabaseDate = getDatabaseDate($this->oDB);
|
||||||
$this->oDB->exec('TRUNCATE import_status');
|
pg_query($this->oDB->connection, 'TRUNCATE import_status');
|
||||||
if (!$sDatabaseDate) {
|
if ($sDatabaseDate === false) {
|
||||||
warn('could not determine database date.');
|
warn('could not determine database date.');
|
||||||
} else {
|
} else {
|
||||||
$sSQL = "INSERT INTO import_status (lastimportdate) VALUES('".$sDatabaseDate."')";
|
$sSQL = "INSERT INTO import_status (lastimportdate) VALUES('".$sDatabaseDate."')";
|
||||||
$this->oDB->exec($sSQL);
|
pg_query($this->oDB->connection, $sSQL);
|
||||||
echo "Latest data imported from $sDatabaseDate.\n";
|
echo "Latest data imported from $sDatabaseDate.\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,12 +477,7 @@ class SetupFunctions
|
|||||||
|
|
||||||
$aDBInstances = array();
|
$aDBInstances = array();
|
||||||
for ($i = 0; $i < $this->iInstances; $i++) {
|
for ($i = 0; $i < $this->iInstances; $i++) {
|
||||||
// https://secure.php.net/manual/en/function.pg-connect.php
|
$aDBInstances[$i] =& getDB(true);
|
||||||
$DSN = CONST_Database_DSN;
|
|
||||||
$DSN = preg_replace('/^pgsql:/', '', $DSN);
|
|
||||||
$DSN = preg_replace('/;/', ' ', $DSN);
|
|
||||||
$aDBInstances[$i] = pg_connect($DSN, PGSQL_CONNECT_FORCE_NEW | PGSQL_CONNECT_ASYNC);
|
|
||||||
pg_ping($aDBInstances[$i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (glob(CONST_Tiger_Data_Path.'/*.sql') as $sFile) {
|
foreach (glob(CONST_Tiger_Data_Path.'/*.sql') as $sFile) {
|
||||||
@@ -510,11 +487,11 @@ class SetupFunctions
|
|||||||
$iLines = 0;
|
$iLines = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
for ($i = 0; $i < $this->iInstances; $i++) {
|
for ($i = 0; $i < $this->iInstances; $i++) {
|
||||||
if (!pg_connection_busy($aDBInstances[$i])) {
|
if (!pg_connection_busy($aDBInstances[$i]->connection)) {
|
||||||
while (pg_get_result($aDBInstances[$i]));
|
while (pg_get_result($aDBInstances[$i]->connection));
|
||||||
$sSQL = fgets($hFile, 100000);
|
$sSQL = fgets($hFile, 100000);
|
||||||
if (!$sSQL) break 2;
|
if (!$sSQL) break 2;
|
||||||
if (!pg_send_query($aDBInstances[$i], $sSQL)) fail(pg_last_error($aDBInstances[$i]));
|
if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($this->oDB->connection));
|
||||||
$iLines++;
|
$iLines++;
|
||||||
if ($iLines == 1000) {
|
if ($iLines == 1000) {
|
||||||
echo '.';
|
echo '.';
|
||||||
@@ -530,17 +507,13 @@ class SetupFunctions
|
|||||||
while ($bAnyBusy) {
|
while ($bAnyBusy) {
|
||||||
$bAnyBusy = false;
|
$bAnyBusy = false;
|
||||||
for ($i = 0; $i < $this->iInstances; $i++) {
|
for ($i = 0; $i < $this->iInstances; $i++) {
|
||||||
if (pg_connection_busy($aDBInstances[$i])) $bAnyBusy = true;
|
if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
|
||||||
}
|
}
|
||||||
usleep(10);
|
usleep(10);
|
||||||
}
|
}
|
||||||
echo "\n";
|
echo "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for ($i = 0; $i < $this->iInstances; $i++) {
|
|
||||||
pg_close($aDBInstances[$i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
info('Creating indexes on Tiger data');
|
info('Creating indexes on Tiger data');
|
||||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_finish.sql');
|
$sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_finish.sql');
|
||||||
$sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
|
$sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
|
||||||
@@ -724,7 +697,7 @@ class SetupFunctions
|
|||||||
);
|
);
|
||||||
|
|
||||||
$aDropTables = array();
|
$aDropTables = array();
|
||||||
$aHaveTables = $this->oDB->getCol("SELECT tablename FROM pg_tables WHERE schemaname='public'");
|
$aHaveTables = chksql($this->oDB->getCol("SELECT tablename FROM pg_tables WHERE schemaname='public'"));
|
||||||
|
|
||||||
foreach ($aHaveTables as $sTable) {
|
foreach ($aHaveTables as $sTable) {
|
||||||
$bFound = false;
|
$bFound = false;
|
||||||
@@ -738,7 +711,7 @@ class SetupFunctions
|
|||||||
}
|
}
|
||||||
foreach ($aDropTables as $sDrop) {
|
foreach ($aDropTables as $sDrop) {
|
||||||
if ($this->bVerbose) echo "Dropping table $sDrop\n";
|
if ($this->bVerbose) echo "Dropping table $sDrop\n";
|
||||||
$this->oDB->exec("DROP TABLE $sDrop CASCADE");
|
@pg_query($this->oDB->connection, "DROP TABLE $sDrop CASCADE");
|
||||||
// ignore warnings/errors as they might be caused by a table having
|
// ignore warnings/errors as they might be caused by a table having
|
||||||
// been deleted already by CASCADE
|
// been deleted already by CASCADE
|
||||||
}
|
}
|
||||||
@@ -753,10 +726,7 @@ class SetupFunctions
|
|||||||
|
|
||||||
private function pgsqlRunDropAndRestore($sDumpFile)
|
private function pgsqlRunDropAndRestore($sDumpFile)
|
||||||
{
|
{
|
||||||
$sCMD = 'pg_restore -p '.$this->aDSNInfo['port'].' -d '.$this->aDSNInfo['database'].' --no-owner -Fc --clean '.$sDumpFile;
|
$sCMD = 'pg_restore -p '.$this->aDSNInfo['port'].' -d '.$this->aDSNInfo['database'].' -Fc --clean '.$sDumpFile;
|
||||||
if ($this->oDB->getPostgresVersion() >= 9.04) {
|
|
||||||
$sCMD .= ' --if-exists';
|
|
||||||
}
|
|
||||||
if (isset($this->aDSNInfo['hostspec'])) {
|
if (isset($this->aDSNInfo['hostspec'])) {
|
||||||
$sCMD .= ' -h '.$this->aDSNInfo['hostspec'];
|
$sCMD .= ' -h '.$this->aDSNInfo['hostspec'];
|
||||||
}
|
}
|
||||||
@@ -806,7 +776,7 @@ class SetupFunctions
|
|||||||
private function pgsqlRunPartitionScript($sTemplate)
|
private function pgsqlRunPartitionScript($sTemplate)
|
||||||
{
|
{
|
||||||
$sSQL = 'select distinct partition from country_name';
|
$sSQL = 'select distinct partition from country_name';
|
||||||
$aPartitions = $this->oDB->getCol($sSQL);
|
$aPartitions = chksql($this->oDB->getCol($sSQL));
|
||||||
if (!$this->bNoPartitions) $aPartitions[] = 0;
|
if (!$this->bNoPartitions) $aPartitions[] = 0;
|
||||||
|
|
||||||
preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
|
preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
|
||||||
@@ -913,7 +883,9 @@ class SetupFunctions
|
|||||||
*/
|
*/
|
||||||
private function pgExec($sSQL)
|
private function pgExec($sSQL)
|
||||||
{
|
{
|
||||||
$this->oDB->exec($sSQL);
|
if (!pg_query($this->oDB->connection, $sSQL)) {
|
||||||
|
fail(pg_last_error($this->oDB->connection));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -923,6 +895,7 @@ class SetupFunctions
|
|||||||
*/
|
*/
|
||||||
private function dbReverseOnly()
|
private function dbReverseOnly()
|
||||||
{
|
{
|
||||||
return !($this->oDB->tableExists('search_name'));
|
$sSQL = "SELECT count(*) FROM pg_tables WHERE tablename = 'search_name'";
|
||||||
|
return !(chksql($this->oDB->getOne($sSQL)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,15 +17,22 @@ function checkInFile($sOSMFile)
|
|||||||
|
|
||||||
function checkModulePresence()
|
function checkModulePresence()
|
||||||
{
|
{
|
||||||
// Try accessing the C module, so we know early if something is wrong.
|
// Try accessing the C module, so we know early if something is wrong
|
||||||
// Raises Nominatim\DatabaseError on failure
|
// and can simply error out.
|
||||||
|
|
||||||
$sModulePath = CONST_Database_Module_Path;
|
$sModulePath = CONST_Database_Module_Path;
|
||||||
$sSQL = "CREATE FUNCTION nominatim_test_import_func(text) RETURNS text AS '";
|
$sSQL = "CREATE FUNCTION nominatim_test_import_func(text) RETURNS text AS '";
|
||||||
$sSQL .= $sModulePath . "/nominatim.so', 'transliteration' LANGUAGE c IMMUTABLE STRICT";
|
$sSQL .= $sModulePath . "/nominatim.so', 'transliteration' LANGUAGE c IMMUTABLE STRICT";
|
||||||
$sSQL .= ';DROP FUNCTION nominatim_test_import_func(text);';
|
$sSQL .= ';DROP FUNCTION nominatim_test_import_func(text);';
|
||||||
|
|
||||||
$oDB = new \Nominatim\DB();
|
$oDB = &getDB();
|
||||||
$oDB->connect();
|
$oResult = $oDB->query($sSQL);
|
||||||
$oDB->exec($sSQL, null, 'Database server failed to load '.$sModulePath.'/nominatim.so module');
|
|
||||||
|
$bResult = true;
|
||||||
|
|
||||||
|
if (PEAR::isError($oResult)) {
|
||||||
|
echo "\nERROR: Failed to load nominatim module. Reason:\n";
|
||||||
|
echo $oResult->userinfo . "\n\n";
|
||||||
|
$bResult = false;
|
||||||
|
}
|
||||||
|
return $bResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
|
|
||||||
|
|
||||||
function _one_row($aAddressLine){
|
function _one_row($aAddressLine){
|
||||||
$bNotUsed = isset($aAddressLine['isaddress']) && !$aAddressLine['isaddress'];
|
$bNotUsed = (isset($aAddressLine['isaddress']) && $aAddressLine['isaddress'] == 'f');
|
||||||
|
|
||||||
echo '<tr class="' . ($bNotUsed?'notused':'') . '">'."\n";
|
echo '<tr class="' . ($bNotUsed?'notused':'') . '">'."\n";
|
||||||
echo ' <td class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>')."</td>\n";
|
echo ' <td class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>')."</td>\n";
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
if ($aPointDetails['calculated_importance']) {
|
if ($aPointDetails['calculated_importance']) {
|
||||||
kv('Importance' , $aPointDetails['calculated_importance'].($aPointDetails['importance']?'':' (estimated)') );
|
kv('Importance' , $aPointDetails['calculated_importance'].($aPointDetails['importance']?'':' (estimated)') );
|
||||||
}
|
}
|
||||||
kv('Coverage' , ($aPointDetails['isarea']?'Polygon':'Point') );
|
kv('Coverage' , ($aPointDetails['isarea']=='t'?'Polygon':'Point') );
|
||||||
kv('Centre Point' , $aPointDetails['lat'].','.$aPointDetails['lon'] );
|
kv('Centre Point' , $aPointDetails['lat'].','.$aPointDetails['lon'] );
|
||||||
kv('OSM' , osmLink($aPointDetails) );
|
kv('OSM' , osmLink($aPointDetails) );
|
||||||
if ($aPointDetails['wikipedia'])
|
if ($aPointDetails['wikipedia'])
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ if ($aPointDetails['icon']) {
|
|||||||
$aPlaceDetails['rank_address'] = (int) $aPointDetails['rank_address'];
|
$aPlaceDetails['rank_address'] = (int) $aPointDetails['rank_address'];
|
||||||
$aPlaceDetails['rank_search'] = (int) $aPointDetails['rank_search'];
|
$aPlaceDetails['rank_search'] = (int) $aPointDetails['rank_search'];
|
||||||
|
|
||||||
$aPlaceDetails['isarea'] = $aPointDetails['isarea'];
|
$aPlaceDetails['isarea'] = ($aPointDetails['isarea'] == 't');
|
||||||
$aPlaceDetails['centroid'] = array(
|
$aPlaceDetails['centroid'] = array(
|
||||||
'type' => 'Point',
|
'type' => 'Point',
|
||||||
'coordinates' => array( (float) $aPointDetails['lon'], (float) $aPointDetails['lat'] )
|
'coordinates' => array( (float) $aPointDetails['lon'], (float) $aPointDetails['lat'] )
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ if (isset($_GET['debug']) && $_GET['debug']) @define('CONST_Debug', true);
|
|||||||
|
|
||||||
// General settings
|
// General settings
|
||||||
@define('CONST_Debug', false);
|
@define('CONST_Debug', false);
|
||||||
@define('CONST_Database_DSN', 'pgsql:dbname=nominatim'); // or add ;host=...;port=...;user=...;password=...
|
@define('CONST_Database_DSN', 'pgsql://@/nominatim'); // <driver>://<username>:<password>@<host>:<port>/<database>
|
||||||
@define('CONST_Database_Web_User', 'www-data');
|
@define('CONST_Database_Web_User', 'www-data');
|
||||||
@define('CONST_Database_Module_Path', CONST_InstallPath.'/module');
|
@define('CONST_Database_Module_Path', CONST_InstallPath.'/module');
|
||||||
@define('CONST_Max_Word_Frequency', '50000');
|
@define('CONST_Max_Word_Frequency', '50000');
|
||||||
|
|||||||
@@ -2318,7 +2318,6 @@ DECLARE
|
|||||||
searchhousename HSTORE;
|
searchhousename HSTORE;
|
||||||
searchrankaddress INTEGER;
|
searchrankaddress INTEGER;
|
||||||
searchpostcode TEXT;
|
searchpostcode TEXT;
|
||||||
postcode_isaddress BOOL;
|
|
||||||
searchclass TEXT;
|
searchclass TEXT;
|
||||||
searchtype TEXT;
|
searchtype TEXT;
|
||||||
countryname HSTORE;
|
countryname HSTORE;
|
||||||
@@ -2326,8 +2325,6 @@ BEGIN
|
|||||||
-- The place ein question might not have a direct entry in place_addressline.
|
-- The place ein question might not have a direct entry in place_addressline.
|
||||||
-- Look for the parent of such places then and save if in for_place_id.
|
-- Look for the parent of such places then and save if in for_place_id.
|
||||||
|
|
||||||
postcode_isaddress := true;
|
|
||||||
|
|
||||||
-- first query osmline (interpolation lines)
|
-- first query osmline (interpolation lines)
|
||||||
IF in_housenumber >= 0 THEN
|
IF in_housenumber >= 0 THEN
|
||||||
SELECT parent_place_id, country_code, in_housenumber::text, 30, postcode,
|
SELECT parent_place_id, country_code, in_housenumber::text, 30, postcode,
|
||||||
@@ -2444,10 +2441,7 @@ BEGIN
|
|||||||
searchcountrycode := location.country_code;
|
searchcountrycode := location.country_code;
|
||||||
END IF;
|
END IF;
|
||||||
IF location.type in ('postcode', 'postal_code') THEN
|
IF location.type in ('postcode', 'postal_code') THEN
|
||||||
postcode_isaddress := false;
|
location.isaddress := FALSE;
|
||||||
IF location.osm_type != 'R' THEN
|
|
||||||
location.isaddress := FALSE;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
END IF;
|
||||||
countrylocation := ROW(location.place_id, location.osm_type, location.osm_id,
|
countrylocation := ROW(location.place_id, location.osm_type, location.osm_id,
|
||||||
location.name, location.class, location.type,
|
location.name, location.class, location.type,
|
||||||
@@ -2491,7 +2485,7 @@ BEGIN
|
|||||||
|
|
||||||
IF searchpostcode IS NOT NULL THEN
|
IF searchpostcode IS NOT NULL THEN
|
||||||
location := ROW(null, null, null, hstore('ref', searchpostcode), 'place',
|
location := ROW(null, null, null, hstore('ref', searchpostcode), 'place',
|
||||||
'postcode', null, false, postcode_isaddress, 5, 0)::addressline;
|
'postcode', null, true, true, 5, 0)::addressline;
|
||||||
RETURN NEXT location;
|
RETURN NEXT location;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,3 @@ Feature: Object details
|
|||||||
| 1 |
|
| 1 |
|
||||||
Then the result is valid html
|
Then the result is valid html
|
||||||
|
|
||||||
# ticket #1343
|
|
||||||
Scenario: Details of a country with keywords
|
|
||||||
When sending details query for R287072
|
|
||||||
| keywords |
|
|
||||||
| 1 |
|
|
||||||
Then the result is valid html
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,18 +26,6 @@ Feature: Searches with postcodes
|
|||||||
| country_code |
|
| country_code |
|
||||||
| li |
|
| li |
|
||||||
|
|
||||||
Scenario: Postcode search with bounded viewbox restriction
|
|
||||||
When sending json search query "9486" with address
|
|
||||||
| bounded | viewbox |
|
|
||||||
| 1 | 9.55,47.20,9.58,47.22 |
|
|
||||||
Then result addresses contain
|
|
||||||
| postcode |
|
|
||||||
| 9486 |
|
|
||||||
When sending json search query "9486" with address
|
|
||||||
| bounded | viewbox |
|
|
||||||
| 1 | 5.00,20.00,6.00,21.00 |
|
|
||||||
Then exactly 0 results are returned
|
|
||||||
|
|
||||||
Scenario: Postcode search with structured query
|
Scenario: Postcode search with structured query
|
||||||
When sending json search query "" with address
|
When sending json search query "" with address
|
||||||
| postalcode | country |
|
| postalcode | country |
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Feature: Status queries against unknown database
|
|||||||
Scenario: Failed status as text
|
Scenario: Failed status as text
|
||||||
When sending text status query
|
When sending text status query
|
||||||
Then a HTTP 500 is returned
|
Then a HTTP 500 is returned
|
||||||
And the page contents equals "ERROR: Database connection failed"
|
And the page contents equals "ERROR: No database"
|
||||||
|
|
||||||
Scenario: Failed status as json
|
Scenario: Failed status as json
|
||||||
When sending json status query
|
When sending json status query
|
||||||
@@ -13,5 +13,5 @@ Feature: Status queries against unknown database
|
|||||||
And the result is valid json
|
And the result is valid json
|
||||||
And results contain
|
And results contain
|
||||||
| status | message |
|
| status | message |
|
||||||
| 700 | Database connection failed |
|
| 700 | No database |
|
||||||
And result has not attributes data_updated
|
And result has not attributes data_updated
|
||||||
|
|||||||
@@ -344,23 +344,3 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to no interpolation
|
Then W1 expands to no interpolation
|
||||||
|
|
||||||
Scenario: Two point interpolation starting at 0
|
|
||||||
Given the places
|
|
||||||
| osm | class | type | housenr | geometry |
|
|
||||||
| N1 | place | house | 0 | 1 1 |
|
|
||||||
| N2 | place | house | 2 | 1 1.001 |
|
|
||||||
And the places
|
|
||||||
| osm | class | type | addr+interpolation | geometry |
|
|
||||||
| W1 | place | houses | even | 1 1, 1 1.001 |
|
|
||||||
And the ways
|
|
||||||
| id | nodes |
|
|
||||||
| 1 | 1,2 |
|
|
||||||
When importing
|
|
||||||
Then W1 expands to interpolation
|
|
||||||
| start | end | geometry |
|
|
||||||
| 0 | 2 | 1 1, 1 1.001 |
|
|
||||||
When sending jsonv2 reverse coordinates 1,1
|
|
||||||
Then results contain
|
|
||||||
| ID | osm_type | osm_id | type | display_name |
|
|
||||||
| 0 | way | 1 | house | 0 |
|
|
||||||
|
|
||||||
|
|||||||
@@ -73,14 +73,12 @@ class NominatimEnvironment(object):
|
|||||||
|
|
||||||
def write_nominatim_config(self, dbname):
|
def write_nominatim_config(self, dbname):
|
||||||
f = open(self.local_settings_file, 'w')
|
f = open(self.local_settings_file, 'w')
|
||||||
# https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
|
f.write("<?php\n @define('CONST_Database_DSN', 'pgsql://%s:%s@%s%s/%s');\n" %
|
||||||
f.write("<?php\n @define('CONST_Database_DSN', 'pgsql:dbname=%s%s%s%s%s');\n" %
|
(self.db_user if self.db_user else '',
|
||||||
(dbname,
|
self.db_pass if self.db_pass else '',
|
||||||
(';host=' + self.db_host) if self.db_host else '',
|
self.db_host if self.db_host else '',
|
||||||
(';port=' + self.db_port) if self.db_port else '',
|
(':' + self.db_port) if self.db_port else '',
|
||||||
(';user=' + self.db_user) if self.db_user else '',
|
dbname))
|
||||||
(';password=' + self.db_pass) if self.db_pass else ''
|
|
||||||
))
|
|
||||||
f.write("@define('CONST_Osm2pgsql_Flatnode_File', null);\n")
|
f.write("@define('CONST_Osm2pgsql_Flatnode_File', null);\n")
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class GenericResponse(object):
|
|||||||
pass
|
pass
|
||||||
elif h == 'osm':
|
elif h == 'osm':
|
||||||
assert_equal(res['osm_type'], row[h][0])
|
assert_equal(res['osm_type'], row[h][0])
|
||||||
assert_equal(res['osm_id'], int(row[h][1:]))
|
assert_equal(res['osm_id'], row[h][1:])
|
||||||
elif h == 'centroid':
|
elif h == 'centroid':
|
||||||
x, y = row[h].split(' ')
|
x, y = row[h].split(' ')
|
||||||
assert_almost_equal(float(y), float(res['lat']))
|
assert_almost_equal(float(y), float(res['lat']))
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Nominatim;
|
|
||||||
|
|
||||||
require_once(CONST_BasePath.'/lib/lib.php');
|
|
||||||
require_once(CONST_BasePath.'/lib/DB.php');
|
|
||||||
|
|
||||||
// subclassing so we can set the protected connection variable
|
|
||||||
class NominatimSubClassedDB extends \Nominatim\DB
|
|
||||||
{
|
|
||||||
public function setConnection($oConnection)
|
|
||||||
{
|
|
||||||
$this->connection = $oConnection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// phpcs:ignore PSR1.Classes.ClassDeclaration.MultipleClasses
|
|
||||||
class DBTest extends \PHPUnit\Framework\TestCase
|
|
||||||
{
|
|
||||||
public function testReusingConnection()
|
|
||||||
{
|
|
||||||
$oDB = new NominatimSubClassedDB('');
|
|
||||||
$oDB->setConnection('anything');
|
|
||||||
$this->assertTrue($oDB->connect());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testDatabaseExists()
|
|
||||||
{
|
|
||||||
$oDB = new \Nominatim\DB('');
|
|
||||||
$this->assertFalse($oDB->databaseExists());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testErrorHandling()
|
|
||||||
{
|
|
||||||
$this->expectException(DatabaseError::class);
|
|
||||||
$this->expectExceptionMessage('Failed to establish database connection');
|
|
||||||
|
|
||||||
$oDB = new \Nominatim\DB('pgsql:dbname=abc');
|
|
||||||
$oDB->connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testErrorHandling2()
|
|
||||||
{
|
|
||||||
$this->expectException(DatabaseError::class);
|
|
||||||
$this->expectExceptionMessage('Database query failed');
|
|
||||||
|
|
||||||
$oPDOStub = $this->getMockBuilder(PDO::class)
|
|
||||||
->setMethods(array('query', 'quote'))
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$oPDOStub->method('query')
|
|
||||||
->will($this->returnCallback(function ($sVal) {
|
|
||||||
return "'$sVal'";
|
|
||||||
}));
|
|
||||||
|
|
||||||
$oPDOStub->method('query')
|
|
||||||
->will($this->returnCallback(function () {
|
|
||||||
throw new \PDOException('ERROR: syntax error at or near "FROM"');
|
|
||||||
}));
|
|
||||||
|
|
||||||
$oDB = new NominatimSubClassedDB('');
|
|
||||||
$oDB->setConnection($oPDOStub);
|
|
||||||
$oDB->getOne('SELECT name FROM');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetPostgresVersion()
|
|
||||||
{
|
|
||||||
$oDBStub = $this->getMockBuilder(\Nominatim\DB::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->setMethods(array('getOne'))
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$oDBStub->method('getOne')
|
|
||||||
->willReturn('100006');
|
|
||||||
|
|
||||||
$this->assertEquals(10, $oDBStub->getPostgresVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetPostgisVersion()
|
|
||||||
{
|
|
||||||
$oDBStub = $this->getMockBuilder(\Nominatim\DB::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->setMethods(array('getOne'))
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$oDBStub->method('getOne')
|
|
||||||
->willReturn('2.4.4');
|
|
||||||
|
|
||||||
$this->assertEquals(2.4, $oDBStub->getPostgisVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testParseDSN()
|
|
||||||
{
|
|
||||||
$this->assertEquals(
|
|
||||||
array(),
|
|
||||||
\Nominatim\DB::parseDSN('')
|
|
||||||
);
|
|
||||||
$this->assertEquals(
|
|
||||||
array(
|
|
||||||
'database' => 'db1',
|
|
||||||
'hostspec' => 'machine1'
|
|
||||||
),
|
|
||||||
\Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1')
|
|
||||||
);
|
|
||||||
$this->assertEquals(
|
|
||||||
array(
|
|
||||||
'database' => 'db1',
|
|
||||||
'hostspec' => 'machine1',
|
|
||||||
'port' => '1234',
|
|
||||||
'username' => 'john',
|
|
||||||
'password' => 'secret'
|
|
||||||
),
|
|
||||||
\Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1;port=1234;user=john;password=secret')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ class DatabaseErrorTest extends \PHPUnit\Framework\TestCase
|
|||||||
|
|
||||||
public function testSqlMessage()
|
public function testSqlMessage()
|
||||||
{
|
{
|
||||||
$oSqlStub = $this->getMockBuilder(PDOException::class)
|
$oSqlStub = $this->getMockBuilder(\DB_Error::class)
|
||||||
->setMethods(array('getMessage'))
|
->setMethods(array('getMessage'))
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
@@ -21,6 +21,9 @@ class DatabaseErrorTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->assertEquals('Sql error', $oErr->getMessage());
|
$this->assertEquals('Sql error', $oErr->getMessage());
|
||||||
$this->assertEquals(123, $oErr->getCode());
|
$this->assertEquals(123, $oErr->getCode());
|
||||||
$this->assertEquals('Unknown table.', $oErr->getSqlError());
|
$this->assertEquals('Unknown table.', $oErr->getSqlError());
|
||||||
|
|
||||||
|
// causes a circular reference warning during dump
|
||||||
|
// $this->assertRegExp('/Mock_DB_Error/', $oErr->getSqlDebugDump());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSqlObjectDump()
|
public function testSqlObjectDump()
|
||||||
@@ -28,4 +31,14 @@ class DatabaseErrorTest extends \PHPUnit\Framework\TestCase
|
|||||||
$oErr = new DatabaseError('Sql error', 123, null, array('one' => 'two'));
|
$oErr = new DatabaseError('Sql error', 123, null, array('one' => 'two'));
|
||||||
$this->assertRegExp('/two/', $oErr->getSqlDebugDump());
|
$this->assertRegExp('/two/', $oErr->getSqlDebugDump());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testChksqlThrows()
|
||||||
|
{
|
||||||
|
$this->expectException(DatabaseError::class);
|
||||||
|
$this->expectExceptionMessage('My custom error message');
|
||||||
|
$this->expectExceptionCode(500);
|
||||||
|
|
||||||
|
$oDB = new \DB_Error;
|
||||||
|
$this->assertEquals(false, chksql($oDB, 'My custom error message'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Nominatim;
|
namespace Nominatim;
|
||||||
|
|
||||||
require_once(CONST_BasePath.'/lib/DB.php');
|
require_once(CONST_BasePath.'/lib/db.php');
|
||||||
require_once(CONST_BasePath.'/lib/Status.php');
|
require_once(CONST_BasePath.'/lib/Status.php');
|
||||||
|
|
||||||
|
|
||||||
@@ -23,20 +23,19 @@ class StatusTest extends \PHPUnit\Framework\TestCase
|
|||||||
public function testNoDatabaseConnectionFail()
|
public function testNoDatabaseConnectionFail()
|
||||||
{
|
{
|
||||||
$this->expectException(\Exception::class);
|
$this->expectException(\Exception::class);
|
||||||
$this->expectExceptionMessage('Database connection failed');
|
$this->expectExceptionMessage('No database');
|
||||||
$this->expectExceptionCode(700);
|
$this->expectExceptionCode(700);
|
||||||
|
|
||||||
$oDbStub = $this->getMockBuilder(Nominatim\DB::class)
|
// causes 'Non-static method should not be called statically, assuming $this from incompatible context'
|
||||||
->setMethods(array('connect'))
|
// failure on travis
|
||||||
->getMock();
|
// $oDB = \DB::connect('', false); // returns a DB_Error instance
|
||||||
|
|
||||||
$oDbStub->method('connect')
|
$oDB = new \DB_Error;
|
||||||
->will($this->returnCallback(function () {
|
$oStatus = new Status($oDB);
|
||||||
throw new \Nominatim\DatabaseError('psql connection problem', 500, null, 'unknown database');
|
$this->assertEquals('No database', $oStatus->status());
|
||||||
}));
|
|
||||||
|
|
||||||
|
$oDB = null;
|
||||||
$oStatus = new Status($oDbStub);
|
$oStatus = new Status($oDB);
|
||||||
$this->assertEquals('No database', $oStatus->status());
|
$this->assertEquals('No database', $oStatus->status());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +47,8 @@ class StatusTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->expectExceptionCode(702);
|
$this->expectExceptionCode(702);
|
||||||
|
|
||||||
// stub has getOne method but doesn't return anything
|
// stub has getOne method but doesn't return anything
|
||||||
$oDbStub = $this->getMockBuilder(Nominatim\DB::class)
|
$oDbStub = $this->getMockBuilder(\DB::class)
|
||||||
->setMethods(array('connect', 'getOne'))
|
->setMethods(array('getOne'))
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
$oStatus = new Status($oDbStub);
|
$oStatus = new Status($oDbStub);
|
||||||
@@ -63,8 +62,8 @@ class StatusTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->expectExceptionMessage('No value');
|
$this->expectExceptionMessage('No value');
|
||||||
$this->expectExceptionCode(704);
|
$this->expectExceptionCode(704);
|
||||||
|
|
||||||
$oDbStub = $this->getMockBuilder(Nominatim\DB::class)
|
$oDbStub = $this->getMockBuilder(\DB::class)
|
||||||
->setMethods(array('connect', 'getOne'))
|
->setMethods(array('getOne'))
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
// return no word_id
|
// return no word_id
|
||||||
@@ -81,8 +80,8 @@ class StatusTest extends \PHPUnit\Framework\TestCase
|
|||||||
|
|
||||||
public function testOK()
|
public function testOK()
|
||||||
{
|
{
|
||||||
$oDbStub = $this->getMockBuilder(Nominatim\DB::class)
|
$oDbStub = $this->getMockBuilder(\DB::class)
|
||||||
->setMethods(array('connect', 'getOne'))
|
->setMethods(array('getOne'))
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
$oDbStub->method('getOne')
|
$oDbStub->method('getOne')
|
||||||
@@ -97,7 +96,7 @@ class StatusTest extends \PHPUnit\Framework\TestCase
|
|||||||
|
|
||||||
public function testDataDate()
|
public function testDataDate()
|
||||||
{
|
{
|
||||||
$oDbStub = $this->getMockBuilder(Nominatim\DB::class)
|
$oDbStub = $this->getMockBuilder(\DB::class)
|
||||||
->setMethods(array('getOne'))
|
->setMethods(array('getOne'))
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace Nominatim;
|
namespace Nominatim;
|
||||||
|
|
||||||
|
// require_once(CONST_BasePath.'/lib/db.php');
|
||||||
|
// require_once(CONST_BasePath.'/lib/cmd.php');
|
||||||
require_once(CONST_BasePath.'/lib/TokenList.php');
|
require_once(CONST_BasePath.'/lib/TokenList.php');
|
||||||
|
|
||||||
|
|
||||||
@@ -54,18 +56,9 @@ class TokenTest extends \PHPUnit\Framework\TestCase
|
|||||||
{
|
{
|
||||||
$this->expectOutputRegex('/<p><tt>/');
|
$this->expectOutputRegex('/<p><tt>/');
|
||||||
|
|
||||||
$oDbStub = $this->getMockBuilder(Nominatim\DB::class)
|
$oDbStub = $this->getMockBuilder(\DB::class)
|
||||||
->setMethods(array('getAll', 'getDBQuotedList'))
|
->setMethods(array('getAll'))
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
$oDbStub->method('getDBQuotedList')
|
|
||||||
->will($this->returnCallback(function ($aVals) {
|
|
||||||
return array_map(function ($sVal) {
|
|
||||||
return "'".$sVal."'";
|
|
||||||
}, $aVals);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
$oDbStub->method('getAll')
|
$oDbStub->method('getAll')
|
||||||
->will($this->returnCallback(function ($sql) {
|
->will($this->returnCallback(function ($sql) {
|
||||||
$aResults = array();
|
$aResults = array();
|
||||||
|
|||||||
@@ -41,8 +41,7 @@
|
|||||||
'path' => 27
|
'path' => 27
|
||||||
);
|
);
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
if (isset($aCMDResult['output-type'])) {
|
if (isset($aCMDResult['output-type'])) {
|
||||||
if (!isset($aRankmap[$aCMDResult['output-type']])) fail('unknown output-type: '.$aCMDResult['output-type']);
|
if (!isset($aRankmap[$aCMDResult['output-type']])) fail('unknown output-type: '.$aCMDResult['output-type']);
|
||||||
@@ -56,7 +55,7 @@
|
|||||||
$oParams = new Nominatim\ParameterParser();
|
$oParams = new Nominatim\ParameterParser();
|
||||||
if (!isset($aCMDResult['language'])) $aCMDResult['language'] = 'xx';
|
if (!isset($aCMDResult['language'])) $aCMDResult['language'] = 'xx';
|
||||||
$aLangPrefOrder = $oParams->getPreferredLanguages($aCMDResult['language']);
|
$aLangPrefOrder = $oParams->getPreferredLanguages($aCMDResult['language']);
|
||||||
$sLanguagePrefArraySQL = $oDB->getArraySQL($oDB->getDBQuotedList($aLangPrefOrder));
|
$sLanguagePrefArraySQL = 'ARRAY['.join(',', array_map('getDBQuoted', $aLangPrefOrder)).']';
|
||||||
|
|
||||||
// output formatting: build up a lookup table that maps address ranks to columns
|
// output formatting: build up a lookup table that maps address ranks to columns
|
||||||
$aColumnMapping = array();
|
$aColumnMapping = array();
|
||||||
@@ -96,7 +95,7 @@
|
|||||||
$sPlacexSQL .= ' and rank_address = '.$iOutputRank;
|
$sPlacexSQL .= ' and rank_address = '.$iOutputRank;
|
||||||
|
|
||||||
if (isset($aCMDResult['restrict-to-country'])) {
|
if (isset($aCMDResult['restrict-to-country'])) {
|
||||||
$sPlacexSQL .= ' and country_code = '.$oDB->getDBQuoted($aCMDResult['restrict-to-country']);
|
$sPlacexSQL .= ' and country_code = '.getDBQuoted($aCMDResult['restrict-to-country']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restriction to parent place id
|
// restriction to parent place id
|
||||||
@@ -116,8 +115,11 @@
|
|||||||
$sOsmId = $aCMDResult['restrict-to-osm-relation'];
|
$sOsmId = $aCMDResult['restrict-to-osm-relation'];
|
||||||
}
|
}
|
||||||
if ($sOsmType) {
|
if ($sOsmType) {
|
||||||
$sSQL = 'select place_id from placex where osm_type = :osm_type and osm_id = :osm_id';
|
$sSQL = 'select place_id from placex where';
|
||||||
$sParentId = $oDB->getOne($sSQL, array('osm_type' => $sOsmType, 'osm_id' => $sOsmId));
|
$sSQL .= ' osm_type = '.getDBQuoted($sOsmType);
|
||||||
|
$sSQL .= ' and osm_id = '.$sOsmId;
|
||||||
|
$sParentId = $oDB->getOne($sSQL);
|
||||||
|
if (PEAR::isError($sParentId)) fail(pg_last_error($oDB->connection));
|
||||||
if (!$sParentId) fail('Could not find place '.$sOsmType.' '.$sOsmId);
|
if (!$sParentId) fail('Could not find place '.$sOsmType.' '.$sOsmId);
|
||||||
}
|
}
|
||||||
if ($sParentId) {
|
if ($sParentId) {
|
||||||
@@ -129,15 +131,18 @@
|
|||||||
// Iterate over placeids
|
// Iterate over placeids
|
||||||
// to get further hierarchical information
|
// to get further hierarchical information
|
||||||
//var_dump($sPlacexSQL);
|
//var_dump($sPlacexSQL);
|
||||||
$oResults = $oDB->getQueryStatement($sPlacexSQL);
|
$aRes =& $oDB->query($sPlacexSQL);
|
||||||
|
if (PEAR::isError($aRes)) fail(pg_last_error($oDB->connection));
|
||||||
$fOutstream = fopen('php://output', 'w');
|
$fOutstream = fopen('php://output', 'w');
|
||||||
while ($aRow = $oResults->fetch()) {
|
while ($aRes->fetchInto($aRow)) {
|
||||||
//var_dump($aRow);
|
//var_dump($aRow);
|
||||||
$iPlaceID = $aRow['place_id'];
|
$iPlaceID = $aRow['place_id'];
|
||||||
$sSQL = "select rank_address,get_name_by_language(name,$sLanguagePrefArraySQL) as localname from get_addressdata(:place_id, -1)";
|
$sSQL = "select rank_address,get_name_by_language(name,$sLanguagePrefArraySQL) as localname from get_addressdata($iPlaceID, -1)";
|
||||||
$sSQL .= ' WHERE isaddress';
|
$sSQL .= ' WHERE isaddress';
|
||||||
$sSQL .= ' order by rank_address desc,isaddress desc';
|
$sSQL .= ' order by rank_address desc,isaddress desc';
|
||||||
$aAddressLines = $oDB->getAll($sSQL, array('place_id' => $iPlaceID));
|
$aAddressLines = $oDB->getAll($sSQL);
|
||||||
|
if (PEAR::IsError($aAddressLines)) fail(pg_last_error($oDB->connection));
|
||||||
|
|
||||||
|
|
||||||
$aOutput = array_fill(0, $iNumCol, '');
|
$aOutput = array_fill(0, $iNumCol, '');
|
||||||
// output address parts
|
// output address parts
|
||||||
@@ -152,10 +157,10 @@
|
|||||||
$sSQL = 'select array_agg(px.postcode) from placex px join place_addressline pa ';
|
$sSQL = 'select array_agg(px.postcode) from placex px join place_addressline pa ';
|
||||||
$sSQL .= 'on px.place_id = pa.address_place_id ';
|
$sSQL .= 'on px.place_id = pa.address_place_id ';
|
||||||
$sSQL .= 'where pa.cached_rank_address in (5,11) ';
|
$sSQL .= 'where pa.cached_rank_address in (5,11) ';
|
||||||
$sSQL .= 'and pa.place_id in (select place_id from place_addressline where address_place_id in (:first_place_id)) ';
|
$sSQL .= 'and pa.place_id in (select place_id from place_addressline where address_place_id in ('.substr($aRow['place_ids'], 1, -1).')) ';
|
||||||
$sSQL .= 'group by postcode order by count(*) desc limit 1';
|
$sSQL .= 'group by postcode order by count(*) desc limit 1';
|
||||||
$sRes = $oDB->getOne($sSQL, array('first_place_id' => substr($aRow['place_ids'], 1, -1)));
|
$sRes = $oDB->getOne($sSQL);
|
||||||
|
if (PEAR::IsError($sRes)) fail(pg_last_error($oDB->connection));
|
||||||
$aOutput[$aColumnMapping['postcode']] = substr($sRes, 1, -1);
|
$aOutput[$aColumnMapping['postcode']] = substr($sRes, 1, -1);
|
||||||
} else {
|
} else {
|
||||||
$aOutput[$aColumnMapping['postcode']] = $aRow['postcode'];
|
$aOutput[$aColumnMapping['postcode']] = $aRow['postcode'];
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ exit;
|
|||||||
$a = array();
|
$a = array();
|
||||||
$a[] = 'test';
|
$a[] = 'test';
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB &= getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
if ($aCMDResult['drop-tables'])
|
if ($aCMDResult['drop-tables'])
|
||||||
{
|
{
|
||||||
@@ -305,9 +304,7 @@ function _templatesToProperties($aTemplates)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($aCMDResult['parse-wikipedia'])) {
|
if (isset($aCMDResult['parse-wikipedia'])) {
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$sSQL = 'select page_title from content where page_namespace = 0 and page_id %10 = ';
|
$sSQL = 'select page_title from content where page_namespace = 0 and page_id %10 = ';
|
||||||
$sSQL .= $aCMDResult['parse-wikipedia'];
|
$sSQL .= $aCMDResult['parse-wikipedia'];
|
||||||
$sSQL .= ' and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\'))';
|
$sSQL .= ' and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\'))';
|
||||||
@@ -369,9 +366,7 @@ function nominatimXMLEnd($hParser, $sName)
|
|||||||
|
|
||||||
|
|
||||||
if (isset($aCMDResult['link'])) {
|
if (isset($aCMDResult['link'])) {
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$aWikiArticles = $oDB->getAll("select * from wikipedia_article where language = 'en' and lat is not null and osm_type is null and totalcount < 31 order by importance desc limit 200000");
|
$aWikiArticles = $oDB->getAll("select * from wikipedia_article where language = 'en' and lat is not null and osm_type is null and totalcount < 31 order by importance desc limit 200000");
|
||||||
|
|
||||||
// If you point this script at production OSM you will be blocked
|
// If you point this script at production OSM you will be blocked
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ $aCMDOptions
|
|||||||
);
|
);
|
||||||
getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
|
getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
|
||||||
|
|
||||||
$oDB = new Nominatim\DB;
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$oParams = new Nominatim\ParameterParser($aCMDResult);
|
$oParams = new Nominatim\ParameterParser($aCMDResult);
|
||||||
|
|
||||||
if ($oParams->getBool('search')) {
|
if ($oParams->getBool('search')) {
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ if ($aCMDResult['setup-db'] || $aCMDResult['all']) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try accessing the C module, so we know early if something is wrong
|
// Try accessing the C module, so we know early if something is wrong
|
||||||
checkModulePresence(); // raises exception on failure
|
if (!checkModulePresence()) {
|
||||||
|
fail('error loading nominatim.so module');
|
||||||
|
}
|
||||||
|
|
||||||
if ($aCMDResult['import-data'] || $aCMDResult['all']) {
|
if ($aCMDResult['import-data'] || $aCMDResult['all']) {
|
||||||
$bDidSomething = true;
|
$bDidSomething = true;
|
||||||
|
|||||||
@@ -52,10 +52,9 @@ if (!isset($aResult['index-rank'])) $aResult['index-rank'] = 0;
|
|||||||
|
|
||||||
date_default_timezone_set('Etc/UTC');
|
date_default_timezone_set('Etc/UTC');
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$aDSNInfo = Nominatim\DB::parseDSN(CONST_Database_DSN);
|
$aDSNInfo = DB::parseDSN(CONST_Database_DSN);
|
||||||
if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
|
if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
|
||||||
|
|
||||||
// cache memory to be used by osm2pgsql, should not be more than the available memory
|
// cache memory to be used by osm2pgsql, should not be more than the available memory
|
||||||
@@ -116,7 +115,7 @@ if ($aResult['init-updates']) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sDatabaseDate = getDatabaseDate($oDB);
|
$sDatabaseDate = getDatabaseDate($oDB);
|
||||||
if (!$sDatabaseDate) {
|
if ($sDatabaseDate === false) {
|
||||||
fail('Cannot determine date of database.');
|
fail('Cannot determine date of database.');
|
||||||
}
|
}
|
||||||
$sWindBack = strftime('%Y-%m-%dT%H:%M:%SZ', strtotime($sDatabaseDate) - (3*60*60));
|
$sWindBack = strftime('%Y-%m-%dT%H:%M:%SZ', strtotime($sDatabaseDate) - (3*60*60));
|
||||||
@@ -129,13 +128,10 @@ if ($aResult['init-updates']) {
|
|||||||
fail('Error running pyosmium tools');
|
fail('Error running pyosmium tools');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oDB->exec('TRUNCATE import_status');
|
pg_query($oDB->connection, 'TRUNCATE import_status');
|
||||||
$sSQL = "INSERT INTO import_status (lastimportdate, sequence_id, indexed) VALUES('";
|
$sSQL = "INSERT INTO import_status (lastimportdate, sequence_id, indexed) VALUES('";
|
||||||
$sSQL .= $sDatabaseDate."',".$aOutput[0].', true)';
|
$sSQL .= $sDatabaseDate."',".$aOutput[0].', true)';
|
||||||
|
if (!pg_query($oDB->connection, $sSQL)) {
|
||||||
try {
|
|
||||||
$oDB->exec($sSQL);
|
|
||||||
} catch (\Nominatim\DatabaseError $e) {
|
|
||||||
fail('Could not enter sequence into database.');
|
fail('Could not enter sequence into database.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +139,7 @@ if ($aResult['init-updates']) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($aResult['check-for-updates']) {
|
if ($aResult['check-for-updates']) {
|
||||||
$aLastState = $oDB->getRow('SELECT sequence_id FROM import_status');
|
$aLastState = chksql($oDB->getRow('SELECT sequence_id FROM import_status'));
|
||||||
|
|
||||||
if (!$aLastState['sequence_id']) {
|
if (!$aLastState['sequence_id']) {
|
||||||
fail('Updates not set up. Please run ./utils/update.php --init-updates.');
|
fail('Updates not set up. Please run ./utils/update.php --init-updates.');
|
||||||
@@ -223,21 +219,20 @@ if ($bHaveDiff) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($aResult['deduplicate']) {
|
if ($aResult['deduplicate']) {
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
if ($oDB->getPostgresVersion() < 9.3) {
|
if (getPostgresVersion($oDB) < 9.3) {
|
||||||
fail('ERROR: deduplicate is only currently supported in postgresql 9.3');
|
fail('ERROR: deduplicate is only currently supported in postgresql 9.3');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sSQL = 'select partition from country_name order by country_code';
|
$sSQL = 'select partition from country_name order by country_code';
|
||||||
$aPartitions = $oDB->getCol($sSQL);
|
$aPartitions = chksql($oDB->getCol($sSQL));
|
||||||
$aPartitions[] = 0;
|
$aPartitions[] = 0;
|
||||||
|
|
||||||
// we don't care about empty search_name_* partitions, they can't contain mentions of duplicates
|
// we don't care about empty search_name_* partitions, they can't contain mentions of duplicates
|
||||||
foreach ($aPartitions as $i => $sPartition) {
|
foreach ($aPartitions as $i => $sPartition) {
|
||||||
$sSQL = 'select count(*) from search_name_'.$sPartition;
|
$sSQL = 'select count(*) from search_name_'.$sPartition;
|
||||||
$nEntries = $oDB->getOne($sSQL);
|
$nEntries = chksql($oDB->getOne($sSQL));
|
||||||
if ($nEntries == 0) {
|
if ($nEntries == 0) {
|
||||||
unset($aPartitions[$i]);
|
unset($aPartitions[$i]);
|
||||||
}
|
}
|
||||||
@@ -246,7 +241,7 @@ if ($aResult['deduplicate']) {
|
|||||||
$sSQL = "select word_token,count(*) from word where substr(word_token, 1, 1) = ' '";
|
$sSQL = "select word_token,count(*) from word where substr(word_token, 1, 1) = ' '";
|
||||||
$sSQL .= ' and class is null and type is null and country_code is null';
|
$sSQL .= ' and class is null and type is null and country_code is null';
|
||||||
$sSQL .= ' group by word_token having count(*) > 1 order by word_token';
|
$sSQL .= ' group by word_token having count(*) > 1 order by word_token';
|
||||||
$aDuplicateTokens = $oDB->getAll($sSQL);
|
$aDuplicateTokens = chksql($oDB->getAll($sSQL));
|
||||||
foreach ($aDuplicateTokens as $aToken) {
|
foreach ($aDuplicateTokens as $aToken) {
|
||||||
if (trim($aToken['word_token']) == '' || trim($aToken['word_token']) == '-') continue;
|
if (trim($aToken['word_token']) == '' || trim($aToken['word_token']) == '-') continue;
|
||||||
echo 'Deduping '.$aToken['word_token']."\n";
|
echo 'Deduping '.$aToken['word_token']."\n";
|
||||||
@@ -254,7 +249,7 @@ if ($aResult['deduplicate']) {
|
|||||||
$sSQL .= ' (select count(*) from search_name where nameaddress_vector @> ARRAY[word_id]) as num';
|
$sSQL .= ' (select count(*) from search_name where nameaddress_vector @> ARRAY[word_id]) as num';
|
||||||
$sSQL .= " from word where word_token = '".$aToken['word_token'];
|
$sSQL .= " from word where word_token = '".$aToken['word_token'];
|
||||||
$sSQL .= "' and class is null and type is null and country_code is null order by num desc";
|
$sSQL .= "' and class is null and type is null and country_code is null order by num desc";
|
||||||
$aTokenSet = $oDB->getAll($sSQL);
|
$aTokenSet = chksql($oDB->getAll($sSQL));
|
||||||
|
|
||||||
$aKeep = array_shift($aTokenSet);
|
$aKeep = array_shift($aTokenSet);
|
||||||
$iKeepID = $aKeep['word_id'];
|
$iKeepID = $aKeep['word_id'];
|
||||||
@@ -264,32 +259,32 @@ if ($aResult['deduplicate']) {
|
|||||||
$sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.'),';
|
$sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.'),';
|
||||||
$sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
|
$sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
|
||||||
$sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
|
$sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
|
|
||||||
$sSQL = 'update search_name set';
|
$sSQL = 'update search_name set';
|
||||||
$sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
|
$sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
|
||||||
$sSQL .= ' where nameaddress_vector @> ARRAY['.$aRemove['word_id'].']';
|
$sSQL .= ' where nameaddress_vector @> ARRAY['.$aRemove['word_id'].']';
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
|
|
||||||
$sSQL = 'update location_area_country set';
|
$sSQL = 'update location_area_country set';
|
||||||
$sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
|
$sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
|
||||||
$sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
|
$sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
|
|
||||||
foreach ($aPartitions as $sPartition) {
|
foreach ($aPartitions as $sPartition) {
|
||||||
$sSQL = 'update search_name_'.$sPartition.' set';
|
$sSQL = 'update search_name_'.$sPartition.' set';
|
||||||
$sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.')';
|
$sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.')';
|
||||||
$sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
|
$sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
|
|
||||||
$sSQL = 'update location_area_country set';
|
$sSQL = 'update location_area_country set';
|
||||||
$sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
|
$sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
|
||||||
$sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
|
$sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
}
|
}
|
||||||
|
|
||||||
$sSQL = 'delete from word where word_id = '.$aRemove['word_id'];
|
$sSQL = 'delete from word where word_id = '.$aRemove['word_id'];
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,7 +306,7 @@ if ($aResult['index']) {
|
|||||||
|
|
||||||
runWithEnv($sCmd, $aProcEnv);
|
runWithEnv($sCmd, $aProcEnv);
|
||||||
|
|
||||||
$oDB->exec('update import_status set indexed = true');
|
$oDB->query('update import_status set indexed = true');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($aResult['update-address-levels']) {
|
if ($aResult['update-address-levels']) {
|
||||||
@@ -340,7 +335,7 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
$fStartTime = time();
|
$fStartTime = time();
|
||||||
$aLastState = $oDB->getRow('SELECT *, EXTRACT (EPOCH FROM lastimportdate) as unix_ts FROM import_status');
|
$aLastState = chksql($oDB->getRow('SELECT *, EXTRACT (EPOCH FROM lastimportdate) as unix_ts FROM import_status'));
|
||||||
|
|
||||||
if (!$aLastState['sequence_id']) {
|
if (!$aLastState['sequence_id']) {
|
||||||
echo "Updates not set up. Please run ./utils/update.php --init-updates.\n";
|
echo "Updates not set up. Please run ./utils/update.php --init-updates.\n";
|
||||||
@@ -352,7 +347,7 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
|
|||||||
$sBatchEnd = $aLastState['lastimportdate'];
|
$sBatchEnd = $aLastState['lastimportdate'];
|
||||||
$iEndSequence = $aLastState['sequence_id'];
|
$iEndSequence = $aLastState['sequence_id'];
|
||||||
|
|
||||||
if ($aLastState['indexed']) {
|
if ($aLastState['indexed'] == 't') {
|
||||||
// Sleep if the update interval has not yet been reached.
|
// Sleep if the update interval has not yet been reached.
|
||||||
$fNextUpdate = $aLastState['unix_ts'] + CONST_Replication_Update_Interval;
|
$fNextUpdate = $aLastState['unix_ts'] + CONST_Replication_Update_Interval;
|
||||||
if ($fNextUpdate > $fStartTime) {
|
if ($fNextUpdate > $fStartTime) {
|
||||||
@@ -418,12 +413,12 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
|
|||||||
$sSQL .= date('Y-m-d H:i:s', $fCMDStartTime)."','";
|
$sSQL .= date('Y-m-d H:i:s', $fCMDStartTime)."','";
|
||||||
$sSQL .= date('Y-m-d H:i:s')."','import')";
|
$sSQL .= date('Y-m-d H:i:s')."','import')";
|
||||||
var_Dump($sSQL);
|
var_Dump($sSQL);
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
|
|
||||||
// update the status
|
// update the status
|
||||||
$sSQL = "UPDATE import_status SET lastimportdate = '$sBatchEnd', indexed=false, sequence_id = $iEndSequence";
|
$sSQL = "UPDATE import_status SET lastimportdate = '$sBatchEnd', indexed=false, sequence_id = $iEndSequence";
|
||||||
var_Dump($sSQL);
|
var_Dump($sSQL);
|
||||||
$oDB->exec($sSQL);
|
chksql($oDB->query($sSQL));
|
||||||
echo date('Y-m-d H:i:s')." Completed download step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
|
echo date('Y-m-d H:i:s')." Completed download step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,11 +440,11 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
|
|||||||
$sSQL .= date('Y-m-d H:i:s', $fCMDStartTime)."','";
|
$sSQL .= date('Y-m-d H:i:s', $fCMDStartTime)."','";
|
||||||
$sSQL .= date('Y-m-d H:i:s')."','index')";
|
$sSQL .= date('Y-m-d H:i:s')."','index')";
|
||||||
var_Dump($sSQL);
|
var_Dump($sSQL);
|
||||||
$oDB->exec($sSQL);
|
$oDB->query($sSQL);
|
||||||
echo date('Y-m-d H:i:s')." Completed index step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
|
echo date('Y-m-d H:i:s')." Completed index step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
|
||||||
|
|
||||||
$sSQL = 'update import_status set indexed = true';
|
$sSQL = 'update import_status set indexed = true';
|
||||||
$oDB->exec($sSQL);
|
$oDB->query($sSQL);
|
||||||
} else {
|
} else {
|
||||||
if ($aResult['import-osmosis-all']) {
|
if ($aResult['import-osmosis-all']) {
|
||||||
echo "Error: --no-index cannot be used with continuous imports (--import-osmosis-all).\n";
|
echo "Error: --no-index cannot be used with continuous imports (--import-osmosis-all).\n";
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ require_once(CONST_BasePath.'/lib/Geocode.php');
|
|||||||
require_once(CONST_BasePath.'/lib/PlaceLookup.php');
|
require_once(CONST_BasePath.'/lib/PlaceLookup.php');
|
||||||
require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
|
require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$bVerbose = $aResult['verbose'];
|
$bVerbose = $aResult['verbose'];
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
sudo yum install -y postgresql-server postgresql-contrib postgresql-devel \
|
sudo yum install -y postgresql-server postgresql-contrib postgresql-devel \
|
||||||
postgis postgis-utils \
|
postgis postgis-utils \
|
||||||
wget git cmake make gcc gcc-c++ libtool policycoreutils-python \
|
wget git cmake make gcc gcc-c++ libtool policycoreutils-python \
|
||||||
php-pgsql php php-intl libpqxx-devel \
|
php-pgsql php php-pear php-pear-DB php-intl libpqxx-devel \
|
||||||
proj-epsg bzip2-devel proj-devel libxml2-devel boost-devel \
|
proj-epsg bzip2-devel proj-devel libxml2-devel boost-devel \
|
||||||
expat-devel zlib-devel
|
expat-devel zlib-devel
|
||||||
|
|
||||||
@@ -34,9 +34,7 @@
|
|||||||
sudo yum install -y python34-pip python34-setuptools python34-devel \
|
sudo yum install -y python34-pip python34-setuptools python34-devel \
|
||||||
php-phpunit-PHPUnit
|
php-phpunit-PHPUnit
|
||||||
pip3 install --user behave nose pytidylib psycopg2
|
pip3 install --user behave nose pytidylib psycopg2
|
||||||
|
sudo pear install PHP_CodeSniffer
|
||||||
composer global require "squizlabs/php_codesniffer=*"
|
|
||||||
sudo ln -s ~/.config/composer/vendor/bin/phpcs /usr/bin/
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Configuration
|
# System Configuration
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
|
|||||||
libbz2-dev libpq-dev libproj-dev \
|
libbz2-dev libpq-dev libproj-dev \
|
||||||
postgresql-server-dev-9.5 postgresql-9.5-postgis-2.2 \
|
postgresql-server-dev-9.5 postgresql-9.5-postgis-2.2 \
|
||||||
postgresql-contrib-9.5 \
|
postgresql-contrib-9.5 \
|
||||||
apache2 php php-pgsql libapache2-mod-php \
|
apache2 php php-pgsql libapache2-mod-php php-pear php-db \
|
||||||
php-intl git
|
php-intl git
|
||||||
|
|
||||||
# If you want to run the test suite, you need to install the following
|
# If you want to run the test suite, you need to install the following
|
||||||
@@ -39,9 +39,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
|
|||||||
python3-psycopg2 python3-tidylib phpunit php-cgi
|
python3-psycopg2 python3-tidylib phpunit php-cgi
|
||||||
|
|
||||||
pip3 install --user behave nose
|
pip3 install --user behave nose
|
||||||
|
sudo pear install PHP_CodeSniffer
|
||||||
composer global require "squizlabs/php_codesniffer=*"
|
|
||||||
sudo ln -s ~/.config/composer/vendor/bin/phpcs /usr/bin/
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Configuration
|
# System Configuration
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export DEBIAN_FRONTEND=noninteractive
|
|||||||
libbz2-dev libpq-dev libproj-dev \
|
libbz2-dev libpq-dev libproj-dev \
|
||||||
postgresql-server-dev-10 postgresql-10-postgis-2.4 \
|
postgresql-server-dev-10 postgresql-10-postgis-2.4 \
|
||||||
postgresql-contrib-10 \
|
postgresql-contrib-10 \
|
||||||
nginx php-fpm php php-pgsql \
|
nginx php-fpm php php-pgsql php-pear php-db \
|
||||||
php-intl git
|
php-intl git
|
||||||
|
|
||||||
export USERNAME=vagrant
|
export USERNAME=vagrant
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
|
|||||||
libbz2-dev libpq-dev libproj-dev \
|
libbz2-dev libpq-dev libproj-dev \
|
||||||
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 \
|
||||||
apache2 php php-pgsql libapache2-mod-php \
|
apache2 php php-pgsql libapache2-mod-php php-pear php-db \
|
||||||
php-intl git
|
php-intl git
|
||||||
|
|
||||||
# If you want to run the test suite, you need to install the following
|
# If you want to run the test suite, you need to install the following
|
||||||
@@ -39,9 +39,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
|
|||||||
python3-psycopg2 python3-tidylib phpunit php-cgi
|
python3-psycopg2 python3-tidylib phpunit php-cgi
|
||||||
|
|
||||||
pip3 install --user behave nose
|
pip3 install --user behave nose
|
||||||
|
sudo pear install PHP_CodeSniffer
|
||||||
composer global require "squizlabs/php_codesniffer=*"
|
|
||||||
sudo ln -s ~/.config/composer/vendor/bin/phpcs /usr/bin/
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Configuration
|
# System Configuration
|
||||||
|
|||||||
@@ -16,18 +16,33 @@ sudo apt-get install -y -qq libboost-dev libboost-system-dev \
|
|||||||
libboost-filesystem-dev libexpat1-dev zlib1g-dev libxml2-dev\
|
libboost-filesystem-dev libexpat1-dev zlib1g-dev libxml2-dev\
|
||||||
libbz2-dev libpq-dev libproj-dev \
|
libbz2-dev libpq-dev libproj-dev \
|
||||||
postgresql-server-dev-9.6 postgresql-9.6-postgis-2.4 postgresql-contrib-9.6 \
|
postgresql-server-dev-9.6 postgresql-9.6-postgis-2.4 postgresql-contrib-9.6 \
|
||||||
apache2 php php-pgsql php-intl
|
apache2 php php-pgsql php-intl php-pear
|
||||||
|
|
||||||
sudo apt-get install -y -qq python3-dev python3-pip python3-psycopg2 php-cgi
|
sudo apt-get install -y -qq python3-dev python3-pip python3-psycopg2 php-cgi
|
||||||
|
|
||||||
pip3 install --quiet behave nose pytidylib psycopg2-binary
|
pip3 install --quiet behave nose pytidylib psycopg2-binary
|
||||||
|
|
||||||
|
# Travis uses phpenv to support multiple PHP versions. We need to make sure
|
||||||
|
# these packages get installed to the phpenv-set PHP (inside /home/travis/.phpenv/),
|
||||||
|
# not the system PHP (/usr/bin/php, /usr/share/php/ etc)
|
||||||
|
|
||||||
|
# $PHPENV_VERSION and $TRAVIS_PHP_VERSION are unset.
|
||||||
|
export PHPENV_VERSION=$(cat /home/travis/.phpenv/version)
|
||||||
|
echo $PHPENV_VERSION
|
||||||
|
|
||||||
|
# https://github.com/pear/DB
|
||||||
|
composer global require "pear/db=1.9.3"
|
||||||
# https://github.com/squizlabs/PHP_CodeSniffer
|
# https://github.com/squizlabs/PHP_CodeSniffer
|
||||||
composer global require "squizlabs/php_codesniffer=*"
|
composer global require "squizlabs/php_codesniffer=*"
|
||||||
sudo ln -s /home/travis/.config/composer/vendor/bin/phpcs /usr/bin/
|
sudo ln -s /home/travis/.config/composer/vendor/bin/phpcs /usr/bin/
|
||||||
|
|
||||||
composer global require "phpunit/phpunit=7.*"
|
|
||||||
sudo ln -s /home/travis/.config/composer/vendor/bin/phpunit /usr/bin/
|
# make sure PEAR.php and DB.php are in the include path
|
||||||
|
tee /tmp/travis.php.ini << EOF
|
||||||
|
include_path = .:/home/travis/.phpenv/versions/$PHPENV_VERSION/share/pear:/home/travis/.config/composer/vendor/pear/db
|
||||||
|
EOF
|
||||||
|
phpenv config-add /tmp/travis.php.ini
|
||||||
|
|
||||||
|
|
||||||
sudo -u postgres createuser -S www-data
|
sudo -u postgres createuser -S www-data
|
||||||
|
|
||||||
@@ -62,7 +77,7 @@ make
|
|||||||
tee settings/local.php << EOF
|
tee settings/local.php << EOF
|
||||||
<?php
|
<?php
|
||||||
@define('CONST_Website_BaseURL', '/nominatim/');
|
@define('CONST_Website_BaseURL', '/nominatim/');
|
||||||
@define('CONST_Database_DSN', 'pgsql:dbname=test_api_nominatim');
|
@define('CONST_Database_DSN', 'pgsql://@/test_api_nominatim');
|
||||||
@define('CONST_Wikipedia_Data_Path', CONST_BasePath.'/test/testdb');
|
@define('CONST_Wikipedia_Data_Path', CONST_BasePath.'/test/testdb');
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,13 @@ ini_set('memory_limit', '200M');
|
|||||||
|
|
||||||
$sOutputFormat = 'html';
|
$sOutputFormat = 'html';
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$sSQL = 'select placex.place_id, country_code,';
|
$sSQL = 'select placex.place_id, country_code,';
|
||||||
$sSQL .= " name->'name' as name, i.* from placex, import_polygon_delete i";
|
$sSQL .= " name->'name' as name, i.* from placex, import_polygon_delete i";
|
||||||
$sSQL .= ' where placex.osm_id = i.osm_id and placex.osm_type = i.osm_type';
|
$sSQL .= ' where placex.osm_id = i.osm_id and placex.osm_type = i.osm_type';
|
||||||
$sSQL .= ' and placex.class = i.class and placex.type = i.type';
|
$sSQL .= ' and placex.class = i.class and placex.type = i.type';
|
||||||
$aPolygons = $oDB->getAll($sSQL, null, 'Could not get list of deleted OSM elements.');
|
$aPolygons = chksql($oDB->getAll($sSQL), 'Could not get list of deleted OSM elements.');
|
||||||
|
|
||||||
if (CONST_Debug) {
|
if (CONST_Debug) {
|
||||||
var_dump($aPolygons);
|
var_dump($aPolygons);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ $sOutputFormat = $oParams->getSet('format', array('html', 'json'), 'html');
|
|||||||
set_exception_handler_by_format($sOutputFormat);
|
set_exception_handler_by_format($sOutputFormat);
|
||||||
|
|
||||||
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
||||||
|
$sLanguagePrefArraySQL = 'ARRAY['.join(',', array_map('getDBQuoted', $aLangPrefOrder)).']';
|
||||||
|
|
||||||
$sPlaceId = $oParams->getString('place_id');
|
$sPlaceId = $oParams->getString('place_id');
|
||||||
$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
|
$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
|
||||||
@@ -25,19 +26,20 @@ $bIncludeHierarchy = $oParams->getBool('hierarchy', $sOutputFormat == 'html');
|
|||||||
$bGroupHierarchy = $oParams->getBool('group_hierarchy', false);
|
$bGroupHierarchy = $oParams->getBool('group_hierarchy', false);
|
||||||
$bIncludePolygonAsGeoJSON = $oParams->getBool('polygon_geojson', $sOutputFormat == 'html');
|
$bIncludePolygonAsGeoJSON = $oParams->getBool('polygon_geojson', $sOutputFormat == 'html');
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$sLanguagePrefArraySQL = $oDB->getArraySQL($oDB->getDBQuotedList($aLangPrefOrder));
|
|
||||||
|
|
||||||
if ($sOsmType && $iOsmId > 0) {
|
if ($sOsmType && $iOsmId > 0) {
|
||||||
$sSQL = 'SELECT place_id FROM placex WHERE osm_type = :type AND osm_id = :id';
|
$sSQL = sprintf(
|
||||||
|
"SELECT place_id FROM placex WHERE osm_type='%s' AND osm_id=%d",
|
||||||
|
$sOsmType,
|
||||||
|
$iOsmId
|
||||||
|
);
|
||||||
// osm_type and osm_id are not unique enough
|
// osm_type and osm_id are not unique enough
|
||||||
if ($sClass) {
|
if ($sClass) {
|
||||||
$sSQL .= " AND class='".$sClass."'";
|
$sSQL .= " AND class='".$sClass."'";
|
||||||
}
|
}
|
||||||
$sSQL .= ' ORDER BY class ASC';
|
$sSQL .= ' ORDER BY class ASC';
|
||||||
$sPlaceId = $oDB->getOne($sSQL, array(':type' => $sOsmType, ':id' => $iOsmId));
|
$sPlaceId = chksql($oDB->getOne($sSQL));
|
||||||
|
|
||||||
// Be nice about our error messages for broken geometry
|
// Be nice about our error messages for broken geometry
|
||||||
|
|
||||||
@@ -52,12 +54,12 @@ if ($sOsmType && $iOsmId > 0) {
|
|||||||
$sSQL .= ' ST_AsText(prevgeometry) AS prevgeom, ';
|
$sSQL .= ' ST_AsText(prevgeometry) AS prevgeom, ';
|
||||||
$sSQL .= ' ST_AsText(newgeometry) AS newgeom';
|
$sSQL .= ' ST_AsText(newgeometry) AS newgeom';
|
||||||
$sSQL .= ' FROM import_polygon_error ';
|
$sSQL .= ' FROM import_polygon_error ';
|
||||||
$sSQL .= ' WHERE osm_type = :type';
|
$sSQL .= " WHERE osm_type = '".$sOsmType."'";
|
||||||
$sSQL .= ' AND osm_id = :id';
|
$sSQL .= ' AND osm_id = '.$iOsmId;
|
||||||
$sSQL .= ' ORDER BY updated DESC';
|
$sSQL .= ' ORDER BY updated DESC';
|
||||||
$sSQL .= ' LIMIT 1';
|
$sSQL .= ' LIMIT 1';
|
||||||
$aPointDetails = $oDB->getRow($sSQL, array(':type' => $sOsmType, ':id' => $iOsmId));
|
$aPointDetails = chksql($oDB->getRow($sSQL));
|
||||||
if ($aPointDetails) {
|
if (!PEAR::isError($aPointDetails) && $aPointDetails) {
|
||||||
if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches)) {
|
if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches)) {
|
||||||
$aPointDetails['error_x'] = $aMatches[1];
|
$aPointDetails['error_x'] = $aMatches[1];
|
||||||
$aPointDetails['error_y'] = $aMatches[2];
|
$aPointDetails['error_y'] = $aMatches[2];
|
||||||
@@ -72,25 +74,25 @@ if ($sOsmType && $iOsmId > 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($sPlaceId === false) userError('Please select a place id');
|
if (!$sPlaceId) userError('Please select a place id');
|
||||||
|
|
||||||
$iPlaceID = (int)$sPlaceId;
|
$iPlaceID = (int)$sPlaceId;
|
||||||
|
|
||||||
if (CONST_Use_US_Tiger_Data) {
|
if (CONST_Use_US_Tiger_Data) {
|
||||||
$iParentPlaceID = $oDB->getOne('SELECT parent_place_id FROM location_property_tiger WHERE place_id = '.$iPlaceID);
|
$iParentPlaceID = chksql($oDB->getOne('SELECT parent_place_id FROM location_property_tiger WHERE place_id = '.$iPlaceID));
|
||||||
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interpolated house numbers
|
// interpolated house numbers
|
||||||
$iParentPlaceID = $oDB->getOne('SELECT parent_place_id FROM location_property_osmline WHERE place_id = '.$iPlaceID);
|
$iParentPlaceID = chksql($oDB->getOne('SELECT parent_place_id FROM location_property_osmline WHERE place_id = '.$iPlaceID));
|
||||||
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
||||||
|
|
||||||
// artificial postcodes
|
// artificial postcodes
|
||||||
$iParentPlaceID = $oDB->getOne('SELECT parent_place_id FROM location_postcode WHERE place_id = '.$iPlaceID);
|
$iParentPlaceID = chksql($oDB->getOne('SELECT parent_place_id FROM location_postcode WHERE place_id = '.$iPlaceID));
|
||||||
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
||||||
|
|
||||||
if (CONST_Use_Aux_Location_data) {
|
if (CONST_Use_Aux_Location_data) {
|
||||||
$iParentPlaceID = $oDB->getOne('SELECT parent_place_id FROM location_property_aux WHERE place_id = '.$iPlaceID);
|
$iParentPlaceID = chksql($oDB->getOne('SELECT parent_place_id FROM location_property_aux WHERE place_id = '.$iPlaceID));
|
||||||
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +127,7 @@ if ($bIncludePolygonAsGeoJSON) {
|
|||||||
$sSQL .= ' FROM placex ';
|
$sSQL .= ' FROM placex ';
|
||||||
$sSQL .= " WHERE place_id = $iPlaceID";
|
$sSQL .= " WHERE place_id = $iPlaceID";
|
||||||
|
|
||||||
$aPointDetails = $oDB->getRow($sSQL, null, 'Could not get details of place object.');
|
$aPointDetails = chksql($oDB->getRow($sSQL), 'Could not get details of place object.');
|
||||||
|
|
||||||
if (!$aPointDetails) {
|
if (!$aPointDetails) {
|
||||||
userError('Unknown place id.');
|
userError('Unknown place id.');
|
||||||
@@ -139,16 +141,25 @@ $aPointDetails['rank_search_label'] = getSearchRankLabel($aPointDetails['rank_se
|
|||||||
$sSQL = 'SELECT (each(name)).key,(each(name)).value FROM placex ';
|
$sSQL = 'SELECT (each(name)).key,(each(name)).value FROM placex ';
|
||||||
$sSQL .= "WHERE place_id = $iPlaceID ORDER BY (each(name)).key";
|
$sSQL .= "WHERE place_id = $iPlaceID ORDER BY (each(name)).key";
|
||||||
$aPointDetails['aNames'] = $oDB->getAssoc($sSQL);
|
$aPointDetails['aNames'] = $oDB->getAssoc($sSQL);
|
||||||
|
if (PEAR::isError($aPointDetails['aNames'])) { // possible timeout
|
||||||
|
$aPointDetails['aNames'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
// Address tags
|
// Address tags
|
||||||
$sSQL = 'SELECT (each(address)).key as key,(each(address)).value FROM placex ';
|
$sSQL = 'SELECT (each(address)).key as key,(each(address)).value FROM placex ';
|
||||||
$sSQL .= "WHERE place_id = $iPlaceID ORDER BY key";
|
$sSQL .= "WHERE place_id = $iPlaceID ORDER BY key";
|
||||||
$aPointDetails['aAddressTags'] = $oDB->getAssoc($sSQL);
|
$aPointDetails['aAddressTags'] = $oDB->getAssoc($sSQL);
|
||||||
|
if (PEAR::isError($aPointDetails['aAddressTags'])) { // possible timeout
|
||||||
|
$aPointDetails['aAddressTags'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
// Extra tags
|
// Extra tags
|
||||||
$sSQL = 'SELECT (each(extratags)).key,(each(extratags)).value FROM placex ';
|
$sSQL = 'SELECT (each(extratags)).key,(each(extratags)).value FROM placex ';
|
||||||
$sSQL .= "WHERE place_id = $iPlaceID ORDER BY (each(extratags)).key";
|
$sSQL .= "WHERE place_id = $iPlaceID ORDER BY (each(extratags)).key";
|
||||||
$aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
|
$aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
|
||||||
|
if (PEAR::isError($aPointDetails['aExtraTags'])) { // possible timeout
|
||||||
|
$aPointDetails['aExtraTags'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
$aAddressLines = false;
|
$aAddressLines = false;
|
||||||
@@ -180,6 +191,9 @@ if ($bIncludeLinkedPlaces) {
|
|||||||
$sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL), ";
|
$sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL), ";
|
||||||
$sSQL .= ' housenumber';
|
$sSQL .= ' housenumber';
|
||||||
$aLinkedLines = $oDB->getAll($sSQL);
|
$aLinkedLines = $oDB->getAll($sSQL);
|
||||||
|
if (PEAR::isError($aLinkedLines)) { // possible timeout
|
||||||
|
$aLinkedLines = array();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All places this is an imediate parent of
|
// All places this is an imediate parent of
|
||||||
@@ -211,25 +225,31 @@ if ($bIncludeHierarchy) {
|
|||||||
$sSQL .= ' localname, ';
|
$sSQL .= ' localname, ';
|
||||||
$sSQL .= ' housenumber';
|
$sSQL .= ' housenumber';
|
||||||
$aHierarchyLines = $oDB->getAll($sSQL);
|
$aHierarchyLines = $oDB->getAll($sSQL);
|
||||||
|
if (PEAR::isError($aHierarchyLines)) { // possible timeout
|
||||||
|
$aHierarchyLines = array();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aPlaceSearchNameKeywords = false;
|
$aPlaceSearchNameKeywords = false;
|
||||||
$aPlaceSearchAddressKeywords = false;
|
$aPlaceSearchAddressKeywords = false;
|
||||||
if ($bIncludeKeywords) {
|
if ($bIncludeKeywords) {
|
||||||
$sSQL = "SELECT * FROM search_name WHERE place_id = $iPlaceID";
|
$sSQL = "SELECT * FROM search_name WHERE place_id = $iPlaceID";
|
||||||
$aPlaceSearchName = $oDB->getRow($sSQL);
|
$aPlaceSearchName = $oDB->getRow($sSQL); // can be null
|
||||||
|
if (!$aPlaceSearchName || PEAR::isError($aPlaceSearchName)) { // possible timeout
|
||||||
|
$aPlaceSearchName = array();
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($aPlaceSearchName)) {
|
if (!empty($aPlaceSearchName)) {
|
||||||
$sWordIds = substr($aPlaceSearchName['name_vector'], 1, -1);
|
$sSQL = 'SELECT * FROM word WHERE word_id in ('.substr($aPlaceSearchName['name_vector'], 1, -1).')';
|
||||||
if (!empty($sWordIds)) {
|
$aPlaceSearchNameKeywords = $oDB->getAll($sSQL);
|
||||||
$sSQL = 'SELECT * FROM word WHERE word_id in ('.$sWordIds.')';
|
if (PEAR::isError($aPlaceSearchNameKeywords)) { // possible timeout
|
||||||
$aPlaceSearchNameKeywords = $oDB->getAll($sSQL);
|
$aPlaceSearchNameKeywords = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$sWordIds = substr($aPlaceSearchName['nameaddress_vector'], 1, -1);
|
$sSQL = 'SELECT * FROM word WHERE word_id in ('.substr($aPlaceSearchName['nameaddress_vector'], 1, -1).')';
|
||||||
if (!empty($sWordIds)) {
|
$aPlaceSearchAddressKeywords = $oDB->getAll($sSQL);
|
||||||
$sSQL = 'SELECT * FROM word WHERE word_id in ('.$sWordIds.')';
|
if (PEAR::isError($aPlaceSearchAddressKeywords)) { // possible timeout
|
||||||
$aPlaceSearchAddressKeywords = $oDB->getAll($sSQL);
|
$aPlaceSearchAddressKeywords = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,7 +258,7 @@ logEnd($oDB, $hLog, 1);
|
|||||||
|
|
||||||
if ($sOutputFormat=='html') {
|
if ($sOutputFormat=='html') {
|
||||||
$sSQL = "SELECT TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' FROM import_status LIMIT 1";
|
$sSQL = "SELECT TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' FROM import_status LIMIT 1";
|
||||||
$sDataDate = $oDB->getOne($sSQL);
|
$sDataDate = chksql($oDB->getOne($sSQL));
|
||||||
$sTileURL = CONST_Map_Tile_URL;
|
$sTileURL = CONST_Map_Tile_URL;
|
||||||
$sTileAttribution = CONST_Map_Tile_Attribution;
|
$sTileAttribution = CONST_Map_Tile_Attribution;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,19 +10,16 @@ $oParams = new Nominatim\ParameterParser();
|
|||||||
|
|
||||||
$sOutputFormat = $oParams->getSet('format', array('html', 'json'), 'html');
|
$sOutputFormat = $oParams->getSet('format', array('html', 'json'), 'html');
|
||||||
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
||||||
|
$sLanguagePrefArraySQL = 'ARRAY['.join(',', array_map('getDBQuoted', $aLangPrefOrder)).']';
|
||||||
|
|
||||||
$sPlaceId = $oParams->getString('place_id');
|
$sPlaceId = $oParams->getString('place_id');
|
||||||
$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
|
$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
|
||||||
$iOsmId = $oParams->getInt('osmid', -1);
|
$iOsmId = $oParams->getInt('osmid', -1);
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$sLanguagePrefArraySQL = $oDB->getArraySQL($oDB->getDBQuotedList($aLangPrefOrder));
|
|
||||||
|
|
||||||
if ($sOsmType && $iOsmId > 0) {
|
if ($sOsmType && $iOsmId > 0) {
|
||||||
$sPlaceId = $oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc");
|
$sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc"));
|
||||||
|
|
||||||
// Be nice about our error messages for broken geometry
|
// Be nice about our error messages for broken geometry
|
||||||
if (!$sPlaceId) {
|
if (!$sPlaceId) {
|
||||||
@@ -31,7 +28,7 @@ if ($sOsmType && $iOsmId > 0) {
|
|||||||
$sSQL .= ' ST_AsText(prevgeometry) as prevgeom, ST_AsText(newgeometry) as newgeom';
|
$sSQL .= ' ST_AsText(prevgeometry) as prevgeom, ST_AsText(newgeometry) as newgeom';
|
||||||
$sSQL .= " from import_polygon_error where osm_type = '".$sOsmType;
|
$sSQL .= " from import_polygon_error where osm_type = '".$sOsmType;
|
||||||
$sSQL .= "' and osm_id = ".$iOsmId.' order by updated desc limit 1';
|
$sSQL .= "' and osm_id = ".$iOsmId.' order by updated desc limit 1';
|
||||||
$aPointDetails = $oDB->getRow($sSQL);
|
$aPointDetails = chksql($oDB->getRow($sSQL));
|
||||||
if ($aPointDetails) {
|
if ($aPointDetails) {
|
||||||
if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches)) {
|
if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches)) {
|
||||||
$aPointDetails['error_x'] = $aMatches[1];
|
$aPointDetails['error_x'] = $aMatches[1];
|
||||||
@@ -48,12 +45,12 @@ if (!$sPlaceId) userError('Please select a place id');
|
|||||||
$iPlaceID = (int)$sPlaceId;
|
$iPlaceID = (int)$sPlaceId;
|
||||||
|
|
||||||
if (CONST_Use_US_Tiger_Data) {
|
if (CONST_Use_US_Tiger_Data) {
|
||||||
$iParentPlaceID = $oDB->getOne('select parent_place_id from location_property_tiger where place_id = '.$iPlaceID);
|
$iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_tiger where place_id = '.$iPlaceID));
|
||||||
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CONST_Use_Aux_Location_data) {
|
if (CONST_Use_Aux_Location_data) {
|
||||||
$iParentPlaceID = $oDB->getOne('select parent_place_id from location_property_aux where place_id = '.$iPlaceID);
|
$iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_aux where place_id = '.$iPlaceID));
|
||||||
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +86,7 @@ if ($sOutputFormat == 'json') {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$aRelatedPlaceIDs = $oDB->getCol("select place_id from placex where linked_place_id = $iPlaceID or place_id = $iPlaceID");
|
$aRelatedPlaceIDs = chksql($oDB->getCol($sSQL = "select place_id from placex where linked_place_id = $iPlaceID or place_id = $iPlaceID"));
|
||||||
|
|
||||||
$sSQL = 'select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level,';
|
$sSQL = 'select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level,';
|
||||||
$sSQL .= " rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, st_area(geometry) as area, ";
|
$sSQL .= " rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, st_area(geometry) as area, ";
|
||||||
@@ -97,7 +94,7 @@ $sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, lengt
|
|||||||
$sSQL .= ' from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ';
|
$sSQL .= ' from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ';
|
||||||
$sSQL .= ' where parent_place_id in ('.join(',', $aRelatedPlaceIDs).') and name is not null order by rank_address asc,rank_search asc limit 500) as obj';
|
$sSQL .= ' where parent_place_id in ('.join(',', $aRelatedPlaceIDs).') and name is not null order by rank_address asc,rank_search asc limit 500) as obj';
|
||||||
$sSQL .= ' order by rank_address asc,rank_search asc,localname,class, type,housenumber';
|
$sSQL .= ' order by rank_address asc,rank_search asc,localname,class, type,housenumber';
|
||||||
$aParentOfLines = $oDB->getAll($sSQL);
|
$aParentOfLines = chksql($oDB->getAll($sSQL));
|
||||||
|
|
||||||
if (!empty($aParentOfLines)) {
|
if (!empty($aParentOfLines)) {
|
||||||
echo '<h2>Parent Of:</h2>';
|
echo '<h2>Parent Of:</h2>';
|
||||||
@@ -121,7 +118,7 @@ if (!empty($aParentOfLines)) {
|
|||||||
echo '<div class="line">';
|
echo '<div class="line">';
|
||||||
echo '<span class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>').'</span>';
|
echo '<span class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>').'</span>';
|
||||||
echo ' (';
|
echo ' (';
|
||||||
echo '<span class="area">'.($aAddressLine['isarea']?'Polygon':'Point').'</span>';
|
echo '<span class="area">'.($aAddressLine['isarea']=='t'?'Polygon':'Point').'</span>';
|
||||||
if ($sOSMType) echo ', <span class="osm"><span class="label"></span>'.$sOSMType.' '.osmLink($aAddressLine).'</span>';
|
if ($sOSMType) echo ', <span class="osm"><span class="label"></span>'.$sOSMType.' '.osmLink($aAddressLine).'</span>';
|
||||||
echo ', <a href="hierarchy.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
|
echo ', <a href="hierarchy.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
|
||||||
echo ', '.$aAddressLine['area'];
|
echo ', '.$aAddressLine['area'];
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ set_exception_handler_by_format($sOutputFormat);
|
|||||||
// Preferred language
|
// Preferred language
|
||||||
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$hLog = logStart($oDB, 'place', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
|
$hLog = logStart($oDB, 'place', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,9 @@ $iDays = $oParams->getInt('days', false);
|
|||||||
$bReduced = $oParams->getBool('reduced', false);
|
$bReduced = $oParams->getBool('reduced', false);
|
||||||
$sClass = $oParams->getString('class', false);
|
$sClass = $oParams->getString('class', false);
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$iTotalBroken = (int) $oDB->getOne('select count(*) from import_polygon_error');
|
$iTotalBroken = (int) chksql($oDB->getOne('select count(*) from import_polygon_error'));
|
||||||
|
|
||||||
$aPolygons = array();
|
$aPolygons = array();
|
||||||
while ($iTotalBroken && empty($aPolygons)) {
|
while ($iTotalBroken && empty($aPolygons)) {
|
||||||
@@ -37,7 +36,7 @@ while ($iTotalBroken && empty($aPolygons)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sSQL .= ' order by updated desc limit 1000';
|
$sSQL .= ' order by updated desc limit 1000';
|
||||||
$aPolygons = $oDB->getAll($sSQL);
|
$aPolygons = chksql($oDB->getAll($sSQL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CONST_Debug) {
|
if (CONST_Debug) {
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ set_exception_handler_by_format($sOutputFormat);
|
|||||||
// Preferred language
|
// Preferred language
|
||||||
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
$aLangPrefOrder = $oParams->getPreferredLanguages();
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
|
|
||||||
$hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
|
$hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
|
||||||
|
|
||||||
@@ -67,7 +66,7 @@ if (isset($aPlace)) {
|
|||||||
$aPlace = array();
|
$aPlace = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
logEnd($oDB, $hLog, count($aPlace) ? 1 : 0);
|
logEnd($oDB, $hLog, count($aPlace));
|
||||||
|
|
||||||
if (CONST_Debug) {
|
if (CONST_Debug) {
|
||||||
var_dump($aPlace);
|
var_dump($aPlace);
|
||||||
@@ -75,16 +74,13 @@ if (CONST_Debug) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($sOutputFormat == 'html') {
|
if ($sOutputFormat == 'html') {
|
||||||
$sDataDate = $oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1");
|
$sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
|
||||||
$sTileURL = CONST_Map_Tile_URL;
|
$sTileURL = CONST_Map_Tile_URL;
|
||||||
$sTileAttribution = CONST_Map_Tile_Attribution;
|
$sTileAttribution = CONST_Map_Tile_Attribution;
|
||||||
} elseif ($sOutputFormat == 'geocodejson') {
|
} elseif ($sOutputFormat == 'geocodejson') {
|
||||||
$sQuery = $fLat.','.$fLon;
|
$sQuery = $fLat.','.$fLon;
|
||||||
if (isset($aPlace['place_id'])) {
|
if (isset($aPlace['place_id'])) {
|
||||||
$fDistance = $oDB->getOne(
|
$fDistance = chksql($oDB->getOne('SELECT ST_Distance(ST_SetSRID(ST_Point('.$fLon.','.$fLat.'),4326), centroid) FROM placex where place_id='.$aPlace['place_id']));
|
||||||
'SELECT ST_Distance(ST_SetSRID(ST_Point(:lon,:lat),4326), centroid) FROM placex where place_id = :placeid',
|
|
||||||
array(':lon' => $fLon, ':lat' => $fLat, ':placeid' => $aPlace['place_id'])
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ require_once(CONST_BasePath.'/lib/Geocode.php');
|
|||||||
require_once(CONST_BasePath.'/lib/output.php');
|
require_once(CONST_BasePath.'/lib/output.php');
|
||||||
ini_set('memory_limit', '200M');
|
ini_set('memory_limit', '200M');
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB =& getDB();
|
||||||
$oDB->connect();
|
|
||||||
$oParams = new Nominatim\ParameterParser();
|
$oParams = new Nominatim\ParameterParser();
|
||||||
|
|
||||||
$oGeocode = new Nominatim\Geocode($oDB);
|
$oGeocode = new Nominatim\Geocode($oDB);
|
||||||
@@ -66,7 +65,7 @@ $hLog = logStart($oDB, 'search', $oGeocode->getQueryString(), $aLangPrefOrder);
|
|||||||
$aSearchResults = $oGeocode->lookup();
|
$aSearchResults = $oGeocode->lookup();
|
||||||
|
|
||||||
if ($sOutputFormat=='html') {
|
if ($sOutputFormat=='html') {
|
||||||
$sDataDate = $oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1");
|
$sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
|
||||||
}
|
}
|
||||||
logEnd($oDB, $hLog, count($aSearchResults));
|
logEnd($oDB, $hLog, count($aSearchResults));
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ require_once(CONST_BasePath.'/lib/Status.php');
|
|||||||
$oParams = new Nominatim\ParameterParser();
|
$oParams = new Nominatim\ParameterParser();
|
||||||
$sOutputFormat = $oParams->getSet('format', array('text', 'json'), 'text');
|
$sOutputFormat = $oParams->getSet('format', array('text', 'json'), 'text');
|
||||||
|
|
||||||
$oDB = new Nominatim\DB();
|
$oDB = DB::connect(CONST_Database_DSN, false);
|
||||||
|
$oStatus = new Nominatim\Status($oDB);
|
||||||
|
|
||||||
|
|
||||||
if ($sOutputFormat == 'json') {
|
if ($sOutputFormat == 'json') {
|
||||||
header('content-type: application/json; charset=UTF-8');
|
header('content-type: application/json; charset=UTF-8');
|
||||||
@@ -15,7 +17,6 @@ if ($sOutputFormat == 'json') {
|
|||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$oStatus = new Nominatim\Status($oDB);
|
|
||||||
$oStatus->status();
|
$oStatus->status();
|
||||||
} catch (Exception $oErr) {
|
} catch (Exception $oErr) {
|
||||||
if ($sOutputFormat == 'json') {
|
if ($sOutputFormat == 'json') {
|
||||||
|
|||||||
Reference in New Issue
Block a user