[Geoserver-devel] KML styles and schema compliance

Hi,
I was looking into the KML 2.1 schemas today and noticed
that any element extending from FeatureType can either have
a styleURL _or_ have an embedded style.
So it seems the easy solution is to embed the styles instead
of putting them just before the feature?

   <complexType name="FeatureType" abstract="true">
     <complexContent>
       <extension base="kml:ObjectType">
         <sequence>
           <element name="name" type="string" minOccurs="0"/>
           <element name="visibility" type="boolean" default="1" minOccurs="0"/>
           <element name="open" type="boolean" default="1" minOccurs="0"/>
           <element name="address" type="string" minOccurs="0"/>
           <element name="phoneNumber" type="string" minOccurs="0"/>
           <element name="Snippet" type="kml:SnippetType" minOccurs="0"/>
           <element name="description" type="string" minOccurs="0"/>
           <element ref="kml:LookAt" minOccurs="0"/>
           <element ref="kml:TimePrimitive" minOccurs="0"/>
           <element ref="kml:styleUrl" minOccurs="0"/>
           <element ref="kml:StyleSelector" minOccurs="0" maxOccurs="unbounded"/>
           <element ref="kml:Region" minOccurs="0"/>
           <element name="Metadata" type="kml:MetadataType" minOccurs="0"/>
         </sequence>
       </extension>
     </complexContent>
   </complexType>

   <complexType name="PlacemarkType" final="#all">
     <complexContent>
       <extension base="kml:FeatureType">
         <sequence>
           <element ref="kml:Geometry" minOccurs="0"/>
         </sequence>
       </extension>
     </complexContent>
   </complexType>

Anyways, the way we're outputting the styles can be kept for
the "shared styles" (see the OGC KML spec), so we can still
leverage it for the SLD styles whose symbolizers do not
reference an attribute directly, which is the vast majority
of them. By direct reference I mean something like:

<CssParameter name="stroke-width"><ogc:PropertyName>width</ogc:PropertyName></CSSParameter>

whilst anything used in a Rule filter can be turned into
a static filter (hint, each Rule gets turned into a KML style,
as each feature gets matched by at most one rule, if there
are multiple feature type styles we have to build the
possible combinations of rules in ft1 and ft2, and so on,
which is a simple exercise with nested loops unless you
want to be smart and avoid generating combinations
that cannot happen in practice).

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

Andrea Aime ha scritto:

   <complexType name="FeatureType" abstract="true">
     <complexContent>
       <extension base="kml:ObjectType">
         <sequence>
           <element name="name" type="string" minOccurs="0"/>
           <element name="visibility" type="boolean" default="1" minOccurs="0"/>
           <element name="open" type="boolean" default="1" minOccurs="0"/>
           <element name="address" type="string" minOccurs="0"/>
           <element name="phoneNumber" type="string" minOccurs="0"/>
           <element name="Snippet" type="kml:SnippetType" minOccurs="0"/>
           <element name="description" type="string" minOccurs="0"/>
           <element ref="kml:LookAt" minOccurs="0"/>
           <element ref="kml:TimePrimitive" minOccurs="0"/>
           <element ref="kml:styleUrl" minOccurs="0"/>
           <element ref="kml:StyleSelector" minOccurs="0" maxOccurs="unbounded"/>

Forgot to mention that StyleSelector is the place for embedded styles,
the Style element is of type StyleType and the latter inherits directly
from StyleSelector

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

The 2.1 schema contains a lot of garbage. I didn't actually read your email (sorry, on my way out :slight_smile: ) , but check http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd

-Arne

Andrea Aime wrote:

Hi,
I was looking into the KML 2.1 schemas today and noticed
that any element extending from FeatureType can either have
a styleURL _or_ have an embedded style.
So it seems the easy solution is to embed the styles instead
of putting them just before the feature?

   <complexType name="FeatureType" abstract="true">
     <complexContent>
       <extension base="kml:ObjectType">
         <sequence>
           <element name="name" type="string" minOccurs="0"/>
           <element name="visibility" type="boolean" default="1" minOccurs="0"/>
           <element name="open" type="boolean" default="1" minOccurs="0"/>
           <element name="address" type="string" minOccurs="0"/>
           <element name="phoneNumber" type="string" minOccurs="0"/>
           <element name="Snippet" type="kml:SnippetType" minOccurs="0"/>
           <element name="description" type="string" minOccurs="0"/>
           <element ref="kml:LookAt" minOccurs="0"/>
           <element ref="kml:TimePrimitive" minOccurs="0"/>
           <element ref="kml:styleUrl" minOccurs="0"/>
           <element ref="kml:StyleSelector" minOccurs="0" maxOccurs="unbounded"/>
           <element ref="kml:Region" minOccurs="0"/>
           <element name="Metadata" type="kml:MetadataType" minOccurs="0"/>
         </sequence>
       </extension>
     </complexContent>
   </complexType>

   <complexType name="PlacemarkType" final="#all">
     <complexContent>
       <extension base="kml:FeatureType">
         <sequence>
           <element ref="kml:Geometry" minOccurs="0"/>
         </sequence>
       </extension>
     </complexContent>
   </complexType>

Anyways, the way we're outputting the styles can be kept for
the "shared styles" (see the OGC KML spec), so we can still
leverage it for the SLD styles whose symbolizers do not
reference an attribute directly, which is the vast majority
of them. By direct reference I mean something like:

<CssParameter name="stroke-width"><ogc:PropertyName>width</ogc:PropertyName></CSSParameter>

whilst anything used in a Rule filter can be turned into
a static filter (hint, each Rule gets turned into a KML style,
as each feature gets matched by at most one rule, if there
are multiple feature type styles we have to build the
possible combinations of rules in ft1 and ft2, and so on,
which is a simple exercise with nested loops unless you
want to be smart and avoid generating combinations
that cannot happen in practice).

Cheers
Andrea

--
Arne Kepp
OpenGeo - http://opengeo.org
Expert service straight from the developers

Arne Kepp ha scritto:

The 2.1 schema contains a lot of garbage. I didn't actually read your email (sorry, on my way out :slight_smile: ) , but check http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd

Oh, ok. Well, in that schema the names changed slightly, but the
substance seems the same:
* PlaceholderType extends from AbstractFeatureType
* AbstractFeatureType can contain a styleUrl or an
   AbstractStyleSelectorGroup that is of type
   AbstractStyleSelectorType
* StyleType extends from AbstractSTyleSelectorType

So besides the much longer to read names (thank you OGC!)
it still seems my suggestion applies

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

+1 , this sounds much better than what I dug up.

In the long run we should still look into shared stylesheets (based on a hash of the style output independent of feature type ids... So still calculate it for every feature, but save a lot of bandwidth).

-Arne

Andrea Aime wrote:

Arne Kepp ha scritto:

The 2.1 schema contains a lot of garbage. I didn't actually read your email (sorry, on my way out :slight_smile: ) , but check http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd

Oh, ok. Well, in that schema the names changed slightly, but the
substance seems the same:
* PlaceholderType extends from AbstractFeatureType
* AbstractFeatureType can contain a styleUrl or an
  AbstractStyleSelectorGroup that is of type
  AbstractStyleSelectorType
* StyleType extends from AbstractSTyleSelectorType

So besides the much longer to read names (thank you OGC!)
it still seems my suggestion applies

Cheers
Andrea

--
Arne Kepp
OpenGeo - http://opengeo.org
Expert service straight from the developers

Ok, this definitely sounds like the way to go. I have updated GEOS-2448 accordingly.

David, hopefully you did not spin too many cycles on the temp file approach?

Arne Kepp wrote:

+1 , this sounds much better than what I dug up.

In the long run we should still look into shared stylesheets (based on a hash of the style output independent of feature type ids... So still calculate it for every feature, but save a lot of bandwidth).

-Arne

Andrea Aime wrote:

Arne Kepp ha scritto:

The 2.1 schema contains a lot of garbage. I didn't actually read your email (sorry, on my way out :slight_smile: ) , but check http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd

Oh, ok. Well, in that schema the names changed slightly, but the
substance seems the same:
* PlaceholderType extends from AbstractFeatureType
* AbstractFeatureType can contain a styleUrl or an
  AbstractStyleSelectorGroup that is of type
  AbstractStyleSelectorType
* StyleType extends from AbstractSTyleSelectorType

So besides the much longer to read names (thank you OGC!)
it still seems my suggestion applies

Cheers
Andrea

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

Okay, just down to the implementation details now. Right now, we avoid encoding placemarks that aren't rendered by the active SLD. To do this, we have the method that encodes the style return a boolean value to the calling code, which then uses that to decide whether or not to encode the placemark itself. In pseudocode:

boolean encodeStyle(feature, sld){
    rules = filterRules(feature, sld);
    if (rules.isEmpty()) return false;
    encodeRules(rules);
    return true;
}

void encode(features, sld){
    for (feature in features){
        if (encodeStyle(feature, sld)) encodePlacemark(feature, sld);
    }
}

However, now we need to know whether or not there are any applicable rules *before* we start encoding the styles, so I'd like to split the operation up a bit:

void encode(features, sld){
    for (feature in features){
        rules = filterRules(feature, sld);
        if (!rules.isEmpty()) encodePlacemark(feature, rules)
    }
}

And then encodePlacemark won't have to re-filter the rules when it comes time to encode. However, a number of methods that pull in the placemark metadata currently expect to be passed the entire style sheet. We could just pass both to the encodePlacemark method, but as long as I'm rewriting these calls I feel like we could rewrite these methods to expect the pre-filtered list, which would save a bit of work overall anyway.

To recap:

boolean encodeStyle(SimpleFeature, FeatureTypeStyle) =>
List<Symbolizer> filterSymbolizers(SimpleFeature, FeatureTypeStyle)

void encodePlacemarkName(SimpleFeature, FeatureTypeStyle) =>
void encodePlacemarkName(SimpleFeature, List<Symbolizer>)

and so on for the other placemark metadata methods.

The only objection I can think of is that the ows5 module in community will be broken by these changes. However, that module doesn't compile for me anyway right now, so it seems a minimal concern.

Are there any other objections?

David Winslow

Justin Deoliveira wrote:

Ok, this definitely sounds like the way to go. I have updated GEOS-2448 accordingly.

David, hopefully you did not spin too many cycles on the temp file approach?

Hi David,

This makes sense to me. I Don't the ows5-kml stuff is really used...just an experiment. So I could go ahead. Andrea can comment on if that code is actually needed. If so it sounds like it will be easy enough to rewrite to come inline with the api changes.

-Justin

David Winslow wrote:

Okay, just down to the implementation details now. Right now, we avoid encoding placemarks that aren't rendered by the active SLD. To do this, we have the method that encodes the style return a boolean value to the calling code, which then uses that to decide whether or not to encode the placemark itself. In pseudocode:

boolean encodeStyle(feature, sld){
    rules = filterRules(feature, sld);
    if (rules.isEmpty()) return false;
    encodeRules(rules);
    return true;
}

void encode(features, sld){
    for (feature in features){
        if (encodeStyle(feature, sld)) encodePlacemark(feature, sld);
    }
}

However, now we need to know whether or not there are any applicable rules *before* we start encoding the styles, so I'd like to split the operation up a bit:

void encode(features, sld){
    for (feature in features){
        rules = filterRules(feature, sld);
        if (!rules.isEmpty()) encodePlacemark(feature, rules)
    }
}

And then encodePlacemark won't have to re-filter the rules when it comes time to encode. However, a number of methods that pull in the placemark metadata currently expect to be passed the entire style sheet. We could just pass both to the encodePlacemark method, but as long as I'm rewriting these calls I feel like we could rewrite these methods to expect the pre-filtered list, which would save a bit of work overall anyway.

To recap:

boolean encodeStyle(SimpleFeature, FeatureTypeStyle) =>
List<Symbolizer> filterSymbolizers(SimpleFeature, FeatureTypeStyle)

void encodePlacemarkName(SimpleFeature, FeatureTypeStyle) =>
void encodePlacemarkName(SimpleFeature, List<Symbolizer>)

and so on for the other placemark metadata methods.

The only objection I can think of is that the ows5 module in community will be broken by these changes. However, that module doesn't compile for me anyway right now, so it seems a minimal concern.

Are there any other objections?

David Winslow

Justin Deoliveira wrote:

Ok, this definitely sounds like the way to go. I have updated GEOS-2448 accordingly.

David, hopefully you did not spin too many cycles on the temp file approach?

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you. Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Geoserver-devel mailing list
Geoserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

Justin Deoliveira ha scritto:

Hi David,

This makes sense to me. I Don't the ows5-kml stuff is really used...just an experiment. So I could go ahead. Andrea can comment on if that code is actually needed. If so it sounds like it will be easy enough to rewrite to come inline with the api changes.

I believe no-one is actually using that ows5 module, thought
there are a couple things there that it would be nice to salvage,
such as dumping the feature attributes out on demand (KML 2.2 has
an optional feature data section, making it go quite close to GML
in terms of simple features).

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.