Düzgün uzunluk özelliği birimi nedir?


11

Düzgün kullanarak bir polyline uzunluğunu çok basit bir hesaplama yapıyorum:

from shapely.geometry import LineString
... 
xy_list = [map(float,e) for e in xy_intm]
line = LineString(xy_list)
s = '%s,%s,%s' % (fr,to,line.length)

Koordinatlarım WGS84'te. Shapely'nin length özelliği hakkında herhangi bir bilgi bulamıyorum. Uzunluk özelliğinin birimi nedir? Km veya metreye dönüştürmenin kolay bir yolu var mı?


İki örnek şekil için koordinat ve uzunluk sağlayabilir misiniz?
Vince

Yanıtlar:


13

Alfaciano'nun düzgün bir şekilde söylediği gibi , mesafe, bir küredeki iki nokta arasındaki Büyük daire mesafesi değil, bir düzlemdeki iki nokta arasındaki Öklid Mesafesi veya Doğrusal mesafedir .

from shapely.geometry import Point
import math


point1 = Point(50.67,4.62)
point2 = Point(51.67, 4.64)

# Euclidean Distance
def Euclidean_distance(point1,point2):
     return math.sqrt((point2.x()-point1.x())**2 + (point2.y()-point1.y())**2)

print Euclidean_distance(point1,point2)
1.00019998 # distance in degrees (coordinates of the points in degrees)

# with Shapely
print point1.distance(point2)
1.0001999800039989 #distance in degrees (coordinates of the points in degrees)

Büyük daire mesafesi için, kosinüs yasası veya Haversine formülü olarak algoritmalar kullanmanız gerekir ( iki enlem-boylam noktası arasındaki mesafeyi hesaplarken kosinüs yasası neden haversinden daha tercih edilir? ) Veya pyproj modülünü kullanın . jeodezik hesaplamalar yapar.

# law of cosines
distance = math.acos(math.sin(math.radians(point1.y))*math.sin(math.radians(point2.y))+math.cos(math.radians(point1.y))*math.cos(math.radians(point2.y))*math.cos(math.radians(point2.x)-math.radians(point1.x)))*6371
print "{0:8.4f}".format(distance)
110.8544 # in km
# Haversine formula
dLat = math.radians(point2.y) - math.radians(point1.y)
dLon = math.radians(point2.x) - math.radians(point1.x)
a = math.sin(dLat/2) * math.sin(dLat/2) + math.cos(math.radians(point1.y)) * math.cos(math.radians(point2.y)) * math.sin(dLon/2) * math.sin(dLon/2)
distance = 6371 * 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
print "{0:8.4f}".format(distance)distance
110.8544 #in km

# with pyproj
import pyproj
geod = pyproj.Geod(ellps='WGS84')
angle1,angle2,distance = geod.inv(point1.x, point1.y, point2.x, point2.y)
print "{0:8.4f}".format(distance/1000)
110.9807 #in km

Sonucu Boylam Enlem Mesafesi Hesaplayıcısında test edebilirsiniz

resim açıklamasını buraya girin


Harika cevap Gene! Çok ayrıntılı açıklamanız için çok teşekkürler.
Antonio Falciano

1
Gerçekten harika bir cevap. Yanılmıyorsam, geopybüyük daire mesafesi ve Vincenty mesafe hesaplaması uygulayan başka bir python paketi var.
LarsVegas

İşte jeodezik mesafe hesaplamasıyla ilgili bazı ayrıntılar geopy.
Antonio Falciano

13

Koordinat sistemleri

[...] Düzgün koordinat sistemi dönüşümlerini desteklemez. İki veya daha fazla özellikteki tüm işlemler, özelliklerin aynı Kartezyen düzlemde var olduğunu varsayar.

Kaynak: http://toblerity.org/shapely/manual.html#coordinate-systems

SRS'ye göre shapelytamamen agnostik olduğundan, uzunluk özelliğinin linestring'inizin aynı koordinat biriminde, yani derecelerde ifade edildiği oldukça açıktır. Aslında:

>>> from shapely.geometry import LineString
>>> line = LineString([(0, 0), (1, 1)])
>>> line.length
1.4142135623730951

Bunun yerine, uzunluğu metre cinsinden ifade etmek istiyorsanız, pyproj kullanarak geometrilerinizi WGS84'ten yansıtılmış bir SRS'ye dönüştürmeniz gerekir (veya daha iyisi, jeodezik mesafe hesaplaması gerçekleştirin, bkz. Gene'nin cevabı). Ayrıntılı olarak, 1.2.18 ( shapely.__version__) sürümü ile birlikte kullanabileceğimiz geometri dönüştürme işlevlerini ( http://toblerity.org/shapely/shapely.html#module-shapely.ops ) shapelydestekliyoruz . İşte kısa bir örnek:pyproj

from shapely.geometry import LineString
from shapely.ops import transform
from functools import partial
import pyproj

line1 = LineString([(15.799406, 40.636069), (15.810173,40.640246)])
print(str(line1.length) + " degrees")
# 0.0115488362184 degrees

# Geometry transform function based on pyproj.transform
project = partial(
    pyproj.transform,
    pyproj.Proj('EPSG:4326'),
    pyproj.Proj('EPSG:32633'))

line2 = transform(project, line1)
print(str(line2.length) + " meters")
# 1021.77585965 meters
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.