Bagaimana cara menghitung jarak dalam urutan titik?

8

Saya mencari bantuan untuk menghitung jarak antara urutan titik yang ada di Shapefile tunggal di QGIS. Di bawah ini adalah tampilan data saya dan kolom jarak kosong yang saya tambahkan untuk menunjukkan betapa saya ingin melihat jarak. Saya ingin tahu jarak antara titik 1 dan 2, 2 dan 3, dll. Saya ingin jarak menjadi dalam meter atau Km, tetapi saat ini Shapefile saya dalam proyeksi dengan satuan desimal.

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    ?

Sejumlah orang telah mengajukan pertanyaan serupa, tetapi tidak ada yang mengerti apa yang ingin saya lakukan. Posting ini dekat, tetapi ini di PostGIS, bukan QGIS Menghitung jarak antara serangkaian titik di postgis

Posting ini membuat saya menjadi bagian dari perjalanan ke sana, tetapi karena saya baru di QGIS, jawabannya tidak memberikan cukup detail bagi saya. Sebagai contoh, setelah saya menginstal plugin GRASS, saya pikir saya perlu menyimpan / mengimpor Shapefile dengan serangkaian titik GPS saya ke GRASS sehingga saya dapat menggunakan modul v.distance, tetapi saya tidak tahu bagaimana cara melakukannya . QGIS menghitung jarak titik di sepanjang garis

Apakah modul GRASS v.distance satu-satunya cara untuk pergi? Atau ada jalan yang lebih lurus ke depan? Jika v. Jarak adalah satu-satunya cara seseorang dapat mengarahkan saya atau menjelaskan lebih banyak langkah demi langkah bagaimana melakukan ini?

Kerrie
sumber
@underdark Bagaimana kita bisa melakukan itu di excel?
user2207232

Jawaban:

8

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: masukkan deskripsi gambar di sini

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.

gen
sumber
5

Jika Anda terbiasa dengan r, coba gunakan kombinasi paket 'sp' dan 'dismo'.

Misalnya seperti ini (dengan asumsi memiliki titik dengan koordinat x, y):

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
Curlew
sumber
3

Mungkin alat matriks jarak mungkin membantu? Itu di bawah menu Vector. Untuk setiap titik ini akan menghitung jarak ke masing-masing titik lainnya dan menyimpan hasilnya dalam file CSV.

Jika Anda ingin jarak dalam meter, saya pikir akan masuk akal untuk mengubah poin Anda dari lat / lon ke shapefile yang diproyeksikan (mungkin UTM51 dalam kasus Anda) sebelum menggunakan alat.

N.

nhopton
sumber
0

Gunakan v.to.db dalam GRASS (mis. Via plugin Sextante) dengan opsi = panjang (panjang garis).

Contoh mengunggah panjang garis (dalam meter) dari setiap garis vektor ke tabel atribut (isi bidang yang sesuai di GUI):

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

markN
sumber
0

Saya menemukan masalah ini paling mudah diselesaikan dengan bekerja di spreadsheet, jangan gunakan gis. Saya menemukan karya Chris Veness sangat membantu -

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

Jika Anda menggulir paragraf bawah, Anda akan menemukan tautan ke dua lembar excel, yaitu;

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

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

Lihat juga;

Mengapa hukum cosinus lebih disukai daripada haversine ketika menghitung jarak antara dua titik lintang-bujur?

dan Anda dapat mencari gis.se untuk haversine.

Bersulang

Willy
sumber
Apakah Anda memerlukan bantuan untuk mendapatkan data dari shapefile ke spreadsheet?
Willy