A Tropo scripting application that finds library locations in Philadelphia.
| <?php | |
| /** | |
| * Find My Library - an IM and SMS application that finds library locations in Philadelphia. | |
| * | |
| * @copyright 2011 Mark J. Headd (http://www.voiceingov.org) | |
| * @author Mark Headd | |
| * | |
| * Deploy this application on http://www.tropo.com | |
| */ | |
| // Constants used to geocode an address. | |
| define("MAPS_LOOKUP_BASE_URL", "http://maps.googleapis.com/maps/api/geocode/json"); | |
| define("MAPS_API_KEY", "your-api-key"); | |
| // CouchDB Details. | |
| define("GEO_COUCH_URL", "http://libraries.phillyapi.com:5984/v1/locations?bbox="); | |
| // Exception classes. | |
| class GeoCodeException extends Exception {} | |
| class GeoCouchException extends Exception {} | |
| // Get the lat / lon for an address. | |
| function geoCodeAddress($address) { | |
| // Format address and URL. | |
| $address = str_replace(" ", "+", $address); | |
| $url = MAPS_LOOKUP_BASE_URL."?address=".$address."&sensor=false&key=".MAPS_API_KEY; | |
| return makeCurlCall($url, GeoCodeException, "Could not Geocode that address."); | |
| } | |
| // Mak call to GeoCouch and get locations. | |
| function getLocations($bb_array) { | |
| // Format URL to GeoCouch instance. | |
| $url = GEO_COUCH_URL; | |
| $url .= implode(",", $bb_array); | |
| return makeCurlCall($url, GeoCouchException, "Could not connect to GeoCouch instance."); | |
| } | |
| // Heler method to make an HTTP request. | |
| function makeCurlCall($url, $exceptionType, $exceptionMessage) { | |
| // Set up cURL call. | |
| $ch = curl_init($url); | |
| curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
| // Execute. | |
| $output = curl_exec($ch); | |
| $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
| // Return results. | |
| if($code != '200') { | |
| throw new $exceptionType($exceptionMessage); | |
| } | |
| else { | |
| return $output; | |
| } | |
| } | |
| // Make a bounding box from a lat / lon pair | |
| function makeBoundingBox($lon, $lat, $factor=.015) { | |
| $bb_array = Array($lon-$factor, $lat-$factor, $lon+$factor, $lat+$factor); | |
| return $bb_array; | |
| } | |
| // Calculate the distance between 2 points. | |
| function calculateDistance($lat1, $lon1, $lat2, $lon2) { | |
| return 3958*3.1415926*sqrt(($lat2-$lat1)*($lat2-$lat1) + cos($lat2/57.29578)*cos($lat1/57.29578)*($lon2-$lon1)*($lon2-$lon1))/180; | |
| } | |
| try { | |
| // Get the address submited by the user. | |
| $result = ask("", array("choices" => "[ANY]")); | |
| // Geocode address and get lat / lon. | |
| $geocoded_address = json_decode(geoCodeAddress($result->value)); | |
| $lat = $geocoded_address->results[0]->geometry->location->lat; | |
| $lon = $geocoded_address->results[0]->geometry->location->lng; | |
| // Create a bound box from the lat / lon pair. | |
| $bb_array = makeBoundingBox($lon, $lat); | |
| // Get the locations from geocouch. | |
| $locations = json_decode(getLocations($bb_array)); | |
| // If locations are found,iterate over JSON and render to user. | |
| if($locations->rows) { | |
| foreach($locations->rows as $location) { | |
| $property = $location->value->properties; | |
| $geometry = $location->value->geometry->coordinates; | |
| $library = 'Library Name: '.strtoupper($property->BRANCH_NAM); | |
| $library .= '. Library Address: '.$property->HOUSENUM.' '.strtoupper($property->ADDRESS); | |
| $distance = round(calculateDistance($lat, $lon, $geometry[1], $geometry[0]), 2); | |
| $library .= ' Distance: '.$distance.' miles.'; | |
| say($library); | |
| } | |
| } | |
| // Otherwise, tell user no locations found. | |
| else { | |
| say("No locations found."); | |
| } | |
| } | |
| // If address can not be Geocoded. | |
| catch (GeoCodeException $ex) { | |
| say("An error occured. ". $ex->getMessage()); | |
| hangup(); | |
| } | |
| // If call can not be made to GeoCoud | |
| catch (GeoCouchException $ex) { | |
| say("An error occured. ". $ex->getMessage()); | |
| hangup(); | |
| } | |
| // Last ditch exception handler. | |
| catch (Exception $ex) { | |
| say("Sorry. Something really bad happened."); | |
| _log("*** ". $ex->getMessage() . " ***"); | |
| hangup(); | |
| } | |
| ?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment