2015-11-20 27 views
11

線ストリングのGeoDataFramesには次のようなものがあります。そのうちの1つは道路を表し、1つは等高線を表します。2つの線ストリングの交差ジオパンダ

>>> 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... 
>>> 

私はこれらをプロットした場合、彼らは次のようになります。

enter image description here

3等高線と2本の道路があります。私は各道に沿って各地点で標高を探したい。基本的に私は道路と輪郭(12ポイントを与えるはずです)を交差させ、両方のジオデータフレーム(道路名と標高)から属性を保持したいと思います。

私は2つのgeodataframesの労働組合の交差点を使用することによってなど12点を生成することができます

>>> 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) 
>>> 

をしかし、どのように私は今、それらの12点のそれぞれについて、道路名と標高を得るのですか?空間結合は、私が期待しているようには動作せず、4ポイントしか返しません(定義によってそのように作成されたので、すべて12行ファイルと交差する必要があります)。

>>> 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 
>>> 

どのように私はこれを行うことができますか?

編集: この問題は交点の作成方法と関係があるようです。道路や等高線をごくわずかな量だけバッファリングすると、交差点は期待どおりに機能します。以下を参照してください:

>>> 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 
>>> 

上記は私が線の交点から作成されたポイントを交差するようにそれらを得るためにラインをバッファリングする必要がある理由としてはわからないが、所望の出力です。あなたは残りの列に格納されたデータを失うので、操作unary_unionintersectionは、GeoDataFrame内部ジオメトリの上に作られています

答えて

5

注意してください。私はこの場合、データフレームの各ジオメトリにアクセスして手作業で行う必要があると思います。次のコード:

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 

が生成する:

 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), ... 

お知らせ各ジオメトリを使用して、ポイント情報によってポイントをしたい場合は、後からアクセスできること、の2点を持っている、またはあなたが導入点ごとに行を作成することができますループのためのポイントを反復、そのようなもの:

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

しかし、あなたは各交点がマルチジオメトリを生成することを知ることに依存し、この場合には

sjoin機能を使用する他の方法については、私が使用しているgeopandasのバージョンにtoolsモジュールがないため、テストできませんでした。何が起こるかを確認するためにbuffer(0.0)を入れてみてください。