1 -- SPDX-License-Identifier: GPL-2.0-only
3 -- This file is part of Nominatim. (https://nominatim.org)
5 -- Copyright (C) 2022 by the Nominatim developer community.
6 -- For a full list of authors see the git log.
7 DROP TABLE IF EXISTS location_property_tiger_import;
8 CREATE TABLE location_property_tiger_import (
12 parent_place_id BIGINT,
19 -- Lookup functions for tiger import when update
20 -- informations are dropped (see gh-issue #2463)
21 CREATE OR REPLACE FUNCTION getNearestNamedRoadPlaceIdSlow(in_centroid GEOMETRY,
29 SELECT place_id INTO out_place_id
32 -- finds rows where name_vector shares elements with search tokens.
33 token_matches_street(in_token_info, name_vector)
35 AND centroid && ST_Expand(in_centroid, 0.015)
36 AND address_rank BETWEEN 26 AND 27
37 ORDER BY ST_Distance(centroid, in_centroid) ASC
46 CREATE OR REPLACE FUNCTION getNearestParallelRoadFeatureSlow(line GEOMETRY)
51 search_diameter FLOAT;
57 IF ST_GeometryType(line) not in ('ST_LineString') THEN
61 p1 := ST_LineInterpolatePoint(line,0);
62 p2 := ST_LineInterpolatePoint(line,0.5);
63 p3 := ST_LineInterpolatePoint(line,1);
65 search_diameter := 0.0005;
66 WHILE search_diameter < 0.01 LOOP
68 SELECT place_id FROM placex
69 WHERE ST_DWithin(line, geometry, search_diameter)
70 AND rank_address BETWEEN 26 AND 27
71 ORDER BY (ST_distance(geometry, p1)+
72 ST_distance(geometry, p2)+
73 ST_distance(geometry, p3)) ASC limit 1
77 search_diameter := search_diameter * 2;
85 CREATE OR REPLACE FUNCTION getNearestRoadPlaceIdSlow(point GEOMETRY)
90 search_diameter FLOAT;
92 search_diameter := 0.00005;
93 WHILE search_diameter < 0.1 LOOP
95 SELECT place_id FROM placex
96 WHERE ST_DWithin(geometry, point, search_diameter)
97 AND rank_address BETWEEN 26 AND 27
98 ORDER BY ST_Distance(geometry, point) ASC limit 1
102 search_diameter := search_diameter * 2;
110 -- Tiger import function
111 CREATE OR REPLACE FUNCTION tiger_line_import(linegeo GEOMETRY, in_startnumber INTEGER,
112 in_endnumber INTEGER, interpolationtype TEXT,
113 token_info JSONB, in_postcode TEXT) RETURNS INTEGER
120 place_centroid GEOMETRY;
121 out_partition INTEGER;
122 out_parent_place_id BIGINT;
127 IF in_endnumber > in_startnumber THEN
128 startnumber := in_startnumber;
129 endnumber := in_endnumber;
131 startnumber := in_endnumber;
132 endnumber := in_startnumber;
133 linegeo := ST_Reverse(linegeo);
136 IF startnumber < 0 THEN
137 RAISE WARNING 'Negative house number range (% to %)', startnumber, endnumber;
141 numberrange := endnumber - startnumber;
143 IF (interpolationtype = 'odd' AND startnumber % 2 = 0) OR (interpolationtype = 'even' AND startnumber % 2 = 1) THEN
144 startnumber := startnumber + 1;
147 IF (interpolationtype = 'odd' OR interpolationtype = 'even') THEN
149 ELSE -- everything else assumed to be 'all'
154 -- Filter out really broken tiger data
156 and numberrange::float/stepsize::float > 500
157 and ST_length(linegeo)/(numberrange::float/stepsize::float) < 0.000001
159 RAISE WARNING 'Road too short for number range % to % (%)',startnumber,endnumber,
160 ST_length(linegeo)/(numberrange::float/stepsize::float);
164 place_centroid := ST_Centroid(linegeo);
165 out_partition := get_partition('us');
167 -- HYBRID LOOKUP LOGIC (see gh-issue #2463)
168 -- if partition tables exist, use them for fast spatial lookups
169 {% if 'location_road_0' in db.tables %}
170 out_parent_place_id := getNearestNamedRoadPlaceId(out_partition, place_centroid,
173 IF out_parent_place_id IS NULL THEN
174 SELECT getNearestParallelRoadFeature(out_partition, linegeo)
175 INTO out_parent_place_id;
178 IF out_parent_place_id IS NULL THEN
179 SELECT getNearestRoadPlaceId(out_partition, place_centroid)
180 INTO out_parent_place_id;
183 -- When updatable information has been dropped:
184 -- Partition tables no longer exist, but search_name still persists.
185 {% elif 'search_name' in db.tables %}
186 -- Fallback: Look up in 'search_name' table
187 -- though spatial lookups here can be slower.
188 out_parent_place_id := getNearestNamedRoadPlaceIdSlow(place_centroid, token_info);
190 IF out_parent_place_id IS NULL THEN
191 out_parent_place_id := getNearestParallelRoadFeatureSlow(linegeo);
194 IF out_parent_place_id IS NULL THEN
195 out_parent_place_id := getNearestRoadPlaceIdSlow(place_centroid);
199 -- If parent was found, insert street(line) into import table
200 IF out_parent_place_id IS NOT NULL THEN
201 INSERT INTO location_property_tiger_import (linegeo, place_id, partition,
202 parent_place_id, startnumber, endnumber,
204 VALUES (linegeo, nextval('seq_place'), out_partition,
205 out_parent_place_id, startnumber, endnumber,
206 stepsize, in_postcode);