Skip to content

Commit 0a99b11

Browse files
committed
Add polygon highlight support
1 parent f00321a commit 0a99b11

File tree

6 files changed

+118
-41
lines changed

6 files changed

+118
-41
lines changed

src/quickgui/qgsquickfeaturehighlight.cpp

+10-11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* *
1414
***************************************************************************/
1515

16+
#include <memory>
17+
1618
#include "qgsvectorlayer.h"
1719

1820
#include "qgsquickfeaturemodel.h"
@@ -64,17 +66,14 @@ QSGNode *QgsQuickFeatureHighlight::updatePaintNode( QSGNode *n, QQuickItem::Upda
6466
QgsCoordinateTransform transf( layer->crs(), mMapSettings->destinationCrs(), mMapSettings->transformContext() );
6567

6668
QgsFeature feature = mModel->feature().feature();
67-
QgsGeometry geom( feature.geometry() );
68-
geom.transform( transf );
69-
70-
// TODO: this is very crude conversion! QgsQuickHighlightsNode should accept any type of geometry
71-
QVector<QgsPoint> points;
72-
for ( auto it = geom.vertices_begin(); it != geom.vertices_end(); ++it )
73-
points.append( *it );
74-
75-
QgsQuickHighlightSGNode *rb = new QgsQuickHighlightSGNode( points, geom.type(), mColor, mWidth );
76-
rb->setFlag( QSGNode::OwnedByParent );
77-
n->appendChildNode( rb );
69+
if ( feature.hasGeometry() )
70+
{
71+
QgsGeometry geom( feature.geometry() );
72+
geom.transform( transf );
73+
std::unique_ptr<QgsQuickHighlightSGNode> rb( new QgsQuickHighlightSGNode( geom, mColor, mWidth ) );
74+
rb->setFlag( QSGNode::OwnedByParent );
75+
n->appendChildNode( rb.release() );
76+
}
7877
}
7978
mDirty = false;
8079

src/quickgui/qgsquickhighlightsgnode.cpp

+91-18
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,70 @@
1414
***************************************************************************/
1515

1616
#include "qgsquickhighlightsgnode.h"
17+
#include "qgstessellator.h"
18+
#include "qgsmultipolygon.h"
19+
#include "qgsgeometrycollection.h"
20+
#include "qgsgeometry.h"
21+
#include "qgstriangle.h"
1722

18-
19-
QgsQuickHighlightSGNode::QgsQuickHighlightSGNode( const QVector<QgsPoint> &points,
20-
QgsWkbTypes::GeometryType type,
21-
const QColor &color, qreal width ) : QSGNode()
23+
QgsQuickHighlightSGNode::QgsQuickHighlightSGNode( const QgsGeometry &geom,
24+
const QColor &color, float width )
25+
: QSGNode()
26+
, mWidth( width )
2227
{
2328
mMaterial.setColor( color );
29+
handleGeometryCollection( geom );
30+
}
31+
32+
void QgsQuickHighlightSGNode::handleGeometryCollection( const QgsGeometry &geom )
33+
{
34+
const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geom.constGet() );
35+
if ( collection && !collection->isEmpty() )
36+
{
37+
for ( int i = 0; i < collection->numGeometries(); ++i )
38+
{
39+
QgsGeometry geomN( collection->geometryN( i )->clone() );
40+
handleSingleGeometry( geomN );
41+
}
42+
}
43+
else
44+
{
45+
handleSingleGeometry( geom );
46+
}
47+
}
2448

25-
// TODO: support multi-part geometries
26-
switch ( type )
49+
void QgsQuickHighlightSGNode::handleSingleGeometry( const QgsGeometry &geom )
50+
{
51+
Q_ASSERT( !geom.isMultipart() );
52+
53+
switch ( geom.type() )
2754
{
2855
case QgsWkbTypes::PointGeometry:
2956
{
57+
QVector<QgsPoint> points;
58+
for ( auto it = geom.vertices_begin(); it != geom.vertices_end(); ++it )
59+
points.append( *it );
60+
3061
if ( !points.isEmpty() )
31-
appendChildNode( createPointGeometry( points.at( 0 ), width ) );
62+
appendChildNode( createPointGeometry( points.at( 0 ) ) );
3263
break;
3364
}
3465

3566
case QgsWkbTypes::LineGeometry:
3667
{
37-
appendChildNode( createLineGeometry( points, width ) );
68+
QVector<QgsPoint> points;
69+
for ( auto it = geom.vertices_begin(); it != geom.vertices_end(); ++it )
70+
points.append( *it );
71+
72+
appendChildNode( createLineGeometry( points ) );
3873
break;
3974
}
4075

4176
case QgsWkbTypes::PolygonGeometry:
4277
{
43-
// TODO: support polygon geometries
78+
const QgsPolygon *poly = qgsgeometry_cast<const QgsPolygon *>( geom.constGet() );
79+
if ( poly )
80+
appendChildNode( createPolygonGeometry( *poly ) );
4481
break;
4582
}
4683

@@ -50,7 +87,7 @@ QgsQuickHighlightSGNode::QgsQuickHighlightSGNode( const QVector<QgsPoint> &point
5087
}
5188
}
5289

53-
QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QVector<QgsPoint> &points, qreal width )
90+
QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QVector<QgsPoint> &points )
5491
{
5592
std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
5693
std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique< QSGGeometry>( QSGGeometry::defaultAttributes_Point2D(), points.count() );
@@ -59,10 +96,13 @@ QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QVector<QgsP
5996
int i = 0;
6097
for ( const QgsPoint &pt : points )
6198
{
62-
vertices[i++].set( pt.x(), pt.y() );
99+
vertices[i++].set(
100+
static_cast< float >( pt.x() ),
101+
static_cast< float >( pt.y() )
102+
);
63103
}
64104

65-
sgGeom->setLineWidth( width );
105+
sgGeom->setLineWidth( mWidth );
66106
sgGeom->setDrawingMode( GL_LINE_STRIP );
67107
node->setGeometry( sgGeom.release() );
68108
node->setMaterial( &mMaterial );
@@ -71,15 +111,18 @@ QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QVector<QgsP
71111
return node.release();
72112
}
73113

74-
QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry( const QgsPoint &point, qreal width )
114+
QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry( const QgsPoint &point )
75115
{
76116
std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
77117
std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique<QSGGeometry>( QSGGeometry::defaultAttributes_Point2D(), 1 );
78118

79119
QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
80-
vertices[0].set( point.x(), point.y() );
120+
vertices[0].set(
121+
static_cast< float >( point.x() ),
122+
static_cast< float >( point.y() )
123+
);
81124
sgGeom->setDrawingMode( GL_POINTS );
82-
sgGeom->setLineWidth( width );
125+
sgGeom->setLineWidth( mWidth );
83126

84127
node->setGeometry( sgGeom.release() );
85128
node->setMaterial( &mMaterial );
@@ -88,8 +131,38 @@ QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry( const QgsPoint &p
88131
return node.release();
89132
}
90133

91-
QSGGeometryNode *QgsQuickHighlightSGNode::createPolygonGeometry( const QVector<QgsPoint> &points )
134+
QSGGeometryNode *QgsQuickHighlightSGNode::createPolygonGeometry( const QgsPolygon &polygon )
92135
{
93-
Q_UNUSED( points );
94-
return 0;
136+
QgsRectangle bounds = polygon.boundingBox();
137+
QgsTessellator tes( bounds.xMinimum(), bounds.yMinimum(), false, false, false );
138+
std::unique_ptr< QgsPolygon > p( qgsgeometry_cast< QgsPolygon * >( polygon.segmentize() ) );
139+
tes.addPolygon( *p.get(), 0.0 );
140+
141+
std::unique_ptr<QgsMultiPolygon> triangles = tes.asMultiPolygon();
142+
int ntris = triangles->numGeometries();
143+
144+
QSGGeometryNode *node = new QSGGeometryNode;
145+
QSGGeometry *sgGeom = new QSGGeometry( QSGGeometry::defaultAttributes_Point2D(), ntris * 3 );
146+
147+
QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
148+
149+
for ( int j = 0; j < ntris; j++ )
150+
{
151+
const QgsTriangle *triangle = qgsgeometry_cast<const QgsTriangle *>( triangles->geometryN( j ) );
152+
if ( triangle )
153+
{
154+
for ( int v = 0; v < 3; ++v )
155+
{
156+
const QgsPoint vertex = triangle->vertexAt( v );
157+
vertices[3 * j + v].x = static_cast< float >( vertex.x() + bounds.xMinimum() ) ;
158+
vertices[3 * j + v].y = static_cast< float >( vertex.y() + bounds.yMinimum() );
159+
}
160+
}
161+
}
162+
sgGeom->setDrawingMode( GL_TRIANGLES );
163+
node->setGeometry( sgGeom );
164+
node->setMaterial( &mMaterial );
165+
node->setFlag( QSGNode::OwnsGeometry );
166+
node->setFlag( QSGNode::OwnedByParent );
167+
return node;
95168
}

src/quickgui/qgsquickhighlightsgnode.h

+17-12
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <QtQuick/QSGFlatColorMaterial>
2121

2222
#include "qgspoint.h"
23-
#include "qgswkbtypes.h"
23+
#include "qgsgeometry.h"
2424

2525
#include "qgis_quick.h"
2626

@@ -29,29 +29,34 @@
2929
*
3030
* This is used to transform (render) QgsGeometry to node for QtQuick scene graph.
3131
*
32-
* Note: support for multi-part geometries and polygons is not implemented
33-
*
3432
* \note QML Type: not exported
3533
*
3634
* \since QGIS 3.2
3735
*/
3836
class QUICK_EXPORT QgsQuickHighlightSGNode : public QSGNode
3937
{
4038
public:
41-
//! Constructor of new QT Quick scene node based on geometry
42-
QgsQuickHighlightSGNode( const QVector<QgsPoint> &points, QgsWkbTypes::GeometryType type, const QColor &color, qreal width );
39+
40+
/**
41+
* Constructor of new QT Quick scene node based on geometry
42+
* \param geom Geometry to render in the map coordinates
43+
* \param color color used to render geom
44+
* \param width width of pen, see QSGGeometry::setLineWidth()
45+
*/
46+
QgsQuickHighlightSGNode( const QgsGeometry &geom, const QColor &color, float width );
4347
//! Destructor
4448
~QgsQuickHighlightSGNode() = default;
4549

46-
protected:
47-
//! Constructs line geometry from points
48-
QSGGeometryNode *createLineGeometry( const QVector<QgsPoint> &points, qreal width );
49-
//! Constructs point geometry from qgs point
50-
QSGGeometryNode *createPointGeometry( const QgsPoint &point, qreal width );
51-
//! Constructs polygon geometry from points (not implemented)
52-
QSGGeometryNode *createPolygonGeometry( const QVector<QgsPoint> &points );
50+
private:
51+
void handleGeometryCollection( const QgsGeometry &geom );
52+
void handleSingleGeometry( const QgsGeometry &geom );
53+
54+
QSGGeometryNode *createLineGeometry( const QVector<QgsPoint> &points );
55+
QSGGeometryNode *createPointGeometry( const QgsPoint &point );
56+
QSGGeometryNode *createPolygonGeometry( const QgsPolygon &polygon );
5357

5458
QSGFlatColorMaterial mMaterial;
59+
float mWidth;
5560
};
5661

5762
#endif // QGSQUICKHIGHLIGHTSGNODE

tests/testdata/polys.dbf

211 Bytes
Binary file not shown.

tests/testdata/polys.shp

256 Bytes
Binary file not shown.

tests/testdata/polys.shx

16 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)