]> git.sur5r.net Git - contagged/blob - inc/Geocoder.php
support non-http URLs in labeledURI fields (e.g. xmpp or mailto)
[contagged] / inc / Geocoder.php
1 <?php
2 class Geocoder
3 {
4     public function __construct()
5     {
6         $file = __DIR__ . '/../cache/geocode.sq3';
7         $new = !file_exists($file);
8         $this->db = new PDO('sqlite:' . $file);
9         if ($new) {
10             $this->db->exec(<<<SQL
11                 CREATE TABLE coords (
12                     address TEXT UNIQUE,
13                     lat REAL,
14                     lon REAL,
15                     expiration TEXT
16                 )
17 SQL
18             );
19         }
20         $this->fetchStmt = $this->db->prepare(
21             'SELECT address, lat, lon FROM coords WHERE address = :address'
22         );
23         $this->insertStmt = $this->db->prepare(
24             'INSERT INTO coords'
25             . '(address, lat, lon, expiration)'
26             . ' VALUES '
27             . '(:address, :lat, :lon, :expiration)'
28         );
29     }
30
31     public function getPrivateCoords($entry)
32     {
33         return $this->getCoords($entry['homestreet']);
34     }
35
36     public function getBusinessCoords($entry)
37     {
38         if (!isset($entry['street']) || !isset($entry['location'])) {
39             return null;
40         }
41         return $this->getCoords(
42             $entry['street'] . ', ' . $entry['zip'] . ' ' . $entry['location']
43             . ', ' . $entry['state'] . ', ' . $entry['country']
44         );
45     }
46
47     public function getCoords($strAddress)
48     {
49         $strAddress = str_replace(array("\r", "\n", ' OT '), ' ', $strAddress);
50         $this->fetchStmt->execute(array(':address' => $strAddress));
51         $coords = $this->fetchStmt->fetchObject();
52         if ($coords !== false) {
53             if ($coords->lat === null) {
54                 return null;
55             }
56             return $coords;
57         }
58
59         $coords = $this->geoCode($strAddress);
60         if ($coords === null) {
61             $this->insertStmt->execute(
62                 array(
63                     'address' => $strAddress,
64                     'lat' => null,
65                     'lon' => null,
66                     'expiration' => time() + 86400
67                 )
68             );
69             return null;
70         }
71
72         $this->insertStmt->execute(
73             array(
74                 'address' => $strAddress,
75                 'lat' => $coords->lat,
76                 'lon' => $coords->lon,
77                 'expiration' => time() + 86400 * 7
78             )
79         );
80         return $coords;
81     }
82
83     public function geoCode($strAddress)
84     {
85         //Docs: http://open.mapquestapi.com/nominatim/
86         $url = 'http://open.mapquestapi.com/nominatim/v1/search'
87             . '?format=json'
88             . '&limit=1'
89             . '&q=' . urlencode($strAddress);
90
91         $context = stream_context_create(
92             array(
93                 'http' => array(
94                     'user_agent' => 'ConTagged LDAP address book'
95                 )
96             )
97         );
98         $json = file_get_contents($url, false, $context);
99         if ($json === false) {
100             return null;
101         }
102         $data = json_decode($json);
103         if ($data === null || $data === false) {
104             return null;
105         }
106
107         if (count($data) == 0) {
108             return null;
109         }
110
111         return (object) array(
112             'lat' => $data[0]->lat,
113             'lon' => $data[0]->lon,
114             'address' => $strAddress
115         );
116     }
117
118     public function cleanup()
119     {
120         $this->db->query(
121             'DELETE FROM coords WHERE expiration < ' . time()
122         );
123     }
124 }
125 ?>