Отримання шару по імені в PyQGIS?


15

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

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

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

    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)

Відповіді:


41

ОНОВЛЕННЯ: 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

EDIT: Як @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
print [lyr for lyr в QgsMapLayerRegistry.instantion (). mapLayers (). значень (), якщо lyr.name () == "ЗЕМЛЯ"] [0] .name ()
Якоб

7
слой = QgsMapLayerRegistry.instantion (). mapLayersByName ("ім'я мого імені") [0]
Якоб

чому ви встановлюєте layer = noneна початку коду? Це здається непотрібним, особливо якщо його у функції
user32882

1
Це значення за замовчуванням, оскільки всередині "for" є "if". Якщо if ніколи не виконується, шар не буде взагалі існувати після. Отже, просто щоб переконатися, що зможете згодом прочитати змінну шару.
Герман Каррілло
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.