Làm thế nào để tính khoảng cách trong một chuỗi điểm?


8

Tôi đang tìm kiếm sự trợ giúp để tính toán khoảng cách giữa một chuỗi các điểm trong một Shapefile duy nhất trong QGIS. Dưới đây là dữ liệu của tôi trông như thế nào và một cột khoảng cách trống tôi đã thêm để hiển thị cách tôi muốn khoảng cách nhìn. Tôi muốn biết khoảng cách giữa điểm 1 và 2, 2 và 3, v.v. Tôi muốn khoảng cách tính bằng mét hoặc Km, nhưng hiện tại Shapefile của tôi nằm trong một phép chiếu có đơn vị là độ thập phân.

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    ?

Một số người đã hỏi những câu hỏi tương tự, nhưng không ai hiểu được những gì tôi muốn làm. Bài đăng này gần, nhưng đây là trong PostGIS, không phải là QGIS Tính khoảng cách giữa các chuỗi điểm trong postgis

Bài đăng này đã cho tôi một phần của cách đó, nhưng vì tôi mới biết đến QGIS nên câu trả lời không cung cấp đủ chi tiết cho tôi. Ví dụ: khi tôi đã cài đặt plugin GRASS, tôi nghĩ rằng tôi cần lưu / nhập Shapefile với loạt điểm GPS của mình vào GRASS để tôi có thể sử dụng mô-đun v.distance, nhưng tôi không biết làm thế nào để làm điều đó . QGIS tính khoảng cách của điểm dọc theo một đường

Là mô-đun GRASS v.distance là cách duy nhất để đi? Hoặc có một cách thẳng hơn về phía trước? Nếu v.distance là cách duy nhất ai đó có thể chỉ cho tôi hoặc giải thích thêm từng bước làm thế nào để làm điều này?


@underdark Làm thế nào chúng ta có thể làm điều đó trong excel?
2207232

Câu trả lời:


8

Tôi quay trở lại vấn đề này vì nó rất giống với Làm thế nào để tôi tìm thấy dòng vectơ trong QGIS hoặc GRASS? và nó có thể được giải quyết bằng Python theo cùng một cách:

1) Khoảng cách Haversine

Người ta có thể tìm thấy rất nhiều tập lệnh bằng cách tìm kiếm khoảng cách Haversine với Python trên Internet và tôi chọn một trong số chúng trong Công thức Haversine trong Python (Mang và Khoảng cách giữa hai điểm 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

Chúng tôi có một loạt các dòng (điểm) trong tệp phải được xử lý theo cặp (điểm 1 - điểm 2) để tính khoảng cách. Để làm điều này, chúng ta sẽ sử dụng một trình vòng lặp đơn giản từ Hầu hết các cách pythonic để lấy phần tử trước đó

def offset(iterable):
    prev = None
    for elem in iterable:
        yield prev, elem
        prev = elem

Bây giờ có thể đọc tệp (ví dụ về Kerrie) theo cặp dòng / điểm

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'})

Sau đó, tạo một shapefile chứa các trường ban đầu của tệp csv và một trường mới cho khoảng cách với các mô-đun Python Shapely và Fiona của 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)})

và kết quả: nhập mô tả hình ảnh ở đây

Cũng có thể làm điều đó với PyQGIS nhưng nó phức tạp hơn Fiona, sử dụng từ điển đơn giản để tạo ra shapefiles.

Bạn có thể sử dụng một hàm khác để tính khoảng cách Haversine ( Tại sao định luật cosin thích hợp hơn haversine khi tính khoảng cách giữa hai điểm kinh độ vĩ độ? ) Mà không có vấn đề gì, chỉ có sự thay đổi tính toán khoảng cách, không phải là quá trình tạo ra shapefile.


5

Nếu bạn quen thuộc với r, hãy thử sử dụng kết hợp gói 'sp' và 'tháo dỡ'.

Ví dụ như thế này (giả sử có các điểm có tọa độ 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

3

Có lẽ các công cụ ma trận khoảng cách có thể giúp đỡ? Nó nằm trong menu Vector. Đối với mỗi điểm, điều này sẽ tính khoảng cách đến từng điểm khác và lưu kết quả vào tệp CSV.

Nếu bạn muốn khoảng cách tính bằng mét, tôi nghĩ sẽ hợp lý khi chuyển điểm của bạn từ lat / lon sang shapefile dự kiến ​​(có thể là UTM51 trong trường hợp của bạn) trước khi sử dụng công cụ.

N


0

Sử dụng v.to.db trong GRASS (ví dụ: thông qua plugin Sextante) với tùy chọn = length (độ dài dòng).

Ví dụ về tải lên độ dài dòng (tính bằng mét) của mỗi dòng vectơ vào bảng thuộc tính (điền vào các trường tương ứng trong GUI):

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


0

Tôi thấy vấn đề này dễ giải quyết nhất bằng cách làm việc trong bảng tính, không sử dụng gis. Tôi thấy công việc của Chris Veness rất hữu ích -

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

Nếu bạn cuộn đoạn dưới cùng, bạn sẽ tìm thấy các liên kết đến hai bảng excel, đó là;

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

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

Xem thêm;

Tại sao định luật cosin lại thích hợp hơn haversine khi tính khoảng cách giữa hai điểm kinh độ vĩ độ?

và bạn có thể tìm kiếm gis.se cho haversine.

chúc mừng


Bạn có cần giúp đỡ để lấy dữ liệu từ shapefile vào bảng tính không?
Willy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.