location.us.inc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. <?php
  2. /**
  3. * Returns a lat/lon pair of the approximate center of the given postal code in the given country
  4. *
  5. * @param $location
  6. * An associative array $location where
  7. * 'street' => the street portion of the location
  8. * 'supplemental' => additional street portion of the location
  9. * 'province' => the province, state, or territory
  10. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  11. * 'postal_code' => the international postal code for this location (REQUIRED)
  12. *
  13. * @return
  14. * An associative array where
  15. * 'lat' => approximate latitude of the center of the postal code's area
  16. * 'lon' => approximate longitude of the center of the postal code's area
  17. *
  18. */
  19. function location_latlon_rough_us($location = array()) {
  20. if (!isset($location['postal_code'])) {
  21. return NULL;
  22. }
  23. $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'], 5, '0', STR_PAD_LEFT), 0, 5)))->fetchObject();
  24. if ($row) {
  25. return array('lat' => $row->latitude, 'lon' => $row->longitude);
  26. }
  27. else {
  28. return NULL;
  29. }
  30. }
  31. /**
  32. * Returns a lat/lon pair of the approximate center of the given postal code in the given country
  33. *
  34. * @param $location
  35. * An associative array $location where only postal code and country are necessary, but can have the keys:
  36. * 'street' => the street portion of the location
  37. * 'supplemental' => additional street portion of the location
  38. * 'province' => the province, state, or territory
  39. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  40. * 'postal_code' => the international postal code for this location (REQUIRED)
  41. *
  42. * @return
  43. * An associative array where
  44. * 'lat' => approximate latitude of the center of the postal code's area
  45. * 'lon' => approximate longitude of the center of the postal code's area
  46. *
  47. */
  48. function location_get_postalcode_data_us($location = array()) {
  49. $dash_index = strpos($location['postal_code'], '-');
  50. // First we strip slash off if we're dealing with a 9-digit US zipcode
  51. if (!($dash_index === FALSE)) {
  52. $location['postal_code'] = substr($location['postal_code'], 0, $dash_index);
  53. }
  54. // Now we pad the thing and query.
  55. $row = db_query("SELECT * FROM {zipcodes} where country = :country AND zip = :zip", array(':country' => $location['country'], ':zip' => str_pad($location['postal_code'], 5, "0", STR_PAD_LEFT)))->fetchObject();
  56. if ($row) {
  57. return array('lat' => $row->latitude, 'lon' => $row->longitude, 'city' => $row->city, 'province' => $row->state, 'country' => $row->country);
  58. }
  59. else {
  60. return NULL;
  61. }
  62. }
  63. /**
  64. * Parameters:
  65. * An associative array $location where
  66. * 'street' => the street portion of the location
  67. * 'supplemental' => additional street portion of the location
  68. * 'province' => the province, state, or territory
  69. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  70. * 'postal_code' => the international postal code for this location (REQUIRED)
  71. *
  72. *
  73. */
  74. function location_latlon_exact_us($location = array()) {
  75. return NULL;
  76. // By uncommenting the line of code below, you legally acknowledge that you understand that you can only
  77. // do so under the terms of the Non-Commercial Share-alike license described at http://creativecommons.org/licenses/by-nc-sa/2.0/
  78. //return _location_latlon_exact_us_geocoder($location);
  79. }
  80. /**
  81. * Calls up a web-service to retrieve a lat/lon pair for a full, correct U.S. location.
  82. *
  83. * @param $location
  84. * An associative array that represents an location where
  85. * 'street' => is the street location
  86. * 'supplemental' => any supplemental portion to the street location
  87. * 'city' => city name
  88. * 'province' => state, province, or territorial abbreviation
  89. * 'postal_code' => postal code
  90. *
  91. * @return
  92. * An associative array where
  93. * 'lat' => Is a float value in latitude
  94. * 'lon' => Is a float value in longitude
  95. * If the location supplied does not provide enough information, NULL is returned.
  96. * "Enough information" means that there is either
  97. * (a valid 'street' AND valid 'postal_code') OR (valid 'street' AND valid 'city' AND valid 'province')
  98. */
  99. function _location_latlon_exact_us_geocoder($location = array()) {
  100. $location_string = '';
  101. if (isset($location['street']) && trim($location['street']) != '') {
  102. if (isset($location['postal_code'])) {
  103. $location_string = $location['street'] .' '. $location['postal_code'];
  104. }
  105. elseif (isset($location['city']) && isset($location['province']) && trim($location['city']) != '' && trim($location['province'])) {
  106. $location_string = $location['street'] .', '. $location['city'] .', '. $location['province'];
  107. }
  108. else { // else geocoder.us won't do bidness with you!
  109. return NULL;
  110. }
  111. }
  112. else {
  113. return NULL;
  114. }
  115. $result = xmlrpc('http://rpc.geocoder.us/service/xmlrpc', array('geocode' => array($location_string)));
  116. 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'])) {
  117. return array('lat' => $result[0]['lat'], 'lon' => $result[0]['long']);
  118. }
  119. return NULL;
  120. }
  121. function location_map_link_us_yahoo($location = array()) {
  122. $get_query = '?';
  123. if (isset($location['street'])) {
  124. $get_query .= 'addr='. urlencode($location['street']) .'&amp;';
  125. }
  126. if ($location['province'] != '' || $location['city'] != '' || $location['postal_code'] != '') {
  127. $get_query .= 'csz='. _location_us_yahoo_csz_get_field($location) .'&amp;';
  128. }
  129. $get_query .= 'country='. urlencode($location['country']);
  130. return ('http://maps.yahoo.com/maps_result'. $get_query);
  131. }
  132. function location_map_link_us_google($location = array()) {
  133. $query_params = array();
  134. $q = NULL;
  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 (location_has_coordinates($location)) {
  141. $q = urlencode($location['latitude'] . ' ' . $location['longitude'] . ' (' . implode(', ', $query_params) . ')' );
  142. } else if (count($query_params) > 0) {
  143. $q = urlencode(implode(", ", $query_params));
  144. }
  145. if ($q != NULL) {
  146. return ('http://maps.google.com?q='.$q );
  147. }
  148. else {
  149. return NULL;
  150. }
  151. }
  152. function location_map_link_us_mapquest($location = array()) {
  153. if (isset($location['street'])) {
  154. $get_query .= 'address='. urlencode($location['street']) .'&amp;';
  155. }
  156. if (isset($location['city'])) {
  157. $get_query .= 'city='. urlencode($location['city']) .'&amp;';
  158. }
  159. if (isset($location['province'])) {
  160. $get_query .= 'state='. urlencode($location['province']) .'&amp;';
  161. }
  162. if (isset($location['postal_code'])) {
  163. $get_query .= 'zipcode='. urlencode($location['postal_code']);
  164. }
  165. if (strlen($get_query)) {
  166. return 'http://www.mapquest.com/maps/map.adp?searchtype=address&amp;country=US&amp;'. $get_query;
  167. }
  168. else {
  169. return NULL;
  170. }
  171. }
  172. /**
  173. * @return
  174. * An array where
  175. * -> 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
  176. * the function that builds a link to a map on Yahoo! Maps would be 'location_map_link_us_yahoo'
  177. * -> the value is itself an array with 3 key/value pairs:
  178. * 'name' => points to the name of the mapping service. For 'yahoo', this would be 'Yahoo! Maps'
  179. * 'url' => the url of the main page of the mapping service. For 'yahoo', this would be 'http://maps.yahoo.com'
  180. * 'tos' => the url of the page that explains the map providers Terms of Service, or Terms of Use. For 'yahoo', this would be
  181. * 'http://help.yahoo.com/help/us/maps/maps-24.html'
  182. */
  183. function location_map_link_us_providers() {
  184. return array('google' => array('name' => 'Google Maps', 'url' => 'http://maps.google.com', 'tos' => 'http://www.google.com/help/terms_local.html'),
  185. 'yahoo' => array('name' => 'Yahoo! Maps', 'url' => 'http://maps.yahoo.com', 'tos' => 'http://help.yahoo.com/help/us/maps/maps-24.html'),
  186. 'mapquest' => array('name' => 'MapQuest', 'url' => 'http://www.mapquest.com', 'tos' => 'http://www.mapquest.com/features/main.adp?page=legal')
  187. );
  188. }
  189. /**
  190. * @return
  191. * An array of values that work as keys to the array returned by location_map_link_us_providers. The idea is that if the
  192. * administrator of the site has not yet had a chance to visit the "Map Links" subtab on the location module's settings page,
  193. * that we can provide deep-linking to a relatively safe default. By 'relatively safe', we mean that the Terms Of Service of
  194. * the provider of the maps are flexible enough for most parties.
  195. *
  196. * For the case of the U.S., 'google' has relatively flexible Terms Of Service, whereas Yahoo! Maps and MapQuest have more
  197. * restrictive Terms Of Service.
  198. *
  199. */
  200. function location_map_link_us_default_providers() {
  201. return array('google');
  202. }
  203. function location_geocode_us_providers() {
  204. return array(
  205. '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')
  206. );
  207. }
  208. function location_geocode_us_yahoo_settings() {
  209. $form = array();
  210. $form['location_geocode_us_yahoo_appid'] = array(
  211. '#type' => 'textfield',
  212. '#title' => t('Yahoo! Web Services Application ID'),
  213. '#size' => 64,
  214. '#maxlength' => 128,
  215. '#default_value' => variable_get('location_geocode_us_yahoo_appid', 'YahooDemo'),
  216. '#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>'))
  217. );
  218. return $form;
  219. }
  220. function location_geocode_us_yahoo($location = array()) {
  221. $service_url = "http://api.local.yahoo.com/MapsService/V1/geocode?appid=". variable_get('location_geocode_us_yahoo_appid', "YahooDemo") ."&location=";
  222. $address = location_address2singleline($location);
  223. $http_reply = drupal_http_request($service_url . urlencode($address));
  224. // address may have been improperly formatted or invalid
  225. if ($http_reply->code == 400) {
  226. return NULL;
  227. }
  228. else {
  229. // got a successful reply, but we only want to return if we have address-level precision
  230. $matches = array();
  231. preg_match('/precision="([a-z]*)"/', $http_reply->data, $matches);
  232. if ($matches[1] != 'address') {
  233. // The precision we got back was not down to the street-address level
  234. return NULL;
  235. }
  236. else {
  237. $lat_match = array();
  238. $lon_match = array();
  239. $latlon = array();
  240. if (preg_match('/<Latitude>(.*)<\/Latitude>/', $http_reply->data, $lat_match)) {
  241. $latlon['lat'] = $lat_match[1];
  242. }
  243. else {
  244. return NULL;
  245. }
  246. if (preg_match('/<Longitude>(.*)<\/Longitude>/', $http_reply->data, $lon_match)) {
  247. $latlon['lon'] = $lon_match[1];
  248. return $latlon;
  249. }
  250. else {
  251. return NULL;
  252. }
  253. }
  254. }
  255. }
  256. /**
  257. * Parameters:
  258. * -> $location_a is an associative array that represents a full location where
  259. * 'street' => the street portions of the location
  260. * 'supplemental' => additional street portion of the location
  261. * 'province' => the province, state, or territory
  262. * 'country' => lower-cased two-letter ISO code (REQUIRED)
  263. * -> $location_b is associative array that represents a full location in the same way that
  264. * parameter $location_b does.
  265. *
  266. * Returns: a link to driving directions
  267. *
  268. * For now, assume site-admin wants American driving directions linked to Yahoo! Driving Directions.
  269. * Maybe later, we can add some kind of country-specific settings page that allows the site-admin to
  270. * decide which site to link to for driving directions.
  271. */
  272. function location_driving_directions_link_us($location_a, $location_b) {
  273. return _location_driving_directions_link_us_yahoo($location_a, $location_b);
  274. }
  275. /**
  276. * Parameters:
  277. * Function that is called by location_driving_directions_link_us() under assumption that it
  278. * is the chosen function
  279. *
  280. * Returns:
  281. * a URL with HTTP GET variables
  282. * Depending on how full the locationes are, the URL will either point to the driving directions
  283. * on Yahoo! or, if only partial locationes are provided, a URL that points to the *form* for
  284. * Yahoo! driving directions where the form is filled with whatever fields have been provided
  285. * for the partial location(es).
  286. */
  287. function _location_driving_directions_link_us_yahoo($location_a, $location_b) {
  288. if (trim($location_b['country']) != 'ca' && trim($location_b['country']) != 'us') {
  289. return '';
  290. }
  291. // These are the fields that need to be in each location if we are to provide a direct
  292. // link to yahoo directions. If all of these fields don't have values, then we generate
  293. // a link to the *form* for Yahoo! driving directions rather than directly to the driving
  294. // directions themselves.
  295. foreach ($location_a as $field => $value) {
  296. $location_a[$field] = trim($value);
  297. }
  298. foreach ($location_b as $field => $value) {
  299. $location_b[$field] = trim($value);
  300. }
  301. if (_location_us_enough_fields_for_yahoo($location_a) && _location_us_enough_fields_for_yahoo($location_b)) {
  302. $yahoo_maps_path = 'dd_result';
  303. }
  304. else {
  305. $yahoo_maps_path = 'dd';
  306. }
  307. $get_query = '?';
  308. $get_query .= 'addr='. urlencode($location_a['street']) .'&amp;';
  309. $get_query .= 'csz='. _location_us_yahoo_csz_get_field($location_a) .'&amp;';
  310. $get_query .= 'country='. urlencode($location_a['country']) .'&amp;';
  311. $get_query .= 'taddr='. urlencode($location_b['street']) .'&amp;';
  312. $get_query .= 'tcsz='. _location_us_yahoo_csz_get_field($location_b) .'&amp;';
  313. $get_query .= 'tcountry='. urlencode($location_b['country']);
  314. $get_query .= '&amp;getrte='. urlencode('Get Directions');
  315. return ('http://maps.yahoo.com/'. $yahoo_maps_path . $get_query);
  316. }
  317. function _location_us_enough_fields_for_yahoo($location) {
  318. // These are the fields that need to be in each location if we are to provide a direct
  319. // link to yahoo directions. If all of these fields don't have values, then we generate
  320. // a link to the *form* for Yahoo! driving directions rather than directly to the driving
  321. // directions themselves.
  322. if (strlen($location['street']) && strlen($location['city']) && strlen($location['province'])) {
  323. return TRUE;
  324. }
  325. if (strlen($location['street']) && strlen($location['postal_code'])) {
  326. return TRUE;
  327. }
  328. if (strlen($location['street']) && strlen($location['city']) && strlen($location['province'])) {
  329. return TRUE;
  330. }
  331. return FALSE;
  332. }
  333. // Don't mess with this function unless you understand its logic. It has to do with
  334. // the question of "to comma or not to comma?"
  335. function _location_us_yahoo_csz_get_field($location) {
  336. // For some reasons, to the end of pinpointing a location, Yahoo! Maps and Driving Directions
  337. // do better a better job with retrieving info based strictly on a Canadian city/province
  338. // than on a Canadian postal code.
  339. if ($location['country'] = 'ca') {
  340. if (strlen($location['city']) && strlen($location['province'])) {
  341. return urlencode($location['city'] .', '. $location['province']);
  342. }
  343. if (strlen($location['postal_code'])) {
  344. return urlencode($location['postal_code']);
  345. }
  346. }
  347. else {
  348. if (strlen($location['postal_code'])) {
  349. return urlencode($location['postal_code']);
  350. }
  351. if (strlen($location['city']) && strlen($location['province'])) {
  352. return urlencode($location['city'] .', '. $location['province']);
  353. }
  354. }
  355. if (strlen($location['city']) || strlen($location['province'])) {
  356. if (strlen($location['city'])) {
  357. return urlencode($location['city']);
  358. }
  359. else {
  360. return urlencode($location['province']);
  361. }
  362. }
  363. return '';
  364. }
  365. function _location_us_geocoder_oneline($location = array()) {
  366. $line = '';
  367. $line .= $location['street'] .', ';
  368. if (strlen($location['city']) && strlen($location['province']) && strlen($location['postal_code'])) {
  369. $line .= $location['city'] .', '. $location['province'] .' '. $location['postal_code'];
  370. }
  371. elseif (strlen($location['city']) && strlen($location['province'])) {
  372. $line .= $location['city'] .', '. $location['province'];
  373. }
  374. elseif (strlen($location['postal_code'])) {
  375. if (strlen($location['city']) || strlen($location['province'])) {
  376. if (strlen($location['city'])) {
  377. $line .= $location['city'] .', '. $location['postal_code'];
  378. }
  379. else {
  380. $line .= $location['province'] .', '. $location['postal_code'];
  381. }
  382. }
  383. else {
  384. $line .= $location['postal_code'];
  385. }
  386. }
  387. // DEBUG: commented code is for testing/debugging purposes
  388. //print '_location_us_geocoder_oneline() RETURNING '. $line ."<br/>\n";
  389. return $line;
  390. }
  391. /**
  392. * Returns an associative array of states/territories where
  393. * -> the keys are integers starting from 1
  394. * -> the values are the English names for those states/territories
  395. *
  396. * The states are grouped together at the beginning of the array and sorted
  397. * alphabetically.
  398. *
  399. * The territories are grouped together at the end of the array and sorted
  400. * alphabetically.
  401. *
  402. */
  403. function location_province_list_us() {
  404. return array('AL' => 'Alabama',
  405. 'AK' => 'Alaska',
  406. 'AZ' => 'Arizona',
  407. 'AR' => 'Arkansas',
  408. 'CA' => 'California',
  409. 'CO' => 'Colorado',
  410. 'CT' => 'Connecticut',
  411. 'DE' => 'Delaware',
  412. 'DC' => 'District Of Columbia',
  413. 'FL' => 'Florida',
  414. 'GA' => 'Georgia',
  415. 'HI' => 'Hawaii',
  416. 'ID' => 'Idaho',
  417. 'IL' => 'Illinois',
  418. 'IN' => 'Indiana',
  419. 'IA' => 'Iowa',
  420. 'KS' => 'Kansas',
  421. 'KY' => 'Kentucky',
  422. 'LA' => 'Louisiana',
  423. 'ME' => 'Maine',
  424. 'MD' => 'Maryland',
  425. 'MA' => 'Massachusetts',
  426. 'MI' => 'Michigan',
  427. 'MN' => 'Minnesota',
  428. 'MS' => 'Mississippi',
  429. 'MO' => 'Missouri',
  430. 'MT' => 'Montana',
  431. 'NE' => 'Nebraska',
  432. 'NV' => 'Nevada',
  433. 'NH' => 'New Hampshire',
  434. 'NJ' => 'New Jersey',
  435. 'NM' => 'New Mexico',
  436. 'NY' => 'New York',
  437. 'NC' => 'North Carolina',
  438. 'ND' => 'North Dakota',
  439. 'OH' => 'Ohio',
  440. 'OK' => 'Oklahoma',
  441. 'OR' => 'Oregon',
  442. 'PA' => 'Pennsylvania',
  443. 'RI' => 'Rhode Island',
  444. 'SC' => 'South Carolina',
  445. 'SD' => 'South Dakota',
  446. 'TN' => 'Tennessee',
  447. 'TX' => 'Texas',
  448. 'UT' => 'Utah',
  449. 'VT' => 'Vermont',
  450. 'VA' => 'Virginia',
  451. 'WA' => 'Washington',
  452. 'WV' => 'West Virginia',
  453. 'WI' => 'Wisconsin',
  454. 'WY' => 'Wyoming',
  455. 'AS' => 'American Samoa',
  456. 'FM' => 'Federated States of Micronesia',
  457. 'GU' => 'Guam',
  458. 'MH' => 'Marshall Islands',
  459. 'MP' => 'Northern Mariana Islands',
  460. 'PW' => 'Palau',
  461. 'PR' => 'Puerto Rico',
  462. 'VI' => 'Virgin Islands'
  463. );
  464. }
  465. /**
  466. * Returns an associative array of states/territories where
  467. * -> the keys are integers starting from 1
  468. * -> the values are the English names for those states/territories
  469. *
  470. * The states are grouped together at the beginning of the array and sorted
  471. * alphabetically.
  472. *
  473. * The territories are grouped together at the end of the array and sorted
  474. * alphabetically.
  475. *
  476. * Currently not being used, but may be in order to be compatible with CiviCRM
  477. * TODO: These numeric indices need to be changed to match those in the CiviCRM database
  478. */
  479. function location_province_list_numeric_us() {
  480. return array('001' => 'Alabama',
  481. '002' => 'Alaska',
  482. '003' => 'Arizona',
  483. '004' => 'Arkansas',
  484. '005' => 'California',
  485. '006' => 'Colorado',
  486. '007' => 'Connecticut',
  487. '008' => 'Delaware',
  488. '009' => 'District Of Columbia',
  489. '010' => 'Florida',
  490. '011' => 'Georgia',
  491. '012' => 'Hawaii',
  492. '013' => 'Idaho',
  493. '014' => 'Illinois',
  494. '015' => 'Indiana',
  495. '016' => 'Iowa',
  496. '017' => 'Kansas',
  497. '018' => 'Kentucky',
  498. '019' => 'Louisiana',
  499. '020' => 'Maine',
  500. '021' => 'Maryland',
  501. '022' => 'Massachusetts',
  502. '023' => 'Michigan',
  503. '024' => 'Minnesota',
  504. '025' => 'Mississippi',
  505. '026' => 'Missouri',
  506. '027' => 'Montana',
  507. '028' => 'Nebraska',
  508. '029' => 'Nevada',
  509. '030' => 'New Hampshire',
  510. '031' => 'New Jersey',
  511. '032' => 'New Mexico',
  512. '033' => 'New York',
  513. '034' => 'North Carolina',
  514. '035' => 'North Dakota',
  515. '036' => 'Ohio',
  516. '037' => 'Oklahoma',
  517. '038' => 'Oregon',
  518. '039' => 'Pennsylvania',
  519. '040' => 'Rhode Island',
  520. '041' => 'South Carolina',
  521. '042' => 'South Dakota',
  522. '043' => 'Tennessee',
  523. '044' => 'Texas',
  524. '045' => 'Utah',
  525. '046' => 'Vermont',
  526. '047' => 'Virginia',
  527. '048' => 'Washington',
  528. '049' => 'West Virginia',
  529. '050' => 'Wisconsin',
  530. '051' => 'Wyoming',
  531. '052' => 'American Samoa',
  532. '053' => 'Federated States of Micronesia',
  533. '054' => 'Guam',
  534. '055' => 'Marshall Islands',
  535. '056' => 'Northern Mariana Islands',
  536. '057' => 'Palau',
  537. '058' => 'Puerto Rico',
  538. '059' => 'Virgin Islands'
  539. );
  540. }
  541. /**
  542. * Returns minimum and maximum latitude and longitude needed to create a bounding box.
  543. */
  544. function location_bounds_us() {
  545. return array(
  546. 'minlng' => -179.22745,
  547. 'minlat' => -56.5109,
  548. 'maxlng' => 158.80735,
  549. 'maxlat' => 71.399467,
  550. );
  551. }