Получение слоя по имени в PyQGIS?

14

У меня есть плагин, который находит буфер для списка городов, при условии расстояния. Названия штатов и городов берутся из таблицы атрибутов и соответствующим образом фильтруются. Я хочу, чтобы мой плагин определял имя слоя или порядок слоя на холсте независимо от других слоев, присутствующих на холсте, и обращался к соответствующим атрибутам этого слоя.

Мне также просто любопытно, может ли указание определенного имени слоя в коде вызвать какую-либо ошибку в итерации, хотя некоторые другие уровни присутствуют?

Ниже мой код, пожалуйста, скажите мне, где я должен внести изменения и что будет изменение?

    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)
User123
источник

Ответы:

39

ОБНОВЛЕНИЕ: 10.04.2018

Используя QGIS 3.x, вы можете использовать mapLayersByNameметод из QgsProjectкласса следующим образом:

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

Поскольку вы можете иметь несколько слоев в QGIS с одним и тем же именем на панели слоев, описанный выше метод дает вам список подходящих слоев.


Для QGIS 2.x :

Вам просто нужно убедиться, что у вашего слоя есть имя, которое вы можете отличить от других. Вместо этого layer = self.iface.activeLayer()сделайте:

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

Если вы не доверяете имени слоя (в конце концов, оно может быть изменено пользователем в любое время), вы можете попробовать проверить источник слоя. Если ваш слой является Shapefile, вы можете проверить путь к Shapefile следующим образом:

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

РЕДАКТИРОВАТЬ: Как @Jakob указал в комментариях, вы можете написать первый блок в одну строку:

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

Или:

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

В любом случае, вам нужно проверить, что layerListне пусто, прежде чем получить доступ к его первому элементу:

if layerList: 
    layer = layerList[0]
Герман Каррильо
источник
2
выведите [lyr для lyr в QgsMapLayerRegistry.instance (). mapLayers (). values ​​() if lyr.name () == "LAND"] [0] .name ()
Якоб
7
layer = QgsMapLayerRegistry.instance (). mapLayersByName ("mylayername") [0]
Jakob
почему вы устанавливаете layer = noneв начале вашего кода? Кажется ненужным, особенно если это в функции
user32882
1
Это значение по умолчанию, потому что внутри for есть if. Если if никогда не встречается, слой вообще не будет существовать после for. Итак, просто чтобы убедиться, что вы можете прочитать переменную layer впоследствии.
Герман Каррильо