Created
February 25, 2011 20:20
-
-
Save mheadd/844421 to your computer and use it in GitHub Desktop.
A Tropo scripting application that finds library locations in Philadelphia.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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