QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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:41
double y
Definition: qgspoint.h:42
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
int numPoints() const override
Returns the number of points in the curve.
Class that takes care of tessellation of polygons into triangles.
const double * xData() const
Returns a const pointer to the x vertex data.
bool isEmpty() const override
Returns true if the geometry is empty.
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:42
Abstract base class for all geometries.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
const double * yData() const
Returns a const pointer to the y vertex data.
int numGeometries() const
Returns the number of geometries within the collection.
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:177
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:139
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
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:115
Polygon geometry type.
Definition: qgspolygon.h:31
double x
Definition: qgspoint.h:41