]> git.openstreetmap.org Git - nominatim.git/blobdiff - sql/partition-functions.src.sql
get address terms from address tags for rank 30
[nominatim.git] / sql / partition-functions.src.sql
index 07e99c97b97b21fa33e8c499452e038ea469b002..63548ab20ec6a1531f0bce77ef8e32c9338a9840 100644 (file)
@@ -10,25 +10,44 @@ CREATE TYPE nearfeaturecentr AS (
   centroid GEOMETRY
 );
 
-create or replace function getNearFeatures(in_partition INTEGER, feature GEOMETRY, maxrank INTEGER, isin_tokens INT[]) RETURNS setof nearfeaturecentr AS $$
+-- feature intersects geoemtry
+-- for areas and linestrings they must touch at least along a line
+CREATE OR REPLACE FUNCTION is_relevant_geometry(de9im TEXT, geom_type TEXT)
+RETURNS BOOLEAN
+AS $$
+BEGIN
+  IF substring(de9im from 1 for 2) != 'FF' THEN
+    RETURN TRUE;
+  END IF;
+
+  IF geom_type = 'ST_Point' THEN
+    RETURN substring(de9im from 4 for 1) = '0';
+  END IF;
+
+  IF geom_type in ('ST_LineString', 'ST_MultiLineString') THEN
+    RETURN substring(de9im from 4 for 1) = '1';
+  END IF;
+
+  RETURN substring(de9im from 4 for 1) = '2';
+END
+$$ LANGUAGE plpgsql IMMUTABLE;
+
+create or replace function getNearFeatures(in_partition INTEGER, feature GEOMETRY, maxrank INTEGER) RETURNS setof nearfeaturecentr AS $$
 DECLARE
   r nearfeaturecentr%rowtype;
 BEGIN
 
 -- start
   IF in_partition = -partition- THEN
-    FOR r IN 
-      SELECT place_id, keywords, rank_address, rank_search, min(ST_Distance(feature, centroid)) as distance, isguess, postcode, centroid
+    FOR r IN
+      SELECT place_id, keywords, rank_address, rank_search,
+             min(ST_Distance(feature, centroid)) as distance,
+             isguess, postcode, centroid
       FROM location_area_large_-partition-
-      WHERE ST_Intersects(geometry, feature) and rank_search < maxrank
+      WHERE geometry && feature
+        AND is_relevant_geometry(ST_Relate(geometry, feature), ST_GeometryType(feature))
+        AND rank_address < maxrank
       GROUP BY place_id, keywords, rank_address, rank_search, isguess, postcode, centroid
-      ORDER BY rank_address, isin_tokens && keywords desc, isguess asc,
-        ST_Distance(feature, centroid) *
-          CASE 
-               WHEN rank_address = 16 AND rank_search = 15 THEN 0.2 -- capital city
-               WHEN rank_address = 16 AND rank_search = 16 THEN 0.25 -- city
-               WHEN rank_address = 16 AND rank_search = 17 THEN 0.5 -- town
-               ELSE 1 END ASC -- everything else
     LOOP
       RETURN NEXT r;
     END LOOP;
@@ -39,7 +58,55 @@ BEGIN
   RAISE EXCEPTION 'Unknown partition %', in_partition;
 END
 $$
-LANGUAGE plpgsql;
+LANGUAGE plpgsql STABLE;
+
+CREATE OR REPLACE FUNCTION get_places_for_addr_tags(in_partition SMALLINT,
+                                                    feature GEOMETRY,
+                                                    address HSTORE, country TEXT)
+  RETURNS SETOF nearfeaturecentr
+  AS $$
+DECLARE
+  r nearfeaturecentr%rowtype;
+  item RECORD;
+BEGIN
+  FOR item IN
+    SELECT (get_addr_tag_rank(key, country)).*, key, name FROM
+      (SELECT skeys(address) as key, svals(address) as name) x
+  LOOP
+   IF item.from_rank is null THEN
+     CONTINUE;
+   END IF;
+
+-- start
+    IF in_partition = -partition- THEN
+        SELECT place_id, keywords, rank_address, rank_search,
+               min(ST_Distance(feature, centroid)) as distance,
+               isguess, postcode, centroid INTO r
+        FROM location_area_large_-partition-
+        WHERE geometry && ST_Expand(feature, item.extent)
+          AND rank_address between item.from_rank and item.to_rank
+          AND word_ids_from_name(item.name) && keywords
+        GROUP BY place_id, keywords, rank_address, rank_search, isguess, postcode, centroid
+        ORDER BY ST_Intersects(ST_Collect(geometry), feature), distance LIMIT 1;
+      IF r.place_id is null THEN
+        -- If we cannot find a place for the term, just return the
+        -- search term for the given name. That ensures that the address
+        -- element can still be searched for, even though it will not be
+        -- displayed.
+        RETURN NEXT ROW(null, addr_ids_from_name(item.name), null, null,
+                        null, null, null, null)::nearfeaturecentr;
+      ELSE
+        RETURN NEXT r;
+      END IF;
+      CONTINUE;
+    END IF;
+-- end
+
+    RAISE EXCEPTION 'Unknown partition %', in_partition;
+  END LOOP;
+END;
+$$
+LANGUAGE plpgsql STABLE;
 
 create or replace function deleteLocationArea(in_partition INTEGER, in_place_id BIGINT, in_rank_search INTEGER) RETURNS BOOLEAN AS $$
 DECLARE
@@ -136,7 +203,7 @@ BEGIN
       FROM search_name_-partition-
       WHERE name_vector && isin_token
             AND centroid && ST_Expand(point, 0.04)
-            AND search_rank between 16 and 22
+            AND address_rank between 16 and 25
       ORDER BY ST_Distance(centroid, point) ASC limit 1;
     RETURN parent;
   END IF;
@@ -145,8 +212,7 @@ BEGIN
   RAISE EXCEPTION 'Unknown partition %', in_partition;
 END
 $$
-LANGUAGE plpgsql;
-
+LANGUAGE plpgsql STABLE;
 
 create or replace function insertSearchName(
   in_partition INTEGER, in_place_id BIGINT, in_name_vector INTEGER[],
@@ -254,7 +320,7 @@ BEGIN
   RAISE EXCEPTION 'Unknown partition %', in_partition;
 END
 $$
-LANGUAGE plpgsql IMMUTABLE;
+LANGUAGE plpgsql STABLE;
 
 CREATE OR REPLACE FUNCTION getNearestParallelRoadFeature(in_partition INTEGER,
                                                          line GEOMETRY)
@@ -298,4 +364,4 @@ BEGIN
   RAISE EXCEPTION 'Unknown partition %', in_partition;
 END
 $$
-LANGUAGE plpgsql IMMUTABLE;
+LANGUAGE plpgsql STABLE;