Wie berechnet man Entfernungen in einer Punktfolge?

8

Ich suche Hilfe bei der Berechnung des Abstands zwischen einer Folge von Punkten, die sich in einem einzelnen Shapefile in QGIS befinden. Im Folgenden sehen Sie, wie meine Daten aussehen, und eine leere Abstandsspalte, die ich hinzugefügt habe, um zu zeigen, wie die Entfernung aussehen soll. Ich möchte den Abstand zwischen Punkt 1 und 2, 2 und 3 usw. wissen. Ich möchte, dass der Abstand in Metern oder km angegeben wird, aber derzeit befindet sich mein Shapefile in einer Projektion, deren Einheiten Dezimalgrade sind.

ID  LAT         LON         TIME        DISTANCE
1   10.08527    124.59833   21:24:37    0
2   10.08523    124.59830   21:25:07    ?
3   10.08526    124.59832   21:25:37    ?
4   10.08526    124.59831   21:26:07    ?

Eine Reihe von Leuten haben ähnliche Fragen gestellt, aber keiner versteht genau, was ich tun möchte. Dieser Beitrag ist in der Nähe, aber dies ist in PostGIS, nicht in QGIS. Berechnen Sie die Abstände zwischen Punktserien in Postgis

Dieser Beitrag hat mich auf dem Weg dorthin dorthin gebracht, aber da ich neu bei QGIS bin, bietet die Antwort nicht genügend Details für mich. Wenn ich beispielsweise das GRASS-Plugin installiert habe, muss ich das Shapefile mit meiner Reihe von GPS-Punkten in GRASS speichern / importieren, damit ich das v.distance-Modul verwenden kann, aber ich weiß nicht, wie das geht . QGIS berechnet die Entfernung des Punkts entlang einer Linie

Ist das GRASS v.distance-Modul der einzige Weg? Oder gibt es einen direkteren Weg? Wenn v.distance der einzige Weg ist, kann mich jemand darauf hinweisen oder Schritt für Schritt erklären, wie das geht?

Kerrie
quelle
@underdark Wie können wir das in Excel machen?
user2207232

Antworten:

8

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: Geben Sie hier die Bildbeschreibung ein

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.

Gen
quelle
5

Wenn Sie mit r vertraut sind, versuchen Sie es mit einer Kombination aus dem Paket 'sp' und 'dismo'.

Zum Beispiel so (vorausgesetzt, es gibt Punkte mit x-, y-Koordinaten):

library(sp)
library(dismo)

data <- read.csv2(..) # Read in your data
coordinates(data) <- ~x+y # point them to your coordinates to make a spatialpoint layer
# Or like this:
Pointlayer <- SpatialPoints(cbind(data$x,data$y))


# then calculate your distance matrix your point sequence
d <- pointDistance(pp,longlat=F)

# Looks for example like this:
head(d)
          [,1]     [,2]     [,3]     [,4]     [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]  0.000000       NA       NA       NA       NA   NA   NA   NA   NA    NA    NA    NA
[2,] 54.561891  0.00000       NA       NA       NA   NA   NA   NA   NA    NA    NA    NA
[3,] 25.000000 73.49830  0.00000       NA       NA   NA   NA   NA   NA    NA    NA    NA
[4,] 50.487622 43.93177 53.14132  0.00000       NA   NA   NA   NA   NA    NA    NA    NA
[5,]  4.123106 57.00877 26.30589 54.58938  0.00000   NA   NA   NA   NA    NA    NA    NA
[6,] 32.249031 37.21559 57.14018 60.30755 32.01562    0   NA   NA   NA    NA    NA    NA

#More information about the method in dismo package help
Brachvogel
quelle
3

Vielleicht hilft das Distanzmatrix-Tool? Es ist unter dem Vektor-Menü. Für jeden Punkt wird der Abstand zu jedem der anderen Punkte berechnet und das Ergebnis in einer CSV-Datei gespeichert.

Wenn Sie die Entfernungen in Metern angeben möchten, ist es meiner Meinung nach sinnvoll, Ihre Punkte von lat / lon in ein projiziertes Shapefile (in Ihrem Fall möglicherweise UTM51) umzuwandeln, bevor Sie das Tool verwenden.

N.

nhopton
quelle
0

Verwenden Sie v.to.db in GRASS (z. B. über das Sextante-Plugin) mit der Option = Länge (Zeilenlänge).

Beispiel für das Hochladen von Zeilenlängen (in Metern) jeder Vektorzeile in die Attributtabelle (füllen Sie die entsprechenden Felder in der GUI aus):

v.to.db map=roads option=length type=line col=linelength units=me

markusN
quelle
0

Ich finde, dass dieses Problem am einfachsten zu lösen ist, indem man in einer Tabelle arbeitet. Verwenden Sie nicht das GIS. Ich fand die Arbeit von Chris Veness sehr hilfreich -

http://www.movable-type.co.uk/scripts/latlong.html

Wenn Sie im unteren Absatz scrollen, finden Sie Links zu zwei Excel-Tabellen:

http://www.movable-type.co.uk/scripts/latlong-distance+bearing.xls

http://www.movable-type.co.uk/scripts/latlong-dest-point.xls

Siehe auch;

Warum ist das Kosinusgesetz bei der Berechnung der Entfernung zwischen zwei Breiten- und Längengradpunkten dem Haversinus vorzuziehen?

und Sie können gis.se nach haversine durchsuchen.

Prost

Willy
quelle
Benötigen Sie Hilfe, um die Daten aus dem Shapefile in die Tabelle zu übertragen?
Willy