My purpose in posting this is to demonstrate a KML drawing library that I'm putting together that is intended to be a rendering companion to LibKML. More about this drawing library, which is currently under construction, will be posted here.
Monday, January 28, 2013
Quantum GIS KML Overlay
I've put together a KML Overlay for Quantum GIS based on the KML Overlay that I'm working on now for FalconView. You can see a video demonstration of it here. The source code is here.
My purpose in posting this is to demonstrate a KML drawing library that I'm putting together that is intended to be a rendering companion to LibKML. More about this drawing library, which is currently under construction, will be posted here.
My purpose in posting this is to demonstrate a KML drawing library that I'm putting together that is intended to be a rendering companion to LibKML. More about this drawing library, which is currently under construction, will be posted here.
Friday, January 18, 2013
How to Create a QGIS Plugin in C++
FalconView has a rich plugin-architecture that I've been writing to for many years. Though I'm very comfortable writing FalconView plugins, I'm in the process now of writing a plugin that needs to work in FalconView and in Quantum GIS. This post is about my learning experience in writing a plugin for Quantum GIS. I find that the documentation on QGIS plugins is sparse, so perhaps what I've learned will help others who want to do something similar.
The full source code for this plugin may be found here. This is a minimalistic plugin that simply draws a rectangle on the screen using screen coordinates. It demonstrates how to register a plugin with Quantum, how to add an action to a QGIS menu, how to register to receive a callback, and how to draw on the map canvas. I call it the Hello World plugin.
(Before I started this process, I had no experience coding to QGIS or to Qt. I'm sure that some of what I've done here does not reflect best practices with either technology, so I invite members of either community to comment here in order to help me and others to understand best practices. I will note that my plugin does not conform to the Quantum GIS coding standards. Instead, I've conformed to the FalconView coding standards since this project is part of a larger effort related to FalconView.)
[[ EDIT: Most QGIS plugins are done in Python, and there is much better documentation for these plugins. ]]
The Header File
The complete header file may be found here. There are two things of interest in the header file. First, notice that the HelloWorldPlugin is a QObject. This comes by deriving from QObject and by including the QOBJECT macro in the class.
class HelloWorldPlugin : public QObject, public QgisPlugin
{
Q_OBJECT
...
The full source code for this plugin may be found here. This is a minimalistic plugin that simply draws a rectangle on the screen using screen coordinates. It demonstrates how to register a plugin with Quantum, how to add an action to a QGIS menu, how to register to receive a callback, and how to draw on the map canvas. I call it the Hello World plugin.
(Before I started this process, I had no experience coding to QGIS or to Qt. I'm sure that some of what I've done here does not reflect best practices with either technology, so I invite members of either community to comment here in order to help me and others to understand best practices. I will note that my plugin does not conform to the Quantum GIS coding standards. Instead, I've conformed to the FalconView coding standards since this project is part of a larger effort related to FalconView.)
[[ EDIT: Most QGIS plugins are done in Python, and there is much better documentation for these plugins. ]]
The Header File
The complete header file may be found here. There are two things of interest in the header file. First, notice that the HelloWorldPlugin is a QObject. This comes by deriving from QObject and by including the QOBJECT macro in the class.
class HelloWorldPlugin : public QObject, public QgisPlugin
{
Q_OBJECT
...
The next point of interest is the declaration of the Qt slots. These are callback methods.
public slots:
void StartOverlay();
void DrawOverlay(QPainter* painter);
Functions Exported from the Library
There are a handful of functions exported from the library that are required for QGIS to load plugin. These are all in the cpp file, and are all declared with the QGISEXTERN macro.
Adding a Menu Item to a QGIS Menu
We do this in the initGui method. The important thing to note is how we register for a callback using connect(...) and how we call into the QGIS interface to add the action to the Plugin menu.
/*virtual*/ void HelloWorldPlugin::initGui()
{
std::cout << "HelloWorldPlugin::initGui" << std::endl;
// add an action to the menu
m_action = new QAction(QIcon("" ), tr("Hello World"), this);
m_action->setWhatsThis(tr("Draw on the map canvas."));
connect(m_action, SIGNAL(triggered()), this, SLOT(StartOverlay()));
m_qgis_if->addRasterToolBarIcon(m_action);
m_qgis_if->addPluginToMenu(tr("&Hello World"), m_action);
}
Handling the Menu Item Selection Event
StartOverlay() handles this event. It gets the map canvas and connects to the render complete signal. I have some code in this sample that demonstrates how to zoom out the map. This is not necessary for drawing the rectangle, but I've left it in for pedagogical reasons.
void HelloWorldPlugin::StartOverlay()
{
std::cout << "HelloWorldPlugin::StartOverlay" << std::endl;
// get the map canvas
QgsMapCanvas* canvas = m_qgis_if->mapCanvas();
// connect to the render complete signal
connect(canvas, SIGNAL(renderComplete(QPainter*)),
this, SLOT(DrawOverlay(QPainter*)));
// zoom out for fun
canvas->zoomOut(); // wheeeeee!!!
}
Drawing the Rectangle
Now that we are registered to receive calls to DrawOverlay when the canvas refreshes, drawing the rectangle is easy.
void HelloWorldPlugin::DrawOverlay(QPainter* painter)
{
std::cout << "HelloWorldPlugin::DrawOverlay" << std::endl;
painter->drawRect(20, 20, 60, 60);
}
Building the Project
The Qt project file is here. First, run qmake qgis_hello_world.pro to make the Makefile. Next, run make to build the library. Notice that Qt will generate some code files that you will find in the project folder.
Trying it Out
Copy the library to your QGIS plugins folder. The command that I use to do this on my Ubuntu system is sudo cp libqgis_hello_world.so.1.0.0 /usr/lib/qgis/plugins/libqgis_hello_world.so.
The Hello World plugin should now appear in the QGIS plugin manager menu. Turn it on. Next, select the menu item that we added to the Plugin menu. The rectangle should draw.
Finding More Help
Be sure to look at the QGIS header files (in /usr/include/qgis on my system) and API reference (http://www.qgis.org/). Also the samples under src/plugins are helpful.
Subscribe to:
Posts (Atom)