【发布时间】:2020-10-11 14:46:26
【问题描述】:
我正在尝试计算区域供热系统。我从 shapefile 获取信息——对于管道,我有一个带有开始和结束坐标的线串几何图形。我创建了一个 geopandas 数据框:
+-------+----------------------------------------------------------------------------------------------------------------------+
| | |
| ID | geometry |
+-------+----------------------------------------------------------------------------------------------------------------------+
| | |
| 0 | LINESTRING (1679896.423 5802688.586, 1679896.034 5802688.745) |
+-------+----------------------------------------------------------------------------------------------------------------------+
| | |
| 1 | LINESTRING (1679896.034 5802688.745, 1679892.419 5802689.660) |
+-------+----------------------------------------------------------------------------------------------------------------------+
| | |
| 2 | LINESTRING (1679908.185 5802692.533, 1679911.830 5802691.936, 1679927.258 5802689.562, 1679945.682 5802686.042) |
+-------+----------------------------------------------------------------------------------------------------------------------+
| | |
| 3 | LINESTRING (1679945.667 5802685.478, 1679945.653 5802685.247) |
+-------+----------------------------------------------------------------------------------------------------------------------+
| | |
| 4 | …. |
+-------+----------------------------------------------------------------------------------------------------------------------+
对于计算,我必须确定线路之间的所有连接(当前管道必须定义上一个管道和下一个管道)。我这样做的方式是创建线串的起点和终点,并将数据框与自身合并(终点与起点配对)。问题是,一些线串(大约 1/5)朝向错误的方向,所以我只是为它们得到 NaN 结果(因为现在当前管道的终点不接触下一个起点,而只是另一个终点点)。
+-------+-------------+-----------------+------------------------------------+------------------------------------+--------------------------------------------------------------------+
| | | | | | |
| ID | PipeNext | PipePrevious | StartPoint | EndPoint | Geometry |
+-------+-------------+-----------------+------------------------------------+------------------------------------+--------------------------------------------------------------------+
| | | | | | |
| 1 | 2 | 477 | POINT (1679896.423 5802688.586) | POINT (1679896.034 5802688.745) | LINESTRING (1679896.423 5802688.586, 1679896.034 5802688.745) |
| | | | | | |
| | | | | | |
+-------+-------------+-----------------+------------------------------------+------------------------------------+--------------------------------------------------------------------+
| | | | | | |
| 7 | 8 | 477 | POINT (1679896.423 5802688.586) | POINT (1679898.491 5802694.799) | LINESTRING (1679896.423 5802688.586, 1679898.491 5802694.799) |
| | | | | | |
| | | | | | |
+-------+-------------+-----------------+------------------------------------+------------------------------------+--------------------------------------------------------------------+
| | | | | | |
| 3 | 467, 468 | Nan | POINT (1679077.671 5802691.617) | POINT (1679060.406 5802674.810) | LINESTRING (1679077.671 5802691.617, 1679060.406 5802674.810) |
| | | | | | |
| | | | | | |
+-------+-------------+-----------------+------------------------------------+------------------------------------+--------------------------------------------------------------------+
另外的问题是,有 10 个管道连续面对错误方向的例子(所以在它们之间,我实际上得到了结果,但它们是错误的)——另一个问题是,有时 PipeNext 是 NaN 仅仅是因为当前行是终点线。 有什么方法可以确定管道朝向错误的方向吗?如果没有,是否可以在绘图上显示线条的方向?
编辑 - 添加当前代码:
import pandas as pd
import geopandas as gpd
import folium
import shapefile
import matplotlib.pyplot as plt
from geopandas import GeoDataFrame
import contextily as ctx
df_pipes=gpd.read_file("DO_Hrastnik_odsek.shp")
df_user=gpd.read_file("DO_Hrastnik_objekt.shp")
df_pipes.crs = {'init': 'epsg:3912'}
df_pipes=df_pipes.to_crs("EPSG:3857")
df_user.crs = {'init': 'epsg:3912'}
df_user=df_user.to_crs("EPSG:3857")
df_pipes["ID"] = df_pipes.index + 1
df_pipes['ID']=df_pipes['ID'].astype(str)
df_pipes=df_pipes[["geometry","ID","LENGTH_3D"]].copy()
from shapely.geometry import Point, LineString
df_pipes["node_ups"] = gpd.GeoSeries([Point(list(pt['geometry'].coords)[0]) for i,pt in df_pipes.iterrows()])
df_pipes["node_dws"] = gpd.GeoSeries([Point(list(pt['geometry'].coords)[-1]) for i,pt in df_pipes.iterrows()])
tmp = df_pipes[['ID', 'node_dws', 'node_ups']]
df_connections=pd.merge(tmp, tmp, left_on='node_dws', right_on='node_ups',how="outer")
df_connections=pd.merge(df_connections, tmp, left_on='node_ups_x', right_on='node_dws',how="outer")
df_connections.drop(['node_dws_y', 'node_ups_y','node_dws', 'node_ups'], axis=1, inplace=True)
df_connections = df_connections[df_connections['ID_x'].notna()]
df_connections = df_connections.rename(columns={'ID_x': 'ID_pipe', 'node_dws_x': 'node_dws','node_ups_x': 'node_ups', 'ID_y': 'pipeNext','ID': 'pipePrevious'})
tmp = df_connections[['ID_pipe', 'pipeNext', 'pipePrevious']]
df_connections=pd.merge(tmp, df_pipes, left_on='ID_pipe', right_on='ID',how="outer")
【问题讨论】:
-
是否无法测试您的线的一个点是否与起点或终点匹配?不是你的管道包含坡度什么的,它只是线路信息,所以这样对待。
-
@MaartenVeerman 问题是某处有多条连续的线朝向错误的方向。在它们之间,我们得到了交换下一个和上一个的邻居(它们的方向是上游)。
-
你能画个小图吗?概述您的问题。
-
@MaartenVeerman - 这是系统的一部分:imgur.com/a/ejbHPru。黄线是方向错误的线。我想过做这样的事情:if endopoint(currentID) meet (endpointNEXTID), swap values (endpointNEXTID-startpointNEXTID), break, restart loop 这将逐行旋转,但看起来很复杂分支结构。
-
你能告诉我们你的代码吗?如果我们能看到您是如何到达第二个 DataFrame 以及可以进行哪些调整以更正它,那么我们可以更轻松地提供帮助。
标签: pandas shapefile geopandas