tags:

views:

97

answers:

4

HI need to be able to select a state and be given a list of the bordering states. Does anyone have or know of code already done for this?

If I have to write it myself, what would be the best way - possibly a mysql database of borders (two state columns for each row), and then select matching?

EDIT: here's a start - list of borders: http://www.econ.umn.edu/~holmes/data/BORDLIST.html

A: 

With the list you provide, I would say it's already pretty easy. I would convert the list into a PHP array like so:

$borders = 
 array("AL-FL",
       "AL-GA",
 ...
 );

then, a primitive (but workable) example for a querying function:

/**
 * @desc Returns an array with the bordering states for a state. 
 * @param string the 2-letter code of the state. Case insensitive. Example: AK
 * @param array the list of borders.
 * @return an array with the 2-letter codes of all neighboring states.
 */

function getBorderingStates($state, $borders)
 {
   $neighbors = array(); 
   $state = strtolower($state);

   foreach ($borders as $border)
    {
      $pair = explode("-", $border)
      if (strtolower($pair[0]) == $state) 
        array_push($neighbors, $pair[1]);

      if (strtolower($pair[1]) == $state) 
        array_push($neighbors, $pair[0]);

     }
     return $neighbors;

 }
Pekka
+5  A: 
<?php
$borders = array (
  'AL' => 
  array (
    0 => 'FL',
    1 => 'GA',
    2 => 'MS',
    3 => 'TN',
  ),
  'FL' => 
  array (
    0 => 'AL',
    1 => 'GA',
  ),
  'GA' => 
  array (
    0 => 'AL',
    1 => 'FL',
    2 => 'NC',
    3 => 'SC',
    4 => 'TN',
  ),
  'MS' => 
  array (
    0 => 'AL',
    1 => 'AR',
    2 => 'LA',
    3 => 'TN',
  ),
  'TN' => 
  array (
    0 => 'AL',
    1 => 'AR',
    2 => 'GA',
    3 => 'KY',
    4 => 'MO',
    5 => 'MS',
    6 => 'NC',
    7 => 'VA',
  ),
  'AR' => 
  array (
    0 => 'LA',
    1 => 'MO',
    2 => 'MS',
    3 => 'OK',
    4 => 'TN',
    5 => 'TX',
  ),
  'LA' => 
  array (
    0 => 'AR',
    1 => 'MS',
    2 => 'TX',
  ),
  'MO' => 
  array (
    0 => 'AR',
    1 => 'IA',
    2 => 'IL',
    3 => 'KS',
    4 => 'KY',
    5 => 'NE',
    6 => 'OK',
    7 => 'TN',
  ),
  'OK' => 
  array (
    0 => 'AR',
    1 => 'CO',
    2 => 'KS',
    3 => 'MO',
    4 => 'NM',
    5 => 'TX',
  ),
  'TX' => 
  array (
    0 => 'AR',
    1 => 'LA',
    2 => 'NM',
    3 => 'OK',
  ),
  'AZ' => 
  array (
    0 => 'CA',
    1 => 'CO',
    2 => 'NM',
    3 => 'NV',
    4 => 'UT',
  ),
  'CA' => 
  array (
    0 => 'AZ',
    1 => 'NV',
    2 => 'OR',
  ),
  'CO' => 
  array (
    0 => 'AZ',
    1 => 'KS',
    2 => 'NE',
    3 => 'NM',
    4 => 'OK',
    5 => 'UT',
    6 => 'WY',
  ),
  'NM' => 
  array (
    0 => 'AZ',
    1 => 'CO',
    2 => 'OK',
    3 => 'TX',
    4 => 'UT',
  ),
  'NV' => 
  array (
    0 => 'AZ',
    1 => 'CA',
    2 => 'ID',
    3 => 'OR',
    4 => 'UT',
  ),
  'UT' => 
  array (
    0 => 'AZ',
    1 => 'CO',
    2 => 'ID',
    3 => 'NM',
    4 => 'NV',
    5 => 'WY',
  ),
  'OR' => 
  array (
    0 => 'CA',
    1 => 'ID',
    2 => 'NV',
    3 => 'WA',
  ),
  'KS' => 
  array (
    0 => 'CO',
    1 => 'MO',
    2 => 'NE',
    3 => 'OK',
  ),
  'NE' => 
  array (
    0 => 'CO',
    1 => 'IA',
    2 => 'KS',
    3 => 'MO',
    4 => 'SD',
    5 => 'WY',
  ),
  'WY' => 
  array (
    0 => 'CO',
    1 => 'ID',
    2 => 'MT',
    3 => 'NE',
    4 => 'SD',
    5 => 'UT',
  ),
  'CT' => 
  array (
    0 => 'MA',
    1 => 'NY',
    2 => 'RI',
  ),
  'MA' => 
  array (
    0 => 'CT',
    1 => 'NH',
    2 => 'NY',
    3 => 'RI',
    4 => 'VT',
  ),
  'NY' => 
  array (
    0 => 'CT',
    1 => 'MA',
    2 => 'NJ',
    3 => 'PA',
    4 => 'VT',
  ),
  'RI' => 
  array (
    0 => 'CT',
    1 => 'MA',
  ),
  'DC' => 
  array (
    0 => 'MD',
    1 => 'VA',
  ),
  'MD' => 
  array (
    0 => 'DC',
    1 => 'DE',
    2 => 'PA',
    3 => 'VA',
    4 => 'WV',
  ),
  'VA' => 
  array (
    0 => 'DC',
    1 => 'KY',
    2 => 'MD',
    3 => 'NC',
    4 => 'TN',
    5 => 'WV',
  ),
  'DE' => 
  array (
    0 => 'MD',
    1 => 'NJ',
    2 => 'PA',
  ),
  'NJ' => 
  array (
    0 => 'DE',
    1 => 'NY',
    2 => 'PA',
  ),
  'PA' => 
  array (
    0 => 'DE',
    1 => 'MD',
    2 => 'NJ',
    3 => 'NY',
    4 => 'OH',
    5 => 'WV',
  ),
  'NC' => 
  array (
    0 => 'GA',
    1 => 'SC',
    2 => 'TN',
    3 => 'VA',
  ),
  'SC' => 
  array (
    0 => 'GA',
    1 => 'NC',
  ),
  'IA' => 
  array (
    0 => 'MN',
    1 => 'MO',
    2 => 'NE',
    3 => 'SD',
    4 => 'WI',
    5 => 'IL',
  ),
  'MN' => 
  array (
    0 => 'IA',
    1 => 'ND',
    2 => 'SD',
    3 => 'WI',
  ),
  'SD' => 
  array (
    0 => 'IA',
    1 => 'MN',
    2 => 'MT',
    3 => 'ND',
    4 => 'NE',
    5 => 'WY',
  ),
  'WI' => 
  array (
    0 => 'IA',
    1 => 'IL',
    2 => 'MI',
    3 => 'MN',
  ),
  'ID' => 
  array (
    0 => 'MT',
    1 => 'NV',
    2 => 'OR',
    3 => 'UT',
    4 => 'WA',
    5 => 'WY',
  ),
  'MT' => 
  array (
    0 => 'ID',
    1 => 'ND',
    2 => 'SD',
    3 => 'WY',
  ),
  'WA' => 
  array (
    0 => 'ID',
    1 => 'OR',
  ),
  'IL' => 
  array (
    0 => 'IA',
    1 => 'IN',
    2 => 'KY',
    3 => 'MO',
    4 => 'WI',
  ),
  'IN' => 
  array (
    0 => 'IL',
    1 => 'KY',
    2 => 'MI',
    3 => 'OH',
  ),
  'KY' => 
  array (
    0 => 'IL',
    1 => 'IN',
    2 => 'MO',
    3 => 'OH',
    4 => 'TN',
    5 => 'VA',
    6 => 'WV',
  ),
  'MI' => 
  array (
    0 => 'IN',
    1 => 'OH',
    2 => 'WI',
  ),
  'OH' => 
  array (
    0 => 'IN',
    1 => 'KY',
    2 => 'MI',
    3 => 'PA',
    4 => 'WV',
  ),
  'WV' => 
  array (
    0 => 'KY',
    1 => 'MD',
    2 => 'OH',
    3 => 'PA',
    4 => 'VA',
  ),
  'NH' => 
  array (
    0 => 'MA',
    1 => 'ME',
    2 => 'VT',
  ),
  'VT' => 
  array (
    0 => 'MA',
    1 => 'NH',
    2 => 'NY',
  ),
  'ME' => 
  array (
    0 => 'NH',
  ),
  'ND' => 
  array (
    0 => 'MN',
    1 => 'MT',
    2 => 'SD',
  ),
);

echo "Illinois borders: \n";
foreach ($borders['IL'] as $s)
  echo "\t$s\n";
konforce
A: 

Like many combinatorial data sets, this one has a time/space trade off.

If you use the A isNextTo B relation, you have a relation that folds on the diagonal, ie, B is also NextTo A.

Hence the full enumeration is twice as big as it needs to be.

However, if you use only half of the relation you will have to search it both ways: A isNextTo X or X isNextTo A.

And keeping this in an SQL database will double the storage again as the index needed to search the data will be the same size as the data, so why bother?

PHP doesn't have native b-trees so perhaps PhpClasses.org's btree class would be of interest so you only have to have the data loaded once.

Don
A: 

You dont have to write it yourself. Yahoo has a nice geolocation api called WOEID that not only records locations and general Geo-data, but relationships aswell; http://developer.yahoo.com/geo/geoplanet/guide/concepts.html#relationships

Andrew Bolster