Skip to content

Commit 4490948

Browse files
Sandro Santillijef-n
Sandro Santilli
authored andcommitted
Add support for Pointcloud layers
1 parent 3dcb640 commit 4490948

File tree

4 files changed

+102
-22
lines changed

4 files changed

+102
-22
lines changed

src/providers/postgres/qgspostgresconn.cpp

+54-14
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,12 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
364364

365365
mLayersSupported.clear();
366366

367-
for ( int i = 0; i < ( hasTopology() ? 3 : 2 ); i++ )
367+
for ( int i = sctGeometry; i <= sctPcPatch; ++i )
368368
{
369369
QString sql, tableName, schemaName, columnName, typeName, sridName, gtableName, dimName;
370370
QgsPostgresGeometryColumnType columnType = sctGeometry;
371371

372-
if ( i == 0 )
372+
if ( i == sctGeometry )
373373
{
374374
tableName = "l.f_table_name";
375375
schemaName = "l.f_table_schema";
@@ -380,7 +380,7 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
380380
gtableName = "geometry_columns";
381381
columnType = sctGeometry;
382382
}
383-
else if ( i == 1 )
383+
else if ( i == sctGeography )
384384
{
385385
tableName = "l.f_table_name";
386386
schemaName = "l.f_table_schema";
@@ -391,8 +391,10 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
391391
gtableName = "geography_columns";
392392
columnType = sctGeography;
393393
}
394-
else if ( i == 2 )
394+
else if ( i == sctTopoGeometry )
395395
{
396+
if ( ! hasTopology() ) continue;
397+
396398
schemaName = "l.schema_name";
397399
tableName = "l.table_name";
398400
columnName = "l.feature_column";
@@ -407,6 +409,25 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
407409
gtableName = "topology.layer";
408410
columnType = sctTopoGeometry;
409411
}
412+
else if ( i == sctPcPatch )
413+
{
414+
if ( ! hasPointcloud() ) continue;
415+
416+
tableName = "l.\"table\"";
417+
schemaName = "l.\"schema\"";
418+
columnName = "l.\"column\"";
419+
typeName = "'POLYGON'";
420+
sridName = "l.srid";
421+
dimName = "2";
422+
gtableName = "pointcloud_columns";
423+
columnType = sctPcPatch;
424+
}
425+
else
426+
{
427+
QgsMessageLog::logMessage( tr( "Unsupported spatial column type %1" )
428+
.arg( displayStringForGeomType(( QgsPostgresGeometryColumnType )i ) ) );
429+
continue;
430+
}
410431

411432
// The following query returns only tables that exist and the user has SELECT privilege on.
412433
// Can't use regclass here because table must exist, else error occurs.
@@ -510,7 +531,7 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
510531
" WHERE c.relkind IN ('v','r','m')"
511532
" AND has_schema_privilege( n.nspname, 'usage' )"
512533
" AND has_table_privilege( '\"' || n.nspname || '\".\"' || c.relname || '\"', 'select' )"
513-
" AND (t.typname IN ('geometry','geography','topogeometry') OR b.typname IN ('geometry','geography','topogeometry'))";
534+
" AND (t.typname IN ('geometry','geography','topogeometry') OR b.typname IN ('geometry','geography','topogeometry','pcpatch'))";
514535

515536
// user has select privilege
516537
if ( searchPublicOnly )
@@ -522,19 +543,19 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
522543
// skip columns of which we already derived information from the metadata tables
523544
if ( nColumns > 0 )
524545
{
525-
if ( foundInTables & 1 )
546+
if ( foundInTables & ( 1 << sctGeometry ) )
526547
{
527548
sql += " AND (n.nspname,c.relname,a.attname) NOT IN (SELECT f_table_schema,f_table_name,f_geometry_column FROM geometry_columns)";
528549
}
529550

530-
if ( foundInTables & 2 )
551+
if ( foundInTables & ( 1 << sctGeography ) )
531552
{
532553
sql += " AND (n.nspname,c.relname,a.attname) NOT IN (SELECT f_table_schema,f_table_name,f_geography_column FROM geography_columns)";
533554
}
534555

535-
if ( foundInTables & 4 )
556+
if ( foundInTables & ( 1 << sctPcPatch ) )
536557
{
537-
sql += " AND (n.nspname,c.relname,a.attname) NOT IN (SELECT schema_name,table_name,feature_column FROM topology.layer)";
558+
sql += " AND (n.nspname,c.relname,a.attname) NOT IN (SELECT \"schema\",\"table\",\"column\" FROM pointcloud_columns)";
538559
}
539560
}
540561

@@ -586,6 +607,10 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
586607
{
587608
layerProperty.geometryColType = sctTopoGeometry;
588609
}
610+
else if ( coltype == "pcpatch" )
611+
{
612+
layerProperty.geometryColType = sctPcPatch;
613+
}
589614
else
590615
{
591616
Q_ASSERT( !"Unknown geometry type" );
@@ -747,6 +772,16 @@ bool QgsPostgresConn::hasTopology()
747772
return mTopologyAvailable;
748773
}
749774

775+
/**
776+
* Check to see if pointcloud is available
777+
*/
778+
bool QgsPostgresConn::hasPointcloud()
779+
{
780+
// TODO: use mPointcloudAvailable function instead
781+
QgsPostgresResult result = PQexec( "SELECT 'pointcloud_columns'::regclass" );
782+
return result.PQntuples() == 1;
783+
}
784+
750785
/* Functions for determining available features in postGIS */
751786
QString QgsPostgresConn::postgisVersion()
752787
{
@@ -1279,12 +1314,15 @@ void QgsPostgresConn::retrieveLayerTypes( QgsPostgresLayerProperty &layerPropert
12791314

12801315
QString query = "SELECT DISTINCT ";
12811316

1317+
bool castToGeometry = layerProperty.geometryColType == sctGeography ||
1318+
layerProperty.geometryColType == sctPcPatch;
1319+
12821320
QGis::WkbType type = layerProperty.types.value( 0, QGis::WKBUnknown );
12831321
if ( type == QGis::WKBUnknown )
12841322
{
12851323
query += QString( "upper(geometrytype(%1%2))" )
12861324
.arg( quotedIdentifier( layerProperty.geometryColName ) )
1287-
.arg( layerProperty.geometryColType == sctGeography ? "::geometry" : "" );
1325+
.arg( castToGeometry ? "::geometry" : "" );
12881326
}
12891327
else
12901328
{
@@ -1299,7 +1337,7 @@ void QgsPostgresConn::retrieveLayerTypes( QgsPostgresLayerProperty &layerPropert
12991337
query += QString( "%1(%2%3)" )
13001338
.arg( majorVersion() < 2 ? "srid" : "st_srid" )
13011339
.arg( quotedIdentifier( layerProperty.geometryColName ) )
1302-
.arg( layerProperty.geometryColType == sctGeography ? "::geometry" : "" );
1340+
.arg( castToGeometry ? "::geometry" : "" );
13031341
}
13041342
else
13051343
{
@@ -1311,7 +1349,7 @@ void QgsPostgresConn::retrieveLayerTypes( QgsPostgresLayerProperty &layerPropert
13111349
query += QString( ",%1(%2%3)" )
13121350
.arg( majorVersion() < 2 ? "ndims" : "st_ndims" )
13131351
.arg( quotedIdentifier( layerProperty.geometryColName ) )
1314-
.arg( layerProperty.geometryColType == sctGeography ? "::geometry" : "" );
1352+
.arg( castToGeometry ? "::geometry" : "" );
13151353
}
13161354

13171355
query += " FROM " + table;
@@ -1426,10 +1464,10 @@ QString QgsPostgresConn::postgisWkbTypeName( QGis::WkbType wkbType )
14261464
return geometryType;
14271465
}
14281466

1429-
QString QgsPostgresConn::postgisTypeFilter( QString geomCol, QGis::WkbType geomType, bool isGeography )
1467+
QString QgsPostgresConn::postgisTypeFilter( QString geomCol, QGis::WkbType geomType, bool castToGeometry )
14301468
{
14311469
geomCol = quotedIdentifier( geomCol );
1432-
if ( isGeography )
1470+
if ( castToGeometry )
14331471
geomCol += "::geometry";
14341472

14351473
switch ( geomType )
@@ -1601,6 +1639,8 @@ QString QgsPostgresConn::displayStringForGeomType( QgsPostgresGeometryColumnType
16011639
return tr( "Geography" );
16021640
case sctTopoGeometry:
16031641
return tr( "TopoGeometry" );
1642+
case sctPcPatch:
1643+
return tr( "PcPatch" );
16041644
}
16051645

16061646
Q_ASSERT( !"unexpected geometry column type" );

src/providers/postgres/qgspostgresconn.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ extern "C"
3434

3535
class QgsField;
3636

37+
/** Spatial column types */
3738
enum QgsPostgresGeometryColumnType
3839
{
3940
sctNone,
4041
sctGeometry,
4142
sctGeography,
42-
sctTopoGeometry
43+
sctTopoGeometry,
44+
sctPcPatch
4345
};
4446

4547
enum QgsPostgresPrimaryKeyType
@@ -187,6 +189,9 @@ class QgsPostgresConn : public QObject
187189
//! get status of topology capability
188190
bool hasTopology();
189191

192+
//! get status of Pointcloud capability
193+
bool hasPointcloud();
194+
190195
//! get status of GIST capability
191196
bool hasGIST();
192197

@@ -299,7 +304,7 @@ class QgsPostgresConn : public QObject
299304
static int postgisWkbTypeDim( QGis::WkbType wkbType );
300305
static void postgisWkbType( QGis::WkbType wkbType, QString &geometryType, int &dim );
301306

302-
static QString postgisTypeFilter( QString geomCol, QGis::WkbType wkbType, bool isGeography );
307+
static QString postgisTypeFilter( QString geomCol, QGis::WkbType wkbType, bool castToGeometry );
303308

304309
static QGis::WkbType wkbTypeFromGeomType( QGis::GeometryType geomType );
305310
static QGis::WkbType wkbTypeFromOgcWkbType( unsigned int ogcWkbType );

src/providers/postgres/qgspostgresfeatureiterator.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -266,15 +266,20 @@ QString QgsPostgresFeatureIterator::whereClauseRect()
266266
.arg( mSource->mRequestedSrid.isEmpty() ? mSource->mDetectedSrid : mSource->mRequestedSrid );
267267
}
268268

269-
QString whereClause = QString( "%1 && %2" )
269+
QString whereClause = QString( "%1%2 && %3" )
270270
.arg( QgsPostgresConn::quotedIdentifier( mSource->mGeometryColumn ) )
271+
.arg( mSource->mSpatialColType == sctPcPatch ? "::geometry" : "" )
271272
.arg( qBox );
273+
274+
bool castToGeometry = mSource->mSpatialColType == sctGeography ||
275+
mSource->mSpatialColType == sctPcPatch;
276+
272277
if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect )
273278
{
274279
whereClause += QString( " AND %1(%2%3,%4)" )
275280
.arg( mConn->majorVersion() < 2 ? "intersects" : "st_intersects" )
276281
.arg( QgsPostgresConn::quotedIdentifier( mSource->mGeometryColumn ) )
277-
.arg( mSource->mSpatialColType == sctGeography ? "::geometry" : "" )
282+
.arg( castToGeometry ? "::geometry" : "" )
278283
.arg( qBox );
279284
}
280285

@@ -283,13 +288,13 @@ QString QgsPostgresFeatureIterator::whereClauseRect()
283288
whereClause += QString( " AND %1(%2%3)=%4" )
284289
.arg( mConn->majorVersion() < 2 ? "srid" : "st_srid" )
285290
.arg( QgsPostgresConn::quotedIdentifier( mSource->mGeometryColumn ) )
286-
.arg( mSource->mSpatialColType == sctGeography ? "::geography" : "" )
291+
.arg( castToGeometry ? "::geometry" : "" )
287292
.arg( mSource->mRequestedSrid );
288293
}
289294

290295
if ( mSource->mRequestedGeomType != QGis::WKBUnknown && mSource->mRequestedGeomType != mSource->mDetectedGeomType )
291296
{
292-
whereClause += QString( " AND %1" ).arg( QgsPostgresConn::postgisTypeFilter( mSource->mGeometryColumn, mSource->mRequestedGeomType, mSource->mSpatialColType == sctGeography ) );
297+
whereClause += QString( " AND %1" ).arg( QgsPostgresConn::postgisTypeFilter( mSource->mGeometryColumn, mSource->mRequestedGeomType, castToGeometry ) );
293298
}
294299

295300
return whereClause;
@@ -316,7 +321,8 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
316321
{
317322
QString geom = QgsPostgresConn::quotedIdentifier( mSource->mGeometryColumn );
318323

319-
if ( mSource->mSpatialColType == sctGeography )
324+
if ( mSource->mSpatialColType == sctGeography ||
325+
mSource->mSpatialColType == sctPcPatch )
320326
geom += "::geometry";
321327

322328
if ( mSource->mForce2d )

src/providers/postgres/qgspostgresprovider.cpp

+30-1
Original file line numberDiff line numberDiff line change
@@ -2513,9 +2513,10 @@ QgsRectangle QgsPostgresProvider::extent()
25132513

25142514
if ( ext.isEmpty() )
25152515
{
2516-
sql = QString( "SELECT %1(%2) FROM %3%4" )
2516+
sql = QString( "SELECT %1(%2%3) FROM %4%5" )
25172517
.arg( connectionRO()->majorVersion() < 2 ? "extent" : "st_extent" )
25182518
.arg( quotedIdentifier( mGeometryColumn ) )
2519+
.arg( mSpatialColType == sctPcPatch ? "::geometry" : "" )
25192520
.arg( mQuery )
25202521
.arg( filterWhereClause() );
25212522

@@ -2609,6 +2610,8 @@ bool QgsPostgresProvider::getGeometryDetails()
26092610
mSpatialColType = sctGeography;
26102611
else if ( geomColType == "topogeometry" )
26112612
mSpatialColType = sctTopoGeometry;
2613+
else if ( geomColType == "pcpatch" )
2614+
mSpatialColType = sctPcPatch;
26122615
else
26132616
mSpatialColType = sctNone;
26142617
}
@@ -2714,6 +2717,30 @@ bool QgsPostgresProvider::getGeometryDetails()
27142717
}
27152718
}
27162719

2720+
if ( detectedType.isEmpty() && connectionRO()->hasPointcloud() )
2721+
{
2722+
// check pointcloud columns
2723+
sql = QString( "SELECT 'POLYGON',srid FROM pointcloud_columns WHERE \"table\"=%1 AND \"column\"=%2 AND \"schema\"=%3" )
2724+
.arg( quotedValue( tableName ) )
2725+
.arg( quotedValue( geomCol ) )
2726+
.arg( quotedValue( schemaName ) );
2727+
2728+
QgsDebugMsg( QString( "Getting pointcloud column: %1" ).arg( sql ) );
2729+
result = connectionRO()->PQexec( sql, false );
2730+
QgsDebugMsg( QString( "Pointcloud column query returned %1" ).arg( result.PQntuples() ) );
2731+
2732+
if ( result.PQntuples() == 1 )
2733+
{
2734+
detectedType = result.PQgetvalue( 0, 0 );
2735+
detectedSrid = result.PQgetvalue( 0, 1 );
2736+
mSpatialColType = sctPcPatch;
2737+
}
2738+
else
2739+
{
2740+
connectionRO()->PQexecNR( "COMMIT" );
2741+
}
2742+
}
2743+
27172744
if ( mSpatialColType == sctNone )
27182745
{
27192746
sql = QString( "SELECT t.typname FROM "
@@ -2736,6 +2763,8 @@ bool QgsPostgresProvider::getGeometryDetails()
27362763
mSpatialColType = sctGeography;
27372764
else if ( geomColType == "topogeometry" )
27382765
mSpatialColType = sctTopoGeometry;
2766+
else if ( geomColType == "pcpatch" )
2767+
mSpatialColType = sctPcPatch;
27392768
}
27402769
else
27412770
{

0 commit comments

Comments
 (0)