PostGIS中ST_DWithin的替代形式

时间:2016-08-19 11:09:49

标签: python postgresql postgis shapely

我有两个线串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

有没有人知道ST_DWithin的替代方案是什么?

1 个答案:

答案 0 :(得分:0)

据我所知,匀称只支持平面坐标(无地理类型)的操作。然而,对于不太大的LineStrings,可以忽略地球的曲率,可以部分地避开"绕过"这个:

  • 在某些平面投影中工作(例如直接在lat / lon或lon / lat坐标中工作)

  • 遵循ST_DWithin文件中的第二个注释和ST_Expand文件中的第一个注释,即:

    1. 检查第二个LineString的边界框是否与第一个LineString的扩展边界框相交
    2. 如果是,检查最小距离是否确实低于规定的阈值

例如:

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系统中,这将代表&#34;中心角度&#34; - 问题在于,对应于固定eta的{​​{3}}不仅取决于纬度和经度的特定值,还取决于位移的方向。但是,如果LineStrings不是太大而且所需的精度不是太高,它可能会赢得great circle distance