我有两个线串 Line1、Line2。
line1 = "LINESTRING(72.863221 18.782499,72.863736 18.770147,72.882275 18.756169,72.881417 18.750805,72.878842 18.736987,72.874379 18.709512,72.860989 18.679593,72.864422 18.653897)"
line2 = "LINESTRING(72.883133 18.780793,72.882103 18.760314,72.862534 18.716422,72.860474 18.683577)"
我正在尝试以匀称的方式执行以下 POSTGIS 查询。到目前为止,我还没有找到 ST_DWithin 命令的替代方法。
road2 = "ST_GeographyFromText('SRID=4326;%s')"%line1
road4 = "ST_GeographyFromText('SRID=4326;%s')"%line2
cur.execute("SELECT ST_AsText(road1) from %s as road1,%s as road2
where ST_DWithin(road1,road2,500)"%(road2,road4))
res = cur.fetchall()
print res
有谁知道在 shapely 中 ST_DWithin 的替代品是什么?
最佳答案
据我所知,shapely 仅支持平面坐标(不支持地理类型)的操作。然而,对于不太大以至于可以忽略地球曲率的 LineStrings,可以通过以下方式部分“规避”这一点:
在某些平面投影中工作(例如直接在纬度/经度或经度/纬度坐标中)
遵循
ST_DWithin
文档中的第二条注释和ST_Expand
文档中的第一个注释,即:- 检查第二个 LineString 的边界框是否与第一个 LineString 的扩展边界框相交
- 如果是,检查最小距离是否确实低于规定的阈值
例如:
from shapely.wkt import dumps, loads
from shapely.geometry.geo import box
spec = [
"LINESTRING(72.863221 18.782499,72.863736 18.770147,72.882275 18.756169,72.881417 18.750805,72.878842 18.736987,72.874379 18.709512,72.860989 18.679593,72.864422 18.653897)",
"LINESTRING(72.883133 18.780793,72.882103 18.760314,72.862534 18.716422,72.860474 18.683577)"
]
lines = list(map(loads, spec))
eta = 0.005
b1 = box(*lines[0].bounds).buffer(eta)
b2 = box(*lines[1].bounds)
flag = b2.intersects(b1) and (lines[0].distance(lines[1]) < eta)
print(eta, flag)
或者,如果您想检查整个第二个 LineString 是否在第一个 LineString 的规定阈值内,您也可以使用 buffer
方法:
lines[0].buffer(eta).contains(lines[1])
此处提供给 buffer
方法的阈值在定义 LineStrings 的同一坐标系中表示。在 lon/lat 系统中,这将代表“中心角”——问题在于 great circle distance对应于一个固定的eta
不仅取决于纬度和经度的特定值,还取决于位移的方向。但是,如果 LineStrings 不是太大并且所需的精度不是太高,它可能不会 matter that much .
关于python - Python 中 PostGIS 的 ST_DWithin 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39037571/