WKTラインストリングの長さを計算するためのPythonの方法を探しています


13

私はマイルのWGS84で線ストリングの長さ計算することにかなり不満でした。与えられたSRIDに従ってWKT線ストリングの長さを計算するためのより便利でPythonicな方法があるかどうか疑問に思いました。

私は次のようなものを心に留めています:

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

sin\cos近似値ではなく、正確な答えを探しています。

何か案は?


tomkralidis、これはGIS Webサイトです。あなたの答えは、これが地理空間座標間の距離であることを無視します(SRIDを検索)。shapely自体は、地図投影の知識がないため、地理空間距離を計算できません。

回答:


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になります。チームのプログラミング時間を節約しました。
アダムMatan

入力アプローチがすでにWGS-84にある場合、このアプローチは@tomkralidisの回答とは異なりますか?
LarsVegas

1
@LarsVegasはい、Shapelyは平面座標のみを処理します。したがって、投影された空間で距離を正確に測定しますが、地理的ではありません(WGS-1984など)。
SCW

4

Shapelyのlengthプロパティを使用することもできます。つまり:

from shapely.wkt import loads

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

この特定の例の長さは、地理座標系(WGS84)であるため、意味がないことに注意してください。
マイクT 14


2

パーティーに遅れたが、うまくいけば役に立つ貢献をした。geopyを使用したscwの答えに基づいて、任意の多くの座標を持つ形状のLineStringオブジェクトの計算を行う小さな関数を作成しました。pairsStackoverflowのイテレータを使用します。

主な機能:docstringはスニペットよりもはるかに長いです。

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
これは間違っています:geopy.distance.distanceは(y、x)の座標を受け入れますが、形の良い線ストリングは「2つ以上(x、y [、z])の順序付けられたシーケンス」であるため、geopyのヘルパー関数lonlat()を使用する必要があります。
マーティンバーチ

@MartinBurch:ああ、あなたは正しい。嫌な事でもないが[, z]、しかし、引数スワップ(y, x)(x, y)それが必要です。見つけてくれてありがとう。この編集でバグが少なく見えるかどうかを確認できますか?
ojdo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.