File: geocode.sql

package info (click to toggle)
postgis 1.3.3-3
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 10,468 kB
  • ctags: 4,310
  • sloc: sql: 73,321; ansic: 35,513; xml: 6,160; java: 6,061; sh: 3,428; perl: 1,447; cpp: 987; makefile: 727; yacc: 276; python: 192
file content (111 lines) | stat: -rw-r--r-- 2,163 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
CREATE OR REPLACE FUNCTION geocode(
    input VARCHAR,
    OUT ADDY NORM_ADDY,
    OUT GEOMOUT GEOMETRY,
    OUT RATING INTEGER
) RETURNS SETOF RECORD
AS $_$
DECLARE
  result REFCURSOR;
  rec RECORD;
BEGIN

  IF input IS NULL THEN
    RETURN;
  END IF;

  -- Pass the input string into the address normalizer
  ADDY := normalize_address(input);
  IF NOT ADDY.parsed THEN
    RETURN;
  END IF;

  OPEN result FOR SELECT * FROM geocode(ADDY);

  LOOP
    FETCH result INTO rec;

    IF NOT FOUND THEN
        RETURN;
    END IF;

    ADDY := rec.addy;
    GEOMOUT := rec.geomout;
    RATING := rec.rating;

    RETURN NEXT;
  END LOOP;

  RETURN;

END;
$_$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION geocode(
    IN_ADDY NORM_ADDY,
    OUT ADDY NORM_ADDY,
    OUT GEOMOUT GEOMETRY,
    OUT RATING INTEGER
) RETURNS SETOF RECORD
AS $_$
DECLARE
  result REFCURSOR;
  rec RECORD;
BEGIN

  IF NOT IN_ADDY.parsed THEN
    RETURN;
  END IF;

  -- Go for the full monty if we've got enough info
  IF IN_ADDY.address IS NOT NULL AND
      IN_ADDY.streetName IS NOT NULL AND
      (IN_ADDY.zip IS NOT NULL OR IN_ADDY.stateAbbrev IS NOT NULL) THEN

    result := geocode_address(IN_ADDY);
  END IF;

  -- Next best is zipcode, if we've got it
  IF result IS NULL AND IN_ADDY.zip IS NOT NULL THEN
    result := geocode_zip(IN_ADDY);
  END IF;

  -- No zip code, try state/location, need both or we'll get too much stuffs.
  IF result IS NULL AND IN_ADDY.stateAbbrev IS NOT NULL AND IN_ADDY.location IS NOT NULL THEN
    result := geocode_location(IN_ADDY);
  END IF;

  IF result IS NULL THEN
    RETURN;
  END IF;

  ADDY.address := IN_ADDY.address;
  ADDY.internal := IN_ADDY.internal;

  LOOP
    FETCH result INTO rec;

    IF NOT FOUND THEN
        RETURN;
    END IF;

    ADDY.preDirAbbrev := rec.fedirp;
    ADDY.streetName := rec.fename;
    ADDY.streetTypeAbbrev := rec.fetype;
    ADDY.postDirAbbrev := rec.fedirs;
    ADDY.location := rec.place;
    ADDY.stateAbbrev := rec.state;
    ADDY.zip := rec.zip;
    ADDY.parsed := TRUE;

    GEOMOUT := rec.address_geom;
    RATING := rec.rating;

    RETURN NEXT;
  END LOOP;

  RETURN;

END;
$_$ LANGUAGE plpgsql;