SQL Server 2008+: лучший метод для обнаружения перекрытия двух полигонов? - PullRequest
2 голосов
/ 10 января 2012

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

Мне пришло в голову, что было бы гораздо приятнеепреобразуйте эти точечные массивы в объекты многоугольника / полилинии в базе данных и используйте sql, чтобы получить переменную погоды, в которой они перекрываются или нет.

Я видел разные методы, предложенные для этого, но ни один из приведенных примеров не-line с моими потребностями.

Я был бы очень рад получить от тех, кто достаточно любезен, чтобы предложить свой опыт.

Дополнительно:

В ответ на вопросы: Этодействительно 2D.и да, любой кроссовер из двух считается верным.Полигоны имеют n точек и могут быть вогнутыми.Многоугольники будут сохраняться как 1 на строку (после задачи преобразования данных) как многоугольники (то есть тип многоугольника .. это можно назвать чем-то еще пространственным / geom, моя память сейчас не на моей стороне)

Ответы [ 3 ]

2 голосов
/ 14 июня 2012

Вы можете использовать .STIntersection с .STAsText () для проверки перекрывающихся полигонов.(Я действительно ненавижу терминологию, которую использует Microsoft (или тот, кто устанавливает стандартные термины). «Касание», по моему мнению, должно быть проверкой того, пересекаются ли две фигуры геометрии / географии вообще, а не просто разделяют границу.)

В любом случае ....

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

SELECT CT.ID AS CTID, CT.[Geom] AS CensusTractGeom
FROM CensusTracts CT
WHERE CT.[Geom].STIntersection(@RadiusGeom).STAsText() <> 'GEOMETRYCOLLECTION EMPTY'

Если ваше поле геометрии пространственно проиндексировано, это выполняется довольно быстро.Я запустил это на 66 000 записей КТ США примерно за 3 секунды.Может быть, есть и лучший способ, но, поскольку никто не получил ответа, это была моя попытка найти для вас ответ.Надеюсь, это поможет!

1 голос
/ 10 января 2012

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

MSSQL поддерживает интеграцию с CLR начиная с версии 2005. Это означает, что вы можете определить свой собственный тип данных в сборке, зарегистрировать сборку в MSSQL, и с этого момента MSSQL будет принимать ваш пользовательский тип данных как допустимый тип для столбца, и он будет вызывать вашу сборку для выполнения операций с вашим пользовательским типом данных.

Пример статьи для этого метода в CodeProject: Создание пользовательских типов данных в SQL Server 2005

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

1 голос
/ 10 января 2012

Рассчитайте и сохраните ограничительный прямоугольник каждого многоугольника в наборе новых полей в строке, связанной с этим многоугольником. (Я предполагаю, что у вас есть один; если нет, создайте его.) Когда ваше приложение dotnet имеет многоугольник и ищет перекрывающиеся многоугольники, оно может извлечь из базы данных только те многоугольники, чьи ограничивающие прямоугольники перекрываются, используя относительно простой оператор SQL SELECT. Таких полигонов должно быть относительно немного, поэтому это будет эффективно. Затем ваше приложение dotnet может выполнить более точные вычисления перекрытия полигонов, чтобы определить, какие из них действительно перекрываются.

...