WKT 선 스트링의 길이를 계산하는 파이썬적인 방법을 찾고


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 웹 사이트입니다. 귀하의 답변은 이것이 지리 공간 좌표 사이의 거리라는 것을 무시합니다 (SRID 조회). 형태 자체로는지도 투영에 대한 지식이 없으므로 지리 ​​공간 거리를 계산할 수 없습니다.

답변:


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이됩니다. 팀의 프로그래밍 시간을 절약했습니다.
Adam Matan

입력 좌표가 이미 WGS-84에있는 경우이 방법이 @tomkralidis 답변과 다른가요?
LarsVegas

1
@LarsVegas 예, Shapely는 평면 좌표 만 처리하므로 투영 된 공간에서 거리를 정확하게 측정하지만 지리적으로는 측정 할 수 없습니다 (예 : WGS-1984).
scw

4

Shapely의 길이 속성을 사용할 수도 있습니다 .

from shapely.wkt import loads

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

이 특정 예의 길이는 지리적 좌표계 (WGS84)이므로 의미가 없습니다.
Mike T


2

파티에 늦었지만 희망적으로 유용한 기여를했습니다. 바탕 SCW의 대답 사용 geopy, 나는 임의적으로 많은 좌표와 매끈한 선 스트링 객체에 대한 계산을하는 작은 함수를 썼다. pairsStackoverflow 의 반복자를 사용합니다 .

주요 기능 : 문서화 문자열이 스 니펫보다 훨씬 깁니다.

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 ()을 사용해야합니다. .
Martin Burch

@MartinBurch : 아야, 당신 말이 맞아. 불쾌한 것은도 아니다 [, z],하지만 인수 스왑 (y, x)(x, y)이 필요합니다. 그것을 찾아 주셔서 감사합니다. 이 편집 내용이 버그에 덜 취약 해 보이는지 여부를 알 수 있습니까?
ojdo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.