File: geocode_address.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 (94 lines) | stat: -rw-r--r-- 3,364 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
-- geocode(cursor, address, directionPrefix, streetName,
-- streetTypeAbbreviation, directionSuffix, location, stateAbbreviation,
-- zipCode)
CREATE OR REPLACE FUNCTION geocode_address(
    parsed NORM_ADDY
) RETURNS REFCURSOR
AS $_$
DECLARE
  result REFCURSOR;
  tempString VARCHAR;
  ziplookup RECORD;
BEGIN
  -- The first step is to determine what weve been given, and if its enough.
  IF parsed.address IS NULL THEN
    -- The address is manditory.
    -- Without it, wed be wandering into strangers homes all the time.
    RETURN NULL;
  END IF;

  IF parsed.streetName IS NULL THEN
    -- A street name must be given.  Think about it.
    RETURN NULL;
  END IF;

  IF parsed.zip IS NOT NULL THEN
    -- If the zip code is given, it is the most useful way to narrow the
    -- search.  We will try it first, and if no results match, we will move
    -- on to a location search.  There is no fuzzy searching on zip codes.
    result := geocode_address_zip(result, parsed);
    IF result IS NOT NULL THEN
      RETURN result;
    END IF;
    -- If we weren't able to find one using the zip code, but the zip code
    -- exists, and location is null, then fill in the location and/or state
    -- based on the zip code so that the location lookup has a chance.
    IF parsed.stateAbbrev IS NULL OR parsed.location IS NULL THEN
        SELECT INTO ziplookup * FROM zip_lookup_base JOIN state_lookup ON (state = name) WHERE zip = parsed.zip;
        IF FOUND THEN
            parsed.stateAbbrev := coalesce(parsed.stateAbbrev,ziplookup.abbrev);
            parsed.location := coalesce(parsed.location,ziplookup.city);
        END IF;
    END IF;
  END IF;

  -- After now, the location becomes manditory.
  IF parsed.location IS NOT NULL THEN
    -- location may be useful, it may not. The first step is to determine if
    -- there are any potenial matches in the place and countysub fields.
    -- This is done against the lookup tables, and will save us time on much
    -- larger queries if they dont match.
    tempString := location_extract_place_exact(parsed.location, parsed.stateAbbrev);
    IF tempString IS NOT NULL THEN
      result := geocode_address_place_exact(result, parsed);
      IF result IS NOT NULL THEN
        RETURN result;
      END IF;
    END IF;

    tempString := location_extract_countysub_exact(parsed.location, parsed.stateAbbrev);
    IF tempString IS NOT NULL THEN
      result := geocode_address_countysub_exact(result, parsed);
      IF result IS NOT NULL THEN
        RETURN result;
      END IF;
    END IF;

    tempString := location_extract_place_fuzzy(parsed.location, parsed.stateAbbrev);
    IF tempString IS NOT NULL THEN
      result := geocode_address_place_fuzzy(result, parsed);
      IF result IS NOT NULL THEN
        RETURN result;
      END IF;
    END IF;

    tempString := location_extract_countysub_fuzzy(parsed.location, parsed.stateAbbrev);
    IF tempString IS NOT NULL THEN
      result := geocode_address_countysub_fuzzy(result, parsed);
      IF result IS NOT NULL THEN
        RETURN result;
      END IF;
    END IF;
  END IF;

  -- Try with just the state if we can't find the location
  IF parsed.stateAbbrev IS NOT NULL THEN
    result := geocode_address_state(result, parsed);
    IF result IS NOT NULL THEN
      RETURN result;
    END IF;
  END IF;

  RETURN NULL;
END;
$_$ LANGUAGE plpgsql;