QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsvectortilebasicrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectortilebasicrenderer.cpp
3  --------------------------------------
4  Date : March 2020
5  Copyright : (C) 2020 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
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 "qgsapplication.h"
19 #include "qgscolorschemeregistry.h"
21 #include "qgsfillsymbollayer.h"
22 #include "qgslinesymbollayer.h"
23 #include "qgsmarkersymbollayer.h"
24 #include "qgssymbollayerutils.h"
25 #include "qgsvectortileutils.h"
26 
27 
29  : mStyleName( stName )
30  , mLayerName( laName )
31  , mGeometryType( geomType )
32 {
33 }
34 
36 {
37  operator=( other );
38 }
39 
41 {
42  mStyleName = other.mStyleName;
43  mLayerName = other.mLayerName;
44  mGeometryType = other.mGeometryType;
45  mSymbol.reset( other.mSymbol ? other.mSymbol->clone() : nullptr );
46  mEnabled = other.mEnabled;
47  mExpression = other.mExpression;
48  mMinZoomLevel = other.mMinZoomLevel;
49  mMaxZoomLevel = other.mMaxZoomLevel;
50  return *this;
51 }
52 
54 
56 {
57  mSymbol.reset( sym );
58 }
59 
60 void QgsVectorTileBasicRendererStyle::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
61 {
62  elem.setAttribute( QStringLiteral( "name" ), mStyleName );
63  elem.setAttribute( QStringLiteral( "layer" ), mLayerName );
64  elem.setAttribute( QStringLiteral( "geometry" ), mGeometryType );
65  elem.setAttribute( QStringLiteral( "enabled" ), mEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
66  elem.setAttribute( QStringLiteral( "expression" ), mExpression );
67  elem.setAttribute( QStringLiteral( "min-zoom" ), mMinZoomLevel );
68  elem.setAttribute( QStringLiteral( "max-zoom" ), mMaxZoomLevel );
69 
70  QDomDocument doc = elem.ownerDocument();
71  QgsSymbolMap symbols;
72  symbols[QStringLiteral( "0" )] = mSymbol.get();
73  QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
74  elem.appendChild( symbolsElem );
75 }
76 
77 void QgsVectorTileBasicRendererStyle::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
78 {
79  mStyleName = elem.attribute( QStringLiteral( "name" ) );
80  mLayerName = elem.attribute( QStringLiteral( "layer" ) );
81  mGeometryType = static_cast<QgsWkbTypes::GeometryType>( elem.attribute( QStringLiteral( "geometry" ) ).toInt() );
82  mEnabled = elem.attribute( QStringLiteral( "enabled" ) ).toInt();
83  mExpression = elem.attribute( QStringLiteral( "expression" ) );
84  mMinZoomLevel = elem.attribute( QStringLiteral( "min-zoom" ) ).toInt();
85  mMaxZoomLevel = elem.attribute( QStringLiteral( "max-zoom" ) ).toInt();
86 
87  mSymbol.reset();
88  QDomElement symbolsElem = elem.firstChildElement( QStringLiteral( "symbols" ) );
89  if ( !symbolsElem.isNull() )
90  {
91  QgsSymbolMap symbolMap = QgsSymbolLayerUtils::loadSymbols( symbolsElem, context );
92  if ( symbolMap.contains( QStringLiteral( "0" ) ) )
93  {
94  mSymbol.reset( symbolMap.take( QStringLiteral( "0" ) ) );
95  }
96  }
97 }
98 
100 
101 
103 {
104 }
105 
107 {
108  return QStringLiteral( "basic" );
109 }
110 
112 {
114  r->mStyles = mStyles;
115  r->mStyles.detach(); // make a deep copy to make sure symbols get cloned
116  return r;
117 }
118 
119 void QgsVectorTileBasicRenderer::startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange )
120 {
121  Q_UNUSED( context )
122  Q_UNUSED( tileRange )
123  // figure out required fields for different layers
124  for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) )
125  {
126  if ( layerStyle.isActive( tileZoom ) && !layerStyle.filterExpression().isEmpty() )
127  {
128  QgsExpression expr( layerStyle.filterExpression() );
129  mRequiredFields[layerStyle.layerName()].unite( expr.referencedColumns() );
130  }
131  }
132 }
133 
134 QMap<QString, QSet<QString> > QgsVectorTileBasicRenderer::usedAttributes( const QgsRenderContext & )
135 {
136  return mRequiredFields;
137 }
138 
140 {
141  Q_UNUSED( context )
142 }
143 
145 {
146  const QgsVectorTileFeatures tileData = tile.features();
147  int zoomLevel = tile.id().zoomLevel();
148 
149  for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) )
150  {
151  if ( !layerStyle.isActive( zoomLevel ) )
152  continue;
153 
154  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) ); // will be deleted by popper
155  scope->setFields( tile.fields()[layerStyle.layerName()] );
156  QgsExpressionContextScopePopper popper( context.expressionContext(), scope );
157 
158  QgsExpression filterExpression( layerStyle.filterExpression() );
159  filterExpression.prepare( &context.expressionContext() );
160 
161  QgsSymbol *sym = layerStyle.symbol();
162  sym->startRender( context, QgsFields() );
163  if ( layerStyle.layerName().isEmpty() )
164  {
165  // matching all layers
166  for ( QString layerName : tileData.keys() )
167  {
168  for ( const QgsFeature &f : tileData[layerName] )
169  {
170  scope->setFeature( f );
171  if ( filterExpression.isValid() && !filterExpression.evaluate( &context.expressionContext() ).toBool() )
172  continue;
173 
174  if ( QgsWkbTypes::geometryType( f.geometry().wkbType() ) == layerStyle.geometryType() )
175  sym->renderFeature( f, context );
176  }
177  }
178  }
179  else if ( tileData.contains( layerStyle.layerName() ) )
180  {
181  // matching one particular layer
182  for ( const QgsFeature &f : tileData[layerStyle.layerName()] )
183  {
184  scope->setFeature( f );
185  if ( filterExpression.isValid() && !filterExpression.evaluate( &context.expressionContext() ).toBool() )
186  continue;
187 
188  if ( QgsWkbTypes::geometryType( f.geometry().wkbType() ) == layerStyle.geometryType() )
189  sym->renderFeature( f, context );
190  }
191  }
192  sym->stopRender( context );
193  }
194 }
195 
196 void QgsVectorTileBasicRenderer::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
197 {
198  QDomDocument doc = elem.ownerDocument();
199  QDomElement elemStyles = doc.createElement( QStringLiteral( "styles" ) );
200  for ( const QgsVectorTileBasicRendererStyle &layerStyle : mStyles )
201  {
202  QDomElement elemStyle = doc.createElement( QStringLiteral( "style" ) );
203  layerStyle.writeXml( elemStyle, context );
204  elemStyles.appendChild( elemStyle );
205  }
206  elem.appendChild( elemStyles );
207 }
208 
209 void QgsVectorTileBasicRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
210 {
211  mStyles.clear();
212 
213  QDomElement elemStyles = elem.firstChildElement( QStringLiteral( "styles" ) );
214  QDomElement elemStyle = elemStyles.firstChildElement( QStringLiteral( "style" ) );
215  while ( !elemStyle.isNull() )
216  {
218  layerStyle.readXml( elemStyle, context );
219  mStyles.append( layerStyle );
220  elemStyle = elemStyle.nextSiblingElement( QStringLiteral( "style" ) );
221  }
222 }
223 
224 void QgsVectorTileBasicRenderer::setStyles( const QList<QgsVectorTileBasicRendererStyle> &styles )
225 {
226  mStyles = styles;
227 }
228 
229 QList<QgsVectorTileBasicRendererStyle> QgsVectorTileBasicRenderer::styles() const
230 {
231  return mStyles;
232 }
233 
234 QList<QgsVectorTileBasicRendererStyle> QgsVectorTileBasicRenderer::simpleStyleWithRandomColors()
235 {
236  QColor polygonFillColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor();
237  QColor polygonStrokeColor = polygonFillColor;
238  polygonFillColor.setAlpha( 100 );
239  double polygonStrokeWidth = DEFAULT_LINE_WIDTH;
240 
241  QColor lineStrokeColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor();
242  double lineStrokeWidth = DEFAULT_LINE_WIDTH;
243 
244  QColor pointFillColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor();
245  QColor pointStrokeColor = pointFillColor;
246  pointFillColor.setAlpha( 100 );
247  double pointSize = DEFAULT_POINT_SIZE;
248 
249  return simpleStyle( polygonFillColor, polygonStrokeColor, polygonStrokeWidth,
250  lineStrokeColor, lineStrokeWidth,
251  pointFillColor, pointStrokeColor, pointSize );
252 }
253 
254 QList<QgsVectorTileBasicRendererStyle> QgsVectorTileBasicRenderer::simpleStyle(
255  const QColor &polygonFillColor, const QColor &polygonStrokeColor, double polygonStrokeWidth,
256  const QColor &lineStrokeColor, double lineStrokeWidth,
257  const QColor &pointFillColor, const QColor &pointStrokeColor, double pointSize )
258 {
259  QgsSimpleFillSymbolLayer *fillSymbolLayer = new QgsSimpleFillSymbolLayer();
260  fillSymbolLayer->setFillColor( polygonFillColor );
261  fillSymbolLayer->setStrokeColor( polygonStrokeColor );
262  fillSymbolLayer->setStrokeWidth( polygonStrokeWidth );
263  QgsFillSymbol *fillSymbol = new QgsFillSymbol( QgsSymbolLayerList() << fillSymbolLayer );
264 
265  QgsSimpleLineSymbolLayer *lineSymbolLayer = new QgsSimpleLineSymbolLayer;
266  lineSymbolLayer->setColor( lineStrokeColor );
267  lineSymbolLayer->setWidth( lineStrokeWidth );
268  QgsLineSymbol *lineSymbol = new QgsLineSymbol( QgsSymbolLayerList() << lineSymbolLayer );
269 
271  markerSymbolLayer->setFillColor( pointFillColor );
272  markerSymbolLayer->setStrokeColor( pointStrokeColor );
273  markerSymbolLayer->setSize( pointSize );
274  QgsMarkerSymbol *markerSymbol = new QgsMarkerSymbol( QgsSymbolLayerList() << markerSymbolLayer );
275 
276  QgsVectorTileBasicRendererStyle st1( QStringLiteral( "Polygons" ), QString(), QgsWkbTypes::PolygonGeometry );
277  st1.setSymbol( fillSymbol );
278 
279  QgsVectorTileBasicRendererStyle st2( QStringLiteral( "Lines" ), QString(), QgsWkbTypes::LineGeometry );
280  st2.setSymbol( lineSymbol );
281 
282  QgsVectorTileBasicRendererStyle st3( QStringLiteral( "Points" ), QString(), QgsWkbTypes::PointGeometry );
283  st3.setSymbol( markerSymbol );
284 
285  QList<QgsVectorTileBasicRendererStyle> lst;
286  lst << st1 << st2 << st3;
287  return lst;
288 }
QgsExpressionContextScope::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
Definition: qgsexpressioncontext.h:317
qgsexpressioncontextutils.h
QgsExpressionContextScopePopper
Definition: qgsexpressioncontextutils.h:354
QgsVectorTileBasicRenderer::setStyles
void setStyles(const QList< QgsVectorTileBasicRendererStyle > &styles)
Sets list of styles of the renderer.
Definition: qgsvectortilebasicrenderer.cpp:224
QgsSymbolLayerUtils::loadSymbols
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
Definition: qgssymbollayerutils.cpp:2944
QgsColorSchemeRegistry::fetchRandomStyleColor
QColor fetchRandomStyleColor() const
Returns a random color for use with a new symbol style (e.g.
Definition: qgscolorschemeregistry.cpp:141
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:580
QgsVectorTileBasicRendererStyle::writeXml
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes object content to given DOM element.
Definition: qgsvectortilebasicrenderer.cpp:60
QgsReadWriteContext
Definition: qgsreadwritecontext.h:34
QgsExpression::referencedColumns
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
Definition: qgsexpression.cpp:217
QgsTileRange
Definition: qgstiles.h:65
QgsSymbolMap
QMap< QString, QgsSymbol * > QgsSymbolMap
Definition: qgsrenderer.h:46
QgsSymbolLayer::setColor
virtual void setColor(const QColor &color)
The fill color.
Definition: qgssymbollayer.h:231
QgsLineSymbolLayer::setWidth
virtual void setWidth(double width)
Sets the width of the line symbol layer.
Definition: qgssymbollayer.h:948
qgssymbollayerutils.h
QgsVectorTileBasicRendererStyle::setSymbol
void setSymbol(QgsSymbol *sym)
Sets symbol for rendering. Takes ownership of the symbol.
Definition: qgsvectortilebasicrenderer.cpp:55
QgsFields
Definition: qgsfields.h:44
QgsVectorTileBasicRenderer::simpleStyle
static QList< QgsVectorTileBasicRendererStyle > simpleStyle(const QColor &polygonFillColor, const QColor &polygonStrokeColor, double polygonStrokeWidth, const QColor &lineStrokeColor, double lineStrokeWidth, const QColor &pointFillColor, const QColor &pointStrokeColor, double pointSize)
Returns a list of styles to render all layers with the given fill/stroke colors, stroke widths and ma...
Definition: qgsvectortilebasicrenderer.cpp:254
QgsExpression::isValid
bool isValid() const
Checks if this expression is valid.
Definition: qgsexpression.cpp:197
qgsmarkersymbollayer.h
QgsVectorTileBasicRenderer
Definition: qgsvectortilebasicrenderer.h:127
QgsVectorTileBasicRenderer::writeXml
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes renderer's properties to given XML element.
Definition: qgsvectortilebasicrenderer.cpp:196
QgsRenderContext
Definition: qgsrendercontext.h:57
QgsApplication::colorSchemeRegistry
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
Definition: qgsapplication.cpp:2089
QgsVectorTileRendererData
Definition: qgsvectortilerenderer.h:37
DEFAULT_POINT_SIZE
const double DEFAULT_POINT_SIZE
Magic number that determines the default point size for point symbols.
Definition: qgis.h:708
QgsSymbol
Definition: qgssymbol.h:63
QgsExpressionContextScope::setFields
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
Definition: qgsexpressioncontext.cpp:195
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:143
QgsVectorTileRendererData::id
QgsTileXYZ id() const
Returns coordinates of the tile.
Definition: qgsvectortilerenderer.h:44
qgsapplication.h
QgsVectorTileBasicRendererStyle::QgsVectorTileBasicRendererStyle
QgsVectorTileBasicRendererStyle(const QString &stName=QString(), const QString &laName=QString(), QgsWkbTypes::GeometryType geomType=QgsWkbTypes::UnknownGeometry)
Constructs a style object.
Definition: qgsvectortilebasicrenderer.cpp:28
QgsVectorTileBasicRenderer::clone
QgsVectorTileBasicRenderer * clone() const override
Returns a clone of the renderer.
Definition: qgsvectortilebasicrenderer.cpp:111
QgsSimpleFillSymbolLayer::setStrokeWidth
void setStrokeWidth(double strokeWidth)
Definition: qgsfillsymbollayer.h:91
QgsVectorTileBasicRendererStyle
Definition: qgsvectortilebasicrenderer.h:47
QgsVectorTileRendererData::fields
QMap< QString, QgsFields > fields() const
Returns per-layer fields.
Definition: qgsvectortilerenderer.h:54
QgsSymbol::stopRender
void stopRender(QgsRenderContext &context)
Ends the rendering process.
Definition: qgssymbol.cpp:460
QgsVectorTileBasicRenderer::QgsVectorTileBasicRenderer
QgsVectorTileBasicRenderer()
Constructs renderer with no styles.
Definition: qgsvectortilebasicrenderer.cpp:102
QgsMarkerSymbol
Definition: qgssymbol.h:917
QgsSymbol::renderFeature
void renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false, int currentVertexMarkerType=0, double currentVertexMarkerSize=0.0) SIP_THROW(QgsCsException)
Render a feature.
Definition: qgssymbol.cpp:819
QgsSimpleLineSymbolLayer
Definition: qgslinesymbollayer.h:39
DEFAULT_LINE_WIDTH
const double DEFAULT_LINE_WIDTH
Definition: qgis.h:709
QgsSimpleMarkerSymbolLayer
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
Definition: qgsmarkersymbollayer.h:198
QgsVectorTileBasicRendererStyle::~QgsVectorTileBasicRendererStyle
~QgsVectorTileBasicRendererStyle()
QgsLineSymbol
Definition: qgssymbol.h:1117
QgsWkbTypes::geometryType
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:937
QgsVectorTileBasicRenderer::startRender
void startRender(QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange) override
Initializes rendering. It should be paired with a stopRender() call.
Definition: qgsvectortilebasicrenderer.cpp:119
QgsSymbol::startRender
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
Definition: qgssymbol.cpp:435
qgsfillsymbollayer.h
QgsExpression::prepare
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
Definition: qgsexpression.cpp:323
QgsTileXYZ::zoomLevel
int zoomLevel() const
Returns tile's zoom level (Z)
Definition: qgstiles.h:59
QgsExpression::evaluate
QVariant evaluate()
Evaluate the feature and return the result.
Definition: qgsexpression.cpp:346
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext....
Definition: qgsexpressioncontext.h:111
QgsVectorTileBasicRenderer::usedAttributes
QMap< QString, QSet< QString > > usedAttributes(const QgsRenderContext &) override
Returns field names of sub-layers that will be used for rendering. Must be called between startRender...
Definition: qgsvectortilebasicrenderer.cpp:134
QgsVectorTileBasicRenderer::styles
QList< QgsVectorTileBasicRendererStyle > styles() const
Returns list of styles of the renderer.
Definition: qgsvectortilebasicrenderer.cpp:229
QgsVectorTileBasicRenderer::stopRender
void stopRender(QgsRenderContext &context) override
Finishes rendering and cleans up any resources.
Definition: qgsvectortilebasicrenderer.cpp:139
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:142
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:141
qgslinesymbollayer.h
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:139
QgsVectorTileBasicRenderer::renderTile
void renderTile(const QgsVectorTileRendererData &tile, QgsRenderContext &context) override
Renders given vector tile. Must be called between startRender/stopRender.
Definition: qgsvectortilebasicrenderer.cpp:144
QgsSimpleMarkerSymbolLayer::setStrokeColor
void setStrokeColor(const QColor &color) override
Sets the marker's stroke color.
Definition: qgsmarkersymbollayer.h:273
QgsSymbolLayerUtils::saveSymbols
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
Definition: qgssymbollayerutils.cpp:3022
QgsSymbolLayerList
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:53
QgsSimpleFillSymbolLayer
Definition: qgsfillsymbollayer.h:39
QgsFillSymbol
Definition: qgssymbol.h:1212
qgscolorschemeregistry.h
QgsVectorTileBasicRenderer::type
QString type() const override
Returns unique type name of the renderer implementation.
Definition: qgsvectortilebasicrenderer.cpp:106
qgsvectortilebasicrenderer.h
QgsMarkerSymbolLayer::setSize
virtual void setSize(double size)
Sets the symbol size.
Definition: qgssymbollayer.h:647
QgsFeature
Definition: qgsfeature.h:55
QgsVectorTileBasicRenderer::simpleStyleWithRandomColors
static QList< QgsVectorTileBasicRendererStyle > simpleStyleWithRandomColors()
Returns a list of styles to render all layers, using random colors.
Definition: qgsvectortilebasicrenderer.cpp:234
QgsVectorTileBasicRenderer::readXml
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads renderer's properties from given XML element.
Definition: qgsvectortilebasicrenderer.cpp:209
QgsVectorTileRendererData::features
QgsVectorTileFeatures features() const
Returns features of the tile grouped by sub-layer names.
Definition: qgsvectortilerenderer.h:59
QgsVectorTileFeatures
QMap< QString, QVector< QgsFeature > > QgsVectorTileFeatures
Features of a vector tile, grouped by sub-layer names (key of the map)
Definition: qgsvectortilerenderer.h:25
qgsvectortileutils.h
QgsVectorTileBasicRendererStyle::readXml
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads object content from given DOM element.
Definition: qgsvectortilebasicrenderer.cpp:77
QgsExpression
Definition: qgsexpression.h:113
QgsVectorTileBasicRendererStyle::operator=
QgsVectorTileBasicRendererStyle & operator=(const QgsVectorTileBasicRendererStyle &other)
Definition: qgsvectortilebasicrenderer.cpp:40
QgsSimpleFillSymbolLayer::setStrokeColor
void setStrokeColor(const QColor &strokeColor) override
Set stroke color.
Definition: qgsfillsymbollayer.h:82
QgsSimpleMarkerSymbolLayer::setFillColor
void setFillColor(const QColor &color) override
Set fill color.
Definition: qgsmarkersymbollayer.h:252
QgsSimpleFillSymbolLayer::setFillColor
void setFillColor(const QColor &color) override
Set fill color.
Definition: qgsfillsymbollayer.h:85