Hi all,
many years ago pissed off by how hard it was to build
styles with code I created the StyleBuilder we have today...
shame on me :)
Now, I would like to propose a new style builder to replace
that old clunky one. I would like it to be very compact,
chock full of default behavior, and fluent.
This mail just strokes out the general ideas, it's not
a full fledged spec of how it would look like.
A OGC Style is structured as a tree:
Style -> FeatureTypeStyle* -> Rule* -> Symbolizer*
Now, one could make a tree of builders, but that would
mean the user would deal explicitly with 4 builders and would
have to compose the results... ugh, better write the
SLD by hand and parse it ;-)
The idea to simplify the above would be that:
- there is one main builder that allows access to
all the child ones with a fluent api
- at every moment, there is only one style, one
FTS, one rule and one symbolizer being built.
When you say you want the symbolizer, it's the
current one
- the only thing you're actually forced to specify
is a symbolizer. Everything else is defaulted
and assumed to be around (no need to actually
make calls to create a fts or a rule). And we
could even default the symbolizer itself (if
you did not say anything about it, it's a default
point style).
- when a higher level object is built, it cascades
the build to the contained objects being built
- when a new object is started, the previous one
is accumulated and will be used when building
the upper level object
Some ideas of how the api might look like, builder
orchestration wise:
StyleBuilder -> the current styleBuilder
StyleBuilder.fts() -> the current feature type style builder
StyleBuilder.rule() -> the current rule builder
StyleBuilder.symbolizer() -> the current symbolizer builder
StyleBuilder.startFTS() -> starts a new feature type style, accumulates
the previous one, if any
StyleBuilder.startRule() -> starts a new rule, accumulates the previous
one if any
StyleBuilder.startPoint() -> starts a new point symbolizer, accumulates
the previous one if any
StyleBuilder.startLine()
StyleBuilder.startPolygon()
StyleBuilder.startRaster()
Some examples of how it could be used:
// builds a default point style
StyleBuilder sb = new StyleBuilder();
sb.startPoint();
Style ps = sb.buildStyle();
// builds a default polygon style
sb.startPolygon();
sb.build();
// builds a blue 2px line style
sb.startLine().stroke(Color.BLUE).strokeWidth(2);
sb.build();
// a default polygon style with a filter and min scale
sb.startPolygon();
sb.rule().filter(myFilter).minScale(minDenominator);
sb.build();
// simple two color thematic map
sb.rule().filter(filter1);
sb.startPolygon().fill(Color.RED);
sb.startRule().filter(filter2);
sb.startPolygon().fill(Color.YELLOW);
sb.build();
// highway style line with two overlapping fts
sb.startLine().stroke(Color.WHITE).strokeWidth(3);
sb.startFTS();
sb.startLine().stroke(Color.GRAY).strokeWidth(1);
sb.build();
build() method wise, I was thinking each nested builder
would show the same method. When called it builds the current
object and resets it along with the lower levels.
So for example sb.rule().build() would cascade to the
current symbolizer, accumulate all the symbolizers found,
and reset both the rule and the symbolizers states.
But the most common case would just to call the top
level build() object to get a full fledged style.
What do you think? Am I on to something?
Cheers
Andrea
--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Geotools-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-devel