एक WKT linestring की लंबाई की गणना करने के लिए एक पायथोनिक तरीके की तलाश है


13

मीलों में WGS84 में लिनस्ट्रेस की लंबाई की गणना से मैं काफी असंतुष्ट था । यह मुझे आश्चर्यचकित करता है कि क्या एक अधिक सुविधाजनक, पाइथोनिक तरीका है जो किसी दिए गए एसआरआईडी के अनुसार डब्ल्यूकेटी लिनेस्ट्रिंग की लंबाई की गणना करता है।

मेरे मन में कुछ इस तरह है:

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

मैं एक सटीक उत्तर की तलाश कर रहा हूं, sin\cosसन्निकटन नहीं ।

कोई विचार?


tomkralidis, यह एक जीआईएस वेबसाइट है। आपका उत्तर इस बात की अनदेखी करता है कि यह भू-स्थानिक निर्देशांक (एसआरआईडी देखें) के बीच की दूरी है। आकार में अपने आप में भू-स्थानिक दूरी की गणना नहीं की जा सकती क्योंकि इसमें मानचित्र प्रक्षेपण का कोई ज्ञान नहीं है।

जवाबों:


18

Geopy मॉड्यूल प्रदान करता है Vincenty सूत्र है, जो सही दीर्घवृत्ताभ दूरी प्रदान करता है। इसे wktशेपली में लोड करने के साथ युगल करें , और आपके पास यथोचित सरल कोड है:

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 होगा। मेरी टीम की प्रोग्रामिंग के घंटे बचे।
एडम मटन

क्या यह दृष्टिकोण @tomkralidis उत्तर से अलग है यदि इनपुट निर्देशांक WGS-84 में पहले से हैं?
लार्सविगास

1
@LarsVegas हाँ, Shapely केवल planar निर्देशांक को संभालता है - इसलिए यह अनुमानित अंतरिक्ष में सटीकता से दूरी को मापेगा, लेकिन भौगोलिक नहीं (उदाहरण के लिए 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) है।
माइक टी


2

पार्टी के लिए देर से, लेकिन एक उपयोगी योगदान के साथ। भूगोल का उपयोग करते हुए एसडब्ल्यू के उत्तर पर निर्माण , मैंने एक छोटा फ़ंक्शन लिखा जो मनमाने ढंग से कई निर्देशांक के साथ एक सुडौल लाइनस्ट्रिंग ऑब्जेक्ट के लिए गणना करता है। यह 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])" इसलिए जियोफाई के सहायक लोनलेट () का उपयोग किया जाना चाहिए ।
मार्टिन बर्च

@MartinBurch: ouch, आप सही हैं। बुरा बात भी नहीं है [, z], लेकिन तर्क स्वैप (y, x)करने के लिए (x, y)आवश्यक है। इसे जगह देने के लिए धन्यवाद। क्या आप देख सकते हैं कि क्या यह संपादन कम बग-ग्रस्त दिखता है?
ओजदो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.