将多边形与最近的邻居线连接起来,创建可切割的模板
我的python脚本连接单独的多边形,带有基于最近的邻居算法的“连接器线”,以便我可以将它们切成 像这样的形状连接的多边形。
这可以正常工作,但我有三个问题:
- 这些线实际上是多边形之间最接近的连接不是。为什么该算法找不到红线(手动插入),而是错误黑线?请参阅此处:错误最近的邻居行 - 最近的点功能只能连接到节点但是不是要在多边形线上指向吗?那可以解释偏移吗?
- 要创建不太“摇摆”的稳定模板,我想添加其他连接线。显然需要一种非常不同的算法。我如何定义“颤抖”,找到这些连接的标准是什么,这些连接会使模板更稳定?我相信答案在于一种方法,可以找到多边形点之间的最短路径,然后将最短路径长度与直线连接的长度进行比较。然后,我会添加连接a)a)通过直接行驶和b)高于Treshold Inn总体“保存”而具有最高百分比。这将必须在迭代上进行,因为新连接将改变所有其他路径的计算。 I have found a number of interesting but complex algorithms that address the first part of the problem: finding a shortest path within one polygon:
- https://pdfs.semanticscholar.org/d59f/b891cac975a3b1d627e096916e352235235ff2.pdff.2.pdf2.pdf2.pdf2.pdf2.pdf
- 100 .1319&amp = rep1&amp = pdf“ rel =“ nofollow noreferrer”> https://citeseerx.ist.ist.ist.psu.edu.edu.edu/viewdoc/viewdoc/download?doi=10.1.1.1.1.1.1.1.1.1.100.100.100.100.1319&amp.empt = rep=rep=rep = rep1&.amp.tepepepepepepectepectectectectectectecte=pdf < /a>
- 一个简单得多的问题:用三个多边形创建GeodataFrame的脚本的一部分似乎非常复杂。我相信有很多更简单的方法可以做到吗?
import osmnx as ox
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.geometry import Point, Polygon, LineString
from shapely.ops import nearest_points
box=(51.4616,51.4522, -0.1354, -0.1628)
p1lat=[51.4596626, 51.4580315, 51.4579446, 51.4589807, 51.4599099, 51.4595690, 51.4587935, 51.4578643, 51.4577373, 51.4590141, 51.4603845, 51.4603578, 51.4596626]
p1long=[-0.1544094,-0.1543021,-0.1536155,-0.1533473,-0.1532292,-0.1521242,-0.1519632,-0.1526713,-0.1520705,-0.1510084,-0.1519740,-0.1538301,-0.1544094]
p1=Polygon(zip(p1long,p1lat))
p2lat=[51.4582654, 51.4572092, 51.4566744, 51.4562599, 51.4561930, 51.4569953, 51.4585930, 51.4594553, 51.4594553, 51.4580983, 51.4569084, 51.4567813, 51.4569552, 51.4571758, 51.4579379, 51.4581652, 51.4582989, 51.4585796, 51.4587601, 51.4582654]
p2long=[-0.1493561,-0.1497531,-0.1492059,-0.1475108,-0.1460624,-0.1456332,-0.1454616,-0.1456439,-0.1460516,-0.1460302,-0.1463413,-0.1471460,-0.1477575,-0.1486588,-0.1486266,-0.1473176,-0.1467168,-0.1466846,-0.1468456,-0.1493561,]
p2=Polygon(zip(p2long,p2lat))
p3lat=[51.4608859, 51.4608424, 51.4604213, 51.4600904, 51.4600235, 51.4602241, 51.4603110, 51.4606385, 51.4606185, 51.4608859]
p3long=[-0.1481116,-0.1507562,-0.1511103,-0.1510674,-0.1480097,-0.1480311,-0.1504290,-0.1504987, -0.1480740,-0.1481116]
p3=Polygon(zip(p3long,p3lat))
polygons = gpd.GeoDataFrame(index=[0], geometry=[p1])
polygons=polygons.append(gpd.GeoDataFrame(index=[0], geometry=[p2]))
polygons=polygons.append(gpd.GeoDataFrame(index=[0], geometry=[p3]))
polygons.set_crs(epsg=4326, inplace=True)
def createcard(layer,lcolor, framewidth, connectorwidth):
dflines = gpd.GeoDataFrame(columns=['ID','Location','geometry']) #connector lines
dfframes =gpd.GeoDataFrame(columns=['ID','Location','geometry']) #frames
df=layer
df=df.dissolve().explode()
df.insert(1,'nearest_geometry', None)
df.insert(2,'queried_geometry', None)
while df.shape[0]>1: #add connector lines to the dataframe, explode and dissolve until therev is only 1 polygon, i.e. everything is connected
for index, row in df.iterrows():
point = row.geometry
multipoint = df.drop(index, axis=0).geometry.unary_union
queried_geom, nearest_geom = nearest_points(point, multipoint)
df.loc[index, 'nearest_geometry'] = nearest_geom
df.loc[index, 'queried_geometry'] = queried_geom
x=LineString([nearest_geom,queried_geom]).buffer(connectorwidth)
dflines=dflines.append({'geometry' : x, 'ID':'2','Location':'test'},ignore_index=True)
df=df.append(dflines).dissolve().explode() # add the connector lines to the df and make it one polygon
fig, ax = plt.subplots(figsize=(15,15))
ox.plot.plot_footprints(df, ax=ax, bbox=box , color=lcolor, alpha=1, bgcolor='#FFFF', save=True, show=False, close=False)
My Python script connects separate polygons with "connector lines" based on a nearest neighbor algorithm so I can cut them out as one shape like this connected polygons.
This works fine but I have three questions:
- The lines are actually not the closest connection between the polygons. Why doesn't the algorithm find the red line (inserted manually) but the wrong black line? See here:wrong nearest neighbor line - Is it possible that the nearest point function only connects to nodes but not to points on a polygon line? That would explain the offset?
- To create a stable stencil that's not too "wobbly", I want to add additional connection lines. Obviously a very different algorithm is needed. How do I define "wobbly", what could be the criteria to find these connections that would make the stencil more stable? I believe the answer lies in an approach to find the shortest path between polygon points and then comparing then shortest path length with the length of a direct line connection. I would then add the connections that a) have the highest percentage in shorteing the path by going direct and b) that are above a treshold inn total "saving". this would have to be done iteratively as a new connection will change the calcualtion for all others paths. I have found a number of interesting but complex algorithms that address the first part of the problem: finding a shortest path within one polygon:
- https://pdfs.semanticscholar.org/d59f/b891cac975a3b1d627e6e096916e35235ff2.pdf
- https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.100.1319&rep=rep1&type=pdf
- A much simpler question: The part of the script that creates the geodataframe with the three polygons seems awfully complicated. I am sure there are much easier ways to do it?
import osmnx as ox
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.geometry import Point, Polygon, LineString
from shapely.ops import nearest_points
box=(51.4616,51.4522, -0.1354, -0.1628)
p1lat=[51.4596626, 51.4580315, 51.4579446, 51.4589807, 51.4599099, 51.4595690, 51.4587935, 51.4578643, 51.4577373, 51.4590141, 51.4603845, 51.4603578, 51.4596626]
p1long=[-0.1544094,-0.1543021,-0.1536155,-0.1533473,-0.1532292,-0.1521242,-0.1519632,-0.1526713,-0.1520705,-0.1510084,-0.1519740,-0.1538301,-0.1544094]
p1=Polygon(zip(p1long,p1lat))
p2lat=[51.4582654, 51.4572092, 51.4566744, 51.4562599, 51.4561930, 51.4569953, 51.4585930, 51.4594553, 51.4594553, 51.4580983, 51.4569084, 51.4567813, 51.4569552, 51.4571758, 51.4579379, 51.4581652, 51.4582989, 51.4585796, 51.4587601, 51.4582654]
p2long=[-0.1493561,-0.1497531,-0.1492059,-0.1475108,-0.1460624,-0.1456332,-0.1454616,-0.1456439,-0.1460516,-0.1460302,-0.1463413,-0.1471460,-0.1477575,-0.1486588,-0.1486266,-0.1473176,-0.1467168,-0.1466846,-0.1468456,-0.1493561,]
p2=Polygon(zip(p2long,p2lat))
p3lat=[51.4608859, 51.4608424, 51.4604213, 51.4600904, 51.4600235, 51.4602241, 51.4603110, 51.4606385, 51.4606185, 51.4608859]
p3long=[-0.1481116,-0.1507562,-0.1511103,-0.1510674,-0.1480097,-0.1480311,-0.1504290,-0.1504987, -0.1480740,-0.1481116]
p3=Polygon(zip(p3long,p3lat))
polygons = gpd.GeoDataFrame(index=[0], geometry=[p1])
polygons=polygons.append(gpd.GeoDataFrame(index=[0], geometry=[p2]))
polygons=polygons.append(gpd.GeoDataFrame(index=[0], geometry=[p3]))
polygons.set_crs(epsg=4326, inplace=True)
def createcard(layer,lcolor, framewidth, connectorwidth):
dflines = gpd.GeoDataFrame(columns=['ID','Location','geometry']) #connector lines
dfframes =gpd.GeoDataFrame(columns=['ID','Location','geometry']) #frames
df=layer
df=df.dissolve().explode()
df.insert(1,'nearest_geometry', None)
df.insert(2,'queried_geometry', None)
while df.shape[0]>1: #add connector lines to the dataframe, explode and dissolve until therev is only 1 polygon, i.e. everything is connected
for index, row in df.iterrows():
point = row.geometry
multipoint = df.drop(index, axis=0).geometry.unary_union
queried_geom, nearest_geom = nearest_points(point, multipoint)
df.loc[index, 'nearest_geometry'] = nearest_geom
df.loc[index, 'queried_geometry'] = queried_geom
x=LineString([nearest_geom,queried_geom]).buffer(connectorwidth)
dflines=dflines.append({'geometry' : x, 'ID':'2','Location':'test'},ignore_index=True)
df=df.append(dflines).dissolve().explode() # add the connector lines to the df and make it one polygon
fig, ax = plt.subplots(figsize=(15,15))
ox.plot.plot_footprints(df, ax=ax, bbox=box , color=lcolor, alpha=1, bgcolor='#FFFF', save=True, show=False, close=False)
Google Colab notebook with the code: https://colab.research.google.com/drive/1As0JIq6zxqsjeaVHmpxcRcccy7bqUIjy?usp=sharing
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
连接线无关,但是我忽略了一些更基本的东西:预测。在上面的示例中,整个地图被扭曲了,但是我只通过查看添加的内容来注意到地图,连接器线。所有预测都扭曲了,您需要为您的目的选择合适的预测。我仍然需要了解有关预测的更多信息,但是FWIW最终以UTM CRS的0,0坐标为中心创建了一个自定义UTM CRS。
It's got nothing to do in with the connector lines, but with something much more fundamental that I disregarded: projections. In my example above the whole map was distorted, but I only noticed by looking at what I added t ok the map, connector lines. All projections are distorted, you need to choose the right one for your purposes. I still need to learn a lot more about projections, but fwiw I ended up creating a custom UTM CRS with the center of my map as the 0,0 coordinates of the UTM CRS.