2015-11-20 24 views
11

Diyelim ki, yollardan birini temsil eden ve biri kontur çizgisini temsil eden linestrings GeoDataFrames'i takip ediyorum. Bunları çizmek durumundaİki Çizginin Kesişimi Geopandalar

>>> import geopandas as gpd 
>>> import geopandas.tools 
>>> import shapely 
>>> from shapely.geometry import * 
>>> 
>>> r1=LineString([(-1,2),(3,2.5)]) 
>>> r2=LineString([(-1,4),(3,0)]) 
>>> Roads=gpd.GeoDataFrame(['Main St','Spruce St'],geometry=[r1,r2], columns=['Name']) 
>>> Roads 
     Name     geometry 
0 Main St LINESTRING (-1 2, 3 2.5) 
1 Spruce St LINESTRING (-1 4, 3 0) 
>>> 

>>> c1=LineString(Point(1,2).buffer(.5).exterior) 
>>> c2=LineString(Point(1,2).buffer(.75).exterior) 
>>> c3=LineString(Point(1,2).buffer(.9).exterior) 
>>> Contours=gpd.GeoDataFrame([100,90,80],geometry=[c1,c2,c3], columns=['Elevation']) 
>>> Contours 
    Elevation           geometry 
0  100 LINESTRING (1.5 2, 1.497592363336099 1.9509914... 
1   90 LINESTRING (1.75 2, 1.746388545004148 1.926487... 
2   80 LINESTRING (1.9 2, 1.895666254004977 1.9117845... 
>>> 

, onlar şuna benzer:

enter image description here

3 kontur çizgisi ve 2 yollar vardır. Her yoldaki her noktada yükselmeyi bulmak istiyorum. Temel olarak yolları ve konturları kesiştirmek istiyorum (ki bu bana 12 puan vermeli) ve her iki geodataframın özelliklerini (yol adı ve yükseklik) koru.

İki geodataframes birliklerinin bir kavşak kullanarak gibi 12 puan oluşturabilir:

Ancak
>>> Intersection=gpd.GeoDataFrame(geometry=list(Roads.unary_union.intersection(Contours.unary_union))) 
>>> Intersection 
             geometry 
0 POINT (0.1118644118110415 2.13898305147638) 
1 POINT (0.2674451642029509 2.158430645525369) 
2 POINT (0.72 2.636396103067893) 
3 POINT (0.4696699141100895 2.530330085889911) 
4 POINT (0.5385205980649126 2.192315074758114) 
5 POINT (0.6464466094067262 2.353553390593274) 
6 POINT (1.353553390593274 1.646446609406726) 
7 POINT (1.399321982208571 2.299915247776072) 
8  POINT (1.530330085889911 1.46966991411009) 
9 POINT (1.636396103067893 1.7) 
10 POINT (1.670759586114587 2.333844948264324) 
11 POINT (1.827239686607525 2.353404960825941) 
>>> 

, nasıl şimdi bu 12 puanlık her biri için yol adı ve yükseklik alabilirim? Uzamsal bir katılım beklediğim gibi davranmıyor ve yalnızca 4 puan döndürüyor (tüm 12, satır dosyaları ile tanımlanarak bu şekilde oluşturulduğundan dolayı).

>>> gpd.tools.sjoin(Intersection, Roads) 
             geometry index_right  Name 
2 POINT (0.72 2.636396103067893)   1 Spruce St 
3 POINT (0.4696699141100895 2.530330085889911)   1 Spruce St 
5 POINT (0.6464466094067262 2.353553390593274)   1 Spruce St 
6 POINT (1.353553390593274 1.646446609406726)   1 Spruce St 
>>> 

Bunu nasıl yapabileceğimize dair herhangi bir öneriniz var mı?

DÜZENLEME: Sorun, kesişim noktalarının nasıl oluşturulduğu ile ilgili olduğu anlaşılıyor. Yolları ve konturları çok az miktarda tamponluyorsam, kesişme beklendiği gibi çalışır. Aşağıya bakın:

>>> RoadsBuff=gpd.GeoDataFrame(Roads, geometry=Roads.buffer(.000005)) 
>>> ContoursBuff=gpd.GeoDataFrame(Contours, geometry=Contours.buffer(.000005)) 
>>> 
>>> Join1=gpd.tools.sjoin(Intersection, RoadsBuff).drop('index_right',1).sort_index() 
>>> Join2=gpd.tools.sjoin(Join1, ContoursBuff).drop('index_right',1).sort_index() 
>>> 
>>> Join2 
              geometry  Name Elevation 
0 POLYGON ((1.636395933642091 1.363596995290097,... Spruce St   80 
1 POLYGON ((1.530329916464109 1.469663012468079,... Spruce St   90 
2 POLYGON ((1.353553221167472 1.646439707764716,... Spruce St  100 
3 POLYGON ((0.5385239436706243 2.192310454047735... Main St  100 
4 POLYGON ((0.2674491823047923 2.158426108877007... Main St   90 
5 POLYGON ((0.1118688004427904 2.138978561144256... Main St   80 
6 POLYGON ((0.6464467873602107 2.353546141571978... Spruce St  100 
7 POLYGON ((0.4696700920635739 2.530322836868614... Spruce St   90 
8 POLYGON ((0.3636040748855915 2.636388854046597... Spruce St   80 
9 POLYGON ((1.399312865255344 2.299919147068011,... Main St  100 
10 POLYGON ((1.670752113626148 2.333849053114361,... Main St   90 
11 POLYGON ((1.827232214119086 2.353409065675979,... Main St   80 
>>> 

yukarıdaki Ben çizgilerinin kesişiminden oluşturulan noktaları kesişmesine onları almak için hatları tampon zorunda neden olarak emin değilim ancak istenilen çıkıştır.

cevap

5

unary_union ve intersection numaralı işlemlerin, GeoDataFrame içindeki geometrilerin üzerinde yapıldığı konusunda dikkat edin, böylece sütunların geri kalanında depolanan verileri kaybedersiniz. Bu durumda, veri çerçevelerindeki her bir geometriye erişerek bunu elle yapmanız gerektiğini düşünüyorum. Aşağıdaki kodu:

import geopandas as gpd 
from shapely.geometry import LineString, Point 

r1=LineString([(-1,2),(3,2.5)]) 
r2=LineString([(-1,4),(3,0)]) 
roads=gpd.GeoDataFrame(['Main St','Spruce St'],geometry=[r1,r2], columns=['Name']) 

c1=LineString(Point(1,2).buffer(.5).exterior) 
c2=LineString(Point(1,2).buffer(.75).exterior) 
c3=LineString(Point(1,2).buffer(.9).exterior) 
contours=gpd.GeoDataFrame([100,90,80],geometry=[c1,c2,c3], columns=['Elevation']) 

columns_data = [] 
geoms = [] 
for _, n, r in roads.itertuples(): 
    for _, el, c in contours.itertuples(): 
     intersect = r.intersection(c) 
     columns_data.append((n,el)) 
     geoms.append(intersect) 

all_intersection = gpd.GeoDataFrame(columns_data, geometry=geoms, 
        columns=['Name', 'Elevation']) 

print all_intersection 

üretir:

 Name Elevation           geometry 
0 Main St  100 (POINT (0.5385205980649125 2.192315074758114),... 
1 Main St   90 (POINT (0.2674451642029509 2.158430645525369),... 
2 Main St   80 (POINT (0.1118644118110415 2.13898305147638), ... 
3 Spruce St  100 (POINT (0.6464466094067262 2.353553390593274),... 
4 Spruce St   90 (POINT (0.4696699141100893 2.53033008588991), ... 
5 Spruce St   80 (POINT (0.7 2.636396103067893), ... 

Bildirimi her geometri iki puanı bulunan, sen noktası bilgilerle noktayı daha sonra istediğinizde erişebilir veya tanıtan her bir nokta için bir satır oluşturabilirsiniz döngü için bu puan üzerinden yinelenir gibi bir şey:

for p in intersect: 
    columns_data.append((n,el)) 
    geoms.append(p) 

Ama her kavşak çok geometriyi ürettiğini bilinmesine bağlı bu durumda.

sjoin işlevini kullanarak diğer yaklaşımınız hakkında, kullanıyorum geopandas sürümü kullanmıyor çünkü tools modülü sağlayın. Ne olduğunu görmek için buffer(0.0)'u eklemeye çalışın.

İlgili konular