--
You received this message because you are subscribed to the GeoScript mailing list.
To post to this group, send email to geos...@googlegroups.com
To unsubscribe from this group, send email to geoscript+...@googlegroups.com
Visit this group at http://groups.google.com/group/geoscript or see http://geoscript.org
I just tossed in the JavaScript map examples in the learning section.
http://github.com/tschaub/geoscript.org/commit/dda1e708394d3ace92783c0ecc185e7b481b2fe8
I agree with Justin that we should better define the purpose of the
narrative docs (as compared to API docs). Perhaps we can come up with a
nice outline. The purpose of examples & learning pages are a bit cloudy
in my mind right now.
I also wonder if we should discuss a bit more the Map API. I think we
came to a good place with Style (and Rule & symbolizers are pretty easy).
Perhaps we don't need better alignment, but in the JS implementation, a
map is a simple collection of layers. As with the other GeoScript
collections (workspace, layer, schema), it's got add and (soon) remove
methods.
The map render method takes (among other things) width, height, and
projection. Perhaps it's pedantic, but size feels more like a rendering
option to me (rather than a map property). Projection and bounds are
derived from the first layer added if not provided to render.
Anyway, if we don't want perfect alignment on the API, then I think the
example narrative shouldn't be specific with regard to property and
method names (these can be in the API docs). If the examples are goal
oriented, then the narrative can set up the goal and the code can
demonstrate the syntax.
I'll put more code into the examples as time allows, but wanted to hear
a bit more discussion first.
Tim
The render method should have good defaults (width = 400, imageType=png, ect...) and I couldn't figure out a good way to do this in Groovy without named parameters and default values(I have Python/Scala envy here), so I moved all parameters out of render (except the OutputStream or File).
class Map {
private val defaults = immutable.Map("width" -> "300", "height" -> 300)
def render(providedParams: collection.Map[String, String]) = {
val params = defaults ++ providedParams
... do stuff with params here
}
}
new LineSymbolizer(strokeColor:"red", strokeWidth:3)
new LineSymbolizer(color:"red", width:"3")
var styles = collection.mutable.Buffer[Style]()
styles +=
Stroke(color="#000000", width=3)
styles +=
Stroke(color="#333333", width=5, linecap="round", z=0) and
Stroke(color="#6699FF", width=3, linecap="round", z=1)
styles +=
Stroke(color="#000000", width=3) when ("type='local-road'")
styles +=
Stroke(color="#000000", width=3) when (ScaleBetween(1.8e9, 3.6e9))
What is the layer property called in this case? I assume styles.
> Also, I think it would be a big win to drop the "stroke" prefix from
> LineSymbolizer properties (and "fill" from PolygonSymbolizer, etc.) For
> example, calls like
>
> new LineSymbolizer(strokeColor:"red", strokeWidth:3)
>
> would go to
>
> new LineSymbolizer(color:"red", width:"3")
>
For clarification, you are proposing "color" mean "strokeColor" for
LineSymbolizer and "fillColor" for PolygonSymbolizer? Then we still
have "strokeColor" for PolygonSymbolizer. And both "strokeColor" and
"fillColor" for PointSymbolizer.
I'm somewhat partial to the consistency we currently have (but for me,
scripting is not about typing fewer characters).
>
> Here's what a Scala style API implementing both ideas might look like
> (based on the Groovy examples from the site sources, in order):
>
> var styles = collection.mutable.Buffer[Style]()
>
> styles +=
>
> Stroke(color="#000000", width=3)
>
> styles +=
>
> Stroke(color="#333333", width=5, linecap="round", z=0) and
>
> Stroke(color="#6699FF", width=3, linecap="round", z=1)
>
> styles +=
>
> Stroke(color="#000000", width=3) when ("type='local-road'")
>
> styles +=
>
> Stroke(color="#000000", width=3) when (ScaleBetween(1.8e9, 3.6e9))
>
This is what I currently write (ommitting cap for brevity):
layer.style = [{
symbolizers: [{strokeColor: "#000000", strokeWidth: 3}]
}, {
symbolizers: [
{strokeColor: "#333333", strokeWidth: 5, zIndex: 0},
{strokeColor: "#6699FF", strokeWidth: 3, zIndex: 1}
]
}, {
symbolizers: [{strokeColor: "#000000", strokeWidth: 3}],
filter: "type='local-road'"
}, {
symbolizers: [{strokeColor: "#000000", strokeWidth: 3}],
minScaleDenominator: 1.8e9,
maxScaleDenominator: 3.6e9
}];
With your proposal, I think this is what I'd write:
layer.style = [
new Stroke({color: "#000000", width: 3}),
new Stroke({color: "#333333", width: 5, zIndex: 0})
.and({color: "#6699FF", width: 3, zIndex: 1}),
new Stroke({color: "#000000", width: 3})
.where("type='local-road'"),
new Stroke({color: "#000000", width: 3})
.range({min: 1.8e9, max: 3.6e9})
];
I like it. This does bring up some questions for me though.
var foo =
new Stroke({color: "fuchsia", width: 10, zIndex: 0})
.and({color: "navy", width: 5, zIndex: 1});
assert(foo instanceof Stroke);
assert(foo.color === "no idea");
Tim
On 10/15/10 7:47 AM, David Winslow wrote:What is the layer property called in this case? I assume styles.
Hey guys, I've been looking over the style API docs, and I have a small
suggestion.
Right now a Style is a container of Rules which are containers of
Symbolizers. I think it would be more convenient and "scripty" to make
Symbolizers themselves styles which can be composed with other styles if
you want multiple styles, or annotated with restrictions if desired.
For clarification, you are proposing "color" mean "strokeColor" for LineSymbolizer and "fillColor" for PolygonSymbolizer? Then we still have "strokeColor" for PolygonSymbolizer. And both "strokeColor" and "fillColor" for PointSymbolizer.
Also, I think it would be a big win to drop the "stroke" prefix from
LineSymbolizer properties (and "fill" from PolygonSymbolizer, etc.) For
example, calls like
new LineSymbolizer(strokeColor:"red", strokeWidth:3)
would go to
new LineSymbolizer(color:"red", width:"3")
Fill(color:blue) and Stroke(color: red)
Fill(fillcolor: blue, strokecolor:red)
I like it. This does bring up some questions for me though.
var foo =
new Stroke({color: "fuchsia", width: 10, zIndex: 0})
.and({color: "navy", width: 5, zIndex: 1});
assert(foo instanceof Stroke);
assert(foo.color === "no idea");
I consistently read Stroke as LineSymbolizer somehow in your previous
email. Seeing that you are indeed talking about creating separate
stroke and fill constructors, I agree the name "color" makes sense.
>
> With your proposal, I think this is what I'd write:
>
> layer.style = [
>
> new Stroke({color: "#000000", width: 3}),
>
> new Stroke({color: "#333333", width: 5, zIndex: 0})
> .and({color: "#6699FF", width: 3, zIndex: 1}),
>
> new Stroke({color: "#000000", width: 3})
> .where("type='local-road'"),
>
> new Stroke({color: "#000000", width: 3})
> .range({min: 1.8e9, max: 3.6e9})
>
> ];
>
>
Indeed what I was thinking I was typing above was LineSymbolizer (or
some shorthand for it) instead of Stroke.
> This looks right to me, assuming that layer.style has a setter which
> automatically composes styles. Otherwise, I'd expect a
> org.geoscript.style.compose() call in there somewhere.
>
> I like it. This does bring up some questions for me though.
>
> var foo =
> new Stroke({color: "fuchsia", width: 10, zIndex: 0})
> .and({color: "navy", width: 5, zIndex: 1});
>
> assert(foo instanceof Stroke);
>
>
> I would expect this assertion to fail, as the result of a
> *.and* operation would be a CompositeStyle or something instead of a Stroke.
>
> assert(foo.color === "no idea");
>
>
> Similarly, CompositeStyles don't have a color of their own; instead,
> they /contain/ styles which /might/ contain colors (or might themselves
> be composites of other styles.)
>
Ok, CompositeStyle is new. It would probably help to list the
constructors you are suggesting.
(I like the way this is going.)
Tim
>
> Tim
>
>
> Here "and" is a Style method which composes two styles, and
> "when" is a
> Style method which adds a constraint. ("when" might be
> overloaded to
> accept Strings (interpreted as CQL) and ScaleBetween's or something,
> specifics are up for debate).
>
> --
> David Winslow
> OpenGeo - http://opengeo.org/
>
> On Fri, Oct 15, 2010 at 12:39 PM, David Winslow
> <cdwi...@gmail.com <mailto:cdwi...@gmail.com>
> <mailto:cdwi...@gmail.com <mailto:cdwi...@gmail.com>>> wrote:
>
> On Wed, Oct 13, 2010 at 5:10 AM, Jared Erickson
> <jared.e...@gmail.com <mailto:jared.e...@gmail.com>
> <mailto:jared.e...@gmail.com
> <mailto:geos...@googlegroups.com>
> To unsubscribe from this group, send email to
> geoscript+...@googlegroups.com
> <mailto:geoscript%2Bunsu...@googlegroups.com>
> Visit this group at http://groups.google.com/group/geoscript or see
> http://geoscript.org
>
>
> --
> You received this message because you are subscribed to the
> GeoScript mailing list.
> To post to this group, send email to geos...@googlegroups.com
> <mailto:geos...@googlegroups.com>
> To unsubscribe from this group, send email to
> geoscript+...@googlegroups.com
> <mailto:geoscript%2Bunsu...@googlegroups.com>
I look forward to finding time to implement this and see how it feels.
I'm tempted to use Brush instead of Paint. And I think below you mean
that Fill and Stroke are constructed with "color" (instead of "fill"
and "stroke"). And the implicit conversion is from String to Paint
(or Brush). Not meaning to nitpick, but these were things that
confused me on first read, so I'm just clarifying.
Fill(color=Graphic("pattern.png"))
(Stroke("blue") when "geometryType(the_geom) = 'Polygon'") and
(Stroke("red") when "geometryType(the_geom) = 'Line'")
Yeah, I hit send too soon. Makes sense.
>
> sounds a bit awkward to me.
> I don't feel strongly about Brush vs. Paint. I suppose Brush has been
> popularized by Photoshop and its ilk, so we can go with that.
> The note about implicit conversions from String to Filter should have said
> String to Paint. Guess it's time to move those docs over to version
> control. (I may have been thinking about how Color should really be
> constructed with an Expression...)
> As for multiple geometry types - is that how things are handled now? I was
> under the impression that a LineSymbolizer and a PolygonSymbolizer with no
> Fill's were 100% equivalent (ie, in your style with a LineSymbolizer and a
> PolygonSymbolizer, lines and polygons would both get filled once and stroked
> twice). On the other hand, there is a CQL function for identifying the type
> of a geometry, so you could do something like:
I see that GeoTools is pretty liberal in how it applies a
PolygonSymbolizer. The spec reads that it "is used draw a polygon (or
other area-type geometries)." This would lead me to believe that you
could use a PolygonSymbolizer and LineSymbolizer to stroke geometries
differently depending on their type.
In any case, I'd be tempted to add a property to Stroke that specified
whether it applied to polygons, lines, or both (default). The CQL
below is clever, but it makes round-tripping SLD a bit more awkward
(not to mention writing CQL to capture the different geometry type
names - in GML at least - that all represent polygons).
Thanks for the responses.
On Sat, Oct 16, 2010 at 5:10 PM, David Winslow <cdwi...@gmail.com> wrote:Yeah, I hit send too soon. Makes sense.
> I named the paint properties for Fill and Stroke, fill and stroke
> respectively. This is because
>>
>> Fill(color=Graphic("pattern.png"))
I see that GeoTools is pretty liberal in how it applies a
>
> sounds a bit awkward to me.
> I don't feel strongly about Brush vs. Paint. I suppose Brush has been
> popularized by Photoshop and its ilk, so we can go with that.
> The note about implicit conversions from String to Filter should have said
> String to Paint. Guess it's time to move those docs over to version
> control. (I may have been thinking about how Color should really be
> constructed with an Expression...)
> As for multiple geometry types - is that how things are handled now? I was
> under the impression that a LineSymbolizer and a PolygonSymbolizer with no
> Fill's were 100% equivalent (ie, in your style with a LineSymbolizer and a
> PolygonSymbolizer, lines and polygons would both get filled once and stroked
> twice). On the other hand, there is a CQL function for identifying the type
> of a geometry, so you could do something like:
PolygonSymbolizer. The spec reads that it "is used draw a polygon (or
other area-type geometries)." This would lead me to believe that you
could use a PolygonSymbolizer and LineSymbolizer to stroke geometries
differently depending on their type.
In any case, I'd be tempted to add a property to Stroke that specified
whether it applied to polygons, lines, or both (default). The CQL
below is clever, but it makes round-tripping SLD a bit more awkward
(not to mention writing CQL to capture the different geometry type
names - in GML at least - that all represent polygons).