Tạo điểm tương đương trong QGIS?


22

Tôi đang cố gắng tạo các điểm (lớp mới) ở khoảng cách cụ thể dọc theo con đường (lớp hiện tại) trong QGIS. Tạo điểm thường xuyên mỗi mét ở cấp quận bằng ArcGIS Desktop? đưa ra giải pháp cho ArcGIS. Làm thế nào để đạt được điều này trong QGIS? Thêm điểm vào lớp vectơ điểm bằng cách sử dụng QGIS? giải thích cách tạo điểm nhưng không làm gì về khoảng cách.


(Tôi đã áp dụng các giải pháp được đề xuất với các số đo độ dài khác nhau mà tôi không biết chuyển đổi)

nhập mô tả hình ảnh ở đây. Ở đây, hình chiếu của các điểm tương đương này khác với đường ban đầu.

Với đề nghị của @ underdark, tôi đã nhận

bức ảnh nàytrong đó các điểm dường như không tương đương nhau. Tôi đoán có một số vấn đề dự đoán với cả hai điều này mà tôi không hiểu.



2
Một vài điểm. Đầu tiên, dòng phải nằm trong CRS dự kiến ​​(không phải lat / lon). Thứ hai, dòng của bạn là một polyline thực sự? Tôi không nghĩ rằng bất kỳ phương pháp nào sẽ hoạt động đúng trên một dòng bao gồm một chuỗi các dòng riêng lẻ. Nick.
nhopton

Ngoài ra với mã của tôi, bạn không cần phải gọi import locatenhiều hơn một lần. Chỉ cần gọi một lần sau đó bạn có thể gọi locate.pointsAlongLine(30)bao nhiêu tùy ý
Nathan W

Một phương pháp khác (được đưa ra là Sextant như được đề xuất bởi một số câu trả lời ở đây là QGIS <chỉ 2.0), cũng là sử dụng plugin có tên QChainage.
andy

Câu trả lời:


14

Lưu ý: Hiện tại đã có plugin QGIS QChainage. Nó làm tất cả điều này và nhiều hơn nữa. Mã dưới đây đã lỗi thời với QGIS 2.0 trở lên.

Đây là một số mã Python mà bạn có thể dán vào một tệp và sử dụng bên trong QGIS:

QGIS có một phương thức trong API để thực hiện tham chiếu lớp lót tuy nhiên tôi không thể làm cho nó hoạt động chính xác, nhưng tôi sẽ liên hệ với tác giả của mã và xem liệu tôi có làm gì sai không.

Còn bây giờ, bạn sẽ cần sự quyến rũ thư viện Python, mà bạn nên cài đặt anyway vì nó tiện dụng để có xung quanh. Nó cũng có tài liệu tuyệt vời tại http://toblerity.github.com/shapely/manual.html

Đây là phần tôi đang sử dụng trong ví dụ sau http://toblerity.github.com/shapely/manual.html#interoperation .

Hầu hết các mã sau đây là mã soạn sẵn của QGIS chỉ tạo các tính năng, các lớp, chuyển đổi từ wkb và wkt và trở lại. Bit cốt lõi là bit point = line.interpolate(currentdistance)trả về một điểm ở khoảng cách dọc theo đường thẳng. Chúng tôi chỉ gói cái này trong một vòng lặp cho đến khi hết dòng.

import qgis
from qgis.core import *
from PyQt4.QtCore import QVariant
from shapely.wkb import loads
from shapely.wkt import dumps

vl = None
pr = None

def createPointsAt(distance, geom):
    if distance > geom.length():
        print "No Way Man!"
        return

    length = geom.length()
    currentdistance = distance
    feats = []  

    while currentdistance < length: 
        line = loads(geom.asWkb())
        point = line.interpolate(currentdistance)
        fet = QgsFeature()
        fet.setAttributeMap( { 0 : currentdistance } )
        qgsgeom = QgsGeometry.fromWkt(dumps(point))
        fet.setGeometry(qgsgeom)
        feats.append(fet)
        currentdistance = currentdistance + distance

    pr.addFeatures(feats)
    vl.updateExtents()

def pointsAlongLine(distance):
    global vl
    vl = QgsVectorLayer("Point", "distance nodes", "memory")
    global pr
    pr = vl.dataProvider()  
    pr.addAttributes( [ QgsField("distance", QVariant.Int) ] )
    layer = qgis.utils.iface.mapCanvas().currentLayer()
    for feature in layer.selectedFeatures():
        geom = feature.geometry()
        createPointsAt(distance, geom)

    QgsMapLayerRegistry.instance().addMapLayer(vl)

Sao chép và dán mã ở trên vào tệp, tôi đã gọi hàm locine của tôi, trong ~./qgis/pythonthư mục (vì nó nằm trong đường dẫn Python) và chỉ cần thực hiện việc này trong bảng điều khiển Python bên trong QGIS.

 import locate
 locate.pointsAlongLine(30)

Điều đó sẽ tạo ra một lớp điểm mới với các điểm ở mỗi 30 mét dọc theo các đường đã chọn, như vậy:

nhập mô tả hình ảnh ở đây

Lưu ý: Mã khá thô và có thể cần phải dọn sạch.

EDIT: Bản dựng devISIS mới nhất hiện có thể thực hiện điều này một cách tự nhiên.

Thay đổi vòng lặp while createPointsAtthành:

 while currentdistance < length: 
    point = geom.interpolate(distance)
    fet = QgsFeature()
    fet.setAttributeMap( { 0 : currentdistance } )
    fet.setGeometry(point)
    feats.append(fet)
    currentdistance = currentdistance + distance

và bạn có thể loại bỏ

from shapely.wkb import loads
from shapely.wkt import dumps

Cảm ơn @Nathan. Tôi không thể có được gói Shapely cho con trăn của tôi. Tôi đã cài đặt python 2.7 nhưng trình cài đặt Shapely nói rằng python 2.7 không có trong sổ đăng ký của tôi. Có cách nào khác để cài đặt Shapely.
Stat-R

Tôi đã theo dõi stackoverflow.com/questions/3652625/ và gõ hai dòng trên để gọi locatevà sử dụng nó nhưng tôi vẫn không nhận được các điểm tương đương. Ngoài ra, tôi là người mới sử dụng Python nên tôi không hiểu chạy mã (1) python ở đâu trong thư mục qgis hoặc (2) tại C: \ Python27 \?
Stat-R

Bạn đang dùng hệ điều hành nào?
Nathan W

Windows 7 Professional
Stat-R

tạo tệp python C:\Users\{you user name}\.qgis\pythonsau đó khởi động lại QGIS nếu mở và đi tới `Plugins-> Python Console . Load a line layer, select a line a call nhập xác định vị trí` vàlocate.pointsAlongLine(30)
Nathan W

5

Bạn có thể sử dụng công cụ v.to.point plugin QGIS GRASS để tạo các điểm dọc theo các dòng đều đặn

# convert line to points; dmax = distance between points
v.to.points -i -v -t in=road out=road_pts type=line dmax=90

Tôi đã sử dụng dmax là 100 và các phép chiếu kết quả cho mỗi lần như sau. (Tôi không biết làm thế nào CRS được chỉ định bởi chính nó.)CRS of Original Shape file, the line = EPSG:26915 - NAD83 / UTM zone 15N, CRS of Grass line vector obtained using v.in.ogr = EPSG:4269 - NAD83, CRS of Grass points vector obtained using v.to.points = EPSG:4326 - WGS 84
Stat-R

Bây giờ cũng như thế này: QGIS -> Sextante -> GRASS -> v.to.point
markusN

5

Nếu bạn muốn vẽ sơ đồ chuỗi theo các khoảng cố định dọc theo một tuyến đường, bạn có thể sử dụng trình cắm 'Hồ sơ từ đường' để thực hiện việc này. Bạn cần một DEM dưới lớp đường, nhưng thủ tục nhanh chóng và rất đơn giản. Nick.

nhập mô tả hình ảnh ở đây


Đây là một phương pháp khá tốt và dễ dàng, cảm ơn!
Shepherdjo

2

Coi chừng rằng mô hình dữ liệu Shapely (Python) / GEOS (C ++) được xác định trong một mặt phẳng. Vì vậy, nếu các điểm của bạn bao gồm các vị trí GPS (vĩ độ, kinh độ) bằng shapely.geometry.LineString.interpolate(distance)phương pháp sẽ xuất ra một vị trí GPS ở khoảng cách euclide dọc theo vị trí đã cho LineString.

Shapely's interpolate()dựa trên geos::linearref::LengthIndexedLinelớp GEOS bằng extractPointphương pháp này.

Giả sử phép nội suy cách đều nhau trong mặt phẳng kinh độ - vĩ độ là đủ cho các ứng dụng xem xét khoảng cách tương đối nhỏ. Tuy nhiên, nói chung, người ta nên xem xét khoảng cách trên một quả cầu cho các ứng dụng GIS (như được định nghĩa trong WGS84 ).

Tôi có thể nghĩ về hai cách giải quyết bằng mô-đun Shapely:

  • LineStringcác thuộc tính là tất cả các điểm đã cho và các đường cong nội suy tuyến tính dọc theo chúng. Có lẽ bạn có thể viết một thành viên truy cập vào các đường cong nội suy và thực hiện tích phân dòng sau thay thế khoảng cách euclide. Tôi thích cách tiếp cận này bởi vì sử dụng đường cong liên tục khôn ngoan, có thể thu được các điểm mong muốn bằng cách tính các giao điểm của các vòng tròn liền kề dọc theo đường cong với bán kính r = radian_measure(arc_length) = arc_length / R, trong đó R bằng bán kính của Trái đất tại vị trí đã cho.
  • mã phương thức nội suy của riêng bạn (không chạm vào mã Shapely) bằng cách sử dụng hàm khoảng cách thích hợp (ví dụ: công thức haversine).

Để đạt được điều này, tôi muốn tham khảo câu hỏi StackOverflow sau đây và câu trả lời này cụ thể:

Nó có thể tạo ra các điểm tương đương dọc theo đường cong. Nhưng phải có nhiều định nghĩa hơn về những gì bạn muốn cho một câu trả lời thực sự. Xin lỗi, nhưng mã tôi đã viết cho nhiệm vụ này là trong MATLAB, nhưng tôi có thể mô tả các ý tưởng chung. Có ba khả năng.

Đầu tiên, các điểm có thực sự tương đương với các nước láng giềng về khoảng cách Euclide đơn giản không? Để làm như vậy sẽ liên quan đến việc tìm giao điểm tại bất kỳ điểm nào trên đường cong với một vòng tròn bán kính cố định. Sau đó chỉ cần bước dọc theo đường cong.

Tiếp theo, nếu bạn dự định khoảng cách có nghĩa là khoảng cách dọc theo đường cong, nếu đường cong là đường thẳng tuyến tính, thì vấn đề lại dễ thực hiện. Chỉ cần bước dọc theo đường cong, vì khoảng cách trên một đoạn đường là dễ dàng để đo.

Cuối cùng, nếu bạn có ý định cho đường cong là một khối vuông, một lần nữa, điều này không khó lắm, nhưng sẽ tốn công hơn một chút. Đây là mẹo:

  • Tính toán arclength tuyến tính từ điểm này đến điểm khác dọc theo đường cong. Gọi nó là t. Tạo một cặp splines hình khối, x (t), y (t).

  • Phân biệt x và y là các hàm của t. Vì đây là các phân đoạn khối, điều này là dễ dàng. Các hàm phái sinh sẽ là
    bậc hai.

  • Sử dụng một bộ giải ode để di chuyển dọc theo đường cong, tích hợp hàm arclength vi sai. Trong MATLAB, ODE45 hoạt động độc đáo.

Do đó, một tích hợp

sqrt((x')^2 + (y')^2)

Một lần nữa, trong MATLAB, ODE45 có thể được đặt để xác định các vị trí mà hàm vượt qua các điểm được chỉ định nhất định.

Nếu các kỹ năng MATLAB của bạn phụ thuộc vào nhiệm vụ, bạn có thể xem mã trong interparc để được giải thích thêm. Đó là mã nhận xét hợp lý tốt.

3 : http://www.mathworks.com/matlabcentral/fileexchange/34874-interparc


1

Sextante có một công cụ có thể phù hợp với bạn. Sextante có thể được tải xuống từ kho lưu trữ plugin Qgis.

Tìm kiếm:
"Công cụ cho các lớp
đường thẳng" "Đường tới các điểm không thể thay thế"


Plugin này dường như không có sẵn cho QGIS 2 hoặc 3.
Martin Burch
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.