QGIS二次开发教程一
——用QGIS的API编写自定义应用程序
教程一:使用QGIS Canvas API编写一个简单的地图显示程序
参考翻译自Quantum GIS官方网站
事实上,我们并不是所有的时候都需要一个庞大、完整的GIS桌面应用程序,有时候我们的应用程序主要用于其他的目的,而我们所需要的只是在用程序中添加一个具有地图显示功能的小工具。譬如一个带有地图显示功能的数据库前端。
接下来我们就创建一个简单的地图小工具,功能仅仅是加载一个shape文件并用随机颜色加以显示。但是通过这个简单的例子你应该能体会到将QGIS作为一个嵌入式的地图组件的潜力。
首先,在我们的应用程序里添加必要的includes:
1 // 2 // QGIS Includes 3 // 4 #include <qgsapplication.h> 5 #include <qgsproviderregistry.h> 6 #include <qgssinglesymbolrenderer.h> 7 #include <qgsmaplayerregistry.h> 8 #include <qgsvectorlayer.h> 9 #include <qgsmapcanvas.h> 10 // 11 // Qt Includes 12 // 13 #include <QString> 14 #include <QApplication> 15 #include <QWidget>
我们用QgsApplication代替Qt中的QApplication来创建应用程序,这样可以方便地调用QGIS中的许多静态方法,比如得到库文件所在的路径等等。
各种数据的提供商plugins通过提供商注册表(QgsProviderRegistry)来管理,它会根据提供商自动加载相应的plugins,我们所需要做的就是指定plugins所存放的目录,让应用程序实例化这样的提供商注册表。
QgsSingleSymbolRenderer是最基本的符号类,它用一种颜色表示点、线、多边形对象。默认情况下颜色是随机选取的,当然,你也可以自己设定希望显示的颜色。每一个矢量图层都有一个对应的符号。
地图图层注册表(QgsMapLayerRegistry)用来管理现在正在使用的图层。QgsVectorLayer 继承自QgsMapLayer,添加了矢量数据特有的功能。
最后,地图画布(QgsMapCanvas)才是问题的关键,我们的地图将被绘制在这个工具上。
现在,我们开始初始化我们的应用程序:
1 int main(int argc, char ** argv) 2 { 3 // Start the Application 4 QgsApplication app(argc, argv, true); 5 6 QString myPluginsDir = "/home/timlinux/apps/lib/qgis"; 7 QString myLayerPath = "/home/timlinux/gisdata/brazil/BR_Cidades/"; 8 QString myLayerBaseName = "Brasil_Cap"; 9 QString myProviderName = "ogr";
这样我们就得到了一个qgsapplication。
变量myLayerPath指定了plugins所在的目录。
变量myLayerPath和myLayerBaseName指向要使用的shape文件。
变量myProviderName很重要,它告诉qgis加载数据文件需要使用哪个数据提供商。一般为”ogr”或”postgres”。
现在我们可以开始创建图层了:
1 // Instantiate Provider Registry 2 QgsProviderRegistry::instance(myPluginsDir);
首先我们需要初始化提供商注册表。QgsMapLayerRegistry是一个单类(singleton class),因此我们使用它的静态函数instance()传递供应商插件库的路径,在此之后它将在这个路径下查找提供商的插件。
接下来我们继续创建图层:
1 QgsVectorLayer * mypLayer = 2 new QgsVectorLayer(myLayerPath, myLayerBaseName, myProviderName); 3 QgsSingleSymbolRenderer *mypRenderer = new QgsSingleSymbolRenderer(mypLayer->geometryType()); 4 QList <QgsMapCanvasLayer> myLayerSet; 5 6 mypLayer->setRenderer(mypRenderer); 7 if (mypLayer->isValid()) 8 { 9 qDebug("Layer is valid"); 10 } 11 else 12 { 13 qDebug("Layer is NOT valid"); 14 } 15 16 // Add the Vector Layer to the Layer Registry 17 QgsMapLayerRegistry::instance()->addMapLayer(mypLayer, TRUE); 18 // Add the Layer to the Layer Set 19 myLayerSet.append(QgsMapCanvasLayer(mypLayer, TRUE));
这段代码的意义显而易见。我们用前面定义的变量创建了一个图层,然后给这个图层分配了一个渲染器(renderer)。在创建渲染器的时候,我们需要指定图层的几何类型,这个可以通过图层对象的geometryType()函数得到。然后将图层对象layer添加到图层列表layerset和地图图层注册表QgsMapLayerRegistry中,layerset告诉QgsMapCanvas那些图层需要渲染、它们的顺序如何。最后,我们要保证这个图层是可见的。
现在我们创建一个地图画布用于显示地图图层。
1 // Create the Map Canvas 2 QgsMapCanvas * mypMapCanvas = new QgsMapCanvas(0, 0); 3 mypMapCanvas->setExtent(mypLayer->extent()); 4 mypMapCanvas->enableAntiAliasing(true); 5 mypMapCanvas->setCanvasColor(QColor(255, 255, 255)); 6 mypMapCanvas->freeze(false); 7 // Set the Map Canvas Layer Set 8 mypMapCanvas->setLayerSet(myLayerSet); 9 mypMapCanvas->setVisible(true); 10 mypMapCanvas->refresh();
这段代码也很简单。我们创建了一个画布,然后将它的范围设置为我们图层的范围。接下来打开反走样功能,并设置背景颜色为白色,解冻画布,设置其为可见并刷新。
1 // Start the Application Event Loop 2 return app.exec(); 3 }
在这最后一步中,我们所做的仅仅是启动Qt事件循环。是不是很简单?
这个例子中的源代码可以通过svn下载(当然,前提是安装了svn工具),下载命令如下:
svn co https://svn.osgeo.org/qgis/trunk/code_examples/1_hello_world_qgis_style