w := getorcreate_word_id(s);
- IF NOT (ARRAY[w] <@ result) THEN
+ IF w IS NOT NULL AND NOT (ARRAY[w] <@ result) THEN
result := result || w;
END IF;
w := getorcreate_word_id(s);
- IF NOT (ARRAY[w] <@ result) THEN
+ IF w IS NOT NULL AND NOT (ARRAY[w] <@ result) THEN
result := result || w;
END IF;
$$
LANGUAGE plpgsql IMMUTABLE;
-CREATE OR REPLACE FUNCTION get_country_code(place geometry, in_country_code VARCHAR(2)) RETURNS TEXT
- AS $$
-DECLARE
- nearcountry RECORD;
-BEGIN
- FOR nearcountry IN select country_code from country_name where country_code = lower(in_country_code)
- LOOP
- RETURN nearcountry.country_code;
- END LOOP;
- RETURN get_country_code(place);
-END;
-$$
-LANGUAGE plpgsql IMMUTABLE;
-
CREATE OR REPLACE FUNCTION get_country_language_code(search_country_code VARCHAR(2)) RETURNS TEXT
AS $$
DECLARE
insert into placex (osm_type, osm_id, class, type, admin_level, housenumber, street, addr_place, isin, postcode,
country_code, parent_place_id, rank_address, rank_search, indexed_status, geometry)
values ('N',prevnode.osm_id, 'place', 'house', prevnode.admin_level, housenum, prevnode.street, prevnode.addr_place, prevnode.isin, coalesce(prevnode.postcode, defpostalcode),
- prevnode.country_code, prevnode.parent_place_id, prevnode.rank_address, prevnode.rank_search, 1, ST_Line_Interpolate_Point(linegeo, (housenum::float-orginalstartnumber::float)/originalnumberrange::float));
+ prevnode.country_code, prevnode.parent_place_id, prevnode.rank_address, prevnode.rank_search, 1, ST_LineInterpolatePoint(linegeo, (housenum::float-orginalstartnumber::float)/originalnumberrange::float));
newpoints := newpoints + 1;
--RAISE WARNING 'interpolation number % % ',prevnode.place_id,housenum;
END LOOP;
NEW.place_id := nextval('seq_place');
NEW.indexed_status := 1; --STATUS_NEW
- NEW.calculated_country_code := lower(get_country_code(NEW.geometry, NEW.country_code));
+ NEW.calculated_country_code := lower(get_country_code(NEW.geometry));
NEW.partition := get_partition(NEW.geometry, NEW.calculated_country_code);
NEW.geometry_sector := geometry_sector(NEW.partition, NEW.geometry);
return NULL;
END IF;
NEW.rank_search := NEW.admin_level * 2;
- NEW.rank_address := NEW.rank_search;
+ IF NEW.type = 'administrative' THEN
+ NEW.rank_address := NEW.rank_search;
+ ELSE
+ NEW.rank_address := 0;
+ END IF;
ELSEIF NEW.class = 'landuse' AND ST_GeometryType(NEW.geometry) in ('ST_Polygon','ST_MultiPolygon') THEN
NEW.rank_search := 22;
NEW.rank_address := NEW.rank_search;
-- Note: won't work on initial import because the classtype tables
-- do not yet exist. It won't hurt either.
classtable := 'place_classtype_' || NEW.class || '_' || NEW.type;
- SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable INTO result;
+ SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable and schemaname = current_schema() INTO result;
IF result THEN
EXECUTE 'INSERT INTO ' || classtable::regclass || ' (place_id, centroid) VALUES ($1,$2)'
USING NEW.place_id, ST_Centroid(NEW.geometry);
-- reclaculate country and partition
IF NEW.rank_search >= 4 THEN
- --NEW.calculated_country_code := lower(get_country_code(NEW.geometry, NEW.country_code));
NEW.calculated_country_code := lower(get_country_code(place_centroid));
ELSE
NEW.calculated_country_code := NULL;
FOR relation IN SELECT place_id FROM placex
WHERE ST_DWithin(location.geometry, placex.geometry, 0.001) and placex.rank_search = 26
and st_geometrytype(location.geometry) in ('ST_LineString')
- ORDER BY (ST_distance(placex.geometry, ST_Line_Interpolate_Point(location.geometry,0))+
- ST_distance(placex.geometry, ST_Line_Interpolate_Point(location.geometry,0.5))+
- ST_distance(placex.geometry, ST_Line_Interpolate_Point(location.geometry,1))) ASC limit 1
+ ORDER BY (ST_distance(placex.geometry, ST_LineInterpolatePoint(location.geometry,0))+
+ ST_distance(placex.geometry, ST_LineInterpolatePoint(location.geometry,0.5))+
+ ST_distance(placex.geometry, ST_LineInterpolatePoint(location.geometry,1))) ASC limit 1
LOOP
--RAISE WARNING 'using nearest street to address interpolation line,0.001 %',relation;
NEW.parent_place_id := relation.place_id;
-- mark everything linked to this place for re-indexing
--DEBUG: RAISE WARNING 'placex_delete:03 % %',OLD.osm_type,OLD.osm_id;
UPDATE placex set indexed_status = 2 from place_addressline where address_place_id = OLD.place_id
- and placex.place_id = place_addressline.place_id and indexed_status = 0;
+ and placex.place_id = place_addressline.place_id and indexed_status = 0 and place_addressline.isaddress;
--DEBUG: RAISE WARNING 'placex_delete:04 % %',OLD.osm_type,OLD.osm_id;
DELETE FROM place_addressline where address_place_id = OLD.place_id;
-- remove from tables for special search
classtable := 'place_classtype_' || OLD.class || '_' || OLD.type;
- SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable INTO b;
+ SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable and schemaname = current_schema() INTO b;
IF b THEN
EXECUTE 'DELETE FROM ' || classtable::regclass || ' WHERE place_id = $1' USING OLD.place_id;
END IF;
-- Just block these - lots and pointless
IF NEW.class in ('landuse','natural') and NEW.name is null THEN
+ -- if the name tag was removed, older versions might still be lurking in the place table
+ DELETE FROM place where osm_type = NEW.osm_type and osm_id = NEW.osm_id and class = NEW.class and type = NEW.type;
RETURN null;
END IF;
DELETE from import_polygon_error where osm_type = NEW.osm_type and osm_id = NEW.osm_id;
DELETE from import_polygon_delete where osm_type = NEW.osm_type and osm_id = NEW.osm_id;
- -- To paraphrase, if there isn't an existing item, OR if the admin level has changed, OR if it is a major change in geometry
- IF existingplacex.osm_type IS NULL THEN
+ -- To paraphrase, if there isn't an existing item, OR if the admin level has changed
+ IF existingplacex.osm_type IS NULL OR
+ (coalesce(existingplacex.admin_level, 15) != coalesce(NEW.admin_level, 15) AND existingplacex.class = 'boundary' AND existingplacex.type = 'administrative')
+ THEN
+
+ IF existingplacex.osm_type IS NOT NULL THEN
+ -- sanity check: ignore admin_level changes on places with too many active children
+ -- or we end up reindexing entire countries because somebody accidentally deleted admin_level
+ --LIMIT INDEXING: SELECT count(*) FROM (SELECT 'a' FROM placex , place_addressline where address_place_id = existingplacex.place_id and placex.place_id = place_addressline.place_id and indexed_status = 0 and place_addressline.isaddress LIMIT 100001) sub INTO i;
+ --LIMIT INDEXING: IF i > 100000 THEN
+ --LIMIT INDEXING: RETURN null;
+ --LIMIT INDEXING: END IF;
+ END IF;
IF existing.osm_type IS NOT NULL THEN
-- pathological case caused by the triggerless copy into place during initial import
geometry = NEW.geometry
where osm_type = NEW.osm_type and osm_id = NEW.osm_id and class = NEW.class and type = NEW.type;
+ IF NEW.class in ('place','boundary') AND NEW.type in ('postcode','postal_code') THEN
+ IF NEW.postcode IS NULL THEN
+ -- postcode was deleted, no longer retain in placex
+ DELETE FROM placex where place_id = existingplacex.place_id;
+ RETURN NULL;
+ END IF;
+
+ NEW.name := hstore('ref', NEW.postcode);
+ END IF;
+
update placex set
name = NEW.name,
housenumber = NEW.housenumber,
CASE WHEN class = 'place' and type = 'postcode' THEN hstore('name', postcode) ELSE name END as name,
class, type, admin_level, fromarea, isaddress,
CASE WHEN address_place_id = for_place_id AND rank_address = 0 THEN 100 WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address,
- distance,calculated_country_code
+ distance,calculated_country_code,postcode
from place_addressline join placex on (address_place_id = placex.place_id)
where place_addressline.place_id = for_place_id
and (cached_rank_address > 0 AND cached_rank_address < searchrankaddress)
IF searchpostcode IS NOT NULL and location.type = 'postcode' THEN
location.isaddress := FALSE;
END IF;
+ IF searchpostcode IS NULL and location.isaddress and location.type != 'postcode' and location.postcode IS NOT NULL THEN
+ searchpostcode := location.postcode;
+ END IF;
IF location.rank_address = 4 AND location.isaddress THEN
hadcountry := true;
END IF;