|
|
Řádek 1: |
Řádek 1: |
| {{Upravit}} | | {{freegiswiki|QGIS / Tvorba zásuvného modulu krok za krokem}} |
| | |
| Stránka obsahuje poznámky pro tvorbu vlastního [http://cs.wikipedia.org/wiki/Plugin zásuvného modulu] pro aplikaci [[QGIS]]. Navržený modul má na vstupu dvě vektorové vrstvy - bodovou a polygonovou. Na výstupu vytvoří novou vektorovou vrstvu obsahující pouze body ležící uvnitř polygonů (viz [[Programování s knihovnou OGR#Prostorové predikáty|příklad pro knihovnu OGR]]). Uvedený text čerpá především z [http://download.osgeo.org/qgis/doc/manual/qgis-1.5.0_coding-compilation_guide_en.pdf QGIS Coding and Compilation Guide]. Zdrojové texty najdete [http://geo.fsv.cvut.cz/~landa/vyuka/2010/qgis/sampleplugin/ zde].
| |
| | |
| __TOC__
| |
| == Minimální kód ==
| |
| | |
| Projekt obsahuje tři soubory:
| |
| | |
| ; Soubor projektu sampleplugin.pro
| |
| | |
| <source lang="cpp">
| |
| # cesta k adresari se zdrojovymi texty QGISu
| |
| QGIS_DIR = /opt/src/qgis_trunk
| |
| TEMPLATE = lib
| |
| CONFIG = qt
| |
| QT += xml
| |
| unix:LIBS += -L/$$QGIS_DIR/lib \
| |
| -lqgis_core \
| |
| -lqgis_gui
| |
| INCLUDEPATH += $$QGIS_DIR/src/ui \
| |
| $$QGIS_DIR/src/plugins \
| |
| $$QGIS_DIR/src/gui \
| |
| $$QGIS_DIR/src/raster \
| |
| $$QGIS_DIR/src/core \
| |
| $$QGIS_DIR
| |
| SOURCES = qgssampleplugin.cpp
| |
| HEADERS = qgssampleplugin.h
| |
| DEST = sampleplugin.so
| |
| DEFINES += GUI_EXPORT= \
| |
| CORE_EXPORT=
| |
| </source>
| |
| | |
| ; Hlavičkový soubor pluginu qgssampleplugin.h
| |
| | |
| <source lang="cpp">
| |
| #ifndef QGSSAMPLEPLUGIN_H
| |
| #define QGSSAMPLEPLUGIN_H
| |
| | |
| #include <qgisplugin.h>
| |
| | |
| /* Testovaci plugin pro QGIS - prostorove predikaty */
| |
| class QgsSamplePlugin: public QgisPlugin
| |
| {
| |
| public:
| |
| QgsSamplePlugin(QgisInterface *);
| |
| ~QgsSamplePlugin();
| |
| | |
| void initGui();
| |
| void unload();
| |
| | |
| private:
| |
| QgisInterface *mIface;
| |
| };
| |
| | |
| #endif // QGSSAMPLEPLUGIN_H
| |
| </source>
| |
| | |
| ; C++ soubor qgssampleplugin.cpp
| |
| | |
| <source lang="cpp">
| |
| #include "qgssampleplugin.h"
| |
| | |
| #ifdef WIN32
| |
| #define QGISEXTERN extern "C" __declspec( dllexport )
| |
| #else
| |
| #define QGISEXTERN extern "C"
| |
| #endif
| |
| | |
| QgsSamplePlugin::QgsSamplePlugin(QgisInterface* iface): mIface(iface)
| |
| {
| |
| }
| |
| | |
| QgsSamplePlugin::~QgsSamplePlugin()
| |
| {
| |
| }
| |
| | |
| // Zobrazit elementy GUI nastrojove listy a menu pluginu
| |
| void QgsSamplePlugin::initGui()
| |
| {
| |
| }
| |
| | |
| // Odstranit alokovane GUI elementy
| |
| void QgsSamplePlugin::unload()
| |
| {
| |
| }
| |
| | |
| // generator pluginu
| |
| QGISEXTERN QgisPlugin* classFactory(QgisInterface* iface)
| |
| {
| |
| return new QgsSamplePlugin(iface);
| |
| }
| |
| | |
| QGISEXTERN QString name()
| |
| {
| |
| return "Within";
| |
| }
| |
| | |
| QGISEXTERN QString description()
| |
| {
| |
| return "Prostorovy predikat within";
| |
| }
| |
| | |
| QGISEXTERN QString version()
| |
| {
| |
| return "0.00001";
| |
| }
| |
| | |
| // Typ pluginu (UI nebo MapLayer plugin)
| |
| QGISEXTERN int type()
| |
| {
| |
| return QgisPlugin::UI;
| |
| }
| |
| | |
| // Odstranit plugin
| |
| QGISEXTERN void unload(QgisPlugin* theQgsSamplePluginPointer)
| |
| {
| |
| delete theQgsSamplePluginPointer;
| |
| }
| |
| </source>
| |
| | |
| == Ikonka, tlačítko a menu pluginu ==
| |
| | |
| Modifikujeme [http://doc.qgis.org/head/classQgisInterface.html QgisInterface], přidáme [http://doc.trolltech.com/4.7/qaction.html QAction] se slotem <tt>within()</tt>. Třída <tt>SamplePlugin</tt> bude odvozena z třídy [http://doc.trolltech.com/latest/qobject.html QObject].
| |
| | |
| ; Hlavičkový soubor pluginu qgssampleplugin.h
| |
| | |
| <source lang="cpp">
| |
| ...
| |
| #include <qgisplugin.h>
| |
| #include <QObject>
| |
| | |
| class QAction;
| |
| | |
| /* Testovaci plugin pro QGIS - prostorove predikaty */
| |
| class QgsSamplePlugin: public QObject, public QgisPlugin
| |
| {
| |
| Q_OBJECT // nutne pro pouziti mechanismu signalu a slotu
| |
| ...
| |
| | |
| private:
| |
| QgisInterface *mIface;
| |
| QAction *mAction;
| |
| | |
| private slots:
| |
| void within();
| |
| };
| |
| | |
| #endif // QGSSAMPLEPLUGIN_H
| |
| </source>
| |
| | |
| ; C++ soubor qgssampleplugin.cpp
| |
| | |
| <source lang="cpp">
| |
| #include <qgisinterface.h>
| |
| | |
| #include "qgssampleplugin.h"
| |
| | |
| #include <QAction>
| |
| | |
| ...
| |
| | |
| QgsSamplePlugin::QgsSamplePlugin(QgisInterface* iface): mIface(iface), mAction(0)
| |
| {
| |
| }
| |
| | |
| ...
| |
| | |
| // Zobrazit elementy GUI nastrojove listy a menu pluginu
| |
| void QgsSamplePlugin::initGui()
| |
| {
| |
| mAction = new QAction(tr("&Within"), this);
| |
| connect(mAction, SIGNAL(activated()), this, SLOT(within()));
| |
| mIface->addToolBarIcon(mAction);
| |
| mIface->addPluginToMenu(tr("&Prostorovy predikat"), mAction);
| |
| }
| |
| | |
| // Odstranit alokovane GUI elementy
| |
| void QgsSamplePlugin::unload()
| |
| {
| |
| mIface->removeToolBarIcon(mAction);
| |
| mIface->removePluginMenu(tr("&Prostorovy predikat"), mAction);
| |
| delete mAction;
| |
| }
| |
| | |
| void QgsSamplePlugin::within()
| |
| {
| |
|
| |
| }
| |
| | |
| ...
| |
| </source>
| |
| | |
| == Debugovací zprávy ==
| |
| | |
| Logovaní zajišťuje třída [http://doc.qgis.org/head/classQgsLogger.html QgsLogger].
| |
| | |
| <source lang="cpp">
| |
| #include <qgslogger.h>
| |
| ...
| |
| QgsLogger::debug("Layer name: " + layer1->name());
| |
| </source>
| |
| | |
| == Implementace funkce within() ==
| |
| | |
| ; C++ soubor qgssampleplugin.cpp
| |
| | |
| <source lang="cpp">
| |
| ...
| |
| #include <qgsmapcanvas.h>
| |
| #include <qgsvectordataprovider.h>
| |
| #include <qgsfeature.h>
| |
| #include <qgsgeometry.h>
| |
| #include <qgslogger.h>
| |
| #include <qgsvectorlayer.h>
| |
| | |
| ...
| |
| #include <QMessageBox>
| |
| | |
| ...
| |
| void QgsSamplePlugin::within()
| |
| {
| |
| QgsMapCanvas *canvas = mIface->mapCanvas();
| |
| | |
| if(canvas->layerCount() < 2) {
| |
| QMessageBox::information(0, tr("Chyba"),
| |
| tr("Tento plugin vyzaduje alespon dve vrstvy"),
| |
| QMessageBox::Ok);
| |
| return;
| |
| }
| |
| | |
| QgsMapLayer *layer1, *layer2;
| |
| layer1 = canvas->layer(0);
| |
| layer2 = canvas->layer(1);
| |
| | |
| QgsVectorLayer* layer_points = dynamic_cast<QgsVectorLayer*>(layer1);
| |
| QgsVectorLayer* layer_polygons = dynamic_cast<QgsVectorLayer*>(layer2);
| |
| | |
| if(!layer_points || !layer_polygons) {
| |
| QMessageBox::information(0, tr("Chyba"),
| |
| tr("Tento plugin vyzaduje alespon dve vektorove vrstvy"),
| |
| QMessageBox::Ok);
| |
| return;
| |
| }
| |
| | |
| QgsVectorDataProvider *provider_points = layer_points->dataProvider();
| |
| QgsVectorDataProvider *provider_polygons = layer_polygons->dataProvider();
| |
| | |
| QgsLogger::debug("Points layer name: " + layer_points->name());
| |
| QgsLogger::debug("Polygon layer name: " + layer_polygons->name());
| |
| | |
| if (!provider_points || !provider_polygons) {
| |
| return;
| |
| }
| |
| | |
| QgsLogger::debug("Points layer provider: " + provider_points->storageType());
| |
| QgsLogger::debug("Polygon layer provider: " + provider_polygons->storageType());
| |
| | |
| layer_points->select(provider_points->attributeIndexes(), canvas->extent(), true, false);
| |
| | |
| QgsFeature feature1, feature2;
| |
| QgsGeometry *geometry1 = NULL, *geometry2 = NULL;
| |
| | |
| while(layer_points->nextFeature(feature1)) {
| |
| QgsLogger::debug("Checking feature " + QString::number(feature1.id()));
| |
| geometry1 = feature1.geometry();
| |
| if (!geometry1)
| |
| continue;
| |
| | |
| layer_polygons->select(provider_polygons->attributeIndexes(), geometry1->boundingBox(), true, true);
| |
| | |
| while(layer_polygons->nextFeature(feature2)) {
| |
| geometry2 = feature2.geometry();
| |
| if (!geometry2)
| |
| continue;
| |
| | |
| if (geometry1->within(geometry2)) {
| |
| QgsLogger::debug("WITHIN Point " + QString::number(feature1.id()) + " within polygon " + QString::number(feature2.id()));
| |
| layer_points->select(feature1.id());
| |
| }
| |
| }
| |
| }
| |
| | |
| return;
| |
| }
| |
| ...
| |
| </source>
| |
| | |
| [[Image:qgis-sampleplugin.png|thumb|800px|center|Demonstrace pluginu]]
| |
| | |
| == Vytvoření nové vektorové vrstvy ==
| |
| | |
| Vektorová vrstva je reprezentována třídou [http://doc.qgis.org/head/classQgsVectorLayer.html QgsVectorLayer]. Nově vytvořenou vrstvu zaregistrujeme pomocí [http://doc.qgis.org/head/classQgsMapLayerRegistry.html QgsMapLayerRegistry]. Vlastnosti vrstvy při vykreslení definuje třída [http://doc.qgis.org/head/classQgsSingleSymbolRenderer.html QgsSingleSymbolRenderer].
| |
| | |
| == Externí odkazy ==
| |
| | |
| * [http://blog.hartwork.org/?p=156 C++ GUI Programming with Qt 4]
| |
| * [http://download.osgeo.org/qgis/doc/manual/qgis-1.6.0_coding-compilation_guide_en.pdf QGIS Coding and Compilation Guide]
| |
| * [http://qgis.org/api/ QGIS API]
| |
| * [http://www.qgis.org/wiki/How_to_debug_QGIS_Plugins How to debug QGIS Plugins]
| |
| * [http://blog.qgis.org/taxonomy/term/1 Tutorials in C++] from Quantum GIS Blog
| |
| * [http://blog.jardinmagique.info/2009/11/how-to-build-and-install-qgis-from-svn.html How to build Debian package]
| |
| * [http://www.qgis.org/pyqgis-cookbook/ PyQGIS Developer Cookbook]
| |
| * [http://www.qgis.org/wiki/How_to_debug_QGIS_Plugins How to debug QGIS Plugins]
| |
| * [http://www.abclinuxu.cz/serialy/qt-4-psani-grafickych-programu Seriál na ABCLinuxu.cz]
| |
| | |
| {{GFOSS}}
| |
| {{Programování}}
| |
| {{C++}}
| |