2014-11-11 5 views
2

Проблема: У меня есть таблица с полигонами (районы страны). Некоторые из этих полигонов имеют определенный атрибут, который может или не может быть проверен. В этом случае атрибут называется «spread», а «проверенное» значение равно 1.Поиск соседних полигонов - запрос postgis

Теперь я хотел бы запустить запрос, который найдет все «проверенные» полигоны. Что-то вроде:

SELECT * FROM gemstat WHERE spread = 1 

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

Во-первых, давайте начнем с запроса, который выбирает все полигоны, которые являются соседями многоугольника с разбросом стоимости = 1

SELECT (b."GEM_NR") 
FROM gemstat_simple5 as a 
JOIN gemstat_simple5 as b 
ON ST_Touches((a.the_geom),b.the_geom) 
where a.spread =1; 

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

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

Update gemstat_simple5 gem set spread=1, time=2 
FROM (
    SELECT (b."GEM_NR") 
    FROM gemstat_simple5 as a, 
    gemstat_simple5 as b 
    WHERE ST_Touches(a.the_geom, b.the_geom) 
    AND a."GEM_NR" != b."GEM_NR" 
    AND a.spread = 1 
) as subquery 
WHERE gem."GEM_NR" = subquery."GEM_NR" 

Выполнить этот запрос и он будет установить атрибуты распространение 1 и время 2 смежных полигонов, не касаясь оригинальных полигонов с распространением = 1. Поэтому он представляет собой прекрасный ответ на мой вопрос.

ответ

2

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

Update gemstat_simple5 gem set spread=1, time=2 
    FROM (
    SELECT (b."GEM_NR") 
     FROM gemstat_simple5 as a, 
      gemstat_simple5 as b 
     WHERE ST_Touches(a.the_geom, b.the_geom) 
     AND a."GEM_NR" != b."GEM_NR" 
     AND a.spread = 1 
    ) as subquery 
WHERE gem."GEM_NR" = subquery."GEM_NR" 

Заметьте, я поставил и а. "GEM_NR" < б. "GEM_NR", который и позволяет избежать случай, когда и а. "GEM_NR" = Ь. "GEM_NR", то есть, само по себе, что вам хотят избегать, а также уменьшать пары мудрых сравнений наполовину. Я также использую подход a, b Where, а не соединение b на st_touches, что то же самое, но я нахожу более запутанным с пространственными объединениями. Наконец, вы просто приравниваете таблицу GEM_NR, которую вы обновляете, к тем, которые были найдены в подзапросе.

+0

Спасибо за хороший вход. Но это, похоже, не работает так, как мне бы хотелось. Я только что протестировал его, и он обновил примерно 2000 полигонов, когда на самом деле есть только 10 смежных полигонов. ... О, я только понял, что я тот, кто неправильно прочитал ваш комментарий. Сожалею. Может быть, это трудно объяснить. Предположим, что у меня есть много полигонов с определенным атрибутом (spread = 1). Теперь я хочу найти всех соседей из этих полигонов и установить их значения spread-значения в 1 (и время до 2). Достаточно ясно? – stopopol

+0

Итак, поместите spread = 1 в подзапрос. Ах, я вижу, что это сработало для вас, отлично. –

+0

Если вы хотите обновить свой исходный вопрос со всеми подробностями, как обновить касание соседа на основе атрибута, я его повышу. Это хороший вопрос. –

0

Прямой ответ

SELECT a.* 
FROM polygon1 as a 
JOIN polygon1 as b 
ON st_intersects((st_buffer(a.the_geom,0.00001)),b.the_geom) 
where b.id = 561334; 

Испытано в моей машине, и это также дает идентификатор, который вы даете в классе где. Мой полигон таблицы Spatial Reference - EPSG: 4326 ...

enter image description here

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