--DEBUG: RAISE WARNING 'get_country_code, start: %', ST_AsText(place_centre);
+ -- Try for a OSM polygon
+ FOR nearcountry IN select country_code from location_area_country where country_code is not null and not isguess and st_covers(geometry, place_centre) limit 1
+ LOOP
+ RETURN nearcountry.country_code;
+ END LOOP;
+
--DEBUG: RAISE WARNING 'osm fallback: %', ST_AsText(place_centre);
-- Try for OSM fallback data
RETURN nearcountry.country_code;
END LOOP;
- -- Try for a OSM polygon
- FOR nearcountry IN select country_code from location_area_country where country_code is not null and not isguess and st_covers(geometry, place_centre) limit 1
- LOOP
- RETURN nearcountry.country_code;
- END LOOP;
-
--DEBUG: RAISE WARNING 'natural earth: %', ST_AsText(place_centre);
-- Natural earth data
FOR nodeidpos in 1..array_upper(waynodes, 1) LOOP
- select min(place_id) from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT and type = 'house' INTO search_place_id;
+ -- If there is a place of a type other than place/house, use that because
+ -- it is guaranteed to be the original node. For place/house types use the
+ -- one with the smallest id because the original node was created first.
+ -- Ignore all nodes marked for deletion. (Might happen when the type changes.)
+ select place_id from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT and indexed_status < 100 order by (type = 'house'),place_id limit 1 INTO search_place_id;
IF search_place_id IS NULL THEN
- -- null record of right type
+ -- if no such node exists, create a record of the right type
select * from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT and type = 'house' limit 1 INTO nextnode;
select ST_SetSRID(ST_Point(lon::float/10000000,lat::float/10000000),4326) from planet_osm_nodes where id = waynodes[nodeidpos] INTO nextnode.geometry;
IF nextnode.geometry IS NULL THEN
-- ideally postcodes should move up to the way
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, prevnode.class, prevnode.type, prevnode.admin_level, housenum, prevnode.street, prevnode.addr_place, prevnode.isin, coalesce(prevnode.postcode, defpostalcode),
+ 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));
newpoints := newpoints + 1;
--RAISE WARNING 'interpolation number % % ',prevnode.place_id,housenum;
--DEBUG: RAISE WARNING '% %',NEW.osm_type,NEW.osm_id;
-- just block these
- IF NEW.class = 'highway' and NEW.type in ('turning_circle','traffic_signals','mini_roundabout','noexit','crossing') THEN
--- RAISE WARNING 'bad highway %',NEW.osm_id;
- RETURN null;
- END IF;
IF NEW.class in ('landuse','natural') and NEW.name is null THEN
-- RAISE WARNING 'empty landuse %',NEW.osm_id;
RETURN null;
ELSEIF NEW.type in ('national_park') THEN
NEW.rank_search := 18;
NEW.rank_address := 18;
- ELSEIF NEW.type in ('suburb','croft','subdivision') THEN
+ ELSEIF NEW.type in ('suburb','croft','subdivision','isolated_dwelling') THEN
NEW.rank_search := 20;
NEW.rank_address := NEW.rank_search;
- ELSEIF NEW.type in ('farm','locality','islet','isolated_dwelling','mountain_pass') THEN
+ ELSEIF NEW.type in ('farm','locality','islet','mountain_pass') THEN
NEW.rank_search := 20;
NEW.rank_address := 0;
-- Irish townlands, tagged as place=locality and locality=townland
END IF;
END IF;
+ END IF;
+
+ -- Name searches can be done for ways as well as relations
+ IF NEW.osm_type in ('W','R') AND NEW.rank_search < 26 THEN
+
-- not found one yet? how about doing a name search
IF NEW.centroid IS NULL AND (NEW.name->'name') is not null and make_standard_name(NEW.name->'name') != '' THEN
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;
- 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;
+ 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;
+
+ IF location.rank_address > parent_place_id_rank THEN
+ NEW.parent_place_id = location.place_id;
+ parent_place_id_rank = location.rank_address;
+ END IF;
- IF location.rank_address > parent_place_id_rank THEN
- NEW.parent_place_id = location.place_id;
- parent_place_id_rank = location.rank_address;
END IF;
+--RAISE WARNING ' Terms: (%) %',location, nameaddress_vector;
+
END IF;
END LOOP;
END IF;
-- Just block these - lots and pointless
- IF NEW.class = 'highway' and NEW.type in ('turning_circle','traffic_signals','mini_roundabout','noexit','crossing') THEN
- RETURN null;
- END IF;
IF NEW.class in ('landuse','natural') and NEW.name is null THEN
RETURN null;
END IF;
IF existingplacex.osm_type IS NULL THEN
IF existing.osm_type IS NOT NULL THEN
+ -- pathological case caused by the triggerless copy into place during initial import
+ -- force delete even for large areas, it will be reinserted later
+ UPDATE place set geometry = ST_SetSRID(ST_Point(0,0), 4326) where osm_type = NEW.osm_type and osm_id = NEW.osm_id and class = NEW.class and type = NEW.type;
DELETE from place where osm_type = NEW.osm_type and osm_id = NEW.osm_id and class = NEW.class and type = NEW.type;
END IF;
postcode = NEW.postcode,
country_code = NEW.country_code,
extratags = NEW.extratags,
+ admin_level = NEW.admin_level,
geometry = NEW.geometry
where osm_type = NEW.osm_type and osm_id = NEW.osm_id and class = NEW.class and type = NEW.type;
country_code = NEW.country_code,
parent_place_id = null,
extratags = NEW.extratags,
+ admin_level = CASE WHEN NEW.admin_level > 15 THEN 15 ELSE NEW.admin_level END,
indexed_status = 2,
geometry = NEW.geometry
where place_id = existingplacex.place_id;
diameter := 0.001; -- 50 to 100 meters
END IF;
IF diameter > 0 THEN
- IF NEW.rank_search >= 26 THEN
+ IF rank >= 26 THEN
-- roads may cause reparenting for >27 rank places
update placex set indexed_status = 2 where indexed_status = 0 and rank_search > rank and ST_DWithin(placex.geometry, placegeom, diameter);
- ELSEIF NEW.rank_search >= 16 THEN
+ ELSEIF rank >= 16 THEN
-- up to rank 16, street-less addresses may need reparenting
update placex set indexed_status = 2 where indexed_status = 0 and rank_search > rank and ST_DWithin(placex.geometry, placegeom, diameter) and (rank_search < 28 or name is not null or addr_place is not null);
ELSE