-CREATE OR REPLACE FUNCTION get_place_boundingbox(search_place_id BIGINT) RETURNS place_boundingbox
- AS $$
-DECLARE
- result place_boundingbox;
- numfeatures integer;
-BEGIN
- select * from place_boundingbox into result where place_id = search_place_id;
- IF result.place_id IS NULL THEN
--- remove isaddress = true because if there is a matching polygon it always wins
- select count(*) from place_addressline where address_place_id = search_place_id into numfeatures;
- insert into place_boundingbox select place_id,
- ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),4)),ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),2)),
- ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),1)),ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),3)),
- numfeatures, ST_Area(geometry),
- geometry as area from location_area where place_id = search_place_id;
- select * from place_boundingbox into result where place_id = search_place_id;
- END IF;
- IF result.place_id IS NULL THEN
--- TODO 0.0001
- insert into place_boundingbox select address_place_id,
- min(ST_Y(ST_Centroid(geometry))) as minlon,max(ST_Y(ST_Centroid(geometry))) as maxlon,
- min(ST_X(ST_Centroid(geometry))) as minlat,max(ST_X(ST_Centroid(geometry))) as maxlat,
- count(*), ST_Area(ST_Buffer(ST_Convexhull(ST_Collect(geometry)),0.0001)) as area,
- ST_Buffer(ST_Convexhull(ST_Collect(geometry)),0.0001) as boundary
- from (select * from place_addressline where address_place_id = search_place_id order by cached_rank_address limit 4000) as place_addressline join placex using (place_id)
- where address_place_id = search_place_id
--- and (isaddress = true OR place_id = search_place_id)
- and (st_length(geometry) < 0.01 or place_id = search_place_id)
- group by address_place_id limit 1;
- select * from place_boundingbox into result where place_id = search_place_id;
- END IF;
- return result;
-END;
-$$
-LANGUAGE plpgsql;
-
--- don't do the operation if it would be slow
-CREATE OR REPLACE FUNCTION get_place_boundingbox_quick(search_place_id BIGINT) RETURNS place_boundingbox
- AS $$
-DECLARE
- result place_boundingbox;
- numfeatures integer;
- rank integer;
-BEGIN
- select * from place_boundingbox into result where place_id = search_place_id;
- IF result IS NULL AND rank > 14 THEN
- select count(*) from place_addressline where address_place_id = search_place_id and isaddress = true into numfeatures;
- insert into place_boundingbox select place_id,
- ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),4)),ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),2)),
- ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),1)),ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),3)),
- numfeatures, ST_Area(geometry),
- geometry as area from location_area where place_id = search_place_id;
- select * from place_boundingbox into result where place_id = search_place_id;
- END IF;
- IF result IS NULL THEN
- select rank_search from placex where place_id = search_place_id into rank;
- IF rank > 20 THEN
--- TODO 0.0001
- insert into place_boundingbox select address_place_id,
- min(ST_Y(ST_Centroid(geometry))) as minlon,max(ST_Y(ST_Centroid(geometry))) as maxlon,
- min(ST_X(ST_Centroid(geometry))) as minlat,max(ST_X(ST_Centroid(geometry))) as maxlat,
- count(*), ST_Area(ST_Buffer(ST_Convexhull(ST_Collect(geometry)),0.0001)) as area,
- ST_Buffer(ST_Convexhull(ST_Collect(geometry)),0.0001) as boundary
- from place_addressline join placex using (place_id)
- where address_place_id = search_place_id
- and (isaddress = true OR place_id = search_place_id)
- and (st_length(geometry) < 0.01 or place_id = search_place_id)
- group by address_place_id limit 1;
- select * from place_boundingbox into result where place_id = search_place_id;
- END IF;
- END IF;
- return result;
-END;
-$$
-LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION update_place(search_place_id BIGINT) RETURNS BOOLEAN
- AS $$
-DECLARE
- result place_boundingbox;
- numfeatures integer;
-BEGIN
- update placex set
- name = place.name,
- housenumber = place.housenumber,
- street = place.street,
- isin = place.isin,
- postcode = place.postcode,
- country_code = place.country_code,
- parent_place_id = null
- from place
- where placex.place_id = search_place_id
- and place.osm_type = placex.osm_type and place.osm_id = placex.osm_id
- and place.class = placex.class and place.type = placex.type;
- update placex set indexed_status = 2 where place_id = search_place_id;
- update placex set indexed_status = 0 where place_id = search_place_id;
- return true;
-END;
-$$
-LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION get_searchrank_label(rank INTEGER) RETURNS TEXT
- AS $$
-DECLARE
-BEGIN
- IF rank < 2 THEN
- RETURN 'Continent';
- ELSEIF rank < 4 THEN
- RETURN 'Sea';
- ELSEIF rank < 8 THEN
- RETURN 'Country';
- ELSEIF rank < 12 THEN
- RETURN 'State';
- ELSEIF rank < 16 THEN
- RETURN 'County';
- ELSEIF rank = 16 THEN
- RETURN 'City';
- ELSEIF rank = 17 THEN
- RETURN 'Town / Island';
- ELSEIF rank = 18 THEN
- RETURN 'Village / Hamlet';
- ELSEIF rank = 20 THEN
- RETURN 'Suburb';
- ELSEIF rank = 21 THEN
- RETURN 'Postcode Area';
- ELSEIF rank = 22 THEN
- RETURN 'Croft / Farm / Locality / Islet';
- ELSEIF rank = 23 THEN
- RETURN 'Postcode Area';
- ELSEIF rank = 25 THEN
- RETURN 'Postcode Point';
- ELSEIF rank = 26 THEN
- RETURN 'Street / Major Landmark';
- ELSEIF rank = 27 THEN
- RETURN 'Minory Street / Path';
- ELSEIF rank = 28 THEN
- RETURN 'House / Building';
- ELSE
- RETURN 'Other: '||rank;
- END IF;
-
-END;
-$$
-LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION get_addressrank_label(rank INTEGER) RETURNS TEXT
- AS $$
-DECLARE
-BEGIN
- IF rank = 0 THEN
- RETURN 'None';
- ELSEIF rank < 2 THEN
- RETURN 'Continent';
- ELSEIF rank < 4 THEN
- RETURN 'Sea';
- ELSEIF rank = 5 THEN
- RETURN 'Postcode';
- ELSEIF rank < 8 THEN
- RETURN 'Country';
- ELSEIF rank < 12 THEN
- RETURN 'State';
- ELSEIF rank < 16 THEN
- RETURN 'County';
- ELSEIF rank = 16 THEN
- RETURN 'City';
- ELSEIF rank = 17 THEN
- RETURN 'Town / Village / Hamlet';
- ELSEIF rank = 20 THEN
- RETURN 'Suburb';
- ELSEIF rank = 21 THEN
- RETURN 'Postcode Area';
- ELSEIF rank = 22 THEN
- RETURN 'Croft / Farm / Locality / Islet';
- ELSEIF rank = 23 THEN
- RETURN 'Postcode Area';
- ELSEIF rank = 25 THEN
- RETURN 'Postcode Point';
- ELSEIF rank = 26 THEN
- RETURN 'Street / Major Landmark';
- ELSEIF rank = 27 THEN
- RETURN 'Minory Street / Path';
- ELSEIF rank = 28 THEN
- RETURN 'House / Building';
- ELSE
- RETURN 'Other: '||rank;
- END IF;
-
-END;
-$$
-LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION get_word_suggestion(srcword TEXT) RETURNS TEXT
- AS $$
-DECLARE
- trigramtoken TEXT;
- result TEXT;
-BEGIN
-
- trigramtoken := regexp_replace(make_standard_name(srcword),E'([^0-9])\\1+',E'\\1','g');
- SELECT word FROM word WHERE word_trigram like ' %' and word_trigram % trigramtoken ORDER BY similarity(word_trigram, trigramtoken) DESC, word limit 1 into result;
-
- return result;
-END;
-$$
-LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION get_word_suggestions(srcword TEXT) RETURNS TEXT[]
- AS $$
-DECLARE
- trigramtoken TEXT;
- result TEXT[];
- r RECORD;
-BEGIN
-
- trigramtoken := regexp_replace(make_standard_name(srcword),E'([^0-9])\\1+',E'\\1','g');
-
- FOR r IN SELECT word,similarity(word_trigram, trigramtoken) as score FROM word
- WHERE word_trigram like ' %' and word_trigram % trigramtoken ORDER BY similarity(word_trigram, trigramtoken) DESC, word limit 4
- LOOP
- result[coalesce(array_upper(result,1)+1,1)] := r.word;
- END LOOP;
-
- return result;
-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;