Skip to content
Permalink
Browse files

Added support for rendering symbols in customized order - "symbol lev…

…els". In renderer dialog one can override the default settings.

git-svn-id: http://svn.osgeo.org/qgis/branches/symbology-ng-branch@11058 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder
wonder committed Jul 13, 2009
1 parent aa4688c commit 74015a6f4bdb905556ee14af2993c610a59aca31
@@ -680,6 +680,68 @@ unsigned char *QgsVectorLayer::drawPolygon(
return ptr;
}

void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool labeling )
{
mRendererV2->startRender(rendererContext);

QgsFeature fet;
while ( nextFeature( fet ) )
{
mRendererV2->renderFeature(fet, rendererContext);

if ( labeling )
mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
}

mRendererV2->stopRender(rendererContext);
}

void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bool labeling )
{
QHash< QgsSymbolV2*, QList<QgsFeature> > features; // key = symbol, value = array of features

// startRender must be called before symbolForFeature() calls to make sure renderer is ready
mRendererV2->startRender(rendererContext);

// 1. fetch features
QgsFeature fet;
while ( nextFeature(fet) )
{
QgsSymbolV2* sym = mRendererV2->symbolForFeature(fet);
if ( !features.contains(sym) )
{
features.insert( sym, QList<QgsFeature>() );
}
features[sym].append( fet );

if ( labeling )
mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
}

// 2. draw features in correct order
QgsSymbolV2LevelOrder& levels = mRendererV2->symbolLevels();
for (int l = 0; l < levels.count(); l++)
{
QgsSymbolV2Level& level = levels[l];
for (int i = 0; i < level.count(); i++)
{
QgsSymbolV2LevelItem& item = level[i];
if (!features.contains(item.symbol()))
{
QgsDebugMsg("level item's symbol not found!");
continue;
}
int layer = item.layer();
QList<QgsFeature>& lst = features[item.symbol()];
QList<QgsFeature>::iterator fit;
for ( fit = lst.begin(); fit != lst.end(); ++fit )
mRendererV2->renderFeature(*fit, rendererContext, layer);
}
}

mRendererV2->stopRender(rendererContext);
}

bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
{
if (mUsingRendererV2)
@@ -688,19 +750,18 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
return FALSE;

QgsDebugMsg("rendering v2:\n" + mRendererV2->dump());

mRendererV2->startRender(rendererContext);


// TODO: really needed?
updateFeatureCount();
int totalFeatures = pendingFeatureCount();
int featureCount = 0;

QgsFeature fet;
QgsAttributeList attributes = mRendererV2->usedAttributes();
if (attributes.count() > 0)
QgsDebugMsg("attrs: " + QString::number(attributes[0]));

bool labeling = FALSE;
if (mLabelingPrepareLayerHook)
if ( mLabelingPrepareLayerHook && mLabelingRegisterFeatureHook )
{
int attrIndex;
if (mLabelingPrepareLayerHook(mLabelingContext, mLabelingLayerContext, attrIndex))
@@ -713,17 +774,11 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )

select( attributes, rendererContext.extent() );

while ( nextFeature( fet ) )
{
mRendererV2->renderFeature(fet, rendererContext);
if (mRendererV2->symbolLevels().isEmpty())
drawRendererV2(rendererContext, labeling);
else
drawRendererV2Levels(rendererContext, labeling);

if (labeling && mLabelingRegisterFeatureHook)
{
mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
}
}

mRendererV2->stopRender(rendererContext);
return TRUE;
}

@@ -175,6 +175,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** set whether to use renderer V2 for drawing. Added in QGIS 1.2 */
void setUsingRendererV2(bool usingRendererV2);

void drawRendererV2( QgsRenderContext& rendererContext, bool labeling );
void drawRendererV2Levels( QgsRenderContext& rendererContext, bool labeling );

/** Returns point, line or polygon */
QGis::GeometryType geometryType() const;

@@ -116,7 +116,7 @@ QgsFeatureRendererV2::QgsFeatureRendererV2(RendererType type)
}


void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext& context)
void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext& context, int layer)
{
QgsSymbolV2* symbol = symbolForFeature(feature);
if (symbol == NULL)
@@ -136,7 +136,7 @@ void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext&
}
QPointF pt;
_getPoint(pt, context.mapToPixel(), geom->asWkb());
((QgsMarkerSymbolV2*)symbol)->renderPoint(pt, context);
((QgsMarkerSymbolV2*)symbol)->renderPoint(pt, context, layer);
}
break;

@@ -149,7 +149,7 @@ void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext&
}
QPolygonF pts;
_getLineString(pts, context.mapToPixel(), geom->asWkb());
((QgsLineSymbolV2*)symbol)->renderPolyline(pts, context);
((QgsLineSymbolV2*)symbol)->renderPolyline(pts, context, layer);
}
break;

@@ -163,7 +163,7 @@ void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext&
QPolygonF pts;
QList<QPolygonF> holes;
_getPolygon(pts, holes, context.mapToPixel(), geom->asWkb());
((QgsFillSymbolV2*)symbol)->renderPolygon(pts, (holes.count() ? &holes : NULL), context);
((QgsFillSymbolV2*)symbol)->renderPolygon(pts, (holes.count() ? &holes : NULL), context, layer);
}
break;

@@ -183,7 +183,7 @@ void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext&
for (unsigned int i = 0; i < num; ++i)
{
ptr = _getPoint(pt, context.mapToPixel(), ptr);
((QgsMarkerSymbolV2*)symbol)->renderPoint(pt, context);
((QgsMarkerSymbolV2*)symbol)->renderPoint(pt, context, layer);
}
}
break;
@@ -204,7 +204,7 @@ void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext&
for (unsigned int i = 0; i < num; ++i)
{
ptr = _getLineString(pts, context.mapToPixel(), ptr);
((QgsLineSymbolV2*)symbol)->renderPolyline(pts, context);
((QgsLineSymbolV2*)symbol)->renderPolyline(pts, context, layer);
}
}
break;
@@ -226,7 +226,7 @@ void QgsFeatureRendererV2::renderFeature(QgsFeature& feature, QgsRenderContext&
for (unsigned int i = 0; i < num; ++i)
{
ptr = _getPolygon(pts, holes, context.mapToPixel(), ptr);
((QgsFillSymbolV2*)symbol)->renderPolygon(pts, (holes.count() ? &holes : NULL), context);
((QgsFillSymbolV2*)symbol)->renderPolygon(pts, (holes.count() ? &holes : NULL), context, layer);
}
}
break;
@@ -357,7 +357,10 @@ QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForValue(QVariant value)
QHash<QString, QgsSymbolV2*>::iterator it = mSymbolHash.find(value.toString());
if (it == mSymbolHash.end())
{
QgsDebugMsg("attribute value not found: " + value.toString());
if (mSymbolHash.count() == 0)
QgsDebugMsg("there are no hashed symbols!!!");
else
QgsDebugMsg("attribute value not found: " + value.toString());
return NULL;
}
else
@@ -11,6 +11,31 @@ class QgsSymbolV2;
class QgsRenderContext;
class QgsFeature;


////////
// symbol levels

class QgsSymbolV2LevelItem
{
public:
QgsSymbolV2LevelItem( QgsSymbolV2* symbol, int layer ) : mSymbol(symbol), mLayer(layer) {}
QgsSymbolV2* symbol() { return mSymbol; }
int layer() { return mLayer; }
protected:
QgsSymbolV2* mSymbol;
int mLayer;
};

// every level has list of items: symbol + symbol layer num
typedef QList< QgsSymbolV2LevelItem > QgsSymbolV2Level;

// this is a list of levels
typedef QList< QgsSymbolV2Level > QgsSymbolV2LevelOrder;


//////////////
// renderers

class QgsFeatureRendererV2
{
public:
@@ -37,17 +62,22 @@ class QgsFeatureRendererV2

virtual ~QgsFeatureRendererV2() {}

void renderFeature(QgsFeature& feature, QgsRenderContext& context);
void renderFeature(QgsFeature& feature, QgsRenderContext& context, int layer = -1);

//! for debugging
virtual QString dump();

//TODO: symbols() for symbol levels

QgsSymbolV2LevelOrder& symbolLevels() { return mLevelOrder; }
void setSymbolLevels(const QgsSymbolV2LevelOrder& levelOrder) { mLevelOrder = levelOrder; }

protected:
QgsFeatureRendererV2(RendererType type);

RendererType mType;

QgsSymbolV2LevelOrder mLevelOrder;
};

class QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
@@ -276,8 +276,15 @@ double QgsMarkerSymbolV2::size()
return maxSize;
}

void QgsMarkerSymbolV2::renderPoint(const QPointF& point, QgsRenderContext& context)
void QgsMarkerSymbolV2::renderPoint(const QPointF& point, QgsRenderContext& context, int layer)
{
if (layer != -1)
{
if ( layer >= 0 && layer < mLayers.count() )
((QgsMarkerSymbolLayerV2*) mLayers[layer])->renderPoint(point, context);
return;
}

for (QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it)
{
QgsMarkerSymbolLayerV2* layer = (QgsMarkerSymbolLayerV2*) *it;
@@ -324,8 +331,15 @@ int QgsLineSymbolV2::width()
return maxWidth;
}

void QgsLineSymbolV2::renderPolyline(const QPolygonF& points, QgsRenderContext& context)
void QgsLineSymbolV2::renderPolyline(const QPolygonF& points, QgsRenderContext& context, int layer)
{
if (layer != -1)
{
if ( layer >= 0 && layer < mLayers.count() )
((QgsLineSymbolLayerV2*) mLayers[layer])->renderPolyline(points, context);
return;
}

for (QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it)
{
QgsLineSymbolLayerV2* layer = (QgsLineSymbolLayerV2*) *it;
@@ -349,8 +363,15 @@ QgsFillSymbolV2::QgsFillSymbolV2(QgsSymbolLayerV2List layers)
mLayers.append(new QgsSimpleFillSymbolLayerV2());
}

void QgsFillSymbolV2::renderPolygon(const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context)
void QgsFillSymbolV2::renderPolygon(const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer)
{
if (layer != -1)
{
if ( layer >= 0 && layer < mLayers.count() )
((QgsFillSymbolLayerV2*) mLayers[layer])->renderPolygon(points, rings, context);
return;
}

for (QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it)
{
QgsFillSymbolLayerV2* layer = (QgsFillSymbolLayerV2*) *it;
@@ -94,7 +94,7 @@ class QgsMarkerSymbolV2 : public QgsSymbolV2
void setSize(double size);
double size();

void renderPoint(const QPointF& point, QgsRenderContext& context);
void renderPoint(const QPointF& point, QgsRenderContext& context, int layer = -1);

virtual QgsSymbolV2* clone() const;
};
@@ -109,7 +109,7 @@ class QgsLineSymbolV2 : public QgsSymbolV2
void setWidth(int width);
int width();

void renderPolyline(const QPolygonF& points, QgsRenderContext& context);
void renderPolyline(const QPolygonF& points, QgsRenderContext& context, int layer = -1);

virtual QgsSymbolV2* clone() const;
};
@@ -121,7 +121,7 @@ class QgsFillSymbolV2 : public QgsSymbolV2
public:
QgsFillSymbolV2(QgsSymbolLayerV2List layers = QgsSymbolLayerV2List());

void renderPolygon(const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context);
void renderPolygon(const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer = -1);

virtual QgsSymbolV2* clone() const;
};
@@ -7,6 +7,7 @@ symbology-ng/qgssymbollayerv2widget.cpp
symbology-ng/qgssymbolv2propertiesdialog.cpp
symbology-ng/qgsrendererv2propertiesdialog.cpp
symbology-ng/qgsstylev2managerdialog.cpp
symbology-ng/qgssymbollevelsv2dialog.cpp
symbology-ng/qgssymbolv2selectordialog.cpp
symbology-ng/qgsvectorgradientcolorrampv2dialog.cpp
symbology-ng/qgsvectorrandomcolorrampv2dialog.cpp
@@ -45,6 +46,7 @@ symbology-ng/qgssymbollayerv2widget.h
symbology-ng/qgssymbolv2propertiesdialog.h
symbology-ng/qgsrendererv2propertiesdialog.h
symbology-ng/qgsstylev2managerdialog.h
symbology-ng/qgssymbollevelsv2dialog.h
symbology-ng/qgssymbolv2selectordialog.h
symbology-ng/qgsvectorgradientcolorrampv2dialog.h
symbology-ng/qgsvectorrandomcolorrampv2dialog.h

0 comments on commit 74015a6

Please sign in to comment.
You can’t perform that action at this time.