mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-03-11 21:34:06 +00:00
use information from tokenizer to determine street vs. place address
So far the SQL logic used the information from the address field to determine if an address is attached to a street or place. This changes the logic to use the information provided in the token_info. This allows sanitizers to enforce a certain parenting without changing the visible address information.
This commit is contained in:
@@ -189,6 +189,28 @@ a house number token text. If a place has multiple house numbers they must
|
|||||||
be listed with a semicolon as delimiter. Must be NULL when the place has no
|
be listed with a semicolon as delimiter. Must be NULL when the place has no
|
||||||
house numbers.
|
house numbers.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
FUNCTION token_is_street_address(info JSONB) RETURNS BOOLEAN
|
||||||
|
```
|
||||||
|
|
||||||
|
Return true if this is an object that should be parented against a street.
|
||||||
|
Only relevant for objects with address rank 30.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
FUNCTION token_has_addr_street(info JSONB) RETURNS BOOLEAN
|
||||||
|
```
|
||||||
|
|
||||||
|
Return true if there are street names to match against for finding the
|
||||||
|
parent of the object.
|
||||||
|
|
||||||
|
|
||||||
|
```sql
|
||||||
|
FUNCTION token_has_addr_place(info JSONB) RETURNS BOOLEAN
|
||||||
|
```
|
||||||
|
|
||||||
|
Return true if there are place names to match against for finding the
|
||||||
|
parent of the object.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
FUNCTION token_matches_street(info JSONB, street_tokens INTEGER[]) RETURNS BOOLEAN
|
FUNCTION token_matches_street(info JSONB, street_tokens INTEGER[]) RETURNS BOOLEAN
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -996,7 +996,7 @@ BEGIN
|
|||||||
|
|
||||||
{% if debug %}RAISE WARNING 'finding street for % %', NEW.osm_type, NEW.osm_id;{% endif %}
|
{% if debug %}RAISE WARNING 'finding street for % %', NEW.osm_type, NEW.osm_id;{% endif %}
|
||||||
NEW.parent_place_id := null;
|
NEW.parent_place_id := null;
|
||||||
is_place_address := coalesce(not NEW.address ? 'street' and NEW.address ? 'place', FALSE);
|
is_place_address := not token_is_street_address(NEW.token_info);
|
||||||
|
|
||||||
-- We have to find our parent road.
|
-- We have to find our parent road.
|
||||||
NEW.parent_place_id := find_parent_for_poi(NEW.osm_type, NEW.osm_id,
|
NEW.parent_place_id := find_parent_for_poi(NEW.osm_type, NEW.osm_id,
|
||||||
@@ -1013,7 +1013,7 @@ BEGIN
|
|||||||
SELECT p.country_code, p.postcode, p.name FROM placex p
|
SELECT p.country_code, p.postcode, p.name FROM placex p
|
||||||
WHERE p.place_id = NEW.parent_place_id INTO location;
|
WHERE p.place_id = NEW.parent_place_id INTO location;
|
||||||
|
|
||||||
IF is_place_address THEN
|
IF is_place_address and NEW.address ? 'place' THEN
|
||||||
-- Check if the addr:place tag is part of the parent name
|
-- Check if the addr:place tag is part of the parent name
|
||||||
SELECT count(*) INTO i
|
SELECT count(*) INTO i
|
||||||
FROM svals(location.name) AS pname WHERE pname = NEW.address->'place';
|
FROM svals(location.name) AS pname WHERE pname = NEW.address->'place';
|
||||||
|
|||||||
@@ -41,10 +41,17 @@ AS $$
|
|||||||
$$ LANGUAGE SQL IMMUTABLE STRICT;
|
$$ LANGUAGE SQL IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION token_is_street_address(info JSONB)
|
||||||
|
RETURNS BOOLEAN
|
||||||
|
AS $$
|
||||||
|
SELECT info->>'street' is not null or info->>'place' is null;
|
||||||
|
$$ LANGUAGE SQL IMMUTABLE;
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION token_has_addr_street(info JSONB)
|
CREATE OR REPLACE FUNCTION token_has_addr_street(info JSONB)
|
||||||
RETURNS BOOLEAN
|
RETURNS BOOLEAN
|
||||||
AS $$
|
AS $$
|
||||||
SELECT info->>'street' is not null;
|
SELECT info->>'street' is not null and info->>'street' != '{}';
|
||||||
$$ LANGUAGE SQL IMMUTABLE;
|
$$ LANGUAGE SQL IMMUTABLE;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ AS $$
|
|||||||
$$ LANGUAGE SQL IMMUTABLE STRICT;
|
$$ LANGUAGE SQL IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION token_is_street_address(info JSONB)
|
||||||
|
RETURNS BOOLEAN
|
||||||
|
AS $$
|
||||||
|
SELECT info->>'street' is not null or info->>'place' is null;
|
||||||
|
$$ LANGUAGE SQL IMMUTABLE;
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION token_has_addr_street(info JSONB)
|
CREATE OR REPLACE FUNCTION token_has_addr_street(info JSONB)
|
||||||
RETURNS BOOLEAN
|
RETURNS BOOLEAN
|
||||||
AS $$
|
AS $$
|
||||||
|
|||||||
@@ -720,7 +720,7 @@ class _TokenInfo:
|
|||||||
self.names: Optional[str] = None
|
self.names: Optional[str] = None
|
||||||
self.housenumbers: Set[str] = set()
|
self.housenumbers: Set[str] = set()
|
||||||
self.housenumber_tokens: Set[int] = set()
|
self.housenumber_tokens: Set[int] = set()
|
||||||
self.street_tokens: Set[int] = set()
|
self.street_tokens: Optional[Set[int]] = None
|
||||||
self.place_tokens: Set[int] = set()
|
self.place_tokens: Set[int] = set()
|
||||||
self.address_tokens: Dict[str, str] = {}
|
self.address_tokens: Dict[str, str] = {}
|
||||||
self.postcode: Optional[str] = None
|
self.postcode: Optional[str] = None
|
||||||
@@ -742,7 +742,7 @@ class _TokenInfo:
|
|||||||
out['hnr'] = ';'.join(self.housenumbers)
|
out['hnr'] = ';'.join(self.housenumbers)
|
||||||
out['hnr_tokens'] = self._mk_array(self.housenumber_tokens)
|
out['hnr_tokens'] = self._mk_array(self.housenumber_tokens)
|
||||||
|
|
||||||
if self.street_tokens:
|
if self.street_tokens is not None:
|
||||||
out['street'] = self._mk_array(self.street_tokens)
|
out['street'] = self._mk_array(self.street_tokens)
|
||||||
|
|
||||||
if self.place_tokens:
|
if self.place_tokens:
|
||||||
@@ -776,6 +776,8 @@ class _TokenInfo:
|
|||||||
def add_street(self, tokens: Iterable[int]) -> None:
|
def add_street(self, tokens: Iterable[int]) -> None:
|
||||||
""" Add addr:street match terms.
|
""" Add addr:street match terms.
|
||||||
"""
|
"""
|
||||||
|
if self.street_tokens is None:
|
||||||
|
self.street_tokens = set()
|
||||||
self.street_tokens.update(tokens)
|
self.street_tokens.update(tokens)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ class TestPlaceAddress:
|
|||||||
def test_process_place_nonexisting_street(self):
|
def test_process_place_nonexisting_street(self):
|
||||||
info = self.process_address(street='Grand Road')
|
info = self.process_address(street='Grand Road')
|
||||||
|
|
||||||
assert 'street' not in info
|
assert info['street'] == '{}'
|
||||||
|
|
||||||
|
|
||||||
def test_process_place_multiple_street_tags(self):
|
def test_process_place_multiple_street_tags(self):
|
||||||
@@ -538,7 +538,7 @@ class TestPlaceAddress:
|
|||||||
def test_process_place_street_empty(self):
|
def test_process_place_street_empty(self):
|
||||||
info = self.process_address(street='🜵')
|
info = self.process_address(street='🜵')
|
||||||
|
|
||||||
assert 'street' not in info
|
assert info['street'] == '{}'
|
||||||
|
|
||||||
|
|
||||||
def test_process_place_street_from_cache(self):
|
def test_process_place_street_from_cache(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user