Bắt lớp theo tên trong PyQGIS?


14

Tôi có một plugin tìm bộ đệm cho danh sách các thành phố, cung cấp khoảng cách. Tên tiểu bang và thành phố được lấy từ bảng thuộc tính và được lọc tương ứng. Điều tôi muốn là Plugin của tôi nên xác định tên lớp hoặc thứ tự của lớp trong canvas, bất kể các lớp khác có trong canvas và truy cập các thuộc tính tương ứng từ lớp đó.

Tôi cũng chỉ tò mò liệu việc chỉ một tên lớp cụ thể trong mã sẽ gây ra bất kỳ lỗi nào trong lần lặp mặc dù có một số lớp khác không?

Dưới đây là mã của tôi xin vui lòng cho tôi biết tôi nên thay đổi ở đâu và thay đổi sẽ là gì?

    if dist and centerCity:
        #QMessageBox.information(self.dlg, "info", "both True")
        st = '"name" = \'' + centerCity + '\''
        exp = QgsExpression(st)
    else:
        QMessageBox.warning(self.dlg, "Enter the distance","Enter the distance and try again.")        
        return          #terminate the function

    layer = self.iface.activeLayer() 
    it = layer.getFeatures(QgsFeatureRequest(exp))
    feature = it.next()
    mbuf = feature.geometry().buffer(dist, 2)       

    iterFeat = layer.getFeatures()

    for f in iterFeat:
        geom2 = f.geometry()
        valTest = QgsGeometry.within(geom2, mbuf)

Câu trả lời:


38

CẬP NHẬT: 10.04.2018

Sử dụng QGIS 3.x bạn có thể sử dụng mapLayersByNamephương thức từ QgsProjectlớp theo cách này:

layers = QgsProject.instance().mapLayersByName('my layer name')

Vì bạn có thể có một vài lớp trong QGIS có cùng tên trong bảng điều khiển lớp, phương thức trên cung cấp cho bạn một danh sách các lớp phù hợp.


Đối với QGIS 2.x :

Bạn chỉ cần đảm bảo rằng lớp của bạn có một tên mà bạn có thể phân biệt với những người khác. Thay vì layer = self.iface.activeLayer(), hãy làm:

layer=None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "YOUR_LAYER_NAME":
        layer = lyr
        break

Nếu bạn không tin tưởng tên lớp (sau tất cả, người dùng có thể thay đổi tên đó bất cứ lúc nào), bạn có thể thử kiểm tra nguồn lớp. Nếu lớp của bạn là Shapefile, bạn có thể kiểm tra đường dẫn đến Shapefile, theo cách này:

layer=None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.source() == "/path/to/shapefile.shp":
        layer = lyr
        break

EDIT: Như @Jakob đã chỉ ra trong các bình luận, bạn có thể viết khối đầu tiên trong một dòng:

layerList = QgsMapLayerRegistry.instance().mapLayersByName("YOUR_LAYER_NAME")

Hoặc là:

layerList = [lyr for lyr in QgsMapLayerRegistry.instance().mapLayers().values() if lyr.name() == "YOUR_LAYER_NAME"]

Dù sao, bạn sẽ cần kiểm tra xem nó layerListcó trống không trước khi truy cập phần tử đầu tiên của nó:

if layerList: 
    layer = layerList[0]

2
in [LYR cho LYR trong QgsMapLayerRegistry.instance () mapLayers () giá trị () nếu lyr.name () == "ĐẤT"..] [0] .name ()
Jakob

7
layer = QssMapLayerRegistry.instance (). mapLayersByName ("mylayername") [0]
Jakob

Tại sao bạn lại thiết lập layer = noneở đầu mã của mình? Có vẻ như không cần thiết đặc biệt là nếu nó có chức năng
user32882

1
Đó là một giá trị mặc định, bởi vì có một nếu bên trong for. Nếu nếu không bao giờ được đáp ứng, lớp sẽ không tồn tại sau khi cho. Vì vậy, chỉ để đảm bảo bạn có thể đọc biến lớp sau đó.
Germán Carrillo
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.