当前位置: 首页 > 知识库问答 >
问题:

两条线串的交叉点地质公园

丘友樵
2023-03-14

假设我有下面的线性字符串的GeoDataFrames,其中一个表示道路,一个表示轮廓线。

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

如果我绘制这些,它们看起来像这样:

有3条等高线和2条道路。我想找到每条道路上每个点的高程。基本上,我希望与道路和等高线相交(应该给我12个点),并保留两个地理数据框(道路名称和高程)的属性。

我可以使用两个GeodataFrame并集的交点生成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.3636038969321072 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.363603896932107)
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.3636038969321072 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
>>> 

以上是所需的输出,尽管我不确定为什么我必须缓冲这些线以使它们与从这些线的交点创建的点相交。

共有1个答案

秦才良
2023-03-14

请注意,操作一元联合交集是在地理数据框内的几何图形上进行的,因此会丢失存储在其余列中的数据。我认为在这种情况下,您必须通过访问数据帧中的每个几何体来手动完成。以下代码:

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

请注意,每个几何都有两个点,如果您需要逐点信息,您可以稍后访问它们,或者您可以为每个点创建一行,引入迭代这些点的for循环,类似于:

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

但在这种情况下,您需要知道每个交点都会生成一个多重几何体。

关于您使用sjoin函数的其他方法,我无法测试它,因为我正在使用的geopandas版本不提供工具模块。试着把缓冲区(0.0)看看会发生什么。

 类似资料:
  • 我有一个geopandas数据框,其中包含几个从lat、lon点数据创建的线串。对于所有直线交点,我需要在每个直线串中找到距离该交点最近的点。 因此,如果dataframe中的两条线相交,我需要在每个linestring中找到距离该相交点最近的点。我使用itertools找到了所有可能的交叉点,这些交叉点与本文中公认的答案类似:https://gis.stackexchange.com/quest

  • 想改进这个问题吗?通过编辑这篇文章来更新问题,使其仅关注一个问题。 请在类 [] 中实现方法 它必须返回两条线的交集 []。 注意,直线由线性方程定义:。行构造函数将和系数作为参数。 如果线重合或不相交,该方法必须返回null。我们使用< code>int作为参数和坐标域,这似乎令人惊讶。关键是使用< code>double会带来一些额外的复杂性,这是我们希望在这个基本练习中避免的。所有测试都在中

  • 本文向大家介绍交叉熵公式相关面试题,主要包含被问及交叉熵公式时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 交叉熵:设p(x)、q(x)是X中取值的两个概率分布,则p对q的相对熵是: 在一定程度上,相对熵可以度量两个随机变量的“距离”,且有D(p||q) ≠D(q||p)。另外,值得一提的是,D(p||q)是必然大于等于0的。 互信息:两个随机变量X,Y的互信息定义为X,Y的联合分布和各自

  • 我有一个超过40年的过去Storm的大数据集(约20000),其中有一个3小时间隔的中心点列表。我试图覆盖一个网格网格到一个大的区域,我想从其中计数的次数每次Storm已经通过任何给定的网格单元,但是我目前的实现只跟踪在这三个小时的时间间隔的位置,导致一些情况当轨道也应该被计算时,它会跳过网格空间。 我尝试使用geopandas来解决这个问题,为每个Storm轨迹创建一个线系列,然后对网格网格执行

  • 其实思想可以按照从尾开始比较两个链表,如果相交,则从尾开始必然一致,只要从尾开始比较,直至不一致的地方即为交叉点,如图所示 # 使用a,b两个list来模拟链表,可以看出交叉点是 7这个节点 a = [1,2,3,7,9,1,5] b = [4,5,7,9,1,5] for i in range(1,min(len(a),len(b))): if i==1 and (a[-1] != b[-

  • 我有一个横跨各种多边形的线串,存储为GeoJsons。我想在每个多边形区域内将线条分割成单独的部分。然而,我还没能做到这一点。这是我到目前为止的一个可复制的例子: 然后我尝试通过多边形分割直线,如下所示: 但我得到了以下输出,这似乎不正确: 我期望有三条线,一条存在于正方形多边形内,然后两条分别存在于多边形外。