excluded place nodes outside parent boundaries from addresses

Changes slightly the logic which decides if a guessed places
(i.e. a place node) is included in an address: it will be
part of the address only if it is inside the next lower
available boundary. This fixes problematic cases where
neighbouring entities have additional admin levels.
This commit is contained in:
Sarah Hoffmann 2012-07-03 22:44:06 +02:00
parent 980632053f
commit afc429fd92
2 changed files with 35 additions and 9 deletions

View File

@ -1213,6 +1213,8 @@ DECLARE
location_rank_search INTEGER; location_rank_search INTEGER;
location_distance FLOAT; location_distance FLOAT;
location_parent GEOMETRY;
location_isaddress BOOLEAN;
tagpairid INTEGER; tagpairid INTEGER;
@ -1629,6 +1631,7 @@ BEGIN
-- Process area matches -- Process area matches
location_rank_search := 100; location_rank_search := 100;
location_distance := 0; location_distance := 0;
location_parent := NULL;
-- RAISE WARNING ' getNearFeatures(%,''%'',%,''%'')',NEW.partition, place_centroid, search_maxrank, isin_tokens; -- RAISE WARNING ' getNearFeatures(%,''%'',%,''%'')',NEW.partition, place_centroid, search_maxrank, isin_tokens;
FOR location IN SELECT * from getNearFeatures(NEW.partition, place_centroid, search_maxrank, isin_tokens) LOOP FOR location IN SELECT * from getNearFeatures(NEW.partition, place_centroid, search_maxrank, isin_tokens) LOOP
@ -1636,15 +1639,27 @@ BEGIN
IF location.rank_search < location_rank_search THEN IF location.rank_search < location_rank_search THEN
location_rank_search := location.rank_search; location_rank_search := location.rank_search;
location_distance := location.distance * 1.5; location_distance := location.distance * 0.5;
END IF; END IF;
IF location.distance < location_distance OR NOT location.isguess THEN IF location.distance < location_distance OR NOT location.isguess THEN
location_isaddress := NOT address_havelevel[location.rank_address];
IF location_isaddress AND location.isguess AND location_parent IS NOT NULL THEN
location_isaddress := ST_Contains(location_parent,location.centroid);
END IF;
-- RAISE WARNING '% isaddress: %', location.place_id, location_isaddress;
-- Add it to the list of search terms -- Add it to the list of search terms
nameaddress_vector := array_merge(nameaddress_vector, location.keywords::integer[]); nameaddress_vector := array_merge(nameaddress_vector, location.keywords::integer[]);
INSERT INTO place_addressline VALUES (NEW.place_id, location.place_id, true, NOT address_havelevel[location.rank_address], location.distance, location.rank_address); INSERT INTO place_addressline VALUES (NEW.place_id, location.place_id, true, location_isaddress, location.distance, location.rank_address);
IF location_isaddress THEN
address_havelevel[location.rank_address] := true; address_havelevel[location.rank_address] := true;
IF NOT location.isguess THEN
SELECT geometry FROM placex WHERE place_id = location.place_id INTO location_parent;
END IF;
END IF;
--RAISE WARNING ' Terms: (%) %',location, nameaddress_vector; --RAISE WARNING ' Terms: (%) %',location, nameaddress_vector;
@ -1690,7 +1705,7 @@ BEGIN
IF location.rank_search < location_rank_search THEN IF location.rank_search < location_rank_search THEN
location_rank_search := location.rank_search; location_rank_search := location.rank_search;
location_distance := location.distance * 1.5; location_distance := location.distance * 0.5;
END IF; END IF;
IF location.distance < location_distance THEN IF location.distance < location_distance THEN

View File

@ -13,6 +13,17 @@ create type nearfeature as (
isguess boolean isguess boolean
); );
drop type nearfeaturecentr cascade;
create type nearfeaturecentr as (
place_id BIGINT,
keywords int[],
rank_address integer,
rank_search integer,
distance float,
isguess boolean,
centroid GEOMETRY
);
CREATE TABLE location_area_country () INHERITS (location_area_large); CREATE TABLE location_area_country () INHERITS (location_area_large);
CREATE INDEX idx_location_area_country_geometry ON location_area_country USING GIST (geometry); CREATE INDEX idx_location_area_country_geometry ON location_area_country USING GIST (geometry);
@ -46,21 +57,21 @@ CREATE INDEX idx_location_road_-partition-_place_id ON location_road_-partition-
-- end -- end
create or replace function getNearFeatures(in_partition INTEGER, point GEOMETRY, maxrank INTEGER, isin_tokens INT[]) RETURNS setof nearfeature AS $$ create or replace function getNearFeatures(in_partition INTEGER, point GEOMETRY, maxrank INTEGER, isin_tokens INT[]) RETURNS setof nearfeaturecentr AS $$
DECLARE DECLARE
r nearfeature%rowtype; r nearfeaturecentr%rowtype;
BEGIN BEGIN
-- start -- start
IF in_partition = -partition- THEN IF in_partition = -partition- THEN
FOR r IN FOR r IN
SELECT place_id, keywords, rank_address, rank_search, min(ST_Distance(point, centroid)) as distance, isguess FROM ( SELECT place_id, keywords, rank_address, rank_search, min(ST_Distance(point, centroid)) as distance, isguess, centroid FROM (
SELECT * FROM location_area_large_-partition- WHERE ST_Contains(geometry, point) and rank_search < maxrank SELECT * FROM location_area_large_-partition- WHERE ST_Contains(geometry, point) and rank_search < maxrank
UNION ALL UNION ALL
SELECT * FROM location_area_country WHERE ST_Contains(geometry, point) and rank_search < maxrank SELECT * FROM location_area_country WHERE ST_Contains(geometry, point) and rank_search < maxrank
) as location_area ) as location_area
GROUP BY place_id, keywords, rank_address, rank_search, isguess, centroid GROUP BY place_id, keywords, rank_address, rank_search, isguess, centroid
ORDER BY rank_address desc, isin_tokens && keywords desc, isguess asc, ORDER BY rank_address, isin_tokens && keywords desc, isguess asc,
ST_Distance(point, centroid) * ST_Distance(point, centroid) *
CASE CASE
WHEN rank_address = 16 AND rank_search = 15 THEN 0.2 -- capital city WHEN rank_address = 16 AND rank_search = 15 THEN 0.2 -- capital city