寻找一种Python方式来计算WKT线串的长度


13

对以WGS84为单位计算线串长度并不满意。它让我想知道是否存在一种更方便的Python方式根据给定的SRID计算WKT线串的长度。

我想到的是:

srid="WGS84"
line="LINESTRING(3.0 4.0, 3.1 4.1)"
print length(line, srid)

我正在寻找一个准确的答案,而不是sin\cos近似值。

有任何想法吗?


tomkralidis,这是一个GIS网站。您的答案忽略了这是地理空间坐标之间的距离(查找SRID)。形状本身无法计算地理空间距离,因为它不了解地图投影。

Answers:


18

所述geopy模块提供Vincenty式,其提供了精确的椭球的距离。将此与wktShapely中的加载相结合,您将获得相当简单的代码:

from geopy import distance
from shapely.wkt import loads

line_wkt="LINESTRING(3.0 4.0, 3.1 4.1)"

# a number of other elipsoids are supported
distance.VincentyDistance.ELLIPSOID = 'WGS-84'
d = distance.distance

line = loads(line_wkt)

# convert the coordinates to xy array elements, compute the distance
dist = d(line.xy[0], line.xy[1])

print dist.meters

1
+1,如果可以的话,则为+10。节省了我团队的编程时间。
亚当·马坦

如果输入坐标已经在WGS-84中,此方法与@tomkralidis答案有什么不同吗?
LarsVegas

1
@LarsVegas是的,Shapely仅处理平面坐标-因此它将精确地测量投影空间中的距离,而不是地理区域(例如WGS-1984)。
scw 2013年

4

您还可以使用Shapely的length属性,即:

from shapely.wkt import loads

l=loads('LINESTRING(3.0 4.0, 3.1 4.1)')
print l.length

请注意,此特定示例的长度是毫无意义的,因为它是地理坐标系(WGS84)。
Mike T


2

晚了晚会,但有希望的贡献。在使用geopy的scw 答案的基础上,我编写了一个小函数,该函数针对具有任意多个坐标的匀称LineString对象进行计算。它使用pairs来自Stackoverflow 的迭代器。

主要功能:文档字符串比代码片段长得多。

def line_length(line):
    """Calculate length of a line in meters, given in geographic coordinates.
    Args:
        line: a shapely LineString object with WGS 84 coordinates
    Returns:
        Length of line in meters
    """
    # Swap shapely (lonlat) to geopy (latlon) points
    latlon = lambda lonlat: (lonlat[1], lonlat[0])
    total_length = sum(distance(latlon(a), latlon(b)).meters
                       for (a, b) in pairs(line.coords))
    return round(total_length, 0)


def pairs(lst):
    """Iterate over a list in overlapping pairs without wrap-around.

    Args:
        lst: an iterable/list

    Returns:
        Yields a pair of consecutive elements (lst[k], lst[k+1]) of lst. Last 
        call yields the last two elements.

    Example:
        lst = [4, 7, 11, 2]
        pairs(lst) yields (4, 7), (7, 11), (11, 2)

    Source:
        /programming/1257413/1257446#1257446
    """
    i = iter(lst)
    prev = i.next()
    for item in i:
        yield prev, item
        prev = item

1
这是错误的:geo​​py.distance.distance接受(y,x)中的坐标,但整齐的线串是“ 2或更大(x,y [,z])的有序序列”,因此必须使用geopy的辅助函数lonlat() 。
Martin Burch

@MartinBurch:哎呀,你是对的。令人讨厌的东西甚至都不是[, z],但必须将参数交换(y, x)(x, y)。感谢您发现它。您能否确定此修改是否看起来少了一些错误?
ojdo '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.