SQL Server 2008 - использование STIntersects из таблицы, определяющей страну - PullRequest
1 голос
/ 13 марта 2011

У меня есть таблица, где каждая строка является частью карты Новой Зеландии. То, что я действительно хочу знать, это точка на карте (то есть данные о стране) или она в воде.

Я понимаю, как работает StIntersects, но все примеры приведены для одного Polygon или LineString, но у меня есть таблица LineStrings - 130 строк, которые определяют границу страны.

Много таких строк

LINESTRING (6252032.7308424888 -3161950.9615992079, 6252033.7275789445 -3161929.3581238855, 6252011.5227283547 -3161906.1086780191, 6251992.0438580718 -3161880.6299652755)

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

Может ли кто-нибудь дать мне пример того, как я мог это сделать?

Первоначальные данные были получены от ShapeFile от www.koordinates.com, называемой береговой линией Новой Зеландии. Затем я использовал Shape2Sql для импорта в SQL Server с использованием геометрии Planer.

Геометрия (сферическая) в Shape2File говорит: «Проекты данных или экстент находятся за пределами того, что поддерживается типом SqlGeography)

Надеюсь, я предоставил достаточно информации?

Ура Крис

Ответы [ 3 ]

1 голос
/ 11 апреля 2013

Скорее всего, вы отошли от этого, но я публикую для дальнейшего использования.

Если я вас правильно понимаю, вам нужно создать один многоугольник из таблицы LINESTRING, которая составляет границу многоугольника?

Сначала объедините все LINESTRING в вашей таблице в одну геометрию следующим образом:

DECLARE @g geometry

SELECT TOP 1 @g = geom from #geom_tmp

SELECT
     @g = @g.STUnion(geom)
FROM
    #geom_tmp

SELECT @g

Затем вы хотите создать многоугольник из вашей однолинейной границы.Есть только две вещи, которые отличаются между вашей однострочной границей и полигоном, во-первых, мы заменим «LINESTRING» на «POLYGON».Затем мы добавляем набор скобок, так как строка WKT многоугольника разделяет несколько многоугольников с круглыми скобками, например:

DECLARE @str NVARCHAR(max)
SET @str = REPLACE(REPLACE(@g.STAsText(),'(','((') + ')','LINESTRING','POLYGON')

SET @g = GEOMETRY::STGeomFromText(@str,0)

SELECT @g

, что даст вам ваш полигон страны.

Тогда вы просто увидите, еслиВаша точка пересекает многоугольник (@p - это геометрия точки):

SELECT @p.STIntersects(@g)

-- OUTPUT is 1 if it intersects and 0 if it does not.

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

SELECT *
FROM point_table
WHERE point.STIntersects(@g) = 1

Поскольку многие из нас не могут перейти на SQL Server 2012 в ближайшее время, это очень удобно.Надеюсь, это поможет.

0 голосов
/ 27 апреля 2011

Дайте мне посмотреть, понимаю ли я вашу проблему.

Вы хотите определить, является ли предопределенная точка INSIDE NZ или OUTSIDE.Теперь у вас есть побережье Новой Зеландии, верно?Эта береговая линия составляет около 130 рядов ... но нам нужно сделать этот единственный ряд ... и ТОГДА посмотреть, находится ли точка внутри этой границы или снаружи.

Если это правильно, то первое, что вы 'Вам нужно будет объединить все строки в один массивный многоугольник ... и нам нужен этот последний ряд в виде Sql Server 2008 GEOGRAPHY type.

Итак, сначала некоторая помощь.Перейдите к Codeplex и захватите эту библиотеку - sql пространственные инструменты .В этой библиотеке есть метод для присоединения всех строк строк.Я думаю, что это называется GeographyUnionAggregate .Выясните, как запустить этот сохраненный процесс, который объединит все строки строк (при условии, что ни одна из них не перепутана).

После выполнения этой задачи у вас будет одна строка GEOGRAPHY, которая повторяет всюбереговая линия Новой Зеландии.

Теперь, это простая инструкция sql, чтобы увидеть, существует ли точка / пересекает границу (страна Новой Зеландии) или нет: -

DECLARE @SomePoint GEOGRAPHY
SET @SomePoint = geography::STGeomFromText('POINT(-122.358 47.653)', 4326);
SELECT CountryId, Name
FROM Countries a
    INNER JOIN a.AdministrativeBoundary.STIntersects(@SomePoint) = 1

И это должно вернутьу вас один результат :) 1020 *

0 голосов
/ 14 марта 2011

Классический подход к определению того, находятся ли две точки на одной стороне (внутри или снаружи) многоугольника, заключается в вычислении количества пересечений между линией, соединяющей эти две точки, и границами многоугольника. Четное число (включая 0) - это одна и та же сторона, нечетное - это разные стороны.

Итак, определите одну (любую) точку, которая точно находится внутри Новой Зеландии (предпочтительно около геометрической середины), затем линию, которая соединяет ее с точкой, которую вы хотите проверить, и затем рассчитайте количество линий, которые она пересекает. Если это 0 или даже, другая точка находится на той же стороне (то есть в Новой Зеландии). Если это нечетно, точка находится за пределами страны. Вам не нужно беспокоиться о порядке или соединении границ.

Становится сложнее, если линия проходит точно через точку соединения между двумя линиями границы, но StIntersects не спасет вас от этого, и, кроме того, если вы работаете с реальными значениями с 17 значимыми точками, вероятность того, что это произойдет минимально.

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

Конечно, чтобы это работало, вам нужно преобразовать линейные строки в набор из одиночных линий и сохранить их, потому что вам нужно найти количество пересечений, а не просто факт: линия пересекает многоугольник (n раз) против 0 раз .

...