前言
本章講述使用qgis c++ Api加載各種類型的矢量地圖數據顯示。
- 說明:文章中的示例代碼均來自開源項目qgis_cpp_api_apps
- 上一章介紹了data provider: ogr,gpx支持的類型,本章繼續(xù)。
加載矢量(vector)圖層
- data provider可以指定的值包括:
| Provider | 說明 |
|---|---|
| ogr | OGR提供了一組基于標準的接口和函數庫,用于處理和操作地理空間數據。 |
| delimitedtext | 文本數據按指定的分隔符進行分割 |
| gpx | GPX(GPS eXchange Format,GPS交換格式)是一種用于存儲坐標數據的 XML 文件格式 |
| spatialite | Spatialite是SQLite數據庫的空間數據引擎。 |
| memory | 數據存在內存中 |
| postgres | POSTGRES是一個對象-關系型數據庫管理系統(tǒng)(ORDBMS) |
| mssql | MSSQL是指微軟的SQLServer數據庫服務器 |
| wfs | WFS(Web Feature Service)是一種允許用戶在分布式環(huán)境下通過HTTP對空間數據進行增加、刪除、修改、查詢的GIS數據服務 |
| grass | GRASS GIS是一個開源的地理信息系統(tǒng),可用于處理柵格、拓撲矢量、影像和圖表數據。 |
delimitedtext
Accesses data in a delimited text file, for example CSV files generated by spreadsheets. The contents of the file are split into columns based on specified delimiter characters. Each record may be represented spatially either by an X and Y coordinate column, or by a WKT (well known text) formatted columns.
The url defines the filename, the formatting options (how the text in the file is divided into data fields, and which fields contain the X,Y coordinates or WKT text definition. The options are specified as url query items.
- XLS/XLSX文件(Excel電子表格)、CSV(逗號分隔)文件、TXT文件(Tab分隔、空格分隔)等類型的電子表格與文本格式的文件可以導入到QGis中
-
注意: QgsVectorLayer構造函數的path(uri)參數中,除指定文件路徑外,還需要指定xField,yField(經緯度所在的列),crs(坐標系)等等,如下示例
image.png
uri如下
file://home/t/gis/maps/QGIS/jilin_maincity.csv?type=csv&maxFields=10000&detectTypes=yes&xField=longitude&yField=latitude&crs=EPSG:4326&spatialIndex=no&subsetIndex=no&watchFile=no
- 更多的uri設置,見
QgsVectorLayer文檔
QGis導入CSV
-
注意: 這里使用Delimited Text
image.png

代碼導入
-
注意: path參數前綴添加
file:
void MainWindow::addCsvSlot()
{
QString filename = QStringLiteral("maps/jilin_maincity.csv");
QFileInfo ff(filename);
QString uri = QString("file:///%1/%2%3").arg(QCoreApplication::applicationDirPath()).arg(filename).arg("?type=csv&xField=longitude&yField=latitude&crs=EPSG:4326");
QgsVectorLayer* vecLayer = new QgsVectorLayer(uri,ff.baseName(),"delimitedtext");
if(!vecLayer->isValid())
{
QMessageBox::critical(this,tr("error"),tr("invalid layer"));
return;
}
QgsProject::instance()->addMapLayer(vecLayer);
zoomToFirstLayer<QgsVectorLayer*>();
}


SpatiaLite data provider (spatialite)
SpatiaLite是一個基于SQLite輕量級數據庫的空間數據引擎。SQLite是一個以單一文件存在的數據庫,數據庫中的所有信息和功能都保存到一個文件中(后綴名通常為“sqlite”、“db”、“sqlite3”、“db3”和“s3db”等),且不需要系統(tǒng)服務的支持。SpatiaLite可以通過關系型表結構支持OGC簡單要素模型,以存儲矢量數據,也可以通過SQL查詢語句進行簡單的空間查詢和分析。
- QgsVectorLayer構造函數中path參數,可以使用QgsDataSourceUri類構造
QgsDataSourceUri
Class for storing the component parts of a RDBMS data source URI (e.g.a Postgres data source).
This structure stores the database connection information, including host, database, user name, password, schema, password, and SQL where clause.
QGis導入spatialite
-
首先新建連接
image.png

-
點擊Connect按鈕,可以看到數據庫中的數據
image.png -
選擇一條數據添加至圖層
image.png

代碼導入
- 構造
QgsDataSourceUri -
setDatabase函數設置數據庫 -
setDataSource函數設置表和列
void MainWindow::addSpatiaLiteSlot()
{
QString filename = QStringLiteral("maps/landuse.sqlite");
QgsDataSourceUri uri;
uri.setDatabase(filename);
uri.setDataSource("","landuse","Geometry");
QFileInfo ff(filename);
QgsVectorLayer* vecLayer = new QgsVectorLayer(uri.uri(),ff.baseName(),"spatialite");
if(!vecLayer->isValid())
{
QMessageBox::critical(this,tr("error"),tr("invalid layer"));
return;
}
QgsProject::instance()->addMapLayer(vecLayer);
zoomToFirstLayer<QgsVectorLayer*>();
}


Web服務
OGC提出了一系列Web服務標準(OWS),包括Web地圖服務(Web Map Service,WMS)、Web地圖切片服務(Web Map Tile Service,WMTS)、Web要素服務(Web Feature Service,WFS)和Web覆蓋服務(Web Coverage Service,WCS)等。許多開源GIS服務器(如GeoServer、MapServer等)提供了上述Web服務標準的具體實現,并且QGIS也提供了訪問這些OWS服務的功能。
WFS (web feature service) data provider (wfs)
WFS直接向網絡提供矢量要素的數據服務。相對于WMS和WMTS,WFS的特點是直接提供完整的數據信息,沒有經過渲染與符號化,因此它更加靈活,常用于點要素的信息傳遞及多用戶編輯等專業(yè)領域。由于WFS返回的數據是原始的,完整的要素數據傳輸到客戶端以后才能進行渲染或處理,因此它在一定程度上會加重網絡負擔和客戶端負擔。WFS的核心方法是GetFeature方法,用于根據地理范圍等參數請求返回矢量要素數據。
QGis添加圖層
-
新建一個Server Connections,填寫Name和URL
image.png -
連接并添加圖層
image.png

代碼添加
- 第一種方法直接使用字符串構造uri,其中必須的參數如下
url=string (mandatory): HTTP url to a WFS server endpoint. e.g http://foobar/wfstypename=string (mandatory): WFS typenamesrsname=string (recommended): SRS like 'EPSG:XXXX'
- 完整參數列表見
QgsVectorLayer文檔 - 第二種參數使用
QgsDataSourceUri,代碼如下
void MainWindow::addWfsSlot()
{
QString uri;
#if 0
uri = QStringLiteral("https://demo.mapserver.org/cgi-bin/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ms:cities");
#else
QgsDataSourceUri dataSourceUri;
dataSourceUri.setParam("url","https://demo.mapserver.org/cgi-bin/wfs");
dataSourceUri.setParam("typename","ms:cities");
dataSourceUri.setParam("version","2.0");
dataSourceUri.setParam("srsname","EPSG:4326");
uri = dataSourceUri.uri();
#endif
auto layer = new QgsVectorLayer(uri,"mapserver","WFS");
QgsProject::instance()->addMapLayer(layer);
zoomToFirstLayer<QgsVectorLayer*>();
}


Memory data providerType (memory)
The memory data provider is used to construct in memory data, for example scratch data or data generated from spatial operations such as contouring. There is no inherent persistent storage of the data. The data source uri is constructed. The url specifies the geometry type ("point", "linestring", "polygon", "multipoint","multilinestring","multipolygon"), optionally followed by url parameters as follows:
- crs=definition Defines the coordinate reference system to use for the layer. definition is any string accepted by QgsCoordinateReferenceSystem::createFromString()
- index=yes Specifies that the layer will be constructed with a spatial index
- field=name:type(length,precision) Defines an attribute of the layer. Multiple field parameters can be added to the data provider definition. type is one of "integer", "double", "string".
- memory類型的data provider數據存儲在內存中
- 數據沒有持久存儲
- 示例url
Point?crs=epsg:4326&field=id:integer&field=name:string(20)&index=yes
QGis新建memory圖層
-
新建Temporary Scratch Layer,Geometry Type為Point類型,添加一個Field
image.png -
開啟圖層編輯
image.png -
添加Point Feature
image.png

代碼創(chuàng)建memory圖層
- 首先構造uri,類型為Point
-
注意: 添加memory圖層之后
- 需要設置符號才能顯示在地圖上
- 添加feature之后才能顯示在地圖上
- feature的添加以及feature符號的設置,后邊的章節(jié)會講
void MainWindow::addMemorySlot()
{
QString uri = QStringLiteral("Point?crs=epsg:4326&field=name:string(20)");
QgsVectorLayer *layer = new QgsVectorLayer(uri,"New stratch layer","memory");
QgsProject::instance()->addMapLayer(layer);
if(layer)
{
//開啟編輯
layer->startEditing();
//設置Feature的符號
QgsFeatureRenderer * layerRenderer= layer->renderer();
QgsSingleSymbolRenderer *singleRenderer = QgsSingleSymbolRenderer::convertFromRenderer(layerRenderer);
//使用Simple Marker
QVariantMap mp;
mp[QString("name")] = QStringLiteral("circle");
mp[QString("color")] = QStringLiteral("red");
mp[QString("size")] = QStringLiteral("2.0");
QgsMarkerSymbol *newsym = QgsMarkerSymbol::createSimple(mp);
singleRenderer->setSymbol(newsym);
layer->setRenderer(singleRenderer);
//添加Feature
QgsVectorDataProvider * dataProvider = layer->dataProvider();
QgsFields fields;
QgsField fName("test");
fields.append(fName);
QgsFeature f(fields);
f.setGeometry(QgsGeometry::fromPointXY(QgsPointXY(-34.0146,20.3046)));
f.setAttribute("test",QString("string1"));
dataProvider->addFeature(f);
//提交改動
layer->commitChanges();
}
zoomToFirstLayer<QgsVectorLayer*>();
}
- 示例ll_qgis_realtime_uavs使用了memory圖層
image.png
其他
- 其他的由于沒有測試環(huán)境,所以暫不介紹










