Geometry——PostgreSQL+PostGIS的使用
Table of Contents
1. PostGIS是什么
PostGIS是对象关系型数据库系统PostgreSQL的一个扩展,PostGIS提供如下空间信息服务功能:空间对象、空间索引、空间操作函数和空间操作符。同时,PostGIS遵循OpenGIS的规范。(via 百度百科)
PostGIS is a spatial database extender for PostgreSQL object-relational database. It adds support for geographic objects allowing location queries to be run in SQL.(via postgis.net)
PostGIS是对PostgreSQL(一个对象关系数据库)的扩展(变成了一个空间数据库), 增加了对地理对象的支持,可以通过SQL语句实现位置查询。
2. PostGIS特性
PostGIS支持所有的空间数据类型,这些类型包括:点(POINT)、线(LINESTRING)、多边形(POLYGON)、多点(MULTIPOINT)、多线(MULTILINESTRING)、多多边形(MULTIPOLYGON)和集合对象集(GEOMETRYCOLLECTION)等。PostGIS支持所有的对象表达方法,比如WKT和WKB。
PostGIS支持所有的数据存取和构造方法,如GeomFromText()、AsBinary(),以及GeometryN()等。
PostGIS提供简单的空间分析函数(如Area和Length)同时也提供其他一些具有复杂分析功能的函数,比如Distance。
PostGIS提供了对于元数据的支持,如GEOMETRY_COLUMNS和SPATIAL_REF_SYS,同时,PostGIS也提供了相应的支持函数,如AddGeometryColumn和DropGeometryColumn。
PostGIS提供了一系列的二元谓词(如Contains、Within、Overlaps和Touches)用于检测空间对象之间的空间关系,同时返回布尔值来表征对象之间符合这个关系。
PostGIS提供了空间操作符(如Union和Difference)用于空间数据操作。比如,Union操作符融合多边形之间的边界。两个交迭的多边形通过Union运算就会形成一个新的多边形,这个新的多边形的边界为两个多边形中最大边界。
(via 百度百科)
PostGIS支持所有OGC(Open Geospatial Consortium) 规范的“Simple Features”类型,同时在此基础上扩展了对3DZ、3DM、4D坐标的支持。
3. 连接数据库
1) 创建数据库连接实例
The QSqlDatabase class provides an interface for accessing a database through a connection. An instance of QSqlDatabase represents the connection. The connection provides access to the database via one of the supported database drivers, which are derived from QSqlDriver. Alternatively, you can subclass your own database driver from QSqlDriver. See How to Write Your Own Database Driver for more information.
Create a connection (i.e., an instance of QSqlDatabase) by calling one of the static addDatabase() functions, where you specify the driver or type of driver to use (depending on the type of database) and a connection name. A connection is known by its own name, not by the name of the database it connects to. You can have multiple connections to one database. QSqlDatabase also supports the concept of a default connection, which is the unnamed connection. To create the default connection, don't pass the connection name argument when you call addDatabase(). Subsequently, the default connection will be assumed if you call any static member function without specifying the connection name.
支持的数据库:
首先,要连接数据库,要先创建一个数据库实例。
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String(defaultConnection))
第一个参数是数据库驱动,第二个参数是连接名称,如果不指定连接名称,系统会给定一个默认的名称。和数据库的链接是根据连接的名称来区分的,而不是数据库本身的名称(可以和同一个数据库有多个连接,如果根据数据库本身的名称进行区分,那就乱套了)。
2)指定连接参数、实现连接
Once the QSqlDatabase object has been created, set the connection parameters with setDatabaseName(), setUserName(), setPassword(), setHostName(), setPort(), and setConnectOptions(). Then call open() to activate the physical connection to the database. The connection is not usable until you open it.
Subsequently, you can get the connection by calling database().
//创建默认名称的数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("acidalia");
db.setDatabaseName("customdb");
db.setUserName("mojito");
db.setPassword("J0a1m8");
bool ok = db.open();
4. 查询数据
QSqlQueryModel is a high-level interface for executing SQL statements and traversing the result set. It is built on top of the lower-level QSqlQuery and can be used to provide data to view classes such as QTableView.
QSqlQueryModel can also be used to access a database programmatically, without binding it to a view.
该类的成员有:
setQuery方法:Resets the model and sets the data provider to be the given query. Note that the query must be active and must not be isForwardOnly().
void QSqlQueryModel::setQuery(const QSqlQuery &query)
void QSqlQueryModel::setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase())
record方法:Returns the record containing information about the fields of the current query. If row is the index of a valid row, the record will be populated with values from that row.
QSqlRecord QSqlQueryModel::record(int row) const
QSqlRecord QSqlQueryModel::record() const//Returns an empty record containing information about the fields of the current query.
5. 利用GDAL解析数据
因为这一步我还没有写出来...所以下面写的可能会有点问题
承接4. 查询
//查询
model->setQuery(QString("SELECT gid, ST_AsBinary(geom) AS geom FROM %1")
.arg(tableName),db);
propertieModel->setQuery(QString("SELECT * FROM %1")
.arg(tableName),db);
//解析
for (int i=0;i<model->rowCount();i++) {
QByteArray wkb = model->record(i).value("geom").toByteArray();
OGRSpatialReference osr;
OGRGeometry *geom = nullptr;
// Parse WKB 转换为OGRwkbGeometry格式
OGRErr err = OGRGeometryFactory::createFromWkb((unsigned char*)wkb.constData(), &osr, &geom);
if (err != OGRERR_NONE){
// process error, like emit signal
}
// Analyse geometry by type and process them as you wish
//下面开始要解析几何信息了
OGRwkbGeometryType type = wkbFlatten(geom->getGeometryType());
switch(type) {
case wkbLineString: {
//线
break;
}
case wkbPoint:{
//点
break;
}
case wkbPolygon:{
//面
break;
}
case wkbMultiPolygon:{
//多面
break;
}
case wkbMultiLineString:{
//线
break;
}
default:
break;
}
//解析属性信息
for (int j=0;j<propertieModel->columnCount();j++) {
QString propertyName = propertieModel->record(i).fieldName(j);
if(propertieName == "gid"||propertieName == "geom")
continue;
QVariant propertyValue = propertieModel->record(i).value(propertieName));
}
// Clean-up
OGRGeometryFactory::destroyGeometry(geom);
}
来源:CSDN
作者:PigChing
链接:https://blog.csdn.net/PigChing/article/details/103793072