Zählen von Features in Schnittpunkte von Shapely Polygons


13

Ich habe ein Geopanda GeoDataFrame mit Hunderten von Formen Polygonund MultiPolygonGeometrien. Die Polygone überlappen sich an vielen Stellen. Ich möchte eine neue Geometrie erstellen, die angibt, wie viele sich überlappen. Etwas wie das:

Überlappungen zählen

Hat jemand Ideen, wie man das angeht? Ich kann nicht mal einen Weg hinein sehen.

Schließlich möchte ich besonders die Polygone gewichten können, damit einige Polygone für sich genommen 2 wert sind. Dies mit shapelydem Z-Feld von zu tun, könnte nett sein.

Übrigens: Ich bin an keine dieser Bibliotheken besonders gebunden, ich bin nur dort gelandet, wo ich gelandet bin. Die Koordinaten in diesen Geometrien sind eigentlich Pixelkoordinaten - ich stolpere dahin, ein Raster zu erstellen, um ein anderes Bild zu überlagern. Ich würde es vorziehen, meinen Footprint so klein wie möglich zu halten, da ich dieses Zeug auf Cloud-Servern usw. bereitstellen möchte, auf denen ich möglicherweise keine zufälligen Sachen installieren kann.


Probieren Sie dieses Beispiel aus . Sie können die Polygone für jede 1-zu-1-Schnittmenge aufteilen und jede Instanz zählen, eine Liste in Python erstellen, um sie mit der Zählnummer und dann mit der Attributtabelle zu füllen.
blu_sr

Es ist zwar kein Code enthalten, aber diese Antwort auf SO beschreibt einen Algorithmus zum Überprüfen, ob sich ein Polygon vollständig innerhalb eines anderen befindet. Ich gehe davon aus, dass, wenn Sie mindestens einen Linienschnittpunkt zwischen Liniensegmenten suchen, dies auf überlappende Polygone hindeutet.
Stevej

Außerdem scheint es eine Geopandas-Funktion zu geben, GeoSeries.intersects ; Ich frage mich, ob es bei Polygonen funktioniert.
Stevej

Können Sie sie rastern? Wenn Sie sie alle rastern, um sie in den Polygonen zu haben, können Sie sie mit numpy addieren. Jede Zahl im Ergebnis gibt an, wie viele Polygone sich an diesem Pixel überlappen.
user1269942

Antworten:


2

Kann vom Thema abweichen, da es sich um eine postgresql / postgis-Lösung handelt:

In postgres / postgis handelt es sich um eine einfache O (N ^ 2) -Abfrage, die auf Geopanda angewendet werden kann / könnte.

$ 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))'));

und definiert 5 Rechtecke:

Bildbeschreibung hier eingeben

Die Schnittmenge mit der Tabelle selbst:

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; 

zeigt, welche Bereiche sich überschneiden:

 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

Auf dieser Basis können Sie die Anzahl für jedes ID-Objekt über die Gruppe nach Clausel aggregieren:

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;

Das Ergebnis zeigt das gewünschte Muster.

 id | count 
----+-------
  1 |     2
  2 |     3
  3 |     3
  4 |     2
  5 |     4
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.