[QGIS-trac] Re: [Quantum GIS] #3222: Fast,
easy and beautiful on the fly rule-based rendering of OSM maps
Quantum GIS
qgis at qgis.org
Wed Dec 22 20:11:39 EST 2010
#3222: Fast, easy and beautiful on the fly rule-based rendering of OSM maps
------------------------------------------------+---------------------------
Reporter: mayeulk | Owner: mayeulk
Type: enhancement | Status: new
Priority: major: does not work as expected | Milestone: Version 1.7.0
Component: Symbology | Version:
Keywords: | Platform_version:
Platform: All | Must_fix: No
Status_info: 0 |
------------------------------------------------+---------------------------
Comment(by mayeulk):
I have made extensive additions to many parts of the code to support some
useful features to render map with complex symbology grammar. Still, I
have problems with the symbol levels. I would like to enable symbol levels
when several rules are matched. It would be useful when a feature
(specially highways) should be represented with a combination of symbols.
For instance, a road can be on a bridge, under a tunnel [with transparent
tunnel symbol], in construction, bordered with trees, etc.
In many cases, it is possible to simply combine the symbols, e.g. one
symbol for the road itself and another one for the bridge "around" it. It
would be possible to use only one rule for all highways (except motorways
if shown with wider symbol).
If we have 30 types of ways and 5 types of additional symbols (bridge,
etc), we could then do this with only 30+5=35 rules instead of 30*5=150.
(Imagine if you add 10 scale-based rules: you got 1500 combinations!!).
For the implementation, I modified the symbolForFeature function (code
below) in src/core/symbology-ng/qgsrulebasedrendererv2.cpp
Here is what I'm trying to do:
For the first matched rule for a given feature, the code makes a copy of
the rule's symbol. If other rules are matched, it merges the layers of the
additional matched rule with the symbol(s) of previously matched rule(s).
It also merges the information on symbol levels.
Tests on rendering on small areas (with features matched by 2 rules) works
partially:
* the symbols are correctly merged. A new symbol is created and
displayed, based on the symbology and levels of the matching rules 8-)
* However, it modifies the symbol associated with the first matched rule
and shown in the style sheet (if you open the layer properties, you see
that the symbol has been permanently modified): the 1st matched rule is
now represented by a combination of the 2 original symbols. This change
is saved permanently in the Layer Properties. Similarly for symbol levels.
8-(
* it crashes very often 8-(
Below is the related draft code. I'm sure there are several incorrect
thinks here. Anyone could help?
Thanks!
Mayuel
{{{
QgsSymbolV2* QgsRuleBasedRendererV2::symbolForFeature( QgsFeature& feature
)
{
// return mCurrentSymbol;
// QgsSymbolV2* mergedSymbols = QgsSymbolV2::defaultSymbol( QGis::Line
); // tmp test
QgsSymbolV2* mergedSymbols; //FIXME is this correct?
int nSym = 0; // Number of symbols for a given feature
for ( QList<Rule*>::iterator it = mCurrentRules.begin(); it !=
mCurrentRules.end(); ++it )
{
Rule* rule = *it;
if ( rule->isFilterOK( mCurrentFields, feature ) )
{
if (nSym == 0){
++nSym;
QgsDebugMsg( "@@@@@@@@@@@@@@@@@@@@@@@@@@ ");
QgsDebugMsg( "@@ 1st symbol to be merged:" +
rule->dump());
mergedSymbols = rule->symbol(); //FIXME is this correct?
is it why the symbol in the rule itself get modified?
}
else
{
QgsDebugMsg( "@@ ADDING ADDITIONAL SYMBOL FOR GIVEN
FEATURE");
QgsSymbolV2* tmpSymbol = rule->symbol();
// tmpSymbol = rule->symbol();
QgsDebugMsg( "num layers tmpSymbol:" + QString::number(
tmpSymbol->symbolLayerCount() ) );
QgsDebugMsg( "tmpSymbol Rule:" + rule->dump());
QgsDebugMsg( "tmpSymbol Pass0 :" + QString::number(
tmpSymbol->symbolLayer( 0 )->renderingPass() ) );
// Merge layers of additional matched rule with symbol(s)
of previously matched rules
QgsSymbolLayerV2* sl = tmpSymbol->symbolLayer( 0 );
QgsDebugMsg( "Highest symbol level : " + QString::number
((mergedSymbols->symbolLayer( (mergedSymbols->symbolLayerCount()) -1
))->renderingPass()));
// insert symbol matching additional rule only if its
first layer is strictly above the last layer of the already merged symbol:
// this is partly to avoid part of the catastrophic
consequences of the bug with insertSymbolLayer a few lines below
// and might be changed when this bug is fixed
if(rule->symbol()->symbolLayer( 0 )->renderingPass() <=
((mergedSymbols->symbolLayer( (mergedSymbols->symbolLayerCount()) -1
))->renderingPass()) ) {QgsDebugMsg("Break"); break;}
QgsDebugMsg( QString::number(rule->symbol()->symbolLayer(
0 )->renderingPass()));
mergedSymbols->insertSymbolLayer(
(mergedSymbols->symbolLayerCount()) , sl ); // probably buggy: modifies
the symbol styles as well!!
//
(mergedSymbols->symbolLayer(1))->setRenderingPass(sl->renderingPass() );
(mergedSymbols->symbolLayer(1))->setRenderingPass(
rule->symbol()->symbolLayer( 0 )->renderingPass() );
QgsDebugMsg( "mergedSymbols layer: " + QString::number(1)
+ " Pass: " +
QString::number(mergedSymbols->symbolLayer(1)->renderingPass()) );
// For testing, currently only one layer is added. Adding several layers
could be done with some code more or less like:
// for( int slid = 0 ; slid < tmpSymbol->symbolLayerCount()
; ++slid ){
// QgsSymbolLayerV2* sl = tmpSymbol->symbolLayer( slid
);
// mergedSymbols->insertSymbolLayer( slid, sl );
//
(mergedSymbols->symbolLayer(slid))->setRenderingPass(sl->renderingPass()
);
// QgsDebugMsg( "mergedSymbols layer: " +
QString::number(slid) + " Pass: " +
//
QString::number(mergedSymbols->symbolLayer(slid)->renderingPass()) );
// }
}
// return rule->symbol(); //work with levels but takes only
first rule
}
}
QgsDebugMsg( "num layers mergedSymbols:" + QString::number(
mergedSymbols->symbolLayerCount() ) );
QgsDebugMsg( " mergedSymbols Pass layer0:"+
QString::number(mergedSymbols->symbolLayer( 0 )->renderingPass() ));
QgsDebugMsg( "@ @ @ @ @ @ return mergedSymbols");
return mergedSymbols;
}
}}}
--
Ticket URL: <http://trac.osgeo.org/qgis/ticket/3222#comment:7>
Quantum GIS <http://qgis.org>
Quantum GIS is an Open Source GIS viewer/editor supporting OGR, PostGIS, and GRASS formats
More information about the QGIS-trac
mailing list