Ich kehre zu diesem Problem zurück, da es sehr ähnlich zu Wie finde ich Vektorlinienpeilung in QGIS oder GRASS? und es kann mit Python auf die gleiche Weise gelöst werden:
1) Haversine Abstand
Man kann viele Skripte finden, indem man die Haversine-Entfernung mit Python im Internet durchsucht, und ich wähle eine davon in der Haversine-Formel in Python (Peilung und Entfernung zwischen zwei GPS-Punkten).
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
Wir haben eine Reihe von Linien (Punkten) in der Datei, die paarweise behandelt werden müssen (Punkt1 - Punkt2), um die Entfernung zu berechnen. Dazu verwenden wir einen einfachen Iterator von Most Python, um das vorherige Element zu erhalten
def offset(iterable):
prev = None
for elem in iterable:
yield prev, elem
prev = elem
Jetzt ist es möglich, die Datei (Beispiel von Kerrie) in Linien- / Punktpaaren zu lesen
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'})
Erstellen Sie dann mit den Python-Modulen Shapely und Fiona von Sean Gillies ein Shapefile, das die ursprünglichen Felder der CSV-Datei und ein neues Feld für die Entfernung enthält:
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)})
und das Ergebnis:
Es ist auch möglich, dies mit PyQGIS zu tun, aber es ist komplexer als Fiona, das einfache Wörterbücher zum Erstellen von Shapefiles verwendet.
Sie können problemlos eine andere Funktion verwenden, um die Haversine-Entfernung zu berechnen ( Warum ist das Cosinusgesetz bei der Berechnung der Entfernung zwischen zwei Breiten- und Längengradpunkten dem Haversine vorzuziehen? ). Nur die Entfernungsberechnung ändert sich, nicht der Prozess der Erstellung des Shapefiles.