QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsquickhighlightsgnode.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsquickhighlightsgnode.cpp
3  --------------------------------------
4  Date : Nov 2017
5  Copyright : (C) 2017 by Matthias Kuhn
6  Email : [email protected]
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgstessellator.h"
19 #include "qgsgeometrycollection.h"
20 #include "qgsgeometry.h"
21 #include "qgslinestring.h"
22 #include "qgspoint.h"
23 #include "qgspolygon.h"
24 
26  const QColor &color, float width )
27  : QSGNode()
28  , mWidth( width )
29 {
30  mMaterial.setColor( color );
31  handleGeometryCollection( geom.constGet(), geom.type() );
32 }
33 
34 void QgsQuickHighlightSGNode::handleGeometryCollection( const QgsAbstractGeometry *geom, QgsWkbTypes::GeometryType type )
35 {
36  const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geom );
37  if ( collection && !collection->isEmpty() )
38  {
39  for ( int i = 0; i < collection->numGeometries(); ++i )
40  {
41  const QgsAbstractGeometry *geomN = collection->geometryN( i );
42  handleSingleGeometry( geomN, type );
43  }
44  }
45  else
46  {
47  handleSingleGeometry( geom, type );
48  }
49 }
50 
51 void QgsQuickHighlightSGNode::handleSingleGeometry( const QgsAbstractGeometry *geom, QgsWkbTypes::GeometryType type )
52 {
53  switch ( type )
54  {
56  {
57  const QgsPoint *point = qgsgeometry_cast<const QgsPoint *>( geom );
58  if ( point )
59  appendChildNode( createPointGeometry( point ) );
60  break;
61  }
62 
64  {
65  const QgsLineString *line = qgsgeometry_cast<const QgsLineString *>( geom );
66  if ( line )
67  appendChildNode( createLineGeometry( line ) );
68  break;
69  }
70 
72  {
73  const QgsPolygon *poly = qgsgeometry_cast<const QgsPolygon *>( geom );
74  if ( poly )
75  appendChildNode( createPolygonGeometry( poly ) );
76  break;
77  }
78 
81  break;
82  }
83 }
84 
85 QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QgsLineString *line )
86 {
87  Q_ASSERT( line );
88 
89  std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
90  std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique< QSGGeometry>( QSGGeometry::defaultAttributes_Point2D(), line->numPoints() );
91  QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
92 
93  const double *x = line->xData();
94  const double *y = line->yData();
95 
96  for ( int i = 0; i < line->numPoints(); ++i )
97  {
98  vertices[i].set(
99  static_cast< float >( x[i] ),
100  static_cast< float >( y[i] )
101  );
102  }
103 
104  sgGeom->setLineWidth( mWidth );
105  sgGeom->setDrawingMode( GL_LINE_STRIP );
106  node->setGeometry( sgGeom.release() );
107  node->setMaterial( &mMaterial );
108  node->setFlag( QSGNode::OwnsGeometry );
109  node->setFlag( QSGNode::OwnedByParent );
110  return node.release();
111 }
112 
113 QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry( const QgsPoint *point )
114 {
115  Q_ASSERT( point );
116 
117  std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
118  std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique<QSGGeometry>( QSGGeometry::defaultAttributes_Point2D(), 1 );
119 
120  QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
121  vertices[0].set(
122  static_cast< float >( point->x() ),
123  static_cast< float >( point->y() )
124  );
125  sgGeom->setDrawingMode( GL_POINTS );
126  sgGeom->setLineWidth( mWidth );
127 
128  node->setGeometry( sgGeom.release() );
129  node->setMaterial( &mMaterial );
130  node->setFlag( QSGNode::OwnsGeometry );
131  node->setFlag( QSGNode::OwnedByParent );
132  return node.release();
133 }
134 
135 QSGGeometryNode *QgsQuickHighlightSGNode::createPolygonGeometry( const QgsPolygon *polygon )
136 {
137  Q_ASSERT( polygon );
138 
139  const QgsRectangle bounds = polygon->boundingBox();
140  QgsTessellator tes( bounds.xMinimum(), bounds.yMinimum(), false, false, false );
141  tes.addPolygon( *polygon, 0.0 );
142 
143  QSGGeometryNode *node = new QSGGeometryNode;
144  QSGGeometry *sgGeom = new QSGGeometry( QSGGeometry::defaultAttributes_Point2D(), tes.dataVerticesCount() );
145 
146  QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
147 
148  // we need to revert translation in tessellator
149  float translateX = static_cast< float >( bounds.xMinimum() );
150  float translateY = static_cast< float >( bounds.yMinimum() );
151 
152  const QVector<float> data = tes.data();
153  int i = 0;
154  for ( auto it = data.constBegin(); it != data.constEnd(); )
155  {
156  float x = *it;
157  vertices[i].x = translateX + x;
158  ++it;
159 
160  ++it; // we do not need z coordinate
161 
162  float y = -( *it );
163  vertices[i].y = translateY + y;
164  ++it;
165 
166  ++i;
167  }
168  sgGeom->setDrawingMode( GL_TRIANGLES );
169  node->setGeometry( sgGeom );
170  node->setMaterial( &mMaterial );
171  node->setFlag( QSGNode::OwnsGeometry );
172  node->setFlag( QSGNode::OwnedByParent );
173  return node;
174 }
A rectangle specified with double values.
Definition: qgsrectangle.h:40
double y
Definition: qgspoint.h:42
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
int numPoints() const override
Returns the number of points in the curve.
Class that takes care of tessellation of polygons into triangles.
bool isEmpty() const override
Returns true if the geometry is empty.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:176
void addPolygon(const QgsPolygon &polygon, float extrusionHeight)
Tessellates a triangle and adds its vertex entries to the output data array.
Geometry collection.
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Definition: qgssurface.h:45
int numGeometries() const
Returns the number of geometries within the collection.
Abstract base class for all geometries.
const double * xData() const
Returns a const pointer to the x vertex data.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:138
QgsQuickHighlightSGNode(const QgsGeometry &geom, const QColor &color, float width)
Constructor of new QT Quick scene node based on geometry.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
Polygon geometry type.
Definition: qgspolygon.h:31
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:166
const double * yData() const
Returns a const pointer to the y vertex data.
double x
Definition: qgspoint.h:41