14
14
***************************************************************************/
15
15
16
16
#include " qgsquickhighlightsgnode.h"
17
+ #include " qgstessellator.h"
18
+ #include " qgsmultipolygon.h"
19
+ #include " qgsgeometrycollection.h"
20
+ #include " qgsgeometry.h"
21
+ #include " qgstriangle.h"
17
22
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 )
22
27
{
23
28
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
+ }
24
48
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 () )
27
54
{
28
55
case QgsWkbTypes::PointGeometry:
29
56
{
57
+ QVector<QgsPoint> points;
58
+ for ( auto it = geom.vertices_begin (); it != geom.vertices_end (); ++it )
59
+ points.append ( *it );
60
+
30
61
if ( !points.isEmpty () )
31
- appendChildNode ( createPointGeometry ( points.at ( 0 ), width ) );
62
+ appendChildNode ( createPointGeometry ( points.at ( 0 ) ) );
32
63
break ;
33
64
}
34
65
35
66
case QgsWkbTypes::LineGeometry:
36
67
{
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 ) );
38
73
break ;
39
74
}
40
75
41
76
case QgsWkbTypes::PolygonGeometry:
42
77
{
43
- // TODO: support polygon geometries
78
+ const QgsPolygon *poly = qgsgeometry_cast<const QgsPolygon *>( geom.constGet () );
79
+ if ( poly )
80
+ appendChildNode ( createPolygonGeometry ( *poly ) );
44
81
break ;
45
82
}
46
83
@@ -50,7 +87,7 @@ QgsQuickHighlightSGNode::QgsQuickHighlightSGNode( const QVector<QgsPoint> &point
50
87
}
51
88
}
52
89
53
- QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry ( const QVector<QgsPoint> &points, qreal width )
90
+ QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry ( const QVector<QgsPoint> &points )
54
91
{
55
92
std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
56
93
std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique< QSGGeometry>( QSGGeometry::defaultAttributes_Point2D (), points.count () );
@@ -59,10 +96,13 @@ QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QVector<QgsP
59
96
int i = 0 ;
60
97
for ( const QgsPoint &pt : points )
61
98
{
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
+ );
63
103
}
64
104
65
- sgGeom->setLineWidth ( width );
105
+ sgGeom->setLineWidth ( mWidth );
66
106
sgGeom->setDrawingMode ( GL_LINE_STRIP );
67
107
node->setGeometry ( sgGeom.release () );
68
108
node->setMaterial ( &mMaterial );
@@ -71,15 +111,18 @@ QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QVector<QgsP
71
111
return node.release ();
72
112
}
73
113
74
- QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry ( const QgsPoint &point, qreal width )
114
+ QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry ( const QgsPoint &point )
75
115
{
76
116
std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
77
117
std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique<QSGGeometry>( QSGGeometry::defaultAttributes_Point2D (), 1 );
78
118
79
119
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
+ );
81
124
sgGeom->setDrawingMode ( GL_POINTS );
82
- sgGeom->setLineWidth ( width );
125
+ sgGeom->setLineWidth ( mWidth );
83
126
84
127
node->setGeometry ( sgGeom.release () );
85
128
node->setMaterial ( &mMaterial );
@@ -88,8 +131,38 @@ QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry( const QgsPoint &p
88
131
return node.release ();
89
132
}
90
133
91
- QSGGeometryNode *QgsQuickHighlightSGNode::createPolygonGeometry ( const QVector<QgsPoint> &points )
134
+ QSGGeometryNode *QgsQuickHighlightSGNode::createPolygonGeometry ( const QgsPolygon &polygon )
92
135
{
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;
95
168
}
0 commit comments