получать граничащие штаты США (php) - PullRequest
3 голосов
/ 13 марта 2010

HI нужно иметь возможность выбрать состояние и получить список граничащих состояний. Кто-нибудь имеет или знает код, уже сделанный для этого?

Если мне придется написать это самому, что будет лучшим способом - возможно, база данных границ mysql (два столбца состояния для каждой строки), а затем выберите соответствие?

РЕДАКТИРОВАТЬ: вот начало - список границ: http://www.econ.umn.edu/~holmes/data/BORDLIST.html

Ответы [ 5 ]

6 голосов
/ 13 марта 2010
<?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";
1 голос
/ 13 марта 2010

Как и многие комбинаторные наборы данных, у этого есть компромисс между временем и пространством.

Если вы используете отношение A isNextTo B, у вас есть отношение, которое складывается по диагонали, т. Е. B также является NextTo A.

Следовательно, полное перечисление в два раза больше, чем должно быть.

Однако, если вы используете только половину отношения, вам придется искать его в обоих направлениях: A isNextTo X или X isNextTo A.

И сохранение этого в базе данных SQL снова удвоит объем хранилища, так как индекс, необходимый для поиска данных, будет иметь тот же размер, что и данные, так зачем беспокоиться?

PHP не имеет собственных b-деревьев, так что, возможно, класс btree на PhpClasses.org будет интересен, поэтому вам нужно только загрузить данные один раз.

0 голосов
/ 10 сентября 2011

Я отобразил все это в базе данных MySQL ( СКАЧАТЬ ЗДЕСЬ ). Он имеет лат и длинный, а также название штата и аббревиатуру.

Это будет пример того, как вы могли бы запросить использование этой таблицы для запроса по состоянию, сокращению и соседям:

#Find state by abbrev
SELECT * FROM states WHERE abbrev = "WA" LIMIT 1;

#Find state by name
SELECT * FROM states WHERE name = "Washington" LIMIT 1;

#Find neighboring states simple
SELECT * FROM states WHERE parent_id = 55;

#Find neighboring states expanded
SELECT * FROM states WHERE parent_id = (SELECT id FROM states WHERE `name` = "West Virginia" LIMIT 1);

* обратите внимание, что соседние данные, которые здесь использовались, были из данных массива из другого поста.

0 голосов
/ 17 марта 2010

Вам не нужно писать это самостоятельно. У Yahoo есть хороший геолокационный API, называемый WOEID, который не только записывает местоположения и общие геоданные, но также и отношения; http://developer.yahoo.com/geo/geoplanet/guide/concepts.html#relationships

0 голосов
/ 13 марта 2010

С предоставленным вами списком, я бы сказал, это уже довольно просто. Я бы преобразовал список в массив PHP так:

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

затем примитивный (но работоспособный) пример для функции запроса:

/**
 * @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;

 }
...