mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-24 09:02:37 +00:00
Change to transform the point if not in nad83 long lat already
git-svn-id: http://svn.osgeo.org/postgis/trunk@6820 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
d4237550af
commit
fd7ccedce4
|
@ -6,7 +6,7 @@
|
|||
-- This function given a point try to determine the approximate street address (norm_addy form)
|
||||
-- and array of cross streets, as well as interpolated points along the streets
|
||||
-- Use case example an address at the intersection of 3 streets: SELECT pprint_addy(r.addy[1]) As st1, pprint_addy(r.addy[2]) As st2, pprint_addy(r.addy[3]) As st3, array_to_string(r.street, ',') FROM reverse_geocode(ST_GeomFromText('POINT(-71.057811 42.358274)',4269)) As r;
|
||||
--set search_path=tiger,public;
|
||||
set search_path=tiger,public;
|
||||
CREATE OR REPLACE FUNCTION reverse_geocode(
|
||||
IN pt geometry,
|
||||
IN include_strnum_range boolean,
|
||||
|
@ -22,13 +22,20 @@ DECLARE
|
|||
var_strnum varchar;
|
||||
var_primary_line geometry := NULL;
|
||||
var_primary_dist numeric(10,2) ;
|
||||
var_pt geometry;
|
||||
BEGIN
|
||||
IF pt IS NULL THEN
|
||||
RETURN;
|
||||
ELSE
|
||||
IF ST_SRID(pt) = 4269 THEN
|
||||
var_pt := pt;
|
||||
ELSE
|
||||
var_pt := ST_Transform(pt, 4269);
|
||||
END IF;
|
||||
END IF;
|
||||
-- Determine state tables to check
|
||||
-- this is needed to take advantage of constraint exclusion
|
||||
var_states := ARRAY(SELECT statefp FROM state WHERE ST_Intersects(the_geom, pt) );
|
||||
var_states := ARRAY(SELECT statefp FROM state WHERE ST_Intersects(the_geom, var_pt) );
|
||||
IF array_upper(var_states, 1) IS NULL THEN
|
||||
-- We don't have any data for this state
|
||||
RETURN;
|
||||
|
@ -42,15 +49,15 @@ BEGIN
|
|||
(SELECT z.place FROM zip_state_loc AS z WHERE z.zip = foo.zip and z.statefp = foo.statefp LIMIT 1) As place, foo.intpt,
|
||||
side, to_number(fromhn, '999999') As fromhn, to_number(tohn, '999999') As tohn, ST_GeometryN(ST_Multi(line),1) As line, foo.dist
|
||||
FROM
|
||||
(SELECT e.the_geom As line, e.fullname, a.zip, s.stusps, ST_ClosestPoint(e.the_geom, pt) As intpt, e.statefp, a.side, a.fromhn, a.tohn, ST_Distance_Sphere(e.the_geom, pt) As dist
|
||||
(SELECT e.the_geom As line, e.fullname, a.zip, s.stusps, ST_ClosestPoint(e.the_geom, var_pt) As intpt, e.statefp, a.side, a.fromhn, a.tohn, ST_Distance_Sphere(e.the_geom, var_pt) As dist
|
||||
FROM edges AS e INNER JOIN state As s ON (e.statefp = s.statefp AND s.statefp = ANY(var_states) )
|
||||
INNER JOIN faces As fl ON (e.tfidl = fl.tfid AND e.statefp = fl.statefp)
|
||||
INNER JOIN faces As fr ON (e.tfidr = fr.tfid AND e.statefp = fr.statefp)
|
||||
INNER JOIN addr As a ON ( e.tlid = a.tlid AND e.statefp = a.statefp AND
|
||||
( ( ST_Contains(fl.the_geom, pt) AND a.side = 'L') OR ( ST_Contains(fr.the_geom, pt) AND a.side = 'R' ) ) )
|
||||
( ( ST_Contains(fl.the_geom, var_pt) AND a.side = 'L') OR ( ST_Contains(fr.the_geom, var_pt) AND a.side = 'R' ) ) )
|
||||
-- INNER JOIN zip_state_loc As z ON (a.statefp = z.statefp AND a.zip = z.zip) /** really slow with this join **/
|
||||
WHERE e.statefp = ANY(var_states) AND a.statefp = ANY(var_states) AND ST_DWithin(e.the_geom, pt, 0.005)
|
||||
ORDER BY ST_Distance_Sphere(e.the_geom, pt) LIMIT 4) As foo
|
||||
WHERE e.statefp = ANY(var_states) AND a.statefp = ANY(var_states) AND ST_DWithin(e.the_geom, var_pt, 0.005)
|
||||
ORDER BY ST_Distance_Sphere(e.the_geom, var_pt) LIMIT 4) As foo
|
||||
WHERE dist < 150 --less than 150 m
|
||||
ORDER BY foo.fullname, foo.dist) As f ORDER BY f.dist LOOP
|
||||
IF var_primary_line IS NULL THEN --this is the first time in the loop and our primary guess
|
||||
|
@ -65,7 +72,7 @@ BEGIN
|
|||
--interploate the number -- note that if fromhn > tohn we will be subtracting which is what we want
|
||||
-- We only consider differential distances are reeally close from our primary pt
|
||||
IF var_redge.dist < var_primary_dist*1.1 THEN
|
||||
var_strnum := (var_redge.fromhn + ST_Line_Locate_Point(var_redge.line, pt)*(var_redge.tohn - var_redge.fromhn))::numeric(10)::varchar;
|
||||
var_strnum := (var_redge.fromhn + ST_Line_Locate_Point(var_redge.line, var_pt)*(var_redge.tohn - var_redge.fromhn))::numeric(10)::varchar;
|
||||
var_addy := normalize_address( COALESCE(var_strnum::varchar || ' ', '') || var_redge.fullname || ', ' || var_redge.place || ', ' || var_redge.stusps || ' ' || var_redge.zip);
|
||||
addy := array_append(addy, var_addy);
|
||||
END IF;
|
||||
|
|
Loading…
Reference in a new issue