location.au.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <?php
  2. // Australia
  3. /**
  4. * Returns a lat/lon pair of the approximate center of the given postal code in the given country
  5. *
  6. * @param $location
  7. * An associative array $location where
  8. * 'street' => the street portion of the location
  9. * 'supplemental' => additional street portion of the location
  10. * 'province' => the province, state, or territory
  11. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  12. * 'postal_code' => the international postal code for this location (REQUIRED)
  13. *
  14. * @return
  15. * An associative array where
  16. * 'lat' => approximate latitude of the center of the postal code's area
  17. * 'lon' => approximate longitude of the center of the postal code's area
  18. *
  19. */
  20. function location_latlon_rough_au($location = array()) {
  21. if (!isset($location['postal_code'])) {
  22. return NULL;
  23. }
  24. $row = db_query("SELECT latitude, longitude FROM {zipcodes} WHERE country = :country AND zip = :zip", array(':country' => $location['country'], ':zip' => substr(str_pad($location['postal_code'], 4, '0', STR_PAD_LEFT), 0, 4)))->fetchObject();
  25. if ($row) {
  26. return array('lat' => $row->latitude, 'lon' => $row->longitude);
  27. }
  28. else {
  29. return NULL;
  30. }
  31. }
  32. /**
  33. * Returns a lat/lon pair of the approximate center of the given postal code in the given country
  34. *
  35. * @param $location
  36. * An associative array $location where only postal code and country are necessary, but can have the keys:
  37. * 'street' => the street portion of the location
  38. * 'supplemental' => additional street portion of the location
  39. * 'province' => the province, state, or territory
  40. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  41. * 'postal_code' => the international postal code for this location (REQUIRED)
  42. *
  43. * @return
  44. * An associative array where
  45. * 'lat' => approximate latitude of the center of the postal code's area
  46. * 'lon' => approximate longitude of the center of the postal code's area
  47. *
  48. */
  49. function _location_latlon_postalcode_au($location = array()) {
  50. $dash_index = strpos($location['postal_code'], '-');
  51. // First we strip slash off if we're dealing with a 8-digit AU zipcode
  52. if (!($dash_index === FALSE)) {
  53. $location['postal_code'] = substr($location['postal_code'], 0, $dash_index);
  54. }
  55. // Now we pad the thing and query.
  56. $row = db_query("SELECT * FROM {zipcodes} where country = :country AND zip = :zip", array(':country' => $location['country'], ':zip' => str_pad($location['postal_code'], 4, "0", STR_PAD_LEFT)))->fetchObject();
  57. if ($row) {
  58. return array('lat' => $row->latitude, 'lon' => $row->longitude, 'city' => $row->city, 'province' => $row->state, 'country' => $row->country);
  59. }
  60. else {
  61. return NULL;
  62. }
  63. }
  64. /**
  65. * Parameters:
  66. * An associative array $location where
  67. * 'street' => the street portion of the location
  68. * 'supplemental' => additional street portion of the location
  69. * 'province' => the province, state, or territory
  70. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  71. * 'postal_code' => the international postal code for this location (REQUIRED)
  72. *
  73. *
  74. */
  75. function location_latlon_exact_au($location = array()) {
  76. return NULL;
  77. // By uncommenting the line of code below, you legally acknowledge that you understand that you can only
  78. // do so under the terms of the Non-Commercial Share-alike license described at http://creativecommons.org/licenses/by-nc-sa/2.0/
  79. //return _location_latlon_exact_us_geocoder($location);
  80. }
  81. /**
  82. * Calls up a web-service to retrieve a lat/lon pair for a full, correct U.S. location.
  83. *
  84. * @param $location
  85. * An associative array that represents an location where
  86. * 'street' => is the street location
  87. * 'supplemental' => any supplemental portion to the street location
  88. * 'city' => city name
  89. * 'province' => state, province, or territorial abbreviation
  90. * 'postal_code' => postal code
  91. *
  92. * @return
  93. * An associative array where
  94. * 'lat' => Is a float value in latitude
  95. * 'lon' => Is a float value in longitude
  96. * If the location supplied does not provide enough information, NULL is returned.
  97. * "Enough information" means that there is either
  98. * (a valid 'street' AND valid 'postal_code') OR (valid 'street' AND valid 'city' AND valid 'province')
  99. */
  100. function _location_latlon_exact_au_geocoder($location = array()) {
  101. $location_string = '';
  102. if (isset($location['street']) && trim($location['street']) != '') {
  103. if (isset($location['postal_code'])) {
  104. $location_string = $location['street'] .' '. $location['postal_code'];
  105. }
  106. elseif (isset($location['city']) && isset($location['province']) && trim($location['city']) != '' && trim($location['province'])) {
  107. $location_string = $location['street'] .', '. $location['city'] .', '. $location['province'];
  108. }
  109. else { // else geocoder.us won't do bidness with you!
  110. return NULL;
  111. }
  112. }
  113. else {
  114. return NULL;
  115. }
  116. $result = xmlrpc('http://rpc.geocoder.us/service/xmlrpc', array('geocode' => array($location_string)));
  117. if (is_array($result) && is_array($result[0]) && isset($result[0]['lat']) && is_numeric($result[0]['lat']) && isset($result[0]['long']) && is_numeric($result[0]['long'])) {
  118. return array('lat' => $result[0]['lat'], 'lon' => $result[0]['long']);
  119. }
  120. return NULL;
  121. }
  122. function location_map_link_au_yahoo($location = array()) {
  123. $get_query = '?';
  124. if (isset($location['street'])) {
  125. $get_query .= 'addr='. urlencode($location['street']) .'&amp;';
  126. }
  127. if ($location['province'] != '' || $location['city'] != '' || $location['postal_code'] != '') {
  128. $get_query .= 'csz='. _location_au_yahoo_csz_get_field($location) .'&amp;';
  129. }
  130. $get_query .= 'country='. urlencode($location['country']);
  131. return ('http://maps.yahoo.com/maps_result'. $get_query);
  132. }
  133. function location_map_link_au_google($location = array()) {
  134. $query_params = array();
  135. foreach (array('street', 'city', 'province', 'postal_code', 'country') as $field) {
  136. if (isset($location[$field])) {
  137. $query_params[] = $location[$field];
  138. }
  139. }
  140. if (count($query_params)) {
  141. return ('http://maps.google.com?q='. urlencode(implode(", ", $query_params)));
  142. }
  143. else {
  144. return NULL;
  145. }
  146. }
  147. function location_map_link_au_mapquest($location = array()) {
  148. if (isset($location['street'])) {
  149. $get_query .= 'address='. urlencode($location['street']) .'&amp;';
  150. }
  151. if (isset($location['city'])) {
  152. $get_query .= 'city='. urlencode($location['city']) .'&amp;';
  153. }
  154. if (isset($location['province'])) {
  155. $get_query .= 'state='. urlencode($location['province']) .'&amp;';
  156. }
  157. if (isset($location['postal_code'])) {
  158. $get_query .= 'zipcode='. urlencode($location['postal_code']);
  159. }
  160. if (strlen($get_query)) {
  161. return 'http://www.mapquest.com/maps/map.adp?searchtype=address&amp;country=AU&amp;'. $get_query;
  162. }
  163. else {
  164. return NULL;
  165. }
  166. }
  167. /**
  168. * @return
  169. * An array where
  170. * -> the key is the word that helps identify the name of function that builds the link. For example, a key of 'yahoo' means the name of the
  171. * the function that builds a link to a map on Yahoo! Maps would be 'location_map_link_us_yahoo'
  172. * -> the value is itself an array with 3 key/value pairs:
  173. * 'name' => points to the name of the mapping service. For 'yahoo', this would be 'Yahoo! Maps'
  174. * 'url' => the url of the main page of the mapping service. For 'yahoo', this would be 'http://maps.yahoo.com'
  175. * 'tos' => the url of the page that explains the map providers Terms of Service, or Terms of Use. For 'yahoo', this would be
  176. * 'http://help.yahoo.com/help/us/maps/maps-24.html'
  177. */
  178. function location_map_link_au_providers() {
  179. return array('google' => array('name' => 'Google Maps', 'url' => 'http://maps.google.com', 'tos' => 'http://www.google.com/help/terms_local.html'),
  180. 'yahoo' => array('name' => 'Yahoo! Maps', 'url' => 'http://maps.yahoo.com', 'tos' => 'http://help.yahoo.com/help/us/maps/maps-24.html'),
  181. 'mapquest' => array('name' => 'MapQuest', 'url' => 'http://www.mapquest.com', 'tos' => 'http://www.mapquest.com/features/main.adp?page=legal')
  182. );
  183. }
  184. /**
  185. * @return
  186. * An array of values that work as keys to the array returned by location_map_link_us_providers. The idea is that if the
  187. * administrator of the site has not yet had a chance to visit the "Map Links" subtab on the location module's settings page,
  188. * that we can provide deep-linking to a relatively safe default. By 'relatively safe', we mean that the Terms Of Service of
  189. * the provider of the maps are flexible enough for most parties.
  190. *
  191. * For the case of the U.S., 'google' has relatively flexible Terms Of Service, whereas Yahoo! Maps and MapQuest have more
  192. * restrictive Terms Of Service.
  193. *
  194. */
  195. function location_map_link_au_default_providers() {
  196. return array('google');
  197. }
  198. function location_geocode_au_providers() {
  199. return array(
  200. 'yahoo' => array('name' => 'Yahoo! Maps Web Services', 'url' => 'http://developer.yahoo.com/maps/rest/V1/geocode.html', 'tos' => 'http://developer.yahoo.com/maps/mapsTerms.html'),
  201. );
  202. }
  203. function location_geocode_au_yahoo_settings() {
  204. $form = array();
  205. $form['location_geocode_au_yahoo_appid'] = array(
  206. '#type' => 'textfield',
  207. '#title' => t('Yahoo! Web Services Application ID'),
  208. '#size' => 64,
  209. '#maxlength' => 128,
  210. '#default_value' => variable_get('location_geocode_au_yahoo_appid', 'YahooDemo'),
  211. '#description' => t('Unless you are using this site to test and develop, you will need to obtain a Yahoo! Web Services Application ID from the %network_link. If you are using for development and testing purposes, you can use \'YahooDemo\' as your AppID. When getting an Application ID from Yahoo!, please also be sure to review the %usage_policy.', array('%network_link' => '<a href="http://api.search.yahoo.com/webservices/register_application">Yahoo! Developer Network</a>', '%usage_policy' => '<a href="http://developer.yahoo.com/usagePolicy/index.html">usage policy</a>'))
  212. );
  213. return $form;
  214. }
  215. function location_geocode_au_yahoo($location = array()) {
  216. $service_url = "http://api.local.yahoo.com/MapsService/V1/geocode?appid=". variable_get('location_geocode_au_yahoo_appid', "YahooDemo") ."&location=";
  217. $address = location_address2singleline($location);
  218. $http_reply = drupal_http_request($service_url . urlencode($address));
  219. // address may have been improperly formatted or invalid
  220. if ($http_reply->code == 400) {
  221. return NULL;
  222. }
  223. else {
  224. // got a successful reply, but we only want to return if we have address-level precision
  225. $matches = array();
  226. preg_match('/precision="([a-z]*)"/', $http_reply->data, $matches);
  227. if ($matches[1] != 'address') {
  228. // The precision we got back was not down to the street-address level
  229. return NULL;
  230. }
  231. else {
  232. $lat_match = array();
  233. $lon_match = array();
  234. $latlon = array();
  235. if (preg_match('/<Latitude>(.*)<\/Latitude>/', $http_reply->data, $lat_match)) {
  236. $latlon['lat'] = $lat_match[1];
  237. }
  238. else {
  239. return NULL;
  240. }
  241. if (preg_match('/<Longitude>(.*)<\/Longitude>/', $http_reply->data, $lon_match)) {
  242. $latlon['lon'] = $lon_match[1];
  243. return $latlon;
  244. }
  245. else {
  246. return NULL;
  247. }
  248. }
  249. }
  250. }
  251. /**
  252. * Parameters:
  253. * -> $location_a is an associative array that represents a full location where
  254. * 'street' => the street portions of the location
  255. * 'supplemental' => additional street portion of the location
  256. * 'province' => the province, state, or territory
  257. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  258. * -> $location_b is associative array that represents a full location in the same way that
  259. * parameter $location_b does.
  260. *
  261. * Returns: a link to driving directions
  262. *
  263. * For now, assume site-admin wants American driving directions linked to Yahoo! Driving Directions.
  264. * Maybe later, we can add some kind of country-specific settings page that allows the site-admin to
  265. * decide which site to link to for driving directions.
  266. */
  267. function location_driving_directions_link_au($location_a, $location_b) {
  268. return _location_driving_directions_link_au_yahoo($location_a, $location_b);
  269. }
  270. /**
  271. * Parameters:
  272. * Function that is called by location_driving_directions_link_au() under assumption that it
  273. * is the chosen function
  274. *
  275. * Returns:
  276. * a URL with HTTP GET variables
  277. * Depending on how full the locationes are, the URL will either point to the driving directions
  278. * on Yahoo! or, if only partial locationes are provided, a URL that points to the *form* for
  279. * Yahoo! driving directions where the form is filled with whatever fields have been provided
  280. * for the partial location(es).
  281. */
  282. function _location_driving_directions_link_au_yahoo($location_a, $location_b) {
  283. if (trim($location_b['country']) != 'ca' && trim($location_b['country']) != 'au') {
  284. return '';
  285. }
  286. // These are the fields that need to be in each location if we are to provide a direct
  287. // link to yahoo directions. If all of these fields don't have values, then we generate
  288. // a link to the *form* for Yahoo! driving directions rather than directly to the driving
  289. // directions themselves.
  290. foreach ($location_a as $field => $value) {
  291. $location_a[$field] = trim($value);
  292. }
  293. foreach ($location_b as $field => $value) {
  294. $location_b[$field] = trim($value);
  295. }
  296. if (_location_au_enough_fields_for_yahoo($location_a) && _location_au_enough_fields_for_yahoo($location_b)) {
  297. $yahoo_maps_path = 'dd_result';
  298. }
  299. else {
  300. $yahoo_maps_path = 'dd';
  301. }
  302. $get_query = '?';
  303. $get_query .= 'addr='. urlencode($location_a['street']) .'&amp;';
  304. $get_query .= 'csz='. _location_au_yahoo_csz_get_field($location_a) .'&amp;';
  305. $get_query .= 'country='. urlencode($location_a['country']) .'&amp;';
  306. $get_query .= 'taddr='. urlencode($location_b['street']) .'&amp;';
  307. $get_query .= 'tcsz='. _location_au_yahoo_csz_get_field($location_b) .'&amp;';
  308. $get_query .= 'tcountry='. urlencode($location_b['country']);
  309. $get_query .= '&amp;getrte='. urlencode('Get Directions');
  310. return ('http://maps.yahoo.com/'. $yahoo_maps_path . $get_query);
  311. }
  312. function _location_au_enough_fields_for_yahoo($location) {
  313. // These are the fields that need to be in each location if we are to provide a direct
  314. // link to yahoo directions. If all of these fields don't have values, then we generate
  315. // a link to the *form* for Yahoo! driving directions rather than directly to the driving
  316. // directions themselves.
  317. if (strlen($location['street']) && strlen($location['city']) && strlen($location['province'])) {
  318. return TRUE;
  319. }
  320. if (strlen($location['street']) && strlen($location['postal_code'])) {
  321. return TRUE;
  322. }
  323. if (strlen($location['street']) && strlen($location['city']) && strlen($location['province'])) {
  324. return TRUE;
  325. }
  326. return FALSE;
  327. }
  328. /**
  329. * Don't mess with this function unless you understand its logic. It has to do with
  330. * the question of "to comma or not to comma?"
  331. */
  332. function _location_au_yahoo_csz_get_field($location) {
  333. // For some reasons, to the end of pinpointing a location, Yahoo! Maps and Driving Directions
  334. // do better a better job with retrieving info based strictly on a Canadian city/province
  335. // than on a Canadian postal code.
  336. if ($location['country'] = 'ca') {
  337. if (strlen($location['city']) && strlen($location['province'])) {
  338. return urlencode($location['city'] .', '. $location['province']);
  339. }
  340. if (strlen($location['postal_code'])) {
  341. return urlencode($location['postal_code']);
  342. }
  343. }
  344. else {
  345. if (strlen($location['postal_code'])) {
  346. return urlencode($location['postal_code']);
  347. }
  348. if (strlen($location['city']) && strlen($location['province'])) {
  349. return urlencode($location['city'] .', '. $location['province']);
  350. }
  351. }
  352. if (strlen($location['city']) || strlen($location['state'])) {
  353. if (strlen($location['city'])) {
  354. return urlencode($location['city']);
  355. }
  356. else {
  357. return urlencode($location['state']);
  358. }
  359. }
  360. return '';
  361. }
  362. function _location_au_geocoder_oneline($location = array()) {
  363. $line = '';
  364. $line .= $location['street'] .', ';
  365. if (strlen($location['city']) && strlen($location['province']) && strlen($location['postal_code'])) {
  366. $line .= $location['city'] .', '. $location['province'] .' '. $location['postal_code'];
  367. }
  368. elseif (strlen($location['city']) && strlen($location['province'])) {
  369. $line .= $location['city'] .', '. $location['state'];
  370. }
  371. elseif (strlen($location['postal_code'])) {
  372. if (strlen($location['city']) || strlen($location['state'])) {
  373. if (strlen($location['city'])) {
  374. $line .= $location['city'] .', '. $location['postal_code'];
  375. }
  376. else {
  377. $line .= $location['state'] .', '. $location['postal_code'];
  378. }
  379. }
  380. else {
  381. $line .= $location['postal_code'];
  382. }
  383. }
  384. // DEBUG: commented code is for testing/debugging purposes
  385. //print '_location_au_geocoder_oneline() RETURNING '. $line ."<br/>\n";
  386. return $line;
  387. }
  388. /**
  389. * Returns an associative array of states/territories where
  390. * -> the keys are integers starting from 1
  391. * -> the values are the English names for those states/territories
  392. *
  393. * The states are grouped together at the beginning of the array and sorted
  394. * alphabetically.
  395. *
  396. * The territories are grouped together at the end of the array and sorted
  397. * alphabetically.
  398. *
  399. */
  400. function location_province_list_au() {
  401. return array(
  402. 'ACT' => 'Australian Capital Territory',
  403. 'NSW' => 'New South Wales',
  404. 'NT' => 'Northern Territory',
  405. 'QLD' => 'Queensland',
  406. 'SA' => 'South Australia',
  407. 'TAS' => 'Tasmania',
  408. 'VIC' => 'Victoria',
  409. 'WA' => 'Western Australia',
  410. );
  411. }
  412. /**
  413. * Returns an associative array of states/territories where
  414. * -> the keys are integers starting from 1
  415. * -> the values are the English names for those states/territories
  416. *
  417. * The states are grouped together at the beginning of the array and sorted
  418. * alphabetically.
  419. *
  420. * The territories are grouped together at the end of the array and sorted
  421. * alphabetically.
  422. *
  423. * Currently not being used, but may be in order to be compatible with CiviCRM
  424. * TODO: These numeric indices need to be changed to match those in the CiviCRM database
  425. */
  426. function location_province_list_numeric_au() {
  427. return array(
  428. '001' => "New South Wales",
  429. '002' => "Queensland",
  430. '003' => "South Australia",
  431. '004' => "Tasmania",
  432. '005' => "Victoria",
  433. '006' => "Western Australia",
  434. '007' => "Australian Capital Territory",
  435. '008' => "Northern Territory",
  436. );
  437. }
  438. /**
  439. * Returns minimum and maximum latitude and longitude needed to create a bounding box.
  440. */
  441. function location_bounds_au() {
  442. return array(
  443. 'minlng' => 72.57625,
  444. 'minlat' => -53.259967,
  445. 'maxlng' => 159.4839,
  446. 'maxlat' => -10.078033,
  447. );
  448. }