INSERT INTO place_addressline (place_id, address_place_id, fromarea,
isaddress, distance, cached_rank_address)
- VALUES (obj_place_id, location.place_id, true,
+ VALUES (obj_place_id, location.place_id, not location.isguess,
location_isaddress, location.distance, location.rank_address);
END LOOP;
END;
$$
LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION get_parent_address_level(geom GEOMETRY, in_level SMALLINT)
- RETURNS SMALLINT
- AS $$
-DECLARE
- address_rank SMALLINT;
-BEGIN
- IF in_level <= 3 or in_level > 15 THEN
- address_rank := 3;
- ELSE
- SELECT rank_address INTO address_rank
- FROM placex
- WHERE osm_type = 'R' and class = 'boundary' and type = 'administrative'
- and admin_level < in_level
- and geometry ~ geom and _ST_Covers(geometry, geom)
- ORDER BY admin_level desc LIMIT 1;
- END IF;
-
- IF address_rank is NULL or address_rank <= 3 THEN
- RETURN 3;
- END IF;
-
- RETURN address_rank;
-END;
-$$
-LANGUAGE plpgsql;
-
-
CREATE OR REPLACE FUNCTION placex_update()
RETURNS TRIGGER
AS $$
addr_street TEXT;
addr_place TEXT;
+ max_rank SMALLINT;
+
name_vector INTEGER[];
nameaddress_vector INTEGER[];
addr_nameaddress_vector INTEGER[];
and NEW.osm_type = 'R' and NEW.rank_address > 0
THEN
-- First, check that admin boundaries do not overtake each other rank-wise.
- parent_address_level := get_parent_address_level(NEW.centroid, NEW.admin_level);
- IF parent_address_level >= NEW.rank_address THEN
- IF parent_address_level >= 24 THEN
- NEW.rank_address := 25;
- ELSE
- NEW.rank_address := parent_address_level + 2;
- END IF;
- END IF;
- -- Second check that the boundary is not completely contained in a
- -- place area with a higher address rank
+ parent_address_level := 3;
FOR location IN
- SELECT rank_address FROM placex
- WHERE class = 'place' and rank_address < 24
- and rank_address > NEW.rank_address
- and geometry ~ NEW.geometry
- and ST_Relate(geometry, NEW.geometry, 'T*T***FF*') -- contains but not equal
- ORDER BY rank_address desc LIMIT 1
+ SELECT rank_address,
+ (CASE WHEN extratags ? 'wikidata' and NEW.extratags ? 'wikidata'
+ and extratags->'wikidata' = NEW.extratags->'wikidata'
+ THEN ST_Equals(geometry, NEW.geometry)
+ ELSE false END) as is_same
+ FROM placex
+ WHERE osm_type = 'R' and class = 'boundary' and type = 'administrative'
+ and admin_level < NEW.admin_level and admin_level > 3
+ and rank_address > 0
+ and geometry && NEW.centroid and _ST_Covers(geometry, NEW.centroid)
+ ORDER BY admin_level desc LIMIT 1
LOOP
- NEW.rank_address := location.rank_address + 2;
+ IF location.is_same THEN
+ -- Looks like the same boundary is replicated on multiple admin_levels.
+ -- Usual tagging in Poland. Remove our boundary from addresses.
+ NEW.rank_address := 0;
+ ELSE
+ parent_address_level := location.rank_address;
+ IF location.rank_address >= NEW.rank_address THEN
+ IF location.rank_address >= 24 THEN
+ NEW.rank_address := 25;
+ ELSE
+ NEW.rank_address := location.rank_address + 2;
+ END IF;
+ END IF;
+ END IF;
END LOOP;
+
+ IF NEW.rank_address > 9 THEN
+ -- Second check that the boundary is not completely contained in a
+ -- place area with a higher address rank
+ FOR location IN
+ SELECT rank_address FROM placex
+ WHERE class = 'place' and rank_address < 24
+ and rank_address > NEW.rank_address
+ and geometry && NEW.geometry
+ and geometry ~ NEW.geometry -- needed because ST_Relate does not do bbox cover test
+ and ST_Relate(geometry, NEW.geometry, 'T*T***FF*') -- contains but not equal
+ ORDER BY rank_address desc LIMIT 1
+ LOOP
+ NEW.rank_address := location.rank_address + 2;
+ END LOOP;
+ END IF;
ELSEIF NEW.class = 'place' and NEW.osm_type = 'N'
and NEW.rank_address between 16 and 23
THEN
SELECT rank_address FROM placex
WHERE osm_type = 'R' and class = 'boundary' and type = 'administrative'
and rank_address = NEW.rank_address
- and geometry ~ NEW.centroid and _ST_Covers(geometry, NEW.centroid)
+ and geometry && NEW.centroid and _ST_Covers(geometry, NEW.centroid)
LIMIT 1
LOOP
NEW.rank_address = NEW.rank_address + 2;
IF NEW.osm_type = 'N' AND addr_street IS NULL AND addr_place IS NULL
AND NEW.housenumber IS NULL THEN
FOR location IN
- -- The additional ~ condition works around the misguided query
+ -- The additional && condition works around the misguided query
-- planner of postgis 3.0.
SELECT address from placex where ST_Covers(geometry, NEW.centroid)
- and geometry ~ NEW.centroid
+ and geometry && NEW.centroid
and (address ? 'housenumber' or address ? 'street' or address ? 'place')
and rank_search > 28 AND ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon')
limit 1
IF NEW.rank_search <= 25 and NEW.rank_address > 0 THEN
result := add_location(NEW.place_id, NEW.country_code, NEW.partition,
name_vector, NEW.rank_search, NEW.rank_address,
- upper(trim(NEW.address->'postcode')), NEW.geometry);
+ upper(trim(NEW.address->'postcode')), NEW.geometry,
+ NEW.centroid);
--DEBUG: RAISE WARNING 'Place added to location table';
END IF;
--DEBUG: RAISE WARNING 'Country names updated';
END IF;
- SELECT * FROM insert_addresslines(NEW.place_id, NEW.partition,
- CASE WHEN NEW.rank_address = 0 THEN NEW.rank_search
- WHEN NEW.rank_address > 25 THEN 25::smallint
- ELSE NEW.rank_address END,
+ IF NEW.rank_address = 0 THEN
+ max_rank := geometry_to_rank(NEW.rank_search, NEW.geometry, NEW.country_code);
+ ELSEIF NEW.rank_address > 25 THEN
+ max_rank := 25;
+ ELSE
+ max_rank = NEW.rank_address;
+ END IF;
+
+ SELECT * FROM insert_addresslines(NEW.place_id, NEW.partition, max_rank,
NEW.address,
- CASE WHEN NEW.rank_search >= 26
- AND NEW.rank_search < 30
- THEN NEW.geometry ELSE NEW.centroid END)
+ CASE WHEN (NEW.rank_address = 0 or
+ NEW.rank_search between 26 and 29)
+ THEN NEW.geometry ELSE NEW.centroid END)
INTO NEW.parent_place_id, NEW.postcode, nameaddress_vector;
--DEBUG: RAISE WARNING 'RETURN insert_addresslines: %, %, %', NEW.parent_place_id, NEW.postcode, nameaddress_vector;
IF NEW.name IS NOT NULL THEN
IF NEW.rank_search <= 25 and NEW.rank_address > 0 THEN
- result := add_location(NEW.place_id, NEW.country_code, NEW.partition, name_vector, NEW.rank_search, NEW.rank_address, upper(trim(NEW.address->'postcode')), NEW.geometry);
+ result := add_location(NEW.place_id, NEW.country_code, NEW.partition, name_vector, NEW.rank_search, NEW.rank_address, upper(trim(NEW.address->'postcode')), NEW.geometry, NEW.centroid);
--DEBUG: RAISE WARNING 'added to location (full)';
END IF;