location.ca.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. <?php
  2. function location_province_list_ca() {
  3. return array(
  4. 'AB' => 'Alberta',
  5. 'BC' => 'British Columbia',
  6. 'MB' => 'Manitoba',
  7. 'NB' => 'New Brunswick',
  8. 'NL' => 'Newfoundland and Labrador',
  9. 'NS' => 'Nova Scotia',
  10. 'ON' => 'Ontario',
  11. 'PE' => 'Prince Edward Island',
  12. 'QC' => 'Quebec',
  13. 'SK' => 'Saskatchewan',
  14. 'NT' => 'Northwest Territories',
  15. 'NU' => 'Nunavut',
  16. 'YT' => 'Yukon Territory',
  17. );
  18. }
  19. function location_province_list_numeric_ca() {
  20. return array(
  21. '001' => 'Alberta',
  22. '002' => 'British Columbia',
  23. '003' => 'Manitoba',
  24. '004' => 'New Brunswick',
  25. '005' => 'Newfoundland and Labrador',
  26. '006' => 'Nova Scotia',
  27. '007' => 'Ontario',
  28. '008' => 'Prince Edward Island',
  29. '009' => 'Quebec',
  30. '010' => 'Saskatchewan',
  31. '011' => 'Northwest Territories',
  32. '012' => 'Nunavut',
  33. '013' => 'Yukon Territory',
  34. );
  35. }
  36. /**
  37. * Returns a lat/lon pair of the approximate center of the given postal code in the given country
  38. *
  39. * @param $location
  40. * An associative array $location where
  41. * 'street' => the street portion of the location
  42. * 'supplemental' => additional street portion of the location
  43. * 'province' => the province, state, or territory
  44. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  45. * 'postal_code' => the international postal code for this location (REQUIRED)
  46. *
  47. * @return
  48. * An associative array where
  49. * 'lat' => approximate latitude of the center of the postal code's area
  50. * 'lon' => approximate longitude of the center of the postal code's area
  51. *
  52. */
  53. function location_latlon_rough_ca($location = array()) {
  54. if (!isset($location['postal_code'])) {
  55. return NULL;
  56. }
  57. $row = db_query("SELECT latitude, longitude FROM {zipcodes} WHERE country = :country AND zip = :zip", array(':country' => $location['country'], ':zip' => $location['postal_code']))->fetchObject();
  58. if ($row) {
  59. return array('lat' => $row->latitude, 'lon' => $row->longitude);
  60. }
  61. else {
  62. return NULL;
  63. }
  64. }
  65. /**
  66. * Returns a lat/lon pair of the approximate center of the given postal code in the given country
  67. *
  68. * @param $location
  69. * An associative array $location where only postal code and country are necessary, but can have the keys:
  70. * 'street' => the street portion of the location
  71. * 'supplemental' => additional street portion of the location
  72. * 'province' => the province, state, or territory
  73. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  74. * 'postal_code' => the international postal code for this location (REQUIRED)
  75. *
  76. * @return
  77. * An associative array where
  78. * 'lat' => approximate latitude of the center of the postal code's area
  79. * 'lon' => approximate longitude of the center of the postal code's area
  80. * 'city' => the city
  81. * 'province' => the province, state, or territory
  82. * 'country' => lower-cased two-letter ISO code
  83. *
  84. */
  85. function location_get_postalcode_data_ca($location = array()) {
  86. // Now we pad the thing and query.
  87. $row = db_query("SELECT * FROM {zipcodes} where country = :country AND zip = :zip", array(':country' => $location['country'], ':zip' => $location['postal_code']))->fetchObject();
  88. if ($row) {
  89. return array('lat' => $row->latitude, 'lon' => $row->longitude, 'city' => $row->city, 'province' => $row->state, 'country' => $row->country);
  90. }
  91. else {
  92. return NULL;
  93. }
  94. }
  95. /**
  96. * Parameters:
  97. * An associative array $location where
  98. * 'street' => the street portion of the location
  99. * 'supplemental' => additional street portion of the location
  100. * 'province' => the province, state, or territory
  101. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  102. * 'postal_code' => the international postal code for this location (REQUIRED)
  103. *
  104. *
  105. */
  106. function location_latlon_exact_ca($location = array()) {
  107. // return location_geocode_ca_geocoder($location);
  108. }
  109. function location_map_link_ca_yahoo($location = array()) {
  110. $get_query = '?';
  111. if (isset($location['street'])) {
  112. $get_query .= 'addr='. urlencode($location['street']) .'&amp;';
  113. }
  114. if ($location['province'] != '' || $location['city'] != '' || $location['postal_code'] != '') {
  115. $get_query .= 'csz='. _location_ca_yahoo_csz_get_field($location) .'&amp;';
  116. }
  117. $get_query .= 'country='. urlencode($location['country']);
  118. return ('http://ca.maps.yahoo.com/maps_result'. $get_query);
  119. }
  120. function location_map_link_ca_google($location = array()) {
  121. $query_params = array();
  122. foreach (array('street', 'city', 'province', 'postal_code', 'country') as $field) {
  123. if (isset($location[$field])) {
  124. $query_params[] = $location[$field];
  125. }
  126. }
  127. if (count($query_params)) {
  128. return ('http://maps.google.ca?q='. urlencode(implode(", ", $query_params)));
  129. }
  130. else {
  131. return NULL;
  132. }
  133. }
  134. function location_map_link_ca_mapquest($location = array()) {
  135. if (isset($location['street'])) {
  136. $get_query .= 'address='. urlencode($location['street']) .'&amp;';
  137. }
  138. if (isset($location['city'])) {
  139. $get_query .= 'city='. urlencode($location['city']) .'&amp;';
  140. }
  141. if (isset($location['province'])) {
  142. $get_query .= 'state='. urlencode($location['province']) .'&amp;';
  143. }
  144. if (isset($location['postal_code'])) {
  145. $get_query .= 'zipcode='. urlencode($location['postal_code']);
  146. }
  147. if (strlen($get_query)) {
  148. return 'http://www.mapquest.com/maps/map.adp?searchtype=address&amp;country=CA&amp;'. $get_query;
  149. }
  150. else {
  151. return NULL;
  152. }
  153. }
  154. function location_map_link_ca_providers() {
  155. return array('google' => array('name' => 'Google Maps', 'url' => 'http://maps.google.ca', 'tos' => 'http://www.google.ca/help/terms_local.html'),
  156. 'yahoo' => array('name' => 'Yahoo! Maps', 'url' => 'http://ca.maps.yahoo.com' , 'tos' => 'http://help.yahoo.com/help/ca/maps/maps-25.html'),
  157. 'mapquest' => array('name' => 'MapQuest', 'url' => 'http://www.mapquest.com', 'tos' => 'http://www.mapquest.com/features/main.adp?page=legal')
  158. );
  159. }
  160. function location_map_link_ca_default_providers() {
  161. return array('google');
  162. }
  163. /**
  164. * Parameters:
  165. * -> $location_a is an associative array that represents a full location where
  166. * 'street' => the street portions of the location
  167. * 'supplemental' => additional street portion of the location
  168. * 'province' => the province, state, or territory
  169. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  170. * -> $location_b is associative array that represents a full location in the same way that
  171. * parameter $location_b does.
  172. *
  173. * Returns: a link to driving directions
  174. *
  175. * For now, assume site-admin wants American driving directions linked to Yahoo! Driving Directions.
  176. * Maybe later, we can add some kind of country-specific settings page that allows the site-admin to
  177. * decide which site to link to for driving directions.
  178. */
  179. function location_driving_directions_link_ca($location_a, $location_b) {
  180. return _location_driving_directions_link_ca_yahoo($location_a, $location_b);
  181. }
  182. /**
  183. * Parameters:
  184. * Function that is called by location_driving_directions_link_ca() under assumption that it
  185. * is the chosen function
  186. *
  187. * Returns:
  188. * a URL with HTTP GET variables
  189. * Depending on how full the locationes are, the URL will either point to the driving directions
  190. * on Yahoo! or, if only partial locationes are provided, a URL that points to the *form* for
  191. * Yahoo! driving directions where the form is filled with whatever fields have been provided
  192. * for the partial location(es).
  193. */
  194. function _location_driving_directions_link_ca_yahoo($location_a, $location_b) {
  195. if (trim($location_b['country']) != 'ca' && trim($location_b['country']) != 'us') {
  196. return '';
  197. }
  198. // These are the fields that need to be in each location if we are to provide a direct
  199. // link to yahoo directions. If all of these fields don't have values, then we generate
  200. // a link to the *form* for Yahoo! driving directions rather than directly to the driving
  201. // directions themselves.
  202. foreach ($location_a as $field => $value) {
  203. $location_a[$field] = trim($value);
  204. }
  205. foreach ($location_b as $field => $value) {
  206. $location_b[$field] = trim($value);
  207. }
  208. if (_location_ca_enough_fields_for_yahoo($location_a) && _location_ca_enough_fields_for_yahoo($location_b)) {
  209. $yahoo_maps_path = 'dd_result';
  210. }
  211. else {
  212. $yahoo_maps_path = 'dd';
  213. }
  214. $get_query = '?';
  215. $get_query .= 'addr='. urlencode($location_a['street']) .'&amp;';
  216. $get_query .= 'csz='. _location_ca_yahoo_csz_get_field($location_a) .'&amp;';
  217. $get_query .= 'country='. urlencode($location_a['country']) .'&amp;';
  218. $get_query .= 'taddr='. urlencode($location_b['street']) .'&amp;';
  219. $get_query .= 'tcsz='. _location_ca_yahoo_csz_get_field($location_b) .'&amp;';
  220. $get_query .= 'tcountry='. urlencode($location_b['country']);
  221. $get_query .= '&amp;getrte='. urlencode('Get Directions');
  222. return ('http://ca.maps.yahoo.com/'. $yahoo_maps_path . $get_query);
  223. }
  224. function _location_ca_enough_fields_for_yahoo($location) {
  225. // These are the fields that need to be in each location if we are to provide a direct
  226. // link to yahoo directions. If all of these fields don't have values, then we generate
  227. // a link to the *form* for Yahoo! driving directions rather than directly to the driving
  228. // directions themselves.
  229. if (strlen($location['street']) && strlen($location['city']) && strlen($location['province'])) {
  230. return TRUE;
  231. }
  232. if (strlen($location['street']) && strlen($location['postal_code'])) {
  233. return TRUE;
  234. }
  235. if (strlen($location['street']) && strlen($location['city']) && strlen($location['province'])) {
  236. return TRUE;
  237. }
  238. return FALSE;
  239. }
  240. // Don't mess with this function unless you understand its logic. It has to do with
  241. // the question of "to comma or not to comma?"
  242. function _location_ca_yahoo_csz_get_field($location) {
  243. // For some reasons, to the end of pinpointing a location, Yahoo! Maps and Driving Directions
  244. // do better a better job with retrieving info based strictly on a Canadian city/province
  245. // than on a Canadian postal code.
  246. if ($location['country'] = 'ca') {
  247. if (strlen($location['city']) && strlen($location['province'])) {
  248. return urlencode($location['city'] .', '. $location['province']);
  249. }
  250. if (strlen($location['postal_code'])) {
  251. return urlencode($location['postal_code']);
  252. }
  253. }
  254. else {
  255. if (strlen($location['postal_code'])) {
  256. return urlencode($location['postal_code']);
  257. }
  258. if (strlen($location['city']) && strlen($location['province'])) {
  259. return urlencode($location['city'] .', '. $location['province']);
  260. }
  261. }
  262. if (strlen($location['city']) || strlen($location['province'])) {
  263. if (strlen($location['city'])) {
  264. return urlencode($location['city']);
  265. }
  266. else {
  267. return urlencode($location['province']);
  268. }
  269. }
  270. return '';
  271. }
  272. function location_geocode_ca_providers() {
  273. return array(
  274. 'geocoder' => array('name' => 'GeoCode.ca geocoding service', 'url' => 'http://geocoder.ca/?api=1', 'tos' => 'http://geocoder.ca/?terms=1http://geocoder.ca/?terms=1'),
  275. );
  276. }
  277. function location_geocode_ca_geocoder_settings() {
  278. $form = array();
  279. $form['location_geocode_ca_geocoder_apikey'] = array(
  280. '#type' => 'textfield',
  281. '#title' => t('Geocoder API Key'),
  282. '#size' => 64,
  283. '#maxlength' => 128,
  284. '#default_value' => variable_get('location_geocode_ca_geocoder_apikey', ''),
  285. '#description' => t('In order to use the Geocoder.ca API geocoding web-service, if you are a commercial entity or wish to use the service without attribution, you will need a Geocoder API Key. You can obtain one at the !sign_up_link for the !geocoder_api.', array('!sign_up_link' => '<a href="http://geocoder.ca/?register=1">sign-up page</a>', '!geocoder_api' => '<a href="http://geocoder.ca/?premium_api=1">Geocoder API</a>'))
  286. );
  287. return $form;
  288. }
  289. /**
  290. * This needs some more work to cover errors and such. I think showing a proper
  291. * Drupal error is a good idea. If an incorrect address is given to geocoder.ca
  292. * it offers a suggestion. If this happens the drupal user should be told.
  293. */
  294. function location_geocode_ca_geocoder($location = array()) {
  295. $service_url = "http://geocoder.ca/?geoit=XML";
  296. if (variable_get('location_geocode_ca_geocoder_apikey', '')) {
  297. $service_url .= '&auth='. variable_get('location_geocode_ca_geocoder_apikey', NULL) .'&locate=';
  298. }
  299. else {
  300. $service_url .= '&locate=';
  301. }
  302. // geocoder gives better results when not usong postal code, country and ,
  303. unset($location['postal_code'], $location['country']);
  304. $address = strtr(location_address2singleline($location), array(', ' => ' '));
  305. $http_reply = drupal_http_request($service_url . urlencode($address));
  306. if ($http_reply->code == 400) {
  307. return NULL;
  308. }
  309. else {
  310. $matches = array();
  311. $lat_match = array();
  312. $lon_match = array();
  313. $latlon = array();
  314. if (preg_match('/<error>(.*)<\/error>/', $http_reply->data, $lat_match)) {
  315. return NULL;
  316. }
  317. if (preg_match('/<latt>(.*)<\/latt>/', $http_reply->data, $lat_match)) {
  318. $latlon['lat'] = $lat_match[1];
  319. }
  320. else {
  321. return NULL;
  322. }
  323. if (preg_match('/<longt>(.*)<\/longt>/', $http_reply->data, $lon_match)) {
  324. $latlon['lon'] = $lon_match[1];
  325. return $latlon;
  326. }
  327. else {
  328. return NULL;
  329. }
  330. }
  331. }
  332. /**
  333. * Returns minimum and maximum latitude and longitude needed to create a bounding box.
  334. */
  335. function location_bounds_ca() {
  336. // NaturalEarth 10m Admin 0 - Countries (v1.3.0)
  337. // EPSG:900913
  338. return array(
  339. 'minlng' => -141.00554,
  340. 'minlat' => 41.6690855,
  341. 'maxlng' => -52.615930,
  342. 'maxlat' => 83.1161164,
  343. );
  344. }