Создание набора данных для возможной интеграции в MySQL и Google Maps API для веб-сайта? (а-ля точка в многоугольнике, теорема о столкновении и т. д.)

За последние несколько месяцев мне удалось выучить PHP, PDO и SQL, и я создал базовый динамический веб-сайт с функциями регистрации пользователей/активации электронной почты/и выхода из системы, следуя рекомендациям PHP/SQL. Теперь я застрял на следующем задании...

Я создал огромный набор данных квадратов/многоугольников (более 3 миллионов), каждая 1 минута широты и долготы в размере, сохраненный в массиве PHP с одним набором координат (верхний левый угол). Чтобы экстраполировать квадратную форму, я просто добавляю 0,016 градуса (~ 1 минуту) в каждое направление и генерирую остальные 3 координаты.

Теперь мне нужно проверить, что каждый многоугольник в указанном массиве находится по крайней мере над какой-то частью земли в Соединенных Штатах .... то есть, если бы кто-то мог создать графический вывод моего завершенного набора данных и взглянуть на береговую линию Сан-Франциско. , они увидят что-то вроде этого.

Это похоже на проблему «точка в многоугольнике», за исключением того, что вместо точки речь идет о другом многоугольнике, другой многоугольник является границей страны, и я не просто смотрю на пересечения. Я хочу проверить, если:

  • Многоугольник/квадрат пересекается с многоугольником. (Подумайте о береговой линии / границе).
  • Многоугольник/квадрат находится внутри многоугольника. (Вспомните континентальную часть США).
  • Многоугольник/квадрат содержит часть многоугольника. (Думаю маленький остров).

Это иллюстрируется моим грубо нарисованным изображением:

Это непросто!

Если он соответствует любому из этих трех условий, я хочу сохранить квадрат. Если он никак не взаимодействует с большим полигоном (т. е. находится над водой), сбросьте его.

Я думал, что большой многоугольник будет шейп-файлом США или файлом KML, из которого я мог бы вырезать координаты, чтобы создать очень сложный многоугольник.

Затем я подумал, что передам эти совпадающие квадраты и идентификаторы квадратов через в файл csv для интеграции в таблицу MySQL, содержащую набор координат каждого квадрата (на самом деле, я даже не уверен из лучших практик по работе с таблицами такого размера в MySQL, но я вернусь к этому, когда это будет необходимо). Конечная цель тогда будет заключаться в разработке карты с использованием Google Maps API через Javascript для отображения этих квадратов на карте на веб-сайте, который я кодирую (очевидно, показывая только квадраты в пределах точки обзора, чтобы убедиться, что я не облагаю налогом свою базу данных до смерти ). Я почти уверен, что мне придется сначала передать такую ​​​​информацию через PHP. Но все это кажется относительно простым по сравнению с задачей создания указанного набора данных.

Очевидно, что это невозможно сделать вручную, поэтому требуется автоматизация. Я немного знаю Python, так что это поможет? Любые другие советы о том, с чего начать? Кто-то готов написать код для меня?


person ReactingToAngularVues    schedule 20.02.2013    source источник
comment
Квадрат в какой проекции? Меркатор? Обратите внимание, что равные квадраты в проекции Меркатора имеют разный размер на разных широтах. И обратите внимание, что в географической проекции у вас будет разное количество квадратов на каждой широте. Кроме того, рассмотрите возможность сохранения координат только одного угла. Вы можете вычислить другие по мере необходимости.   -  person Olexa    schedule 20.02.2013
comment
Вероятно, Меркатор, я полагаю, что это то, что закодировано в Google Maps. Хорошее замечание о координатах ... но как я могу сгенерировать многоугольники в первую очередь?   -  person ReactingToAngularVues    schedule 20.02.2013
comment
Google использует «особую» странную проекцию, похожую на проекцию Меркатора: alastaira.wordpress.com/2011/01/23/   -  person Olexa    schedule 20.02.2013
comment
Прямоугольник пересекает многоугольник, если любая точка многоугольника находится внутри прямоугольника или если любой угол прямоугольника находится внутри многоугольника. См. это, чтобы проверить, находится ли точка внутри многоугольника: ">stackoverflow.com/questions/217578/. Проверить, находится ли точка внутри прямоугольника, конечно, намного проще (просто сравнить координаты).   -  person Olexa    schedule 22.02.2013
comment
Вы можете показать нам, что у вас есть до сих пор? как в формате данных у вас уже есть? квадраты в одном массиве и многоугольники в другом? так далее   -  person lollercoaster    schedule 01.03.2013
comment
Пока мне особо нечего делать. У меня есть массив PHP, который имеет единственные верхние левые координаты для каждой квадратной минуты. Это в макете: Array => (0 => (0 => latCoords 1 => longCoords), 1 => (0 => latCoords 1=> longCoords)) и т. д. Я просмотрел несколько шейп-файлов/файлов разметки замочной скважины, и ни один из них, похоже, не имеет нужного мне разрешения и слишком зубчатый, если смотреть вблизи.   -  person ReactingToAngularVues    schedule 01.03.2013
comment
Я не особо разбираюсь в специфике этой проблемы (структуры данных и т.д.), но мне интересно, не будет ли проще проверить, нет ли в квадрате ничего, чем проверять все случаи того, как многоугольник может быть частично в квадрате. Я действительно не думал об этом подробно, но я чувствую, что этот подход может уменьшить сложность задачи (по крайней мере, в вашем уме :-P)   -  person kutschkem    schedule 01.03.2013


Ответы (2)


Вот решение, которое будет эффективным и максимально простым в реализации. Заметьте, я говорю не просто, а максимально просто. Это сложная проблема, как оказалось.

1) Получите данные полигонов США с помощью шейп-файлов или KFL, которые дадут набор форм полигонов (сухопутных массивов), каждый из которых определяется списком вершин.

2) Создайте набор прямоугольников ограничивающей рамки с выравниванием по оси (AABB) для Соединенных Штатов: по одному для Аляски и каждого острова Аляски, по одному для каждого Гавайского острова, по одному для континентальной части Соединенных Штатов и по одному для каждого маленького острова у побережья США. континентальная часть США (например, остров Болд-Хед в Северной Каролине, Каталина у побережья Калифорнии). Каждая ограничивающая рамка определяется как прямоугольник с углами, которые являются минимальной и максимальной широтой и долготой для формы. Я предполагаю, что их будет несколько сотен. Например, для большого острова Гавайи широта простирается от 18°55′ северной широты до 28°27′ северной широты, а долгота — от 154°48′ западной долготы до 178°22′ западной долготы. Большинство ваших глобальных пар широта/долгота отбрасываются на этом шаге, так как они не находятся ни в одной из этих нескольких сотен ограничительных рамок. Например, ваша ограничительная рамка на 10°20'з.д., 30°40'с.ш. (место в Атлантическом океане недалеко от Лас-Пальмаса, Африка) не перекрывает Гавайи, потому что 10°20'з.д. меньше, чем 154°48'з.д. . Этот бит было бы легко закодировать на Python.

3) Если пара широта/долгота ДЕЙСТВИТЕЛЬНО перекрывает один из нескольких сотен прямоугольников AABB, вам необходимо проверить ее на одном полигоне внутри прямоугольника AABB. Для этого настоятельно рекомендуется использовать разность Минковского (MD). Сначала внимательно просмотрите этот веб-сайт:

http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/

В частности, взгляните на демо "poly vs poly" в середине страницы и немного поиграйте с ним. Когда вы это сделаете, вы увидите, что когда вы берете MD двух фигур, если эта MD содержит начало координат, то две формы перекрываются. Итак, все, что вам нужно сделать, это взять разность Минковского двух полигонов, которая сама по себе дает новый полигон (B - A, в демонстрации), а затем посмотреть, содержит ли этот полигон начало координат.

4) В Интернете есть много статей об алгоритмах реализации MD, но я не знаю, сможете ли вы прочитать статью и перевести ее в код. Поскольку вычислить MD двух многоугольников (прямоугольник широты/долготы, который вы тестируете, и многоугольник, содержащийся в ограничивающей рамке, которая перекрывает прямоугольник широты/долготы) сложно с помощью векторной математики, и вы сказали нам, что ваш опыт уровень еще не высок, я бы предложил использовать библиотеку, которая уже реализует MD, или, что еще лучше, реализует обнаружение коллизий.

Например:

http://physics2d.com/content/gjk-algorithm

Здесь вы можете увидеть соответствующий псевдокод, который вы можете портировать на Python:

if aO cross ac > 0 //if O is to the right of ac
    if aO dot ac > 0 //if O is ahead of the point a on the line ac
        simplex = [a, c]
        d =-((ac.unit() dot aO) * ac + a)
    else // O is behind a on the line ac
        simplex = [a]
        d = aO
else if ab cross aO > 0 //if O is to the left of ab
    if ab dot aO > 0 //if O is ahead of the point a on the line ab
        simplex = [a, b]
        d =-((ab.unit() dot aO) * ab + a)
    else // O is behind a on the line ab
        simplex = [a]
        d = aO
else // O if both to the right of ac and to the left of ab
    return true //we intersect!

Если вы не можете портировать это самостоятельно, возможно, вы могли бы связаться с одним из авторов двух ссылок, которые я включил здесь - они оба реализовали алгоритм MD во Flash, возможно, вы могли бы лицензировать исходный код.

5) Наконец, предполагая, что вы обработали обнаружение коллизий, вы можете просто сохранить в базе данных логическое значение, указывающее, является ли пара широта/долгота частью Соединенных Штатов. Как только это будет сделано, я не сомневаюсь, что вы сможете делать все, что хотите, со своей частью Google Maps.

Итак, подводя итог, единственной сложной частью здесь является либо 1) реализация алгоритма обнаружения столкновений GJK, либо, альтернативно, 2) написание алгоритма, который сначала вычислит разницу Минковского между вашей парой широта/долгота и многоугольником земли, содержащимся внутри ваш AABB, а затем, во-вторых, посмотрите, содержит ли этот многоугольник MD начало координат. Если вы используете этот подход, Ray Casting (типичное решение «точка в полигоне») сделает свое дело со второй частью.

Я надеюсь, что это даст вам начало в правильном направлении!

person J.T. Taylor    schedule 01.03.2013
comment
Спасибо... вы разделили проблему на несколько шагов! Я думаю, что мне нужно прочитать много математики, а затем, как правильно кодировать, это другое дело, поэтому я могу попытаться связаться с некоторыми авторами ресурсов, на которые вы ссылались, как вы сказали. Спасибо еще раз! - person ReactingToAngularVues; 02.03.2013
comment
Круто, рада, что вам было полезно! После того, как вы закодируете алгоритм MD или GJK, вы можете подумать о том, чтобы разместить его на GitHub, так как это будет чрезвычайно полезный фрагмент кода, который, как мне кажется, в настоящее время не существует в сообществе с открытым исходным кодом. Ты мог бы стать настоящим героем, если бы сделал это! - person J.T. Taylor; 02.03.2013

Я думаю, что этот другой вопрос отвечает на большую часть того, что вы пытаетесь сделать.

Как определить, пересекаются ли два выпуклых многоугольника?

Другая часть заключается в том, что если вы используете базу данных, я бы загрузил все полигоны рядом с вашей точкой обзора из обоих наборов (набор полигонов карты и набор других сгенерированных вами полигонов), а затем запустил вышеуказанный алгоритм на этом меньшем набор полигонов, и вы можете создать список всех полигонов в вашем наборе, которые должны быть наложены на карту.

person Daniel Williams    schedule 01.03.2013
comment
объедините это с методом поиска выпуклого ограничивающего многоугольника, и у вас будет приблизительное решение (я сомневаюсь, что суша в США выпуклая :-P) - person kutschkem; 01.03.2013