Работа с проектными файлами .qgs в PyQGis

Вопросы по свободной ГИС QGIS. Сообщения об ошибках, предложения по улучшению, локализация.
Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 10 апр 2012, 13:39

Доброго времени суток. Собственно вопрос в следующем: существуют ли встроенные методы работы с проектными файлами .qgs. Например, что-то вроде QgsLoadProject. Как вообще в PyQGis работать с проектными файлами? Все статьи, которые я смог нагуглить - это описание процесса загрузки слоев(векторных или растровых). Но векторный слой - это еще далеко не все. Если открыть проектный файл блокнотом, то там достаточно большой объем информации. Пожалуйста, если есть люди с положительным опытом работы с проектными файлами .qgs, поделитесь инфой или ссылками на мануалы, а если еще и пример на python - это будет вообще шикарно!
Заранее спасибо!

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Voltron » 10 апр 2012, 14:59

Существуют.
Смотрим описание QGIS API и что видим? Правильно, класс QgsProject

Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 10 апр 2012, 17:33

Спасибо за ответ, но мои познания в данном вопросе больше 0.0 :) Класс QgsProject я уже ковырял. Это первое, с чего я начал, но, насколько я понял, при помощи этого класса можно только парсить проектный файл. Каким образом с ним работать? Загружать из проекта все настройки, а дальше? У Canvas тоже есть методы чтения проектного файла. А при помощи QXml я и сам прекрасно могу парсить файлы qgs. Меня интересует алгоритм работы с проектным файлом именно для отрисовки карты. Т.е. какие опции необходимо считать из qgs, и куда эти опции потом распихать? В CookBook ничего про это не нашел. Вывод на конву векторных слоев не интересует, ибо эта задача тревиальна и решена уже давно.
Еще раз спасибо за ответ!

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Voltron » 10 апр 2012, 19:22

Togran писал(а):Спасибо за ответ, но мои познания в данном вопросе больше 0.0 :) Класс QgsProject я уже ковырял. Это первое, с чего я начал, но, насколько я понял, при помощи этого класса можно только парсить проектный файл.
Извините, но из вашего первого сообщения это не очевидно. А тратить свое время на уточняющие вопросы и игры в телепатов мне надоело.
Togran писал(а):Каким образом с ним работать? Загружать из проекта все настройки, а дальше?
Вот через QgsProject и работайте. Вызов QgsProject->read() загрузит ваши слои, установит СК и охват, активирует перепроецирование и т.д. Какие еще настройки вам нужны: цвет фона? Считывайте его через readNumEntry() и «пихайте» в QgsMapCanvas->setCanvasColor()

Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 11 апр 2012, 13:34

Voltron писал(а): Вот через QgsProject и работайте. Вызов QgsProject->read() загрузит ваши слои, установит СК и охват, активирует перепроецирование и т.д. Какие еще настройки вам нужны: цвет фона? Считывайте его через readNumEntry() и «пихайте» в QgsMapCanvas->setCanvasColor()
Т.е. если я правильно Вас понял, то алгоритм такой (python):
prj = QgsProject.instance()
prj.setFileName("....qgs")
prj.read()

Настройки я считал, но вот что делать дальше? Вытаскивать эти настройки при помощи prj.readEntry(...), а потом передавать конве? Не очень понятно назначение параметров метода readEntry. Что такое scope, def, key и ok? Информации тут http://qgis.org/api/ очень мало. Если можно, приведите пример типа

entry = prj.readEntry(BLA BLA BLA)
QgsMapCanvas.setBLABLABLA(entry)

Заранее спасибо!

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Voltron » 11 апр 2012, 14:20

Togran писал(а):Настройки я считал, но вот что делать дальше? Вытаскивать эти настройки при помощи prj.readEntry(...), а потом передавать конве?
Да, именно так. Кстати, эти настройки можно по пальцам пересчитать.
Togran писал(а):Не очень понятно назначение параметров метода readEntry. Что такое scope, def, key и ok?
scope — раздел в котором находится ключ, например "Gui"
key — собственно название ключа, например "/CanvasColorRedPart" (обратите внимание на слеш в начале!)
def — значение по умолчанию
ok — признак успешного заверщения операции
Togran писал(а):Если можно, приведите пример типа
Для консоли

Код: Выделить всё

from qgis.core import *
from PyQt4.QtCore import *
proj = QgsProject.instance()
proj.read( QFileInfo( "/path/to/project.qgs" ) )
r, ok = proj.readNumEntry( "Gui", "/CanvasColorRedPart", 0 )
g, ok = proj.readNumEntry( "Gui", "/CanvasColorGreenPart", 0 )
b, ok = proj.readNumEntry( "Gui", "/CanvasColorBluePart", 0 )
col = QColor( r, g, b )
qgis.utils.iface.mapCanvas().setCanvasColor( col )
qgis.utils.iface.mapCanvas().refresh()

Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 12 апр 2012, 15:24

Voltron писал(а): Да, именно так. Кстати, эти настройки можно по пальцам пересчитать.
Это радует. А не существует ли механизма передать все параметры и слои, считанные из проектного файла на конву в автоматическом режиме(что-то типа QgsMapCanvas.readProject(proj))? Я написал прогу, которая считывает необходимы мне параметры для каждого слоя. Осталось только передать все эти данные на QgsMapCanvas(), но я плохо себе представляю, как это проще всего сделать. К примеру я прочитал из проектного файла информацию о слоях, их названиях и типах. Но мне нужны не все слои, а только часть из них. Я считываю информацию только об этих слоях при помощи
QgsProject.read(layers[index]), где layers - это elementByTagName("maplayer") из распарсенного проектного файла, но вот как мне теперь отобразить все это безобразие? Передавать слои вместе с их параметрами вручную в цикле кажется мне не совсем рациональным занятием. Подскажите, пожалуйста как это правильнее всего сделать.
Спасибо!

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Voltron » 12 апр 2012, 15:36

Togran писал(а):А не существует ли механизма передать все параметры и слои, считанные из проектного файла на конву в автоматическом режиме(что-то типа QgsMapCanvas.readProject(proj))?
Если правильно вас понял, то QgsProject.read() именно это и делает
Togran писал(а):Но мне нужны не все слои, а только часть из них... Подскажите, пожалуйста как это правильнее всего сделать.
Правильнее всего не включать в проект ненужные слои.

Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 13 апр 2012, 09:50

Voltron писал(а): Если правильно вас понял, то QgsProject.read() именно это и делает
Т.е. после того, как я прочитал проектный файл методом QgsProject.read(), мне достаточно сделать QgsMapCanvas.refresh() и все считанные слои отобразятся? Или нужны какие-то предварительные действия?

P.S. Надеюсь, я не утомил Вас своими вопросами:) К сожалению документация по API QGis крайне скудная, а CookBook не дает ответы на все вопросы... Возможно эта тема поможет многим людям. Когда моя программа заработает адекватно, я выложу исходные коды на Питоне(если это не запрещено правилами конечно же).

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Voltron » 13 апр 2012, 16:33

Togran писал(а):Т.е. после того, как я прочитал проектный файл методом QgsProject.read(), мне достаточно сделать QgsMapCanvas.refresh() и все считанные слои отобразятся? Или нужны какие-то предварительные действия?
Слои отобразятся сразу же после read(), обновление канвы необходимо при смене цвета фона.
Togran писал(а):К сожалению документация по API QGis крайне скудная
Как раз API описан полностью
Togran писал(а):а CookBook не дает ответы на все вопросы...
Перед ней такой задачи и не стоит
Togran писал(а):Когда моя программа заработает адекватно, я выложу исходные коды на Питоне(если это не запрещено правилами конечно же).
Единственное правило — ваша программа должна распространяться под GPL 2

Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 16 апр 2012, 10:18

Voltron писал(а): Слои отобразятся сразу же после read(), обновление канвы необходимо при смене цвета фона.
Хмммм... Возможно тупой вопрос, но все же, от какого класса мне в таком случае наследоваться, чтобы и QgsMapCanvas и QgsProject заработали вместе? Сейчас я имею два разных класса - в одном у меня как параметр QgsProject, в другом у меня происходит отрисовка слоев через QgsMapCanvas(точнее не происходит:) ) Думал сделать обращение к проектному файлу следующим образом:
Класс обработки проектного файла:

Код: Выделить всё

class ReadProj():
        ..............
     def __init__(........):
        self.project = QgsProject.instance()
Класс отрисовки:

Код: Выделить всё

class MapWidget(.....):
     def __init__(......):
     .....................
     def paint(self):
         proj = ReadProj.project
         self.canvas.refresh()
При этом на виджете ничего не отображается...
Voltron писал(а): Как раз API описан полностью
Несовсем так... API описан полностью у QT3, QT4 и то существуют недокументированные возможности.
Мало описать, что делает функция или метод, желательно еще и подробное описание входных/выходных параметров, а также возвращаемые значения и вызываемые исключения, если таковые присутствуют.
Voltron писал(а): Единственное правило — ваша программа должна распространяться под GPL 2
Само собой :)

Еще раз хочу поблагодарить за поддержание темы! Спасибо!

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Voltron » 16 апр 2012, 19:26

Togran писал(а):Хмммм... Возможно тупой вопрос, но все же, от какого класса мне в таком случае наследоваться, чтобы и QgsMapCanvas и QgsProject заработали вместе? Сейчас я имею два разных класса - в одном у меня как параметр QgsProject, в другом у меня происходит отрисовка слоев через QgsMapCanvas(точнее не происходит:) )
QMainWindow? Правда, не совсем понимаю, зачем вам еще оборачивать QgsProject и QgsMapCanvas. Мне кажется вы излишне усложняете
Togran писал(а):Несовсем так... API описан полностью у QT3, QT4 и то существуют недокументированные возможности. Мало описать, что делает функция или метод, желательно еще и подробное описание входных/выходных параметров, а также возвращаемые значения и вызываемые исключения, если таковые присутствуют.
Что ж, не буду спорить. У вас свое представление, у меня свое.

Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 17 апр 2012, 08:59

Voltron писал(а): QMainWindow? Правда, не совсем понимаю, зачем вам еще оборачивать QgsProject и QgsMapCanvas. Мне кажется вы излишне усложняете
Собственно от него я и наследуюсь для отрисовки окон... Согласен, два класса тут наверное не нужны. Сейчас перепишу в один класс. Возможно исчезнет проблемма отрисовки загружаемых из проекта слоев, но тем не менее, в чем тут может быть проблема? Почему после загрузки проекта канва остается пустой в моем случае? При этом сам QGis прекрасно открывает этот же проект и отрисовывает все слои корректно. Я заметил, что в плагинах для QGis в конструктор передается iface. Может в этом проблема?

Чуть позже отпишусь о тестировании переписанного класса...

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Voltron » 17 апр 2012, 11:39

Togran писал(а):Согласен, два класса тут наверное не нужны. Сейчас перепишу в один класс. Возможно исчезнет проблемма отрисовки загружаемых из проекта слоев, но тем не менее, в чем тут может быть проблема? Почему после загрузки проекта канва остается пустой в моем случае?
Без кода трудно сказать. Загрузка проекта выполняется корректно? Возможно, не подключены некоторые сигналы и слоты.
Togran писал(а):Я заметил, что в плагинах для QGis в конструктор передается iface. Может в этом проблема?
iface это экземпляр QgisInterface и используется модулями для взаимодействия с главным окном QGIS. В вашем случае доступ ко всем элементам есть и так.

Togran
Новоприбывший
Сообщения: 11
Зарегистрирован: 10 апр 2012, 13:26
Репутация: 0

Re: Работа с проектными файлами .qgs в PyQGis

Сообщение Togran » 17 апр 2012, 16:51

А вот собственно и код программы. Я убрал все лишнее, в том числе и 2 дополнительных класса. Все вроде бы правильно, но канва по прежнему пуста... Буду рад любым советам по поводу изменения кода!

Код: Выделить всё

# -*- coding: utf-8 -*-
"""Виджет для отображения электронных карт"""

import sys, os

from PyQt4 import QtCore, QtGui

from qgis.core import *
from qgis.gui import *
from GisCoord import *

from mainwindow_ui import Ui_MainWindow
#from LayerDialog import ReadProject
retval = False

class MapWidget(QtGui.QMainWindow, Ui_MainWindow):
    """Реализация виджета"""
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setupUi(self)
        self.setWindowTitle("QGis_Test_by_Togran")
        """Creating map"""
        self.canvas = QgsMapCanvas()
        self.project = QgsProject.instance()
        """Set Background color"""
        self.canvas.setCanvasColor(QtGui.QColor(200, 200, 255))
        self.canvas.enableAntiAliasing(False)
        self.canvas.show()
        self.layout = QtGui.QVBoxLayout(self.frame)
        self.layout.addWidget(self.canvas)
        """Creating signals"""
        self.connect(self.actionAdd, QtCore.SIGNAL("triggered()"), self.openProject)
        self.connect(self.actionZoom_In, QtCore.SIGNAL("triggered()"), self.zoomIn)
        self.connect(self.actionZoom_Out, QtCore.SIGNAL("triggered()"), self.zoomOut)
        self.connect(self.actionPan, QtCore.SIGNAL("triggered()"), self.pan)
        self.connect(self.actionZoom_Full, QtCore.SIGNAL("triggered()"), self.zoomFull)
        self.connect(self.actionExit, QtCore.SIGNAL("triggered()"), self.appExit)
        self.connect(self.canvas, QtCore.SIGNAL("xyCoordinates(QgsPoint)"), self.showCoordinates)
        """Creating menu item"""
        self.toolbar = self.addToolBar(u"Карта")
        self.toolbar.addAction(self.actionAdd)
        self.toolbar.addAction(self.actionZoom_In)
        self.toolbar.addAction(self.actionZoom_Out)
        self.toolbar.addAction(self.actionPan)
        self.toolbar.addAction(self.actionZoom_Full)
        #self.toolbar.addAction(self.actionExit)
        """Creating QGis instruments"""
        self.toolPan = QgsMapToolPan(self.canvas)
        self.toolPan.setAction(self.actionPan)
        self.toolZoomIn = QgsMapToolZoom(self.canvas, False)
        self.toolZoomIn.setAction(self.actionZoom_In)
        self.toolZoomOut = QgsMapToolZoom(self.canvas, True)
        self.toolZoomOut.setAction(self.actionZoom_Out)
        
        
        
    
    def zoomIn(self):
        """Функция приближения"""
        self.canvas.setMapTool(self.toolZoomIn)
    
    
    def zoomOut(self):
        """Функция отдаления"""
        self.canvas.setMapTool(self.toolZoomOut)
    
        
    def pan(self):
        """Функция перемещения карты"""
        self.canvas.setMapTool(self.toolPan)
    
        
    def zoomFull(self):
        """Функция максимального приближения"""
        self.canvas.zoomToFullExtent()
    
        
    def appExit(self):
        """Функция выхода из программы"""
        QgsApplication.exitQgis()
        sys.exit(retval)

        
    def openProject(self):
        """Функция добавления проекта"""
        projectPath = QtGui.QFileDialog.getOpenFileName(self, u"Открыть файл", "./",
                                                      u"QgsProject (*.qgs);;Все файлы(*.*)")
        if(projectPath.isEmpty()):
            return
        self.project.read(QtCore.QFileInfo(projectPath))
#        window = ReadProject(projectPath, self.project)
#        window.populateTable()
#        window.show()
#        window.exec_()
        self.canvas.refresh()


    def showCoordinates(self, point):
        """Функция отображения координат"""
#        coord = GisCoord()
#        self.statusbar.showMessage(coord.toStr(p))
        self.statusbar.showMessage(point.toDegreesMinutesSeconds(2))
        
def main(app):

    QgsApplication.setPrefixPath("/usr/local", True)
    QgsApplication.initQgis()
    
    wnd = MapWidget()
    wnd.show()

    retval = app.exec_()
    QgsApplication.exitQgis()
    sys.exit(retval)



if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    main(app)


Ответить

Вернуться в «QGIS»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя