Saya kembali ke masalah ini karena sangat mirip dengan Bagaimana saya menemukan bantalan garis vektor di QGIS atau GRASS? dan itu bisa diselesaikan dengan Python dengan cara yang sama:
1) Jarak Haversine
Satu dapat menemukan banyak skrip dengan mencari jarak Haversine dengan Python di Internet dan saya memilih salah satu dari mereka dalam rumus Haversine dengan Python (Bearing dan Jarak antara dua titik 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
Kami memiliki serangkaian garis (titik) dalam file yang harus diperlakukan berpasangan (titik1 - titik2) untuk menghitung jarak. Untuk ini kita akan menggunakan iterator sederhana dari cara Most pythonic untuk mendapatkan elemen sebelumnya
def offset(iterable):
prev = None
for elem in iterable:
yield prev, elem
prev = elem
Sekarang dimungkinkan untuk membaca file (contoh Kerrie) berpasangan garis / titik
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'})
Kemudian buat shapefile yang berisi bidang asli file csv dan bidang baru untuk jarak dengan modul Python Shapely dan Fiona dari 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)})
dan hasilnya:
Dimungkinkan juga untuk melakukannya dengan PyQGIS tetapi lebih kompleks daripada Fiona yang menggunakan kamus sederhana untuk membuat shapefile.
Anda dapat menggunakan fungsi lain untuk menghitung jarak Haversine ( Mengapa hukum cosinus lebih disukai daripada haversine ketika menghitung jarak antara dua titik lintang-bujur? ) Tanpa masalah, hanya perhitungan jarak yang berubah, bukan proses pembuatan shapefile.