X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/85ab12c4716ce96f4d666fcc0bd59fa32d68874e..8d6d813f6b8782c05a71980e0f139bbb18739c28:/sql/functions.sql diff --git a/sql/functions.sql b/sql/functions.sql index 777d20d0..b1280cac 100644 --- a/sql/functions.sql +++ b/sql/functions.sql @@ -598,8 +598,8 @@ BEGIN isArea := true; centroid := ST_Centroid(geometry); - FOR geometry IN select split_geometry(geometry) as geometry LOOP - x := insertLocationAreaLarge(partition, place_id, country_code, keywords, rank_search, rank_address, false, centroid, geometry); + FOR secgeo IN select split_geometry(geometry) AS geom LOOP + x := insertLocationAreaLarge(partition, place_id, country_code, keywords, rank_search, rank_address, false, centroid, secgeo); END LOOP; ELSEIF rank_search < 26 THEN @@ -769,6 +769,13 @@ BEGIN -- null record of right type select * from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::INTEGER 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 + -- we don't have any information about this point, most likely + -- because an excerpt was updated and the node never imported + -- because the interpolation is outside the region of the excerpt. + -- Give up. + RETURN newpoints; + END IF; ELSE select * from placex where place_id = search_place_id INTO nextnode; END IF; @@ -1213,6 +1220,8 @@ DECLARE location_rank_search INTEGER; location_distance FLOAT; + location_parent GEOMETRY; + location_isaddress BOOLEAN; tagpairid INTEGER; @@ -1225,7 +1234,7 @@ DECLARE result BOOLEAN; BEGIN - IF NEW.indexed_status != 0 OR OLD.indexed_status = 0 THEN + IF NEW.indexed_status != 0 OR OLD.indexed_status = 0 OR NEW.linked_place_id is not null THEN RETURN NEW; END IF; @@ -1256,7 +1265,7 @@ BEGIN RETURN NEW; END IF; - IF OLD.indexed_status > 1 THEN + IF OLD.indexed_status > 0 THEN result := deleteSearchName(NEW.partition, NEW.place_id); DELETE FROM place_addressline WHERE place_id = NEW.place_id; DELETE FROM place_boundingbox where place_id = NEW.place_id; @@ -1627,24 +1636,39 @@ BEGIN -- RAISE WARNING 'ISIN: %', isin_tokens; -- Process area matches - location_rank_search := 100; + location_rank_search := 0; location_distance := 0; --- RAISE WARNING ' getNearFeatures(%,''%'',%,''%'')',NEW.partition, place_centroid, search_maxrank, isin_tokens; + location_parent := NULL; + -- added ourself as address already + address_havelevel[NEW.rank_address] := true; + -- 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 --RAISE WARNING ' AREA: %',location; - IF location.rank_search < location_rank_search THEN - location_rank_search := location.rank_search; + IF location.rank_address != location_rank_search THEN + location_rank_search := location.rank_address; location_distance := location.distance * 1.5; END IF; 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 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); - address_havelevel[location.rank_address] := true; + 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; @@ -1683,13 +1707,13 @@ BEGIN -- for long ways we should add search terms for the entire length IF st_length(NEW.geometry) > 0.05 THEN - location_rank_search := 100; + location_rank_search := 0; location_distance := 0; FOR location IN SELECT * from getNearFeatures(NEW.partition, NEW.geometry, search_maxrank, isin_tokens) LOOP - IF location.rank_search < location_rank_search THEN - location_rank_search := location.rank_search; + IF location.rank_address != location_rank_search THEN + location_rank_search := location.rank_address; location_distance := location.distance * 1.5; END IF; @@ -1739,7 +1763,7 @@ DECLARE b BOOLEAN; classtable TEXT; BEGIN - RAISE WARNING 'placex_delete % %',OLD.osm_type,OLD.osm_id; + -- RAISE WARNING 'placex_delete % %',OLD.osm_type,OLD.osm_id; update placex set linked_place_id = null where linked_place_id = OLD.place_id; --DEBUG: RAISE WARNING 'placex_delete:01 % %',OLD.osm_type,OLD.osm_id; @@ -1806,8 +1830,8 @@ BEGIN --DEBUG: RAISE WARNING 'delete: % % % %',OLD.osm_type,OLD.osm_id,OLD.class,OLD.type; - -- deleting large polygons can have a massive effect ont he system - require manual intervention to let them through - IF st_area(OLD.geometry) > 2 THEN + -- deleting large polygons can have a massive effect on the system - require manual intervention to let them through + IF st_area(OLD.geometry) > 2 and st_isvalid(OLD.geometry) THEN insert into import_polygon_delete values (OLD.osm_type,OLD.osm_id,OLD.class,OLD.type); RETURN NULL; END IF; @@ -2156,7 +2180,7 @@ BEGIN FOR location IN select * from get_addressdata(for_place_id) where isaddress order by rank_address desc LOOP currresult := trim(get_name_by_language(location.name, languagepref)); - IF currresult != prevresult AND currresult IS NOT NULL THEN + IF currresult != prevresult AND currresult IS NOT NULL AND result[(100 - location.rank_address)] IS NULL THEN result[(100 - location.rank_address)] := trim(get_name_by_language(location.name, languagepref)); prevresult := currresult; END IF; @@ -2213,14 +2237,14 @@ BEGIN END IF; IF for_place_id IS NULL THEN - select parent_place_id, calculated_country_code, housenumber, rank_address, postcode, name, class, type from placex + select parent_place_id, calculated_country_code, housenumber, rank_search, postcode, name, class, type from placex WHERE place_id = in_place_id and rank_address = 30 INTO for_place_id, searchcountrycode, searchhousenumber, searchrankaddress, searchpostcode, searchhousename, searchclass, searchtype; END IF; IF for_place_id IS NULL THEN for_place_id := in_place_id; - select calculated_country_code, housenumber, rank_address, postcode, null from placex where place_id = for_place_id + select calculated_country_code, housenumber, rank_search, postcode, null from placex where place_id = for_place_id INTO searchcountrycode, searchhousenumber, searchrankaddress, searchpostcode, searchhousename; END IF; @@ -2560,93 +2584,6 @@ END; $$ LANGUAGE plpgsql; -CREATE OR REPLACE FUNCTION tigger_create_interpolation(linegeo GEOMETRY, in_startnumber INTEGER, - in_endnumber INTEGER, interpolationtype TEXT, - in_street TEXT, in_isin TEXT, in_postcode TEXT) RETURNS INTEGER - AS $$ -DECLARE - - startnumber INTEGER; - endnumber INTEGER; - stepsize INTEGER; - housenum INTEGER; - newpoints INTEGER; - numberrange INTEGER; - rangestartnumber INTEGER; - place_centroid GEOMETRY; - out_partition INTEGER; - out_parent_place_id BIGINT; - location RECORD; - address_street_word_id INTEGER; - -BEGIN - - IF in_endnumber > in_startnumber THEN - startnumber = in_startnumber; - endnumber = in_endnumber; - ELSE - startnumber = in_endnumber; - endnumber = in_startnumber; - END IF; - - numberrange := endnumber - startnumber; - rangestartnumber := startnumber; - - IF (interpolationtype = 'odd' AND startnumber%2 = 0) OR (interpolationtype = 'even' AND startnumber%2 = 1) THEN - startnumber := startnumber + 1; - stepsize := 2; - ELSE - IF (interpolationtype = 'odd' OR interpolationtype = 'even') THEN - stepsize := 2; - ELSE -- everything else assumed to be 'all' - stepsize := 1; - END IF; - END IF; - - -- Filter out really broken tiger data - IF numberrange > 0 AND (numberrange::float/stepsize::float > 500) - AND ST_length(linegeo)/(numberrange::float/stepsize::float) < 0.000001 THEN - RAISE WARNING 'Road too short for number range % to % on %, % (%)',startnumber,endnumber,in_street,in_isin, - ST_length(linegeo)/(numberrange::float/stepsize::float); - RETURN 0; - END IF; - - place_centroid := ST_Centroid(linegeo); - out_partition := get_partition(place_centroid, 'us'); - out_parent_place_id := null; - - address_street_word_id := get_name_id(make_standard_name(in_street)); - IF address_street_word_id IS NOT NULL THEN - FOR location IN SELECT * from getNearestNamedRoadFeature(out_partition, place_centroid, address_street_word_id) LOOP - out_parent_place_id := location.place_id; - END LOOP; - END IF; - - IF out_parent_place_id IS NULL THEN - FOR location IN SELECT place_id FROM getNearestParellelRoadFeature(out_partition, linegeo) LOOP - out_parent_place_id := location.place_id; - END LOOP; - END IF; - - IF out_parent_place_id IS NULL THEN - FOR location IN SELECT place_id FROM getNearestRoadFeature(out_partition, place_centroid) LOOP - out_parent_place_id := location.place_id; - END LOOP; - END IF; - - newpoints := 0; - FOR housenum IN startnumber..endnumber BY stepsize LOOP - insert into location_property_tiger (place_id, partition, parent_place_id, housenumber, postcode, centroid) - values (nextval('seq_place'), out_partition, out_parent_place_id, housenum, in_postcode, - ST_Line_Interpolate_Point(linegeo, (housenum::float-rangestartnumber::float)/numberrange::float)); - newpoints := newpoints + 1; - END LOOP; - - RETURN newpoints; -END; -$$ -LANGUAGE plpgsql; - CREATE OR REPLACE FUNCTION aux_create_property(pointgeo GEOMETRY, in_housenumber TEXT, in_street TEXT, in_isin TEXT, in_postcode TEXT, in_countrycode char(2)) RETURNS INTEGER AS $$ @@ -2878,10 +2815,10 @@ BEGIN IF st_intersects(geometry, secbox) THEN secgeo := st_intersection(geometry, secbox); IF NOT ST_IsEmpty(secgeo) AND ST_GeometryType(secgeo) in ('ST_Polygon','ST_MultiPolygon') THEN - FOR geo IN select quad_split_geometry(secgeo, maxarea, remainingdepth) as geometry LOOP - IF NOT ST_IsEmpty(geo.geometry) AND ST_GeometryType(geo.geometry) in ('ST_Polygon','ST_MultiPolygon') THEN + FOR geo IN select quad_split_geometry(secgeo, maxarea, remainingdepth) as geom LOOP + IF NOT ST_IsEmpty(geo.geom) AND ST_GeometryType(geo.geom) in ('ST_Polygon','ST_MultiPolygon') THEN added := added + 1; - RETURN NEXT geo.geometry; + RETURN NEXT geo.geom; END IF; END LOOP; END IF; @@ -2900,8 +2837,8 @@ DECLARE geo RECORD; BEGIN -- 10000000000 is ~~ 1x1 degree - FOR geo IN select quad_split_geometry(geometry, 0.25, 20) as geometry LOOP - RETURN NEXT geo.geometry; + FOR geo IN select quad_split_geometry(geometry, 0.25, 20) as geom LOOP + RETURN NEXT geo.geom; END LOOP; RETURN; END;