それは非常によく似ているので、私はこの問題に戻って、私はQGISやGRASSのベクトルラインのベアリングを見つけるにはどうすればよいですか?そしてそれは同じようにPythonで解決できます:
1)ハバシン距離
インターネット上のPythonでHaversine距離を検索することで多くのスクリプトを見つけることができ、私はそれらの1つをPythonのHaversine Formula(ベアリングと2つのGPSポイント間の距離)で選択します
def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(math.radians, [lon1, lat1, lon2, lat2])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.asin(math.sqrt(a))
km = 6367 * c
return km
ファイルには、距離を計算するためにペア(point1-point2)で処理する必要がある一連の線(ポイント)があります。このために、ほとんどのpythonic方法の単純なイテレータを使用して、前の要素を取得します
def offset(iterable):
prev = None
for elem in iterable:
yield prev, elem
prev = elem
これで、ライン/ポイントのペアでファイル(Kerrieの例)を読み取ることができます
import csv
with open('testhavers.csv', 'rb') as f:
reader = csv.DictReader(f)
for pair in offset(reader):
print pair
(None, {'LAT': '10.08527', 'LON': '124.59833', 'ID': '1', 'TIME': '21:24:37'})
({'LAT': '10.08527', 'LON': '124.59833', 'ID': '1', 'TIME': '21:24:37'},
{'LAT': '10.08523', 'LON': '124.59830', 'ID': '2', 'TIME': '21:25:07'})
({'LAT': '10.08523', 'LON': '124.59830', 'ID': '2', 'TIME': '21:25:07'},
{'LAT': '10.08526', 'LON': '124.59832', 'ID': '3', 'TIME': '21:25:37'})
({'LAT': '10.08526', 'LON': '124.59832', 'ID': '3', 'TIME': '21:25:37'},
{'LAT': '10.08526', 'LON': '124.59831', 'ID': '4', 'TIME': '21:26:07'})
次に、csvファイルの元のフィールドと、PythonモジュールShapelyおよびFiona of Sean Gilliesを使用して距離の新しいフィールドを含むシェープファイルを作成します。
import fiona
from shapely.geometry import Point, mapping
# creation of the schema of the shapefile (geometry and fields)
schema = { 'geometry': 'Point', 'properties':{'ID': 'int', 'LAT':'float', 'LON':'float', 'TIME':'str','distance' : 'float'}}
# creation of the shapefile:
with fiona.collection("result.shp", "w", "ESRI Shapefile", schema) as output:
# reading the csv file
with open('testhavers.csv', 'rb') as f:
reader = csv.DictReader(f)
# we need here to eliminate the first pair of point with None
for i, pair in enumerate(offset(reader)):
if i == 0: (pair with None)
# writing of the point geometry and the attributes
point = Point(float(pair[1]['LON']), float(pair[1]['LAT']))
dist = 0 # None
output.write({'properties': {'ID':int(pair[1]['ID']),'LAT':float(pair[1]['LAT']),'LON':float(pair[1]['LON']), 'TIME':pair[1]['TIME'],'distance': dist},'geometry': mapping(point)})
else:
# writing of the point geometry and the attributes
point = Point(float(pair[1]['LON']), float(pair[1]['LAT']))
# Haversine distance between pairs of points
dist = haversine(float(pair[0]['LON']), float(pair[0]['LAT']), float(pair[1]['LON']),float(pair[1]['LAT']))
output.write({'properties': {'ID':int(pair[1]['ID']),'LAT':float(pair[1]['LAT']),'LON':float(pair[1]['LON']), 'TIME':pair[1]['TIME'],'distance': dist},'geometry': mapping(point)})
そして結果:
PyQGISでそれを行うことも可能ですが、シンプルな辞書を使用してシェープファイルを作成するFionaよりも複雑です。
別の関数を使用して、Haversine距離を計算できます(2つの緯度と経度のポイント間の距離を計算するときに、コサインの法則が hasrsine よりも好ましいのはなぜですか?)、問題なく、距離計算のみが変更され、シェープファイルの作成プロセスは変更されません。