python – 使用Geopandas计算与最近特征的距离

前端之家收集整理的这篇文章主要介绍了python – 使用Geopandas计算与最近特征的距离前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望使用Geopandas / Shapely来完成相当于ArcPy Generate Near Table的操作.我是Geopandas和Shapely的新手,并开发了一种有效的方法,但我想知道是否有更有效的方法.

我有两个点文件数据集 – Census Block Centroids和餐馆.我希望找到每个人口普查区块中心距离它最近的餐厅的距离.对于同一个餐厅而言,对于多个街区来说,最近的餐厅没有任何限制.

这对我来说有点复杂的原因是因为Geopandas Distance function根据索引计算元素,匹配.因此,我的一般方法是将Restaurants文件转换为多点文件,然后将blocks文件的索引设置为全部相同的值.然后,所有块质心和餐馆都具有相同的索引值.

import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon,Point,MultiPoint

现在阅读Block Centroid和Restaurant Shapefiles:

Blocks=gpd.read_file(BlockShp)
Restaurants=gpd.read_file(RestaurantShp)

由于Geopandas距离函数按元素计算距离,我将Restaurant GeoSeries转换为MultiPoint GeoSeries:

RestMulti=gpd.GeoSeries(Restaurants.unary_union)
RestMulti.crs=Restaurants.crs
RestMulti.reset_index(drop=True)

然后我将Blocks的索引设置为等于0(与Restaurants多点相同的值)作为元素计算的解决方法.

Blocks.index=[0]*len(Blocks)

最后,我使用Geopandas距离函数计算每个Block质心到最近餐馆的距离.

Blocks['Distance']=Blocks.distance(RestMulti)

请提供有关如何改进这方面的任何建议.我并不喜欢使用Geopandas或Shapely,但我希望学习ArcPy的替代方案.

谢谢您的帮助!

解决方法

如果我正确理解您的问题,块和餐馆的尺寸可能会有很大差异.出于这个原因,尝试通过重建索引强制转换为表格格式可能是一种糟糕的方法.

我会绕过街区并获得到餐馆的最小距离(就像@shongololo建议的那样).

我会稍微更通用一些(因为我已经记下了这段代码)并且在点与线之间做了一段距离,但是相同的代码应该从点到点或从多边形到多边形.我将从点开始使用GeoDataFrame,然后我将创建一个与行距离最小的新列.

%matplotlib inline
import matplotlib.pyplot as plt
import shapely.geometry as geom
import numpy as np
import pandas as pd
import geopandas as gpd

lines = gpd.GeoSeries(
    [geom.LineString(((1.4,3),(0,0))),geom.LineString(((1.1,2.),(0.1,0.4))),geom.LineString(((-0.1,3.),(1,2.)))])

# 10 points
n  = 10
points = gpd.GeoSeries([geom.Point(x,y) for x,y in np.random.uniform(0,3,(n,2))])

# Put the points in a dataframe,with some other random column
df_points = gpd.GeoDataFrame(np.array([points,np.random.randn(n)]).T)
df_points.columns = ['Geometry','Property1']

points.plot()
lines.plot()

现在获取点到线的距离,并且只保存每个点的最小距离(请参阅下面的适用版本)

min_dist = np.empty(n)
for i,point in enumerate(points):
    min_dist[i] = np.min([point.distance(line) for line in lines])
df_points['min_dist_to_lines'] = min_dist
df_points.head(3)

这使

Geometry                                       Property1    min_dist_to_lines
0   POINT (0.2479424516236574 2.944916965334865)    2.621823    0.193293
1   POINT (1.465768457667432 2.605673714922998)     0.6074484   0.226353
2   POINT (2.831645235202689 1.125073838462032)     0.657191    1.940127

—-编辑—-

(取自github问题)使用apply更好,更符合你在熊猫中的表现:

def min_distance(point,lines):
    return lines.distance(point).min()

df_points['min_dist_to_lines'] = df_points.geometry.apply(min_distance,df_lines)

猜你在找的Python相关文章