2012-01-10 3 views
2

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

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

Я видел различные методы, предлагаемые для этого, но не из приведенных примеров были вполне соответствующими моим потребностям.

Я был бы очень рад получить помощь от такого рода, чтобы предложить свой опыт.

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

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

+1

Не могли бы вы более подробно остановиться на хранении многоугольников? * (3 точки на полигон, или 'n' точек на полигон? Одна строка на точку или одна строка на полигон?) * Определение таблицы с примерными данными было бы замечательным. – MatBailie

+0

О, и если один многоугольник полностью внутри другого, я предполагаю, что вы считаете, что это перекрытие? – MatBailie

+0

вопрос обновлен - спасибо – Nick

ответ

2

Вы можете использовать .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 секунды. Там может быть лучший способ, но поскольку никто другой не ответил, это была моя попытка ответить за вас. Надеюсь, поможет!

+0

Спасибо Джейсону это замечательно: o) – Nick

1

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

+0

Описание предполагает только два измерения, но может быть экстраполировано на три ... – MatBailie

+0

ОП содержит слово «Полилиния», которое намекает на 2-мерную, а не на 3-мерную. Нет? –

+0

'база данных, полная полигонов',' конвертировать эти точечные массивы в объекты полигона/полилинии'. И даже Линия может существовать в трехмерном пространстве. – MatBailie

1

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

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

Пример статьи по этой методике на CodeProject: Creating User-Defined Data Types in SQL Server 2005

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

Смежные вопросы