[wms] feature drawing order

2 messages Options
Embed this post
Permalink
Reijer Copier

[wms] feature drawing order

Reply Threaded More More options
Print post
Permalink
Hi,

We occasionally run into a situation where it is desirable to force a
particular drawing order within a single wms layer. As far as I know
there is currently no straightforward way to accomplish this.

I knew about the Layer/DataSource/FilterCondition configuration option
in the wms configuration and theorized the wfs query put there to be
used as a template while creating the GetFeature request. Therefore I
(incorrectly) expected that any SortBy added to this query would also
automatically appear in the GetFeature request sent to the (local) wfs.
This way I would be able to control the order of features in the feature
collection received by the wms and therefore the drawing order of those
features.

Fragment of the configuration I use:
<deegreewms:DataSource failOnException="0" queryable="1">
   <deegreewms:Name>app:test</deegreewms:Name>
   <deegreewms:Type>LOCALWFS</deegreewms:Type>
   <deegreewms:GeometryProperty>app:geom</deegreewms:GeometryProperty>
   <deegreewms:FilterCondition>
      <wfs:Query typeName="app:test" xmlns:gml="http://www.opengis.net/gml"
         xmlns:ogc="http://www.opengis.net/ogc"
         xmlns:wfs="http://www.opengis.net/wfs">
         <ogc:SortBy>
            <ogc:SortProperty>
               <ogc:PropertyName>app:order</ogc:PropertyName>
               <ogc:SortOrder>DESC</ogc:SortOrder>
            </ogc:SortProperty>
         </ogc:SortBy>
      </wfs:Query>
   </deegreewms:FilterCondition>
</deegreewms:DataSource>

Unfortunately the SortBy I put in the wms configuration was ignored.
Therefore I modified (see attached patch) the GetMapServiceInvokerForNL
class to get it to work anyway.

Did someone ever consider to sort features before drawing them in order
to get the drawing order as desired? I think we could solve really
interesting drawing problems using this approach, like correct rendering
of multi level road parts (overpasses, flyovers etc.), meaningful
visualization of multiple spatial plans for the same area (by drawing
the oldest plan first and more recent plans on top) etc.

Regards,

Reijer

Index: C:/Users/copierrj/geoide-workspace/deegree/src/org/deegree/ogcwebservices/wms/GetMapServiceInvokerForNL.java
===================================================================
--- C:/Users/copierrj/geoide-workspace/deegree/src/org/deegree/ogcwebservices/wms/GetMapServiceInvokerForNL.java (revision 20030)
+++ C:/Users/copierrj/geoide-workspace/deegree/src/org/deegree/ogcwebservices/wms/GetMapServiceInvokerForNL.java (working copy)
@@ -98,6 +98,7 @@
 import org.deegree.model.spatialschema.WKTAdapter;
 import org.deegree.ogcbase.PropertyPath;
 import org.deegree.ogcbase.PropertyPathFactory;
+import org.deegree.ogcbase.SortProperty;
 import org.deegree.ogcwebservices.InconsistentRequestException;
 import org.deegree.ogcwebservices.InvalidParameterValueException;
 import org.deegree.ogcwebservices.OGCWebService;
@@ -304,7 +305,8 @@
 
         Envelope bbox = transformBBOX( ds );
 
-        LinkedList<StringBuffer> filters = new LinkedList<StringBuffer>();
+        LinkedList<StringBuffer> filters = new LinkedList<StringBuffer>(),
+         sortProperties = new LinkedList<StringBuffer>();
 
         List<PropertyPath> pp = null;
         if ( style != null ) {
@@ -390,6 +392,12 @@
         if ( query != null ) {
             Filter filter = query.getFilter();
             filters.addAll( extractFilters( filter ) );
+            SortProperty[] sps = query.getSortProperties();
+            if ( sps != null ) {
+             for ( SortProperty sp : sps ) {
+             sortProperties.add ( extractSortProperty ( sp ) );
+             }
+            }
         }
         // filters from SLD
         if ( layer != null ) {
@@ -429,7 +437,15 @@
         if ( filters.size() > 1 ) {
             sb.append( "</ogc:And>" );
         }
-        sb.append( "</ogc:Filter></Query></GetFeature>" );
+        sb.append( "</ogc:Filter>" );
+        if ( sortProperties.size() > 0 ) {
+         sb.append( "<ogc:SortBy>" );
+         for( StringBuffer s : sortProperties ) {
+         sb.append( s );
+         }
+         sb.append( "</ogc:SortBy>" );
+        }
+        sb.append( "</Query></GetFeature>" );
 
         // create dom representation of the request
         Document doc = XMLTools.parse( new StringReader( sb.toString() ) );
@@ -444,9 +460,9 @@
         GetFeature gfr = GetFeature.create( "" + idg.generateUniqueID(), doc.getDocumentElement() );
 
         return gfr;
-    }
+    }    
 
-    private StringBuffer handleDimension( DimensionValues values, Dimension dim, String dimProp )
+ private StringBuffer handleDimension( DimensionValues values, Dimension dim, String dimProp )
                             throws OGCWebServiceException {
         if ( values == null && dim.getDefaultValue() != null ) {
             values = new DimensionValues( dim.getDefaultValue() );
@@ -505,6 +521,20 @@
         sb.append( "</ogc:Or>" );
         return sb;
     }
+
+ private static StringBuffer extractSortProperty( SortProperty sp ) {
+ StringBuffer sb = new StringBuffer();
+ sb.append( "<ogc:SortProperty>" );
+ sb.append( "<ogc:PropertyName>" );
+ sb.append( sp.getSortProperty().toString() );
+ sb.append( "</ogc:PropertyName>" );
+ sb.append( "<ogc:SortOrder>" );
+ sb.append( sp.getSortOrder() ? "ASC" : "DESC" );
+ sb.append( "</ogc:SortOrder>" );
+ sb.append( "</ogc:SortProperty>" );
+
+ return sb;
+ }
 
     private static LinkedList<StringBuffer> extractFilters( Filter filter ) {
         LinkedList<StringBuffer> filters = new LinkedList<StringBuffer>();

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
deegree-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/deegree-devel
Andreas Schmitz

Re: [wms] feature drawing order

Reply Threaded More More options
Print post
Permalink
Reijer Copier wrote:

Hi,

> We occasionally run into a situation where it is desirable to force a
> particular drawing order within a single wms layer. As far as I know
> there is currently no straightforward way to accomplish this.
>
> I knew about the Layer/DataSource/FilterCondition configuration option
> in the wms configuration and theorized the wfs query put there to be
> used as a template while creating the GetFeature request. Therefore I
> (incorrectly) expected that any SortBy added to this query would also
> automatically appear in the GetFeature request sent to the (local) wfs.
> This way I would be able to control the order of features in the feature
> collection received by the wms and therefore the drawing order of those
> features.
>
> Fragment of the configuration I use:
> <deegreewms:DataSource failOnException="0" queryable="1">
>    <deegreewms:Name>app:test</deegreewms:Name>
>    <deegreewms:Type>LOCALWFS</deegreewms:Type>
>    <deegreewms:GeometryProperty>app:geom</deegreewms:GeometryProperty>
>    <deegreewms:FilterCondition>
>       <wfs:Query typeName="app:test" xmlns:gml="http://www.opengis.net/gml"
>          xmlns:ogc="http://www.opengis.net/ogc"
>          xmlns:wfs="http://www.opengis.net/wfs">
>          <ogc:SortBy>
>             <ogc:SortProperty>
>                <ogc:PropertyName>app:order</ogc:PropertyName>
>                <ogc:SortOrder>DESC</ogc:SortOrder>
>             </ogc:SortProperty>
>          </ogc:SortBy>
>       </wfs:Query>
>    </deegreewms:FilterCondition>
> </deegreewms:DataSource>
>
> Unfortunately the SortBy I put in the wms configuration was ignored.
> Therefore I modified (see attached patch) the GetMapServiceInvokerForNL
> class to get it to work anyway.
>
> Did someone ever consider to sort features before drawing them in order
> to get the drawing order as desired? I think we could solve really
> interesting drawing problems using this approach, like correct rendering
> of multi level road parts (overpasses, flyovers etc.), meaningful
> visualization of multiple spatial plans for the same area (by drawing
> the oldest plan first and more recent plans on top) etc.
yes, we've run into this problem before ;-)

I've committed your patch, thanks.

I think for single layers, this is indeed useful. Another (simple)
option for deegree 3 would be to allow a SORTBY vendor specific
parameter to make this flexible on the fly. The unsolved problem is
still if you want to sort drawing order across layers, and I'm afraid
that there is no simple solution for that. If you break it down on the
database level, you'd have to somehow interleave the result from
multiple tables and paint one row at a time...

Best regards, Andreas
--
l a t / l o n  GmbH
Aennchenstrasse 19           53177 Bonn, Germany
phone ++49 +228 18496-0      fax ++49 +228 1849629
http://www.lat-lon.de        http://www.deegree.org


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
deegree-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/deegree-devel

signature.asc (204 bytes) Download Attachment