Подсчет элементов в пересечениях Shapely Polygons

13

У меня есть геопанда, GeoDataFrame содержащая сотни стройныхPolygon и MultiPolygonгеометрических фигур . Полигоны перекрываются во многих местах. Я хотел бы сделать новую геометрию, которая содержит подсчет того, сколько из них перекрывается. Что-то вроде этого:

Подсчет перекрытий

У кого-нибудь есть идеи, как к этому подойти? Я даже не вижу пути внутрь.

В конце концов, мне особенно хотелось бы иметь возможность взвешивать полигоны, чтобы некоторые полигоны могли стоить 2 самостоятельно. Делать это с shapelyZ-полем может быть неплохо.

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

kwinkunks
источник
Попробуйте этот пример . Вы можете разделить полигоны для каждого пересечения 1-к-1 и сосчитать каждый экземпляр, составить список в python для заполнения номером подсчета и затем таблицей атрибутов.
blu_sr
Хотя код не включен, но в этом ответе на SO описан алгоритм проверки того, находится ли один многоугольник целиком в другом. Я предполагаю, что если вы проверите хотя бы одно пересечение линий между отрезками, то это будет указывать на перекрывающиеся полигоны.
Стивей
Также, похоже, есть функция геопанда GeoSeries.intersects ; Интересно, работает ли это на полигонах.
Стивей
у вас есть возможность их растеризовать? если вы растеризуете их все, чтобы они были в многоугольниках, вы можете затем использовать numpy, чтобы сложить их вместе, и каждое число в результате будет указывать, сколько многоугольников перекрываются в этом пикселе.
user1269942

Ответы:

2

Может быть не по теме, потому что это решение postgresql / postgis:

В postgres / postgis это простой O (N ^ 2) запрос, который может / может быть принят в геопанду.

$ psql gis_se;
-- create the postgis extension  
create extension postgis;

-- create a polygon table 
create table test_overlap(id serial primary key);

-- Add the geometry
select addgeometrycolumn('public','test_overlap','geom',4326,'POLYGON',2);
insert into test_overlap(geom) values
(ST_GeomFromEWKT('SRID=4326;POLYGON((-2 -2, -2 -1,-1 -1,-1 -2, -2 -2))')),
(ST_GeomFromEWKT('SRID=4326;POLYGON((-2 -2, -2 0, 0 0, 0 -2, -2 -2))')),
(ST_GeomFromEWKT('SRID=4326;POLYGON((2 2, 2 0, 0 0, 0 2, 2 2))')),
(ST_GeomFromEWKT('SRID=4326;POLYGON((2 2, 2 1,1 1,1 2, 2 2))')),
(ST_GeomFromEWKT('SRID=4326;POLYGON((-1.5 -1.5, -1.5 1.5,1.5 1.5,1.5 -1.5, -1.5 -1.5))'));

и определяет 5 прямоугольников:

введите описание изображения здесь

Запрос на пересечение с самой таблицей:

select a.id, b.id, st_intersects(a.geom, b.geom) 
from test_overlap as a, test_overlap as b 
where a.id<>b.id; 

показывает, какие области пересекаются друг с другом:

 id | id | st_intersects 
----+----+---------------
  1 |  2 | t
  1 |  3 | f
  1 |  4 | f
  1 |  5 | t
  2 |  1 | t
  2 |  3 | t
  2 |  4 | f
  2 |  5 | t
  3 |  1 | f
  3 |  2 | t
  3 |  4 | t
  3 |  5 | t
  4 |  1 | f
  4 |  2 | f
  4 |  3 | t
  4 |  5 | t
  5 |  1 | t
  5 |  2 | t
  5 |  3 | t
  5 |  4 | t

Используя эту основу, вы можете агрегировать количество для каждого объекта ID через группу по clausel:

select id, count(id)                         
from (select 
       a.id as id, b.id as bid, 
       st_intersects(a.geom, b.geom) as intersects 
       from test_overlap as a, test_overlap as b where a.id<>b.id
) as i
where intersects
group by id
order by id;

Результат показывает нужный шаблон.

 id | count 
----+-------
  1 |     2
  2 |     3
  3 |     3
  4 |     2
  5 |     4
huckfinn
источник