[mapguide-internals] RFC 60 questions about ComputeUsedColors
UV
uvwild at gmail.com
Tue Mar 24 21:54:47 EDT 2009
Thanks Walt for having a look.
I hope this is not opening a can of worms as the use case for our client
is already sufficiently implemented ;-)
1) And yes you are right I only read text string colors so far......
thats what I could extract from the XML schemas....
However, the code is collecting simply a unique list of strings here....
which leaves us a lot of room to do other things with them!
The strings are translated into colors only in the rendering service
before they are passed to the AGG renderer.
BTW, I did not manage to find more detailed information on the theming
bit so far ..... I suppose, however, that in the long run the
color collecting code needs to be deeper integrated into the
mapping/rendering code which uses the theming capabilities.
In the moment I am lacking sufficient documentation and samples to see a
way how to get there.
2) Currently the code is evaluating Area/Line/Point Rules and collects
colors from the corresponding xxxSymbolization classes.
This seemed sufficient for our use case as only the areas are really
affected.
Also I did not manage to follow the symbol definitions and
compositeTypeStyles to the actual definition of colors in my samples.....
If I get a few use cases and examples of how this is used and what
else need to be done to retrieve those colors I am happy to add that for
completeness.
(I believe in this case the code should be merged further with the
rendering/mapping code doing that lookup already to avoid unnecessary
overhead in calling the resource service)
The color collection is done in the
VectorLayerDefinition.::ComputeUsedColors and this code is called from
the StylizeLayers right after stylization....
As I do not really understanding all details here that was the place
seeming logical... :)
3) I included the relevant code bits here and I will be posting a patch
later today after cleaning up and synching with the repository.
If there will be votes to add more StylizationTypes to the color
extraction thats fine with me....
I will require some support in forms of examples and test cases =
maps to do so.
Also the following up of ResourceIds which I believe will be
essential to do the SymbolDefintions need more considerations
In the current approach the simple rescanning of the in memory layer
defs seems performant enough to just plug it into the Stylize Layer code
as is.
Cheers,
UV
Walt Welton-Lair wrote:
> Hi UV,
>
> I like the change you've made in your RFC about not storing user stored palettes. It simplifies things significantly.
>
> The updated RFC suggests adding a new ComputeUsedColors method to VectorLayerDefinition. Just to be sure I understand, the purpose of the method is to iterate through the layer definition data model and build a list of all colors reference by the styles? If so, I have a couple of questions:
>
> 1/ How will the new method work with colors which are set to expressions? While not a very common use case - color variation is generally done via theming - MapGuide does support it. Getting that use case to fully work with your RFC seems like it would require two passes through the features - one pass to evaluate the color expression(s) against all the features which want to be rendered, and the second pass to do the actual rendering using the updated tile palette. I'm not suggesting we actually do this, but I think it needs to be pointed out as a limitation with your updated approach.
>
> 2/ With the new enhanced stylization (RFC 14) the layer definition can reference symbol definitions (in addition to inlining them). The symbols, of course, define colors which need to be accounted for. Accessing referenced symbol definitions requires the resource service - we need to get the symbol definition resource from the service. The MdfModel project (where VectorLayerDefinition is stored) does not have access (nor want access) to the resource service. So if you want to properly support the new enhanced stylization with your RFC (you should) then we'll probably have to move this ComputeUsedColors method somewhere else. There's a method - MgMappingUtil::ComputeStylizationOffset - which does something analogous to ComputeUsedColors, so possibly we can add ComputeUsedColors to MgMappingUtil.
>
I added the call just a few lines below the call to the
MgMappingUtil::ComputeStylizationOffset right after the
stylization
#line 565
if (NULL != fdoReader.p)
{
// stylize into output format
dr->StartLayer(&layerInfo, &fcinfo);
ds->StylizeVectorLayer(vl, dr, rsReader,
xformer, scale, NULL, NULL);
dr->EndLayer();
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// COLORPALETTE CODE from UV for Ticket #813
// add the colors from this scaleRange and
vectorlayer to the map colors
// (overrideFilters == NULL could tells us
// that we have been called for rendering a map
and not for selection)
{
// the map object owns the color list so get
a pointer from there
PSTRCOLORLIST pStringColorPalette =
map->GetColorPalette();
PSTRCOLORLIST vLayerColors =
vl->ComputeUsedColors(scaleRange);
if (!vLayerColors->empty())
{
assert (pStringColorPalette);
// add the vectorLayer's Colors to the
map's color list
STRCOLORLIST::iterator it =
vLayerColors->begin();
for(; it != vLayerColors->end(); it++)
{ // uppercase the colorcodes
(FFABDEFF) and filter empty strings
if (*it == L"") continue;
STRING upc = *it;
std::transform( upc.begin(),
upc.end(), upc.begin(), towupper);
pStringColorPalette->push_back(upc);
}
assert (pStringColorPalette ==
map->GetColorPalette()); /// make sure this is the same palette
// the property setter canonicalizes the
palette
map->SetColorPalette(pStringColorPalette);
}
#ifdef _DEBUG
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
StylizeLayers::Palette->size(): %d\n", pStringColorPalette->size());
#endif
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
}
Here is the Compute UsedColors method
//-------------------------------------------------------------------------
// PURPOSE: Accessor method for the base colors defined in this Layer and scaleRange.
// RETURNS: A pointer to the list of colors of the collected colors (maybe empty but not null)
//-------------------------------------------------------------------------
PSTRCOLORLIST VectorLayerDefinition::ComputeUsedColors(VectorScaleRange* scaleRange)
{
PSTRCOLORLIST foundColors = new STRCOLORLIST(); // always create
// iterate through the featuretypecollection
FeatureTypeStyleCollection* pftsColl = scaleRange->GetFeatureTypeStyles();
int ftsccount = pftsColl->GetCount();
for (int j=0; j< ftsccount; j++)
{
FeatureTypeStyle* pfts = pftsColl->GetAt(j);
// iterate through the rulecollection
RuleCollection* ruleColl = pfts->GetRules();
int rccount = ruleColl->GetCount();
for (int k=0; k < rccount; k++)
{
Rule* rule = ruleColl->GetAt(k);
// get the label which will be the key in the color map
const MdfString& label = rule->GetLegendLabel();
// do the casting to access the relevant members
// this is bad style (instead of virtual functions in each subclass)
// but we save touching too many different files
AreaRule* paRule = dynamic_cast<AreaRule*>(rule);
LineRule* plRule = dynamic_cast<LineRule*>(rule);
PointRule* ppRule = dynamic_cast<PointRule*>(rule);
//CompositeRule* pcRule = dynamic_cast<CompositeRule*>(rule); // no colors in there
// AreaRule Symbolization.....
if (paRule != NULL)
{
AreaSymbolization2D* pasym = paRule->GetSymbolization();
if (pasym->GetFill() != NULL) {
foundColors->push_back(pasym->GetFill()->GetForegroundColor());
foundColors->push_back(pasym->GetFill()->GetBackgroundColor());
}
if (pasym->GetEdge() != NULL)
foundColors->push_back(pasym->GetEdge()->GetColor());
}
// LineRule Symbolization.....
if (plRule != NULL)
{
LineSymbolizationCollection* plsymcol = plRule->GetSymbolizations();
// iterate through the linesymbolizations
int lsccount = plsymcol->GetCount();
for (int l=0; l < lsccount; l++)
{
LineSymbolization2D* plsym = plsymcol->GetAt(l);
if (plsym->GetStroke() != NULL)
foundColors->push_back(plsym->GetStroke()->GetColor());
}
}
// PointRule Symbolization.....
if (ppRule != NULL)
{
PointSymbolization2D* ppsym = ppRule->GetSymbolization();
if (ppsym)
{
Symbol *sym = ppsym->GetSymbol();
MdfModel::BlockSymbol* blockSymbol = dynamic_cast<MdfModel::BlockSymbol*>(sym);
MdfModel::FontSymbol* fontSymbol = dynamic_cast<MdfModel::FontSymbol*>(sym);
MdfModel::MarkSymbol* markSymbol = dynamic_cast<MdfModel::MarkSymbol*>(sym);
MdfModel::TextSymbol* textSymbol = dynamic_cast<MdfModel::TextSymbol*>(sym);
MdfModel::W2DSymbol* w2dSymbol = dynamic_cast<MdfModel::W2DSymbol*>(sym);
if (blockSymbol != NULL)
{
foundColors->push_back(blockSymbol->GetBlockColor());
foundColors->push_back(blockSymbol->GetLayerColor());
}
if (fontSymbol != NULL)
{
foundColors->push_back(fontSymbol->GetForegroundColor());
}
if (markSymbol != NULL)
{
if (markSymbol->GetEdge() != NULL)
foundColors->push_back(markSymbol->GetEdge()->GetColor());
if (markSymbol->GetFill() != NULL) {
foundColors->push_back(markSymbol->GetFill()->GetForegroundColor());
foundColors->push_back(markSymbol->GetFill()->GetBackgroundColor());
}
}
if (textSymbol != NULL)
{
foundColors->push_back(textSymbol->GetForegroundColor());
foundColors->push_back(textSymbol->GetBackgroundColor());
}
if (w2dSymbol != NULL)
{
foundColors->push_back(w2dSymbol->GetFillColor());
foundColors->push_back(w2dSymbol->GetLineColor());
foundColors->push_back(w2dSymbol->GetTextColor());
}
} // if pointSymbolization
} // end pointRule
} // for GetRules
} // for GetFeatureTypeStyles
#ifdef _DEBUG
printf("|||||||||||||||||||||||||||||||||||||||||||||||VectorLayerDefinition %s found %d colors\n",
this->GetFeatureName(), foundColors->size());
#endif
return foundColors;
}
> Walt
>
> W E @__ __o
> A T R @___ _ \<,_
> L @_ (*)/ (*)
>
>
> _______________________________________________
> mapguide-internals mailing list
> mapguide-internals at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/mapguide-internals
>
>
More information about the mapguide-internals
mailing list