我希望使用Geopandas/Shapely 做相当于ArcPy Generate Near Table的工作.我是Geopandas和Shapely的新手,并开发了一种有效的方法,但我想知道是否有更有效的方法.
我有两个点文件数据集 - Census Block Centroids和餐馆.我希望找到每个人口普查区块中心距离它最近的餐厅的距离.对于同一个餐厅而言,对于多个街区来说,最近的餐厅没有任何限制.
这对我来说有点复杂的原因是因为Geopandas距离函数根据索引计算元素,匹配.因此,我的一般方法是将Restaurants文件转换为多点文件,然后将blocks文件的索引设置为全部相同的值.然后,所有块质心和餐馆都具有相同的索引值.
import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon, Point, MultiPoint
Run Code Online (Sandbox Code Playgroud)
现在阅读Block Centroid和Restaurant Shapefiles:
Blocks=gpd.read_file(BlockShp)
Restaurants=gpd.read_file(RestaurantShp)
Run Code Online (Sandbox Code Playgroud)
由于Geopandas距离函数按元素计算距离,我将Restaurant GeoSeries转换为MultiPoint GeoSeries:
RestMulti=gpd.GeoSeries(Restaurants.unary_union)
RestMulti.crs=Restaurants.crs
RestMulti.reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)
然后我将Blocks的索引设置为等于0(与Restaurants多点相同的值)作为元素计算的解决方法.
Blocks.index=[0]*len(Blocks)
Run Code Online (Sandbox Code Playgroud)
最后,我使用Geopandas距离函数计算每个Block质心到最近餐馆的距离.
Blocks['Distance']=Blocks.distance(RestMulti)
Run Code Online (Sandbox Code Playgroud)
请提供有关如何改进这方面的任何建议.我并不喜欢使用Geopandas或Shapely,但我希望学习ArcPy的替代方案.
谢谢您的帮助!
我有一个应用程序,它接收一个地址字符串,将其发送到谷歌地图API并获得纬度/经度坐标,然后我想显示这一点的X meteres内的所有用户(lat/long存储在我的数据库中) ,然后我想过滤结果只显示某些宠物的用户
首先,我有我的模特
class User(UserMixin, Base):
first_name = Column(Unicode)
address = Column(Unicode)
location = Column(Geometry('POINT'))
pets = relationship('Pet', secondary=user_pets, backref='pets')
class Pet(Base):
__tablename__ = 'pets'
id = Column(Integer, primary_key=True)
name = Column(Unicode)
user_pets = Table('user_pets', Base.metadata,
Column('user_id', Integer, ForeignKey('users.id')),
Column('pet_id', Integer, ForeignKey('pets.id'))
)
Run Code Online (Sandbox Code Playgroud)
我从谷歌API获取我的lat/long并将其存储在我的数据库中,所以从地址字符串"伦敦英格兰"我得到
POINT (-0.1198244000000000 51.5112138999999871)
Run Code Online (Sandbox Code Playgroud)
这存储在我的数据库中,如:
0101000000544843D7CFACBEBF5AE102756FC14940
Run Code Online (Sandbox Code Playgroud)
现在一切正常,现在阅读Geoalchemy2文档,我似乎无法找到解决我的问题的exmaple查询.
我想传递的是Geoalchemy2的另一组lat/long坐标,然后返回最近的10个用户.在查询这个问题的同时,我也只会过滤那些有某些宠物的用户(这对我的查询起作用并不重要,但我想展示查询实际上会做什么).
我不想在没有提供示例查询的情况下回答问题,但我真的不知道应该使用哪些函数来实现我所需的结果.
我猜我需要使用"ST_DWithin"或"ST_DFullyWithin",但我找不到任何一个函数的完整示例.谢谢.
所以我知道有一个有效的查询
distance = 10
address_string = "London, England"
results = Geocoder.geocode(address_string)
# load long[1], lat[0] into shapely
center_point = Point(results.coordinates[1], results.coordinates[0])
print center_point
# 'POINT (-0.1198244000000000 …Run Code Online (Sandbox Code Playgroud) 我正在尝试构建一个GeoJSON对象.我的输入是一个带有地址列,lat列和lon列的csv.然后,我从坐标中创建了Shapely点,用给定的半径缓冲它们,并通过映射选项获得坐标字典 - 到目前为止,非常好.然后,在提到这个问题后,我编写了以下函数来获得一系列字典:
def make_geojson(row):
return {'geometry':row['geom'], 'properties':{'address':row['address']}}
我这样应用了它:
data['new_output'] = data.apply(make_geojson, axis=1)
Run Code Online (Sandbox Code Playgroud)
我的结果列充满了以下内容: <built-in method values of dict object at 0x10...
最奇怪的部分是,当我直接调用函数(即make_geojson(data.loc[0])我其实做得到我期待字典.甚至离奇的是,当我打电话,我从得到的功能应用(例如data.output[0](),data.loc[0]['output']())我得到的相当于以下列表:
[data.loc[0]['geom'], {'address':data.loc[0]['address']}],即我想要获得的字典的值(但不是键).
对于那些在家里玩的人来说,这是一个玩具示例:
from shapely.geometry import Point, mapping
import pandas as pd
def make_geojson(row):
return {'geometry':row['geom'], 'properties':{'address':row['address']}}
data = pd.DataFrame([{'address':'BS', 'lat':34.017, 'lon':-117.959}, {'address':'BS2', 'lat':33.989, 'lon':-118.291}])
data['point'] = map(Point, zip(data['lon'], data['lat']))
data['buffer'] = data['point'].apply(lambda x: x.buffer(.1))
data['geom'] = data.buffer.apply(mapping)
data['output'] = data.apply(make_geojson, axis=1)
Run Code Online (Sandbox Code Playgroud) 我有一个案例,它基于在一条线上投射一个点,然后在它上面分开这一行.我的用例稍微复杂一些,但我的问题可以通过以下代码重现:
from shapely import *
line1 = LineString([(1,1.2), (2,2), (3, 2.), (4,1.2)])
pt = Point(2.5, 1.2)
pr = line1.interpolate(line1.project(pt))
Run Code Online (Sandbox Code Playgroud)
通过构造,"pr"应该在第1行和它们的交叉点上:
line1.contains(pr)
line1.intersects(LineString([pt, pr]))
Run Code Online (Sandbox Code Playgroud)
打印两次"True".但是改变输入坐标会略微制动工作流程:
from shapely import *
line1 = LineString([(1,1.2), (2,2), (3, 2.3), (4,1.2)])
pt = Point(2.5, 1.2)
pr = line1.interpolate(line1.project(pt))
line1.contains(pr)
line1.intersects(LineString([pt, pr]))
Run Code Online (Sandbox Code Playgroud)
打印"假".
我理解这背后的浮动精度问题,但这是否意味着我永远无法测试线上的点?当我根据点列表构建一条线时,我能确定至少所有"构造"点都在线上吗?
我有两个在各个部分相交的匀称MultiPolygon实例(由lon,lat点组成).我正在尝试循环,确定两个多边形之间是否存在交集,然后创建一个排除该交集的新多边形.从附图中,我基本上不希望红色圆圈与黄色轮廓重叠,我希望边缘正好是黄色轮廓开始的位置.
我已经尝试按照这里的说明进行操作,但它根本不会改变我的输出,而且我不想将它们合并到一个级联联合中.我没有收到任何错误消息,但是当我将这些MultiPolygons添加到KML文件(只是python中的原始文本操作,没有花哨的程序)时,它们仍然显示为圆圈而没有任何修改.
# multipol1 and multipol2 are my shapely MultiPolygons
from shapely.ops import cascaded_union
from itertools import combinations
from shapely.geometry import Polygon,MultiPolygon
outmulti = []
for pol in multipoly1:
for pol2 in multipoly2:
if pol.intersects(pol2)==True:
# If they intersect, create a new polygon that is
# essentially pol minus the intersection
intersection = pol.intersection(pol2)
nonoverlap = pol.difference(intersection)
outmulti.append(nonoverlap)
else:
# Otherwise, just keep the initial polygon as it is.
outmulti.append(pol)
finalpol = MultiPolygon(outmulti)
Run Code Online (Sandbox Code Playgroud)
我有一个包含芝加哥地址的 DataFrame,我已将其地理编码为纬度和经度值,然后编码为 Point 对象(使 DataFrame 成为 GeoDataFrame)。一小部分已使用芝加哥以外的 LatLong 值进行了错误的地理编码。我有一个用于芝加哥边界(GeoDataFrame)的 shapefile,我想选择点位于芝加哥边界多边形之外的所有行。
选择多边形内的所有点很容易(通过 geopandas sjoin 函数),但我还没有找到一种选择不在多边形内的点的好方法。一个存在吗?
我正在使用 CV2 从图像中查找轮廓,然后使用 Shapely 将它们转换为多边形。我目前陷入困境,因为当我尝试将其中一个轮廓数组放入Polygon()Shapely 时,它会引发未指定的错误。
我已经仔细检查过我导入了我需要的所有东西,并且当我手动输入数组坐标点时,创建一个 Shapely 多边形是有效的。
这是代码的问题部分:
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
testcontour = contours[1]
ply = Polygon(testcontour)
Run Code Online (Sandbox Code Playgroud)
轮廓列表如下所示:
contours = [np.array([[[700, 700]],
[[700, 899]],
[[899, 899]],
[[899, 700]]]),
np.array([[[774, 775]],
[[775, 774]],
[[824, 774]],
[[825, 775]],
[[825, 824]],
[[824, 825]],
[[775, 825]],
[[774, 824]]]),
np.array([[[200, 200]],
[[200, 399]],
[[399, 399]],
[[399, 200]]]),
np.array([[[274, 275]],
[[275, 274]],
[[324, 274]],
[[325, 275]],
[[325, 324]],
[[324, 325]],
[[275, 325]],
[[274, 324]]])]
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
---------------------------------------------------------------------------
AssertionError Traceback (most …Run Code Online (Sandbox Code Playgroud) 如何为某个点附近最近的 LINESTRING 提供资金?
首先,我有一个 LINESTRING 和点值列表。我如何获得距离点(5.41 3.9)最近的线串以及距离?
from shapely.geometry import Point, LineString
line_string = [LINESTRING (-1.15.12 9.9, -1.15.13 9.93), LINESTRING (-2.15.12 8.9, -2.15.13 8.93)]
point = POINT (5.41 3.9)
#distance
line_string [0].distance(point)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我认为我通过对第一个 LINESTRING 执行 line_string [0].distance(point) 来获得距离值,但我只是想确保我以正确的方式进行操作。