mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e39e51e531 | ||
|
|
d545554615 | ||
|
|
07120f9af5 | ||
|
|
2a5c6b1570 | ||
|
|
6f6ebbd7be | ||
|
|
2635389a87 | ||
|
|
e022d41a01 |
@@ -20,7 +20,7 @@ project(nominatim)
|
|||||||
|
|
||||||
set(NOMINATIM_VERSION_MAJOR 4)
|
set(NOMINATIM_VERSION_MAJOR 4)
|
||||||
set(NOMINATIM_VERSION_MINOR 3)
|
set(NOMINATIM_VERSION_MINOR 3)
|
||||||
set(NOMINATIM_VERSION_PATCH 1)
|
set(NOMINATIM_VERSION_PATCH 2)
|
||||||
|
|
||||||
set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
|
set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
4.3.2
|
||||||
|
* fix potential SQL injection issue for 'nominatim admin --collect-os-info'
|
||||||
|
* PHP frontend: fix on-the-fly lookup of postcode areas near boundaries
|
||||||
|
* Python frontend: improve handling of viewbox
|
||||||
|
* Python frontend: correct deployment instructions
|
||||||
|
|
||||||
4.3.1
|
4.3.1
|
||||||
* reintroduce result rematching
|
* reintroduce result rematching
|
||||||
* improve search of multi-part names
|
* improve search of multi-part names
|
||||||
|
|||||||
@@ -43,6 +43,22 @@ virtualenv /srv/nominatim-venv
|
|||||||
Next you need to set up the service that runs the Nominatim frontend. This is
|
Next you need to set up the service that runs the Nominatim frontend. This is
|
||||||
easiest done with a systemd job.
|
easiest done with a systemd job.
|
||||||
|
|
||||||
|
First you need to tell systemd to create a socket file to be used by
|
||||||
|
hunicorn. Crate the following file `/etc/systemd/system/nominatim.socket`:
|
||||||
|
|
||||||
|
``` systemd
|
||||||
|
[Unit]
|
||||||
|
Description=Gunicorn socket for Nominatim
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=/run/nominatim.sock
|
||||||
|
SocketUser=www-data
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can add the systemd service for Nominatim itself.
|
||||||
Create the following file `/etc/systemd/system/nominatim.service`:
|
Create the following file `/etc/systemd/system/nominatim.service`:
|
||||||
|
|
||||||
``` systemd
|
``` systemd
|
||||||
@@ -74,12 +90,14 @@ its own Python process using
|
|||||||
[`NOMINATIM_API_POOL_SIZE`](../customize/Settings.md#nominatim_api_pool_size)
|
[`NOMINATIM_API_POOL_SIZE`](../customize/Settings.md#nominatim_api_pool_size)
|
||||||
connections to the database to serve requests in parallel.
|
connections to the database to serve requests in parallel.
|
||||||
|
|
||||||
Make the new service known to systemd and start it:
|
Make the new services known to systemd and start it:
|
||||||
|
|
||||||
``` sh
|
``` sh
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
sudo systemctl enable nominatim
|
sudo systemctl enable nominatim.socket
|
||||||
sudo systemctl start nominatim
|
sudo systemctl start nominatim.socket
|
||||||
|
sudo systemctl enable nominatim.service
|
||||||
|
sudo systemctl start nominatim.service
|
||||||
```
|
```
|
||||||
|
|
||||||
This sets the service up, so that Nominatim is automatically started
|
This sets the service up, so that Nominatim is automatically started
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ BEGIN
|
|||||||
-- If the place had a postcode assigned, take this one only
|
-- If the place had a postcode assigned, take this one only
|
||||||
-- into consideration when it is an area and the place does not have
|
-- into consideration when it is an area and the place does not have
|
||||||
-- a postcode itself.
|
-- a postcode itself.
|
||||||
IF location.fromarea AND location.isaddress
|
IF location.fromarea AND location_isaddress
|
||||||
AND (place.address is null or not place.address ? 'postcode')
|
AND (place.address is null or not place.address ? 'postcode')
|
||||||
THEN
|
THEN
|
||||||
place.postcode := null; -- remove the less exact postcode
|
place.postcode := null; -- remove the less exact postcode
|
||||||
|
|||||||
@@ -512,8 +512,8 @@ class PostcodeSearch(AbstractSearch):
|
|||||||
sql = sql.where(t.c.geometry.intersects(VIEWBOX_PARAM))
|
sql = sql.where(t.c.geometry.intersects(VIEWBOX_PARAM))
|
||||||
else:
|
else:
|
||||||
penalty += sa.case((t.c.geometry.intersects(VIEWBOX_PARAM), 0.0),
|
penalty += sa.case((t.c.geometry.intersects(VIEWBOX_PARAM), 0.0),
|
||||||
(t.c.geometry.intersects(VIEWBOX2_PARAM), 1.0),
|
(t.c.geometry.intersects(VIEWBOX2_PARAM), 0.5),
|
||||||
else_=2.0)
|
else_=1.0)
|
||||||
|
|
||||||
if details.near is not None:
|
if details.near is not None:
|
||||||
if details.near_radius is not None:
|
if details.near_radius is not None:
|
||||||
@@ -634,8 +634,8 @@ class PlaceSearch(AbstractSearch):
|
|||||||
sql = sql.where(tsearch.c.centroid.ST_Intersects_no_index(VIEWBOX2_PARAM))
|
sql = sql.where(tsearch.c.centroid.ST_Intersects_no_index(VIEWBOX2_PARAM))
|
||||||
else:
|
else:
|
||||||
penalty += sa.case((t.c.geometry.intersects(VIEWBOX_PARAM), 0.0),
|
penalty += sa.case((t.c.geometry.intersects(VIEWBOX_PARAM), 0.0),
|
||||||
(t.c.geometry.intersects(VIEWBOX2_PARAM), 1.0),
|
(t.c.geometry.intersects(VIEWBOX2_PARAM), 0.5),
|
||||||
else_=2.0)
|
else_=1.0)
|
||||||
|
|
||||||
if details.near is not None:
|
if details.near is not None:
|
||||||
if details.near_radius is not None:
|
if details.near_radius is not None:
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ def zoom_to_rank(zoom: int) -> int:
|
|||||||
return REVERSE_MAX_RANKS[max(0, min(18, zoom))]
|
return REVERSE_MAX_RANKS[max(0, min(18, zoom))]
|
||||||
|
|
||||||
|
|
||||||
FEATURE_TYPE_TO_RANK: Dict[Optional[str], Any] = {
|
FEATURE_TYPE_TO_RANK: Dict[Optional[str], Tuple[int, int]] = {
|
||||||
'country': (4, 4),
|
'country': (4, 4),
|
||||||
'state': (8, 8),
|
'state': (8, 8),
|
||||||
'city': (14, 16),
|
'city': (14, 16),
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class Cursor(psycopg2.extras.DictCursor):
|
|||||||
""" Query execution that logs the SQL query when debugging is enabled.
|
""" Query execution that logs the SQL query when debugging is enabled.
|
||||||
"""
|
"""
|
||||||
if LOG.isEnabledFor(logging.DEBUG):
|
if LOG.isEnabledFor(logging.DEBUG):
|
||||||
LOG.debug(self.mogrify(query, args).decode('utf-8')) # type: ignore[arg-type]
|
LOG.debug(self.mogrify(query, args).decode('utf-8'))
|
||||||
|
|
||||||
super().execute(query, args)
|
super().execute(query, args)
|
||||||
|
|
||||||
|
|||||||
@@ -118,4 +118,4 @@ class CopyBuffer:
|
|||||||
"""
|
"""
|
||||||
if self.buffer.tell() > 0:
|
if self.buffer.tell() > 0:
|
||||||
self.buffer.seek(0)
|
self.buffer.seek(0)
|
||||||
cur.copy_from(self.buffer, table, columns=columns) # type: ignore[arg-type]
|
cur.copy_from(self.buffer, table, columns=columns)
|
||||||
|
|||||||
@@ -12,14 +12,13 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional, Tuple, Union, cast
|
from typing import List, Optional, Tuple, Union
|
||||||
|
|
||||||
import psutil
|
import psutil
|
||||||
from psycopg2.extensions import make_dsn, parse_dsn
|
from psycopg2.extensions import make_dsn, parse_dsn
|
||||||
|
|
||||||
from nominatim.config import Configuration
|
from nominatim.config import Configuration
|
||||||
from nominatim.db.connection import connect
|
from nominatim.db.connection import connect
|
||||||
from nominatim.typing import DictCursorResults
|
|
||||||
from nominatim.version import NOMINATIM_VERSION
|
from nominatim.version import NOMINATIM_VERSION
|
||||||
|
|
||||||
|
|
||||||
@@ -107,15 +106,15 @@ def report_system_information(config: Configuration) -> None:
|
|||||||
postgresql_ver: str = convert_version(conn.server_version_tuple())
|
postgresql_ver: str = convert_version(conn.server_version_tuple())
|
||||||
|
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
cur.execute(f"""
|
num = cur.scalar("SELECT count(*) FROM pg_catalog.pg_database WHERE datname=%s",
|
||||||
SELECT datname FROM pg_catalog.pg_database
|
(parse_dsn(config.get_libpq_dsn())['dbname'], ))
|
||||||
WHERE datname='{parse_dsn(config.get_libpq_dsn())['dbname']}'""")
|
nominatim_db_exists = num == 1 if isinstance(num, int) else False
|
||||||
nominatim_db_exists = cast(Optional[DictCursorResults], cur.fetchall())
|
|
||||||
if nominatim_db_exists:
|
if nominatim_db_exists:
|
||||||
with connect(config.get_libpq_dsn()) as conn:
|
with connect(config.get_libpq_dsn()) as conn:
|
||||||
postgis_ver: str = convert_version(conn.postgis_version_tuple())
|
postgis_ver: str = convert_version(conn.postgis_version_tuple())
|
||||||
else:
|
else:
|
||||||
postgis_ver = "Unable to connect to database"
|
postgis_ver = "Unable to connect to database"
|
||||||
|
|
||||||
postgresql_config: str = get_postgresql_config(int(float(postgresql_ver)))
|
postgresql_config: str = get_postgresql_config(int(float(postgresql_ver)))
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class NominatimVersion(NamedTuple):
|
|||||||
return f"{self.major}.{self.minor}.{self.patch_level}-{self.db_patch_level}"
|
return f"{self.major}.{self.minor}.{self.patch_level}-{self.db_patch_level}"
|
||||||
|
|
||||||
|
|
||||||
NOMINATIM_VERSION = NominatimVersion(4, 3, 1, 0)
|
NOMINATIM_VERSION = NominatimVersion(4, 3, 2, 0)
|
||||||
|
|
||||||
POSTGRESQL_REQUIRED_VERSION = (9, 6)
|
POSTGRESQL_REQUIRED_VERSION = (9, 6)
|
||||||
POSTGIS_REQUIRED_VERSION = (2, 2)
|
POSTGIS_REQUIRED_VERSION = (2, 2)
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ class TestNameOnlySearches:
|
|||||||
@pytest.mark.parametrize('viewbox', ['5.0,4.0,6.0,5.0', '5.7,4.0,6.0,5.0'])
|
@pytest.mark.parametrize('viewbox', ['5.0,4.0,6.0,5.0', '5.7,4.0,6.0,5.0'])
|
||||||
def test_prefer_viewbox(self, apiobj, viewbox):
|
def test_prefer_viewbox(self, apiobj, viewbox):
|
||||||
lookup = FieldLookup('name_vector', [1, 2], 'lookup_all')
|
lookup = FieldLookup('name_vector', [1, 2], 'lookup_all')
|
||||||
ranking = FieldRanking('name_vector', 0.9, [RankedTokens(0.0, [21])])
|
ranking = FieldRanking('name_vector', 0.2, [RankedTokens(0.0, [21])])
|
||||||
|
|
||||||
results = run_search(apiobj, 0.1, [lookup], [ranking])
|
results = run_search(apiobj, 0.1, [lookup], [ranking])
|
||||||
assert [r.place_id for r in results] == [101, 100]
|
assert [r.place_id for r in results] == [101, 100]
|
||||||
|
|||||||
Reference in New Issue
Block a user