diff --git a/BaseGeocode.php b/BaseGeocode.php new file mode 100755 index 0000000..c667907 --- /dev/null +++ b/BaseGeocode.php @@ -0,0 +1,227 @@ +setEarthRadius( 3963.1676 ); + $this->setKey( $key ); + } + + /** + * Modifier for the earth mean radius + * + * @param float $rad The new radius of the earth to use. + * @access public + */ + public function setEarthRadius( $rad ) { + $this->earthRadius = $rad; + } + + /** + * Modifier for the API key + * + * @param string $key The geocoding service API key to use. + * @access public + */ + public function setKey( $key ) { + $this->apiKey = $key; + } + + /** + * Load XML from an address + * + * @param string $address The address representing the XML source + * @access protected + */ + protected function loadXML( $address ) { + $retVal = array(); + $contents = file_get_contents( $address ); + + if( !empty( $http_response_header ) ) { + $code = $http_response_header[0]; + $matches = array(); + preg_match('/^HTTP\/\d+\.\d+\s+(\d+)\s+[\w\s]+$/',$code, $matches); + + $retVal['response'] = $matches[1]; + $retVal['contents'] = $contents; + } + + return $retVal; + } + + /** + * Abstract function which will accept a string address + * and return an array of geocoded information for the given address. + * + * Return types for this function are mixed based on HTTP Response Codes: + * Server not found: array() + * + * 404: array( 'Response' => array( + * 'Status' => 404, + * 'Request' => the subclass specific request + * ) + * ); + * + * 200: The returned geocode information will be presented in the following format + * While the example below only contains a single result, multiple results for a single + * geocode request are possible and should be supported by subclasses + * + * array( 'Response' => array( + * 'Status' => ... + * 'Request' => ... + * ), + * 'Placemarks' => array( + * array( + * 'Accuracy' => ..., + * 'Country' => ..., + * 'AdministrativeArea' => ..., + * 'SubAdministrativeArea => ..., + * 'Locality' => ..., + * 'Thoroughfare' => ..., + * 'PostalCode' => ..., + * 'Latitude' => ..., + * 'Longitude' => ... + * ), + * array( + * 'Accuracy' => ..., + * 'Country' => ..., + * . + * . + * . + * ) + * ) + * ) + * + * @param string $address A string representing the address the user wants decoded. + * @return array This function returns an array of geocoded location information for the given address. + * @access public + */ + abstract public function geocode( $address ); + + /** + * Find the distance between the two latitude and longitude coordinates + * Where the latitude and longitude coordinates are in decimal degrees format. + * + * This function uses the haversine formula as published in the article + * "Virtues of the Haversine", Sky and Telescope, vol. 68 no. 2, 1984, p. 159 + * + * References: + * http://en.wikipedia.org/w/index.php?title=Haversine_formula&oldid=176737064 + * http://www.movable-type.co.uk/scripts/gis-faq-5.1.html + * + * @param float $lat1 The first coordinate's latitude + * @param float $ong1 The first coordinate's longitude + * @param float $lat2 The second coordinate's latitude + * @param float $long2 The second coordinate's longitude + * @return float The distance between the two points in the same unit as the earth radius as set by setEarthRadius() (default miles). + * @access public + */ + public function haversinDistance( $lat1, $long1, $lat2, $long2 ) + { + $lat1 = deg2rad( $lat1 ); + $lat2 = deg2rad( $lat2 ); + $long1 = deg2rad( $long1); + $long2 = deg2rad( $long2); + + $dlong = $long2 - $long1; + $dlat = $lat2 - $lat1; + + $sinlat = sin( $dlat/2 ); + $sinlong = sin( $dlong/2 ); + + $a = ($sinlat * $sinlat) + cos( $lat1 ) * cos( $lat2 ) * ($sinlong * $sinlong); + $c = 2 * asin( min( 1, sqrt( $a ) )); + + return $this->earthRadius * $c; + } + + /** + * Find the distance between two latitude and longitude points using the + * spherical law of cosines. + * + * @param float $lat1 The first coordinate's latitude + * @param float $ong1 The first coordinate's longitude + * @param float $lat2 The second coordinate's latitude + * @param float $long2 The second coordinate's longitude + * @return float The distance between the two points in the same unit as the earth radius as set by setEarthRadius() (default miles). + * @access public + */ + public function sphericalLawOfCosinesDistance( $lat1, $long1, $lat2, $long2 ) + { + $lat1 = deg2rad( $lat1 ); + $lat2 = deg2rad( $lat2 ); + $long1 = deg2rad( $long1); + $long2 = deg2rad( $long2); + + return $this->earthRadius * acos( + sin( $lat1 ) * sin( $lat2 ) + + cos( $lat1 ) * cos( $lat2 ) * cos( $long2 - $long1 ) + ); + } + + /** + * Find the distance between two latitude and longitude coordinates + * Where the latitude and the longitude coordinates are in decimal degrees format. + * + * @param float $lat1 The first coordinate's latitude + * @param float $ong1 The first coordinate's longitude + * @param float $lat2 The second coordinate's latitude + * @param float $long2 The second coordinate's longitude + * @return float The distance between the two points in the same unit as the earth radius as set by setEarthRadius() (default miles). + * @access public + */ + public function distanceBetween( $lat1, $long1, $lat2, $long2 ) + { + return $this->haversinDistance( $lat1, $long1, $lat2, $long2 ); + } +} + +?> diff --git a/GoogleGeocode.php b/GoogleGeocode.php new file mode 100755 index 0000000..8d5084e --- /dev/null +++ b/GoogleGeocode.php @@ -0,0 +1,216 @@ +apiKey; + + $nsKml = 'http://earth.google.com/kml/2.0'; + $nsUrn = 'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'; + + $file = $this->loadXML( $url ); + + if( empty( $file ) ) { + return $retVal; + } + + $retVal['Response'] = array( + 'Status' => (int)$file['response'], + 'Request' => 'geo' + ); + + if( $file['response'] == 200 ) { + $xml = new SimpleXMLElement( $file['contents'] ); + + $xml->registerXPathNamespace( 'kml', $nsKml ); + $xml->registerXPathNamespace( 'urn', $nsUrn ); + + //Now that we have the google request, and we succeeded in getting a response + //from the server, lets replace oure response portion with the google response + $retVal['Response']['Status'] = (int)$xml->Response->Status->code; + $retVal['Response']['Request'] = (string)$xml->Response->Status->request; + + $retVal['Placemarks'] = array(); + if( $xml && $retVal['Response']['Status'] == GoogleGeocode::SUCCESS ) + { + $placemarks = $xml->xpath('//kml:Placemark'); + $countries = $xml->xpath('//urn:CountryNameCode'); + $adminAreas = $xml->xpath('//urn:AdministrativeAreaName'); + $subAdminAreas = $xml->xpath('//urn:SubAdministrativeAreaName'); + $localities = $xml->xpath('//urn:LocalityName'); + $thoroughfares = $xml->xpath('//urn:ThoroughfareName'); + $postalCodes = $xml->xpath('//urn:PostalCodeNumber'); + + for( $i = 0; $i < count( $placemarks ); $i++ ) + { + list($longitude, $latitude) = explode( ',' , $placemarks[$i]->Point->coordinates ); + $attributes = $placemarks[$i]->AddressDetails->attributes(); + + $retVal['Placemarks'][$i] = array(); + $retVal['Placemarks'][$i]['Accuracy'] = (int)$attributes['Accuracy']; + $retVal['Placemarks'][$i]['Country'] = (string)$countries[$i]; + + if( count( $adminAreas ) > $i ) { + $retVal['Placemarks'][$i]['AdministrativeArea'] = (string)$adminAreas[$i]; + } + + if( count( $subAdminAreas ) > $i ) { + $retVal['Placemarks'][$i]['SubAdministrativeArea'] = (string)$subAdminAreas[$i]; + } + + if( count( $localities ) > $i ) { + $retVal['Placemarks'][$i]['Locality'] = (string)$localities[$i]; + } + + if( count( $thoroughfares ) > $i ) { + $retVal['Placemarks'][$i]['Thoroughfare'] = (string)$thoroughfares[$i]; + } + + if( count( $postalCodes ) > $i ) { + $retVal['Placemarks'][$i]['PostalCode'] = (int)$postalCodes[$i]; + } + + $retVal['Placemarks'][$i]['Latitude']= (double)$latitude; + $retVal['Placemarks'][$i]['Longitude'] = (double)$longitude; + } + } + } + return $retVal; + } +} + +?> diff --git a/YahooGeocode.php b/YahooGeocode.php new file mode 100755 index 0000000..6f42015 --- /dev/null +++ b/YahooGeocode.php @@ -0,0 +1,168 @@ +apiKey; + + $file = $this->loadXML( $request ); + + if( empty( $file ) ) { + return $retVal; + } + + $retVal['Response'] = array( + 'Status' => $file['response'], + 'Request' => 'geocode' + ); + + if( $retVal['Response']['Status'] == YahooGeocode::SUCCESS ) { + $xml = new SimpleXMLElement( $file['contents'] ); + + $xml->registerXPathNamespace('urn','urn:yahoo:maps'); + + $retVal['Placemarks'] = array(); + if( $xml ) { + $results = $xml->xpath('//urn:Result'); + $countries = $xml->xpath('//urn:Country'); + $adminAreas = $xml->xpath('//urn:State'); + //Yahoo Geocoding has no Sub-Administrative Area (County) support. + $localities = $xml->xpath('//urn:City'); + $thoroughfares = $xml->xpath('//urn:Address'); + $postalCodes = $xml->xpath('//urn:Zip'); + $latitudes = $xml->xpath('//urn:Latitude'); + $longitudes = $xml->xpath('//urn:Longitude'); + + if( $results ) { + for( $i = 0; $i < count( $results ); $i++ ) { + $attributes = $results[$i]->attributes(); + + $retVal['Placemarks'][$i]['Accuracy'] = (string)$attributes['precision']; + $retVal['Placemarks'][$i]['Country'] = (string)$countries[$i]; + + if( count($adminAreas) > $i && !empty($adminAreas[$i]) ) { + $retVal['Placemarks'][$i]['AdministrativeArea'] = (string) $adminAreas[$i]; + } + + if( count($localities) > $i && !empty($localities[$i]) ) { + $retVal['Placemarks'][$i]['Locality'] = (string) $localities[$i]; + } + + if( count($thoroughfares) > $i && !empty($thoroughfares[$i]) ) { + $retVal['Placemarks'][$i]['Thoroughfare'] = (string) $thoroughfares[$i]; + } + + if( count($postalCodes) > $i && !empty($postalCodes[$i]) ) { + $postalCode = explode( '-', $postalCodes[$i] ); + $retVal['Placemarks'][$i]['PostalCode'] = (int) $postalCode[0]; + } + + $retVal['Placemarks'][$i]['Latitude'] = (double)$latitudes[$i]; + $retVal['Placemarks'][$i]['Longitude'] = (double)$longitudes[$i]; + + } + } + } + } + return $retVal; + } +} + +?> diff --git a/event.php b/event.php index c83e3e6..4110998 100755 --- a/event.php +++ b/event.php @@ -44,7 +44,14 @@ ?> '.$event["localisation"].''; - echo '
'; + $url = 'https://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($event["localisation"]).'&key=AIzaSyB8Cd8NP8VOa0wIlvvYGEMZMzCKwROiHxU'; + $obj = json_decode(file_get_contents($url), true); + $lat = $obj["results"][0]["geometry"]["location"]["lat"]; + $lng = $obj["results"][0]["geometry"]["location"]["lng"]; + $urlFrame = 'http://www.openstreetmap.org/export/embed.html?bbox='.$lng.','.$lat.','.$lng.','.$lat.'&layer=mapnik&floor'; + echo ''; if(isset($event["urlImage"]) || isset($event["description"])) echo '