Archive for the ‘GeoServer’ Category

GeoServer in a clustered configuration (part 2)

In our last post on clustering, we talked about the theory behind some different options for clustering. In this post, we’ll go into an example of clustering, taken from our recent experience with one of our OpenGeo Suite Enterprise clients. If you’ll be attending FOSS4G-NA and want to learn more about clustering and GeoServer consider attending our GeoServer training and Juan Marin’s GeoServer in Production presentation (scheduled for 5/23/2013 at 11:30 am).

Clustering Scenario

In this following scenario, we will work through the installation and configuration of two GeoServers each inside their own servlet container instances on the same machine. Each servlet container will use the same JRE and the same container binaries (Apache Tomcat 7), but they will have independent configurations that allow them to run on different ports. These two GeoServer/Tomcat instances will be fronted by a local software proxy called HAProxy which acts as a HTTP/TCP load balancer. Load balancer configurations provide very basic “round robin” balancing of GeoServers. More sophisticated load-balancing configurations are possible, but are beyond the scope of this example. All GeoServers will be deployed as WAR files placed into each of the Tomcat webapps directories. It is possible to have multiple instances of Tomcat share a single web-application through the use of contexts. This is useful if you anticipate your web-application (GeoServer) will be changed/updated frequently, but isn’t necessary. Read the rest of this entry »

GeoServer in a clustered configuration (part 1)

Recently, we helped one of our clients who wanted to set up a GeoServer cluster. There are different ways to accomplish clustering depending on your specific needs, but we thought it would be illustrative to show what we did in this particular situation. Keep in mind this is a specific treatment and fairly tailored. We encourage you all to experiment with the newest features, but remember to do so in your testing environment!

We’ll start with some clustering theory and tips before launching into the actual details of how to do it.

Background

A computing cluster consists of two or more machines working together to provide a higher level of availability, reliability, and scalability than can be obtained from a single node. Nodes in a cluster are positioned behind a proxy server and/or load balancer that delegates requests to cluster members based on any one member’s ability/availability to handle load.

Clustering

Clustering

Similar to other applications with long-running in-memory states and high data I/O, GeoServer sees performance gains with two (or more) nodes clustered behind a load balancer—even with the slight overhead of the load balancer that sits in front of the cluster.

Generally, there are two complementary purposes for clustering GeoServer:

  • To provide high-performance and/or throughput
  • To achieve high availability

In the most demanding situations, GeoServer can be deployed in combinations of high-performance and high-availability instances.

High-Performance Clusters

A high-performance GeoServer configuration deploys several instances of GeoServer on a single machine.

High-performance cluster

High-performance cluster

Each GeoServer instance is deployed into its own servlet container (Tomcat, Jetty, etc.). Individual servlet containers are configured independently and spin up their own JVM, each with it’s own memory and processor allocations (borrowed from the pool of resources on the host machine). GeoServer’s memory and CPU runtime footprint are optimized for high throughput under heavy concurrency with such a deployment, but always consider that these different deployed units will compete for the physical server’s resources. To find the best balance we recommend, as always, to test for your particular scenario.

A load balancer or proxy fronts the cluster, and directs traffic to the member of the cluster most able to handle the current request. In this case, nodes will likely share the same server name or IP address, but listen for requests on different ports. For example:

Load Balancer @ http://<server>:80/<alias> forwards to one of:

  • GeoServer 1 in Tomcat 1 @ http://<server>/geoserver:8081
  • GeoServer 2 in Tomcat 2 @ http://<server>/geoserver:8082
  • GeoServer 3 in Tomcat 3 @ http://<server>/geoserver:8083
  • GeoServer 4 in Tomcat 4 @ http://<server>/geoserver:8084

An approach that deploys multiple instances of GeoServer into the same servlet container is not recommended. In this case, since host resource allocation (to a common JVM) will not be sequestered as neatly, competition for those resources will occur, limiting the benefits.

Users might also consider using the built-in clustering capabilities found in Enterprise Application Servers (such as Oracle Weblogic or JBoss), however this is beyond the scope of this discussion.

High-Availability Clusters

A high-availability implementation will spread several GeoServer instances across several machines (nodes) in a cluster. These nodes can be physical or virtual machines.

High-availability cluster

High-availability cluster

Nodes are normally located behind a load balancer that redirects traffic to any single GeoServer based on traffic volume and availability. In this case, nodes will likely be on different servers or IP addresses and listen for requests on the same port. For example:

Load Balancer @ http://<server>:80/<alias> forwards to one of:

  • GeoServer 1 in Tomcat 1 @ http://<server1>/geoserver:8080
  • GeoServer 1 in Tomcat 1 @ http://<server2>/geoserver:8080
  • GeoServer 1 in Tomcat 1 @ http://<server3>/geoserver:8080

Data directory location and catalog reloads

Some important considerations to be made when clustering several instances of GeoServer concern the location of the GeoServer data directory and a strategy for reloading all cluster members’ data catalogs.

The GeoServer data directory is the location in the file system where GeoServer stores its configuration information. The configuration defines things such as what data is served by GeoServer, where it is stored, and how services such as WFS and WMS interact with and serve the data. The data directory also contains a number of support files used by GeoServer for various purposes.

The spatial data accessed by GeoServer doesn’t need to reside within the GeoServer data directory, just pointers to the data locations. This should be obvious for data stored in spatial databases, which are certainly in different locations (on disk) and often on different machines; however the same is true for file-based spatial data. (Read more about the GeoServer data directory.)

GeoServer’s catalog is an in-memory representation of the configurations in the data directory. Storing the configurations in memory means that GeoServer can access this information faster than by reading these instructions off disk. However, this sometimes requires that the in-memory catalog be refreshed when configurations changes are made to the disk-based GeoServer data directory, or to the actual data served in GeoServer.

Unless catalog (re)configurations are largely static, or some amount of catalog discrepancy or availability is acceptable, a common GeoServer data directory location for all clustered instances is highly recommended.

The location of the GeoServer data directory is stored in the GEOSERVER_DATA_DIR variable. It can be configured in one of three ways: in each instance’s web.xml file (/webapps/geoserver/WEB-INF), through a common environment variable, or through a parameter passed to the JVM in the container start-up command.

Some implementations have clustered GeoServer instances using separate data directories that are synchronized manually (low change frequency) and automatically (using rsync), but neither approach is as common or recommended as a shared data directory.

Regardless of the mechanism for synchronization, changes to the data directory and the in-memory catalog will normally be directed by one master GeoServer. This can be enforced by disabling the GeoServer user interface on all “slave” GeoServers or by configuring the front-end load balancer to only direct user interface requests to /geoserver/web to the master GeoServer.

Changes to the master GeoServer’s data catalog must be explicitly refreshed on slave instances. This can be accomplished manually through the GeoServer Admin web UI (/geoserver/web), or with some measure of automation (on a schedule, or after a trigger is fired) using GeoServer’s REST API (e.g. by sending a POST/PUT request to /geoserver/rest/reload?recurse=true).

Clustering Enhancements

Enhancements to our clustering story are coming! Specifically, in future releases of GeoServer the data directory will have the option to be database-backed. This means that a central configuration store can be queried more optimally than a file-based counterpart and doesn’t all need to be read into memory.

In the next post, we’ll go into the details on setting up a clustered instance. Remember, Enterprise: Platform clients and higher get custom clustering and deployment advice included in their maintenance agreements.

Have you been looking at deploying GeoServer in a clustered environment? Tell us about it!

How to publish GDAL/MrSID image formats on a production GeoServer on Windows

We had a support ticket recently about adding / enabling the GDAL and MrSID image formats to be able to be published by GeoServer. The client’s production server was Windows Server 2012 running Tomcat as a service. Below is a description of the steps taken to accomplish this.

We followed the instructions as part of our User Manual, but here I’ve added some screenshots from the specific implementation. For more information, please see the section on Enabling GDAL image formats support

Instructions for other operating systems are to be found at the above link, but are similar to this procedure. Also, this example is specific to Tomcat running as a service—instructions are slightly different when Tomcat is run as a local user process.

Out of the box

This is what things look like with a stock installation. Notice that there is no OGR format driver among the Vector Store types, and there aren’t that many Raster Store options.

Put the GDAL JAR in place

The next step is to copy the GDAL JAR to the classpath of GeoServer, which in this case was <TOMCAT_HOME>\webapps\geoserver\WEB-INF\lib. While in our case there already was a GDAL JAR there, I overwrote the existing file to ensure that I had the latest and greatest version (at the time of writing, gdal-1.9.1.jar) .

Add the GDAL libraries to Tomcat

Now we had to add the GDAL libraries to the Tomcat bin directory so that Tomcat would pick them up. This was also pretty straightforward—I copy and paste like a champion.

As with most library changes though, the application will need to be restarted before any changes will occur.

Restart Tomcat

Restarting Tomcat gets us most of the way there. OGR is now available as a Vector Store type and the Raster Store types include some but not all of the GDAL formats. These are the open format types, the ones that don’t require any additional proprietary drivers.

Add the MrSID libraries to Tomcat

The next step installs the piece needed to access proprietary rasters, in this case JP2MRSID and MrSID format. I downloaded the MrSID binaries from the link listed in the first step of the instructions and extracted it to <TOMCAT_HOME>\bin\gdalplugins.

One more restart and MrSID is available as an available datastore and can be published through GeoServer.

Have you published any interesting data using MrSID or GDAL image formats in GeoServer? We’d like to hear about it! Tell us in the comments below, or send us a note.

Chaining Rendering Transformations in GeoServer

We’ve mentioned in previous posts how Rendering Transformations in GeoServer can produce rich visualization effects such as contour maps and interpolated surfaces, all generated dynamically.

Rendering transformations are implemented as standard GeoServer WPS processes. As processes can be chained together—that is, the output of one process can be the input of another—rendering transformations can be made even more complex and powerful.

One example of a chained rendering transformation is dynamic visualization of temperature contours (also known as isotherms), given a data set consisting of scattered temperature observations from around the globe.

Temperature Observations

Temperature Observations

A refresher on rendering transformations

Recall that rendering transformations are defined in SLD styles by using the <Transformation> element within a <FeatureTypeStyle>. The process is indicated by a <Function> whose name attribute is the name of the underlying WPS process. The parameters to the process are provided by the arguments to this function, and are themselves wrapped in calls to the special parameter function. This function takes as arguments a <Literal> containing the name of the process parameter being specified, followed by other (optional) <Literal>s containing the argument values.

<Transformation>
  <ogc:Function name="gs:someProcess">
    <ogc:Function name="data">
      <ogc:Literal>someParameter</ogc:Literal>
      <ogc:Literal>someValue</ogc:Literal>    </ogc:Function>
    <ogc:Function name="parameter">
      ...   
    </ogc:Function>
  ...

To be able to be used as a rendering transformation, a process must include one parameter that accepts the data to be transformed (which in this case is the layer being styled). As with other process parameters, this is expressed using the parameter function. The name of the process parameter is determined by the particular process being used. In the simple non-chained case, no arguments are supplied with this parameter; the data is provided implicitly by the SLD rendering engine.

In order to chain transformations, an upstream (inner) process is called as the argument to a downstream (outer) process’s data parameter. The upstream process must also include its own data parameter, which will not have an explicit value (if this is the first/innermost process in the chain). During rendering, the upstream process is executed on the original layer data, and the downstream process is executed on the result of the upstream process. The symbology defined in the SLD must be appropriate for the output format of the final process in the chain, regardless of the original or intermediate formats.

Making isotherms

Getting back to our example, the rendering transformation for isotherms consists of the Barnes Surface process chained to the Contour process. When applied to the temperature data this generates a contour map of estimated average temperatures, as shown in the image below.

Barnes_Contours

Barnes Surface and Contours

The image above is actually displaying three different layers:

  1. base map showing world countries
  2. layer showing the estimated temperature surface, computed using the Barnes Surface rendering transformation
  3. layer showing the isotherm lines generated by contouring the Barnes Surface

Here are the parameters used for this chain:

Barnes Surface:

  • data: [the layer itself]
  • valueAttr: MxTmp
  • dataLimit: 500
  • scale: 15.0
  • convergence: 0.2
  • passes: 3
  • minObservations: 2
  • maxObservations: 15
  • pixelsPerCell: 8
  • queryBuffer: 40

Contour:

  • data: [output of Barnes Surface processes]
  • levels: [-10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]
  • simplify: true

Download the SLD for the Barnes Surface/Contour style

The relevant snippet for the <Transformation> element expressing the chained rendering transformation is shown below. Note how the downstream gs:Contour process has the upstream gs:BarnesSurface process nested inside the data parameter. It’s worth pointing out that the data gets converted from vector to raster and back to vector during this chained process. The symbology in the SLD uses symbolizers appropriate for vector data, as that is the final data format.

One final note: The contour levels are defined explicitly with the Contour process levels parameter. These need to match the range of data values which are computed for the surface.

<Transformation>
  <ogc:Function name="gs:Contour">
    <ogc:Function name="parameter">
      <ogc:Literal>data</ogc:Literal>
      <ogc:Function name="gs:BarnesSurface">
        <ogc:Function name="parameter">
          <ogc:Literal>data</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>valueAttr</ogc:Literal>
          <ogc:Literal>MxTmp</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>dataLimit</ogc:Literal>
          <ogc:Literal>500</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>scale</ogc:Literal>
          <ogc:Literal>15.0</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>convergence</ogc:Literal>
          <ogc:Literal>0.2</ogc:Literal>
        </ogc:Function><ogc:Function name="parameter">
          <ogc:Literal>passes</ogc:Literal>
          <ogc:Literal>3</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>minObservations</ogc:Literal>
          <ogc:Literal>2</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>maxObservationDistance</ogc:Literal>
          <ogc:Literal>15</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>pixelsPerCell</ogc:Literal>
          <ogc:Literal>8</ogc:Literal>
        </ogc:Function>
        <ogc:Function name="parameter">
          <ogc:Literal>outputBBOX</ogc:Literal>
          <ogc:Function name="env">
        <ogc:Literal>wms_bbox</ogc:Literal>
        </ogc:Function>
      </ogc:Function>
      <ogc:Function name="parameter">
        <ogc:Literal>outputWidth</ogc:Literal>
        <ogc:Function name="env">
          <ogc:Literal>wms_width</ogc:Literal>
        </ogc:Function>
      </ogc:Function>
      <ogc:Function name="parameter">
        <ogc:Literal>outputHeight</ogc:Literal>
          <ogc:Function name="env">
            <ogc:Literal>wms_height</ogc:Literal>
          </ogc:Function>
      </ogc:Function>
      <ogc:Function name="parameter">
        <ogc:Literal>queryBuffer</ogc:Literal>
        <ogc:Literal>40</ogc:Literal>
      </ogc:Function>
    </ogc:Function>
  </ogc:Function>
  <ogc:Function name="parameter">
    <ogc:Literal>levels</ogc:Literal>
    <ogc:Literal>-10</ogc:Literal>
    <ogc:Literal>-5</ogc:Literal>
    <ogc:Literal>0</ogc:Literal>
    <ogc:Literal>5</ogc:Literal>
    <ogc:Literal>10</ogc:Literal>
    <ogc:Literal>15</ogc:Literal>
    <ogc:Literal>20</ogc:Literal>
    <ogc:Literal>25</ogc:Literal>
    <ogc:Literal>30</ogc:Literal>
    <ogc:Literal>35</ogc:Literal>
    <ogc:Literal>40</ogc:Literal>
  </ogc:Function>
  <ogc:Function name="parameter">
    <ogc:Literal>simplify</ogc:Literal>
    <ogc:Literal>true</ogc:Literal>
  </ogc:Function>
  </ogc:Function>
</Transformation>

Ideas for new rendering transformations welcome

At the moment there are only a few processes in GeoServer which are suitable for implementing chained rendering transformations. We want to continue expanding our offerings but not in a vacuum. What do you wish you could do with rendering transformations? Leave a comment below to let us know.

GeoServer CSS module: style in style

OpenGeo is excited to share the GeoServer CSS module, an alternative to SLD for thematic map styling in the OpenGeo Suite. Compared to SLD, GeoServer CSS brings many advantages for web cartographers.

GeoServer CSS is customized for use in GeoServer and provides access to spatial utilities such as powerful filter expressions that are useful not only for choosing which features to render but also for transforming geometries and other attributes on-the-fly during the rendering process. Thanks to its custom syntax (which builds on OGC CQL the same way that SLD builds on OGC Filter Encoding XML) it is much more compact, allowing authors to see more of the style without scrolling and to make edits without worrying about details such as closing nested XML tags in the proper order. GeoServer CSS is also simpler because it eschews some non-styling aspects of SLD such as embedded geometries.

As an example, let’s say we are styling polygons representing the habitats of several bird species. We would like to distinguish species by color (orioles have an orange area, bluebirds have a blue one, etc.), but all polygons should have a consistent opacity to help us identify places where habitats overlap. A style in CSS notation might look like this:

[species="bluebird"] {
    fill: blue;
    fill-opacity: 70%;
}

[species="oriole"] {
    fill: orange;
    fill-opacity: 70%;
}

[species="robin"] {
    fill: brown;
    fill-opacity: 70%;
}

Read the rest of this entry »

Adding Layers to GeoServer Using the REST API

At OpenGeo we’re often asked how to ingest large amounts of data into a system for storage (on disk, or in PostGIS) and publishing (through GeoServer and/or GeoWebCache).

GeoServer’s graphical administrative tools offer a convenient UI for managing data as workspaces, stores, layers and styles but will only handle them one at a time. If you have a significant amount of data to upload into GeoServer anew, or migrate from an existing implementation from another vendor, one-at-a-time just won’t cut it.

Enter GeoServer’s REST API (REST stands for REpresentational State Transfer). There’s a ton of general information online about REST but here it is in 50 words or less: REST lets you GET a representation of the current state of something through a URI, which you are then free to modify as/if needed, and finally PUT that representation back to the URI, where (if the request is authenticated and/or valid) the object’s state is modified.
In the GeoServer world, you might GET (a true HTTP GET) the current representation of a datastore, update something in that datastore configuration (correct a username, password or path), and then PUT the corrected representation back onto the server to update the configuration. If the service permits, you can also POST a new configuration to create a new object, or fire off a DELETE to an endpoint to remove an object from it. The specific methods you can apply to a REST endpoint and the objects you can apply those REQUESTS are often advertised by the endpoint itself. A RESTful interface should also offer written (prose) documentation of its capabilities. Read the rest of this entry »

Creating dynamic contour maps with server-side processing

As an avid cartophile and hiker, I’ve always enjoyed working with contour maps—vector maps in which lines circumscribe areas of similar or equal value—as they provide just the right amount of context for the vertical aspect of a trail. I routinely use contour maps when evaluating hikes, since being able to see the densely-spaced contour lines at given points is much more helpful than just knowing the total elevation gain of a trail.

So, when I learned that the OpenGeo Suite 3.0 contains a process to generate contour lines from raster data, I jumped at the opportunity to play with it. Neat, I can create my own contour maps! My thoughts turned to Mt. Rainier National Park, where I spent some time this past summer; I was eager to test the contour generation process on the largest eminence in the contiguous United States.

Mount Rainier (Wikipedia)

Mt. Rainier raster data in GeoExplorer

The first step was to acquire topological raster data. Despite a somewhat cumbersome download process I was able to obtain high-quality data via the National Elevation Dataset from the USGS, provided.  I eventually acquired a GeoTIFF with one arcsecond detail and loaded the data into GeoServer. While I could have taken advantage of new raster support in PostGIS 2.0, those features primarily support analysis, not visualization.

There are two ways of generating a contour map using the tools in the OpenGeo Suite: statically and dynamically.

I started out with the static case, processing the raster data and generating a vector layer of the contours using the Web Processing Service (WPS), which allows for server-side processing of data in GeoServer. With WPS, you can perform complex calculations and conversions, either by pulling from almost 100 built-in processes or by creating your own. For my case, the gs:Contourprocess was sufficient for my needs. While quite rudimentary, I used the WPS Request Builder in the GeoServer UI to generate my contour bands, since it’s more straightforward than having to generate the raw XML code for executing the process.

Contour process in WPS Request Builder

The data that I possessed had elevation data in meters, from a low of about 500 meters above sea level to Mt. Rainier’s peak at 4,392 meters. For a nice round number I chose 100 meter increments and then ran this through the WPS process,  piping the output back into GeoServer. In this case I saved the output as a shapefile and then imported the layer back into GeoServer, but I could just as easily have chained the output of gs:Contour to the input of gs:Import to accomplish the same thing.

With this vector data published, I styled the output by adding rules to label the lines and draw the 500 meter interval lines thicker, all features one would expect from a contour map. I also optimized my cartography for the web by only drawing the 100 meter bands at certain zoom levels to keep the map from becoming too cluttered when zoomed out.

Contour map of Mt. Rainier

Once satisfied that my style worked with the generated vector output, I set about creating a contour map dynamically by utilizing new processing features in OpenGeo Suite 3.0.  Using rendering transformations eliminated the intermediate step of generating derivative data by instead applying the gs:Contour process directly to the raster data using the layer’s style. I only needed to specify the transformation in the SLD and associate it with my raster layer to get exactly the same output in real time—without generating any new vector layers!

Contour map of Mt. Rainier in GeoExplorer

Though I stopped at this point, there are other ways I could have improved this further. For example, instead of using the SLD to selectively display the 100 or 500 meter intervals, I could have tied the interval parameter to the scale denominator of the map. This way, I could zoom the map in all the way and have bands with, say, 10 meter intervals, and then zoom out and render bands with 1000 meter intervals. This would further improve the interactivity of the web map without adding much overhead.

Learn more about creating a dynamic contour map with GeoServer WPS, including the SLD code used in the creation of this map.

Have you tried using GeoServer WPS processes? What have you accomplished with them? Let us know about your experiences by commenting below. And, if you’re ever in Mt. Rainier, I highly recommend the Skyline Trail—just be sure to bring winter clothing, even in summer and at lower elevations there’s likely to be snow!

Surface Interpolation in GeoServer

NASA’s Global Learning and Observations to Benefit the Environment (GLOBE) Program, a federally funded education initiative, collects meteorological data from schools around the world to create a database of environmental measurements. The data is  displayed using contour surfaces on the GLOBE website. Using the OpenGeo Suite, we’ve been working with GLOBE to help improve the functionality and usability of the GLOBE website by rebuilding the map to allow fast, dynamic presentation of surfaces for observations on any chosen day.

The surfaces are generated using Barnes Surface Interpolation,  a technique that computes a surface estimated from scattered data observations.  We implemented a version of this algorithm in Java and optimized it to provide the performance needed for dynamic web mapping applications.

The Barnes Surface Interpolation algorithm is accessed via a powerful new GeoServer feature called Rendering Transformations.  Rendering Transformations allow performing custom geoprocessing within the map rendering pipeline in a highly flexible way.  Transformations can change data representation from vector to raster or vice-versa, depending on the kind of visual effect required.

In this case, the output of the Barnes Surface transformation is a raster representing the interpolated surface.  The raster can be styled using GeoServer’s SLD styling language and the styled surface can be combined with other GeoServer layers to do things like display the observation data points or computed contour lines.  The final map image can then be displayed over any base map, resulting in a fast, informative display of the contoured surface.  The speed of display allows dynamic zooming and panning, as well as quick changes to map options including measurement type, date range, or even the surface interpolation parameters.

Having this capability available directly in the server provides access to many of the powerful features of GeoServer, such as tiling and time-based animations. Other kinds of interpolated surfaces (such as Inverse-Distance Weighting or Kriging) can be added easily.  In fact, we’re currently developing more Rendering Transformations for spatial visualization techniques, including heatmaps and point clustering.  If you have any ideas for spatial data visualization, leave a comment!

Thematic map creation with SLD is now much easier

While the SLD styling language used in GeoServer is very powerful, it’s no secret that it’s somewhat verbose to author.  One reason for this is the need to define multiple rules to specify different styles based on attribute values.  The OGC Symbology Encoding specification introduced transformation functions which can help make attribute-based styling more concise.  The functions Recode, Categorize, and Interpolate transform values in several different ways.  They can be used to convert attribute values directly into styling parameters such as color, width, and opacity.  These have recently been added to GeoServer as Filter Functions, so they’re now available to help make your SLDs shorter and more readable.

The first two functions are analogous to SQL’s “inline CASE expression”.  The Recode function transforms a set of discrete values into another set of values.  A typical use in styling is to produce a chloropleth map by converting the values of an attribute into a set of colors.  As an example, in the map below states have a REGION attribute with values such as “N Eng” and “Mtn”.  This would normally require multiple rules to style with different fill colors, but this can be expressed more concisely by using Recode to convert the REGION values into colors directly for use in the Fill styling parameter.

Using Recode to theme US states by region

The Categorize function is similar to Recode, but transforms attribute value ranges into a set of discrete values.  A list of threshold values determines the input ranges, each of which is then assigned an output value.  For example, in the map below, the population density of the states is computed as the population divided by the land area.  Categorize is used to convert density ranges into color values (in this case, three different colors show densities of less than 20, between 20 and 100, and greater than 100 persons per square kilometer).

Using Categorize to theme US states by population density

The Interpolate function is the most powerful of the three.  It transforms a continuous-valued attribute into another continuous range of values, using a curve to define the mapping between them.  Input values are interpolated along the curve to compute a corresponding output value.  The function even provides the ability to specify the kind of interpolation used, with options of linear, cosine or cubic curves. It is also able to interpolate across RGB color values as the output domain.  This makes it easy to create thematic maps using smoothly varying colors to represent a continuous attribute.  In the map below, Interpolate is used to compute a continuously-varying color range from an attribute containing the population of each state.

Using Interpolate to theme US states by population

A more in-depth explanation and the XML code for the above examples is available in the GeoServer User Guide Styling section.

Managing fault tolerance in GeoServer metadata

All dynamic WMS sessions start with a client requesting a server’s “GetCapabilities” document.  This document tells the client what layers are available, what parts of the world they cover, and what styles are available to view them with—in short, what the map server is capable of serving.

Sometimes, though, the GetCapabilities document can become corrupted. This is often caused by layer data that GeoServer is unable to access successfully.  Perhaps the administrator had a bad day and made a typo in the password, or there’s a bug in the script that publishes new layers via GeoServer’s REST API, or there might even be a network outage preventing connection to the database.  Whatever the reason, sometimes there are layers in your GeoServer configuration that GeoServer just can’t access.

Historically, when this has happened, any such error would cause GeoServer to produce an error message instead of a normal response. This means that a single layer with a small misconfiguration can effectively block out all WMS clients from accessing your server!  While this type of error reporting does benefit administrators by providing a clear place to find out what layer is causing a problem, it also pushes server errors onto clients unnecessarily.

To remedy this, we recently added a new option to GeoServer called lenient resource handling. With lenient resource handling, GeoServer performs the same error checking that it normally would, but instead of erroring out at the first sign of trouble, it simply omits metadata for layers without usable configurations (while still logging errors on the server).  This way, GeoServer will continue to publish all working layers.

In addition to WMS GetCapabilities response documents, this feature also affects the following responses:

  • WFS GetCapabilities
  • WCS GetCapabilities
  • WFS DescribeFeatureType
  • WCS DescribeCoverage

For DescribeFeatureType and DescribeCoverage, the lenient error handling only affects requests which do not specify layers explicitly in the request.

Lenient error handling is not enabled by default, but you can switch it on easily from the GeoServer web administration interface: In the Global Settings section, set the Resource Error Handling dropdown to SKIP_MISCONFIGURED_LAYERS.

This feature is available in GeoServer nightly builds, and will be included in any upcoming releases.