Wednesday, 12 May 2010

How To Configure GeoServer For The GBIF Data Portal

We are Daniel Amariles and Hector Tobon, we work for the International Center for Tropical Agriculture, based in Cali, Colombia, and we are currently correcting some bugs on the GBIF Data Portal.

A few days ago we had to install Geoserver in order to deal with some map issues from the GBIF Data Portal. We want to take this opportunity to document our experience (installation and configuration) so that anybody inside the community can benefit from this knowledge. This post refers to a customised installation of GeoServer for the GBIF Data Portal.



Installing GeoServer

 There are different ways to install GeoServer:
  •  Install Geoserver as a WAR in Apache Tomcat
  •  Install Geoserver as a binary file (OS independent) 
Configuring system variables

Configure the following variables according to your system configuration.

JAVA_HOME=Your JAVA installation path
JAVA_OPTS="-XX:PermSize=512M -Xmx1g -Djava.awt.headless=true -Dcom.sun.management.jmxremote"

Install GeoServer as a WAR in Apache tomcat (recommended)
  • Unzip the tomcat file and place it in a location of your choice and put the GeoServer WAR file in the folder $TOMCAT/webapps/geoserver.war
  • Start Tomcat by running $TOMCAT/bin/startup.sh or $TOMCAT/bin/startup.bat according to your OS.
     How to change the port
  • Shutdown Tomcat running $TOMCAT/bin/shutdown.sh or $TOMCAT/bin/shutdown.bat
  • Open file $TOMCAT/conf/server.xml
  • Search line <connector port="8080" protocol="HTTP/1.1" ... and change the default to your convenience port.
  • Start Tomcat 
Install GeoServer as Binary (OS independent)

Note: If you install Geoserver as Binary it will be run by a jetty server rather than Tomcat. 
  • Unzip the folder and place it in a location of your choice.
  • Run $GEOSERVER/bin/startup.bat or $GEOSERVER/bin/startup.sh according to your OS.
     How to change the port
  • Shutdown Jetty server running
    $GEOSERVER/bin/shutdown.sh or $GEOSERVER/bin/shutdown.bat 
  • Open file $GEOSERVER/etc/jetty.xml 
  • Search line <Set name="port">8081</Set>
  • Start Jet
Resources & libraries

Shapefile

Copy the files corresponding to the country shape file

      country.dbf country.fix country.ORG.dbf country.prj country.qix country.shp country.shx

to the shapefiles directory of the GeoServer $GEOSERVER/data_dir/data/shapefiles

The gt-ala-tab library

Copy the library  gt-ala-tab-1.0-SNAPSHOT.jar to the libraries directory of the GeoServer $GEOSERVER\geoserver\WEB-INF\lib

Workspace

Create the Workspace named gbif with URI http://www.gbif.org and set it as default workspace

Stores

country stores

Add the stores type Shapefile with names country_borders, country_fill and country_names. With the following parameters:
  • Workspace: gbif
  • URL: file:data/shapefiles/country.shp
tab_density store

Add the store tab_density of type Tab Url DataStore.With the following parameters:
  • Workspace: gbif
  • minx: -180
  • miny: -90
  • maxx: 180
  • maxy: 90
Styles

Add the following SLD styles. Click on the validate button to verify the style is a valid SLD document.

     country_borders style

<?xml version="1.0" encoding="ISO-8859-1"?> 
    <StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" 
      xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"> 
      <NamedLayer> 
        <Name>Countries Borders</Name> 
        <UserStyle> 
          <Title>Countries Borders</Title> 
          <Abstract>A style that just draws a 1 pixel stroke around each countries borders</Abstract> 
          <FeatureTypeStyle> 
            <Rule> 
              <Title>Polygon</Title> 
              <PolygonSymbolizer> 
                <Stroke> 
                  <CssParameter name="stroke">#006600</CssParameter> 
                  <CssParameter name="stroke-width">1</CssParameter> 
                </Stroke> 
              </PolygonSymbolizer> 
            </Rule> 
          </FeatureTypeStyle> 
        </UserStyle> 
      </NamedLayer> 
    </StyledLayerDescriptor> 

     country_fill style

<?xml version="1.0" encoding="ISO-8859-1"?> 
    <StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" 
      xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"> 
      <NamedLayer> 
        <Name>Country Polygons Fill</Name> 
        <UserStyle> 
          <Title>Country Polygons style</Title> 
          <Abstract>A style that fills the countries polygons with a specific color</Abstract> 
          <FeatureTypeStyle> 
            <Rule> 
              <Title>Polygon</Title> 
              <PolygonSymbolizer> 
                <Fill> 
                  <CssParameter name="fill">#003333</CssParameter> 
                  <CssParameter name="fill-opacity"><ogc:Literal>1</ogc:Literal></CssParameter>               
                </Fill> 
              </PolygonSymbolizer> 
            </Rule> 
          </FeatureTypeStyle> 
        </UserStyle> 
      </NamedLayer> 
    </StyledLayerDescriptor>

     country_names style

<?xml version="1.0" encoding="ISO-8859-1"?> 
<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" 
  xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"> 
  <NamedLayer> 
    <Name>Country Names</Name> 
    <UserStyle> 
      <Title>Country Names</Title> 
      <Abstract>Style that renders the names of the countries on the map</Abstract> 
      <FeatureTypeStyle> 
  <Rule> 
  <TextSymbolizer> 
    <Label> 
      <ogc:PropertyName>CNTRY_NAME</ogc:PropertyName> 
    </Label>   
    <Font> 
      <CssParameter name="font-family"><ogc:Literal>Lucida Sans</ogc:Literal></CssParameter> 
      <CssParameter name="font-style"><ogc:Literal>normal</ogc:Literal></CssParameter> 
      <CssParameter name="font-size"><ogc:Literal>10.0</ogc:Literal></CssParameter> 
      <CssParameter name="font-weight"><ogc:Literal>bold</ogc:Literal></CssParameter> 
    </Font>   
<LabelPlacement> 
<PointPlacement> 
<AnchorPoint> 
<AnchorPointX>0.5</AnchorPointX> 
<AnchorPointY>0.5</AnchorPointY> 
</AnchorPoint> 
</PointPlacement> 
</LabelPlacement> 
    <Fill> 
      <CssParameter name="fill">#6e8686</CssParameter> 
    </Fill> 
  </TextSymbolizer> 
  </Rule> 
      </FeatureTypeStyle> 
    </UserStyle> 
  </NamedLayer> 
</StyledLayerDescriptor>

     density_layer style

<?xml version="1.0" encoding="UTF-8"?> 
<StyledLayerDescriptor version="1.0.0" 
 xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" 
 xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" 
 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
 <NamedLayer> 
   <Name>densityLayer</Name> 
   <UserStyle> 
     <FeatureTypeStyle> 
       <!-- If it is a point data, render as such --> 
       <Rule> 
         <ogc:Filter> 
           <ogc:PropertyIsEqualTo> 
             <ogc:Function name="geometryType"> 
               <ogc:PropertyName>geom</ogc:PropertyName> 
             </ogc:Function> 
             <ogc:Literal>Point</ogc:Literal> 
           </ogc:PropertyIsEqualTo> 
         </ogc:Filter> 
         <PointSymbolizer> 
           <Graphic> 
             <Mark> 
               <WellKnownName>circle</WellKnownName>
               <Fill> 
                 <CssParameter name="fill">#cc0000</CssParameter> 
                 <CssParameter name="fill-opacity">1.0</CssParameter> 
               </Fill> 
             </Mark> 
             <Size>6</Size> 
           </Graphic> 
         </PointSymbolizer> 
       </Rule> 
       <!-- 1-9 --> 
       <Rule> 
         <ogc:Filter> 
           <ogc:And> 
             <ogc:PropertyIsGreaterThanOrEqualTo> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>1</ogc:Literal> 
             </ogc:PropertyIsGreaterThanOrEqualTo> 
             <ogc:PropertyIsLessThan> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>10</ogc:Literal> 
             </ogc:PropertyIsLessThan> 
           </ogc:And> 
         </ogc:Filter> 
         <PolygonSymbolizer> 
           <Fill> 
             <CssParameter name="fill"> 
               <ogc:Literal>#ffff00</ogc:Literal> 
             </CssParameter> 
             <CssParameter name="fill-opacity"> 
               <ogc:Literal>1</ogc:Literal> 
             </CssParameter> 
           </Fill> 
          <Stroke> 
            <CssParameter name="stroke">#ffff00</CssParameter> 
            <CssParameter name="stroke-width">0</CssParameter> 
          </Stroke> 
         </PolygonSymbolizer> 
       </Rule> 
       <!-- 10-99 --> 
       <Rule> 
         <ogc:Filter> 
           <ogc:And> 
             <ogc:PropertyIsGreaterThanOrEqualTo> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>10</ogc:Literal> 
             </ogc:PropertyIsGreaterThanOrEqualTo> 
             <ogc:PropertyIsLessThan> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>100</ogc:Literal> 
             </ogc:PropertyIsLessThan> 
           </ogc:And> 
         </ogc:Filter> 
         <PolygonSymbolizer> 
           <Fill> 
             <CssParameter name="fill"> 
               <ogc:Literal>#ffcc00</ogc:Literal> 
             </CssParameter> 
             <CssParameter name="fill-opacity"> 
               <ogc:Literal>1</ogc:Literal> 
             </CssParameter> 
           </Fill> 
          <Stroke> 
            <CssParameter name="stroke">#ffcc00</CssParameter> 
            <CssParameter name="stroke-width">0</CssParameter> 
          </Stroke> 
         </PolygonSymbolizer> 
       </Rule> 
       <!-- 100-999 --> 
       <Rule> 
         <ogc:Filter> 
           <ogc:And> 
             <ogc:PropertyIsGreaterThanOrEqualTo> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>100</ogc:Literal> 
             </ogc:PropertyIsGreaterThanOrEqualTo> 
             <ogc:PropertyIsLessThan> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>1000</ogc:Literal> 
             </ogc:PropertyIsLessThan> 
           </ogc:And> 
         </ogc:Filter> 
         <PolygonSymbolizer> 
           <Fill> 
             <CssParameter name="fill"> 
               <ogc:Literal>#ff9900</ogc:Literal> 
             </CssParameter> 
             <CssParameter name="fill-opacity"> 
               <ogc:Literal>1</ogc:Literal> 
             </CssParameter> 
           </Fill> 
          <Stroke> 
            <CssParameter name="stroke">#ff9900</CssParameter> 
            <CssParameter name="stroke-width">0</CssParameter> 
          </Stroke> 
         </PolygonSymbolizer> 
       </Rule> 
       <!-- 1000-9999 --> 
       <Rule> 
         <ogc:Filter> 
           <ogc:And> 
             <ogc:PropertyIsGreaterThanOrEqualTo> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>1000</ogc:Literal> 
             </ogc:PropertyIsGreaterThanOrEqualTo> 
             <ogc:PropertyIsLessThan> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>10000</ogc:Literal> 
             </ogc:PropertyIsLessThan> 
           </ogc:And> 
         </ogc:Filter> 
         <PolygonSymbolizer> 
           <Fill> 
             <CssParameter name="fill"> 
               <ogc:Literal>#ff6600</ogc:Literal> 
             </CssParameter> 
             <CssParameter name="fill-opacity"> 
               <ogc:Literal>1</ogc:Literal> 
             </CssParameter> 
           </Fill> 
          <Stroke> 
            <CssParameter name="stroke">#ff6600</CssParameter> 
            <CssParameter name="stroke-width">0</CssParameter> 
          </Stroke> 
         </PolygonSymbolizer> 
       </Rule> 
       <!-- 10000-99999 --> 
       <Rule> 
         <ogc:Filter> 
           <ogc:And> 
             <ogc:PropertyIsGreaterThanOrEqualTo> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>10000</ogc:Literal> 
             </ogc:PropertyIsGreaterThanOrEqualTo> 
             <ogc:PropertyIsLessThan> 
               <ogc:PropertyName>count</ogc:PropertyName> 
               <ogc:Literal>100000</ogc:Literal> 
             </ogc:PropertyIsLessThan> 
           </ogc:And> 
         </ogc:Filter> 
         <PolygonSymbolizer> 
           <Fill> 
             <CssParameter name="fill"> 
               <ogc:Literal>#ff3300</ogc:Literal> 
             </CssParameter> 
             <CssParameter name="fill-opacity"> 
               <ogc:Literal>1</ogc:Literal> 
             </CssParameter> 
           </Fill> 
          <Stroke> 
            <CssParameter name="stroke">#ff3300</CssParameter> 
            <CssParameter name="stroke-width">0</CssParameter> 
          </Stroke> 
         </PolygonSymbolizer> 
       </Rule> 
       <!-- 100000+ --> 
       <Rule> 
         <ogc:Filter> 
           <ogc:PropertyIsGreaterThanOrEqualTo> 
             <ogc:PropertyName>count</ogc:PropertyName> 
             <ogc:Literal>100000</ogc:Literal> 
           </ogc:PropertyIsGreaterThanOrEqualTo> 
         </ogc:Filter> 
         <PolygonSymbolizer> 
           <Fill> 
             <CssParameter name="fill"> 
               <ogc:Literal>#cc0000</ogc:Literal> 
             </CssParameter> 
             <CssParameter name="fill-opacity"> 
               <ogc:Literal>1</ogc:Literal> 
             </CssParameter> 
           </Fill> 
          <Stroke> 
            <CssParameter name="stroke">#cc0000</CssParameter> 
            <CssParameter name="stroke-width">0</CssParameter> 
          </Stroke> 
         </PolygonSymbolizer> 
       </Rule> 
     </FeatureTypeStyle> 
   </UserStyle> 
 </NamedLayer> 
</StyledLayerDescriptor> 

     country_borders_black style

<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc"
 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
 <NamedLayer>
   <Name>Countries Borders</Name>
   <UserStyle>
     <Title>Countries Borders</Title>
     <Abstract>A style that just draws a 1 pixel stroke around each countries borders</Abstract>
     <FeatureTypeStyle>
       <Rule>
         <Title>Polygon</Title>
         <PolygonSymbolizer>
           <Stroke>
             <CssParameter name="stroke">#000000</CssParameter>
             <CssParameter name="stroke-width">1</CssParameter>
           </Stroke>
         </PolygonSymbolizer>
       </Rule>
     </FeatureTypeStyle>
   </UserStyle>
 </NamedLayer>
</StyledLayerDescriptor>

     country_names_black style

<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc"
 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
 <NamedLayer>
   <Name>Country Names</Name>
   <UserStyle>
     <Title>Country Names</Title>
     <Abstract>Style that renders the names of the countries on the map</Abstract>
     <FeatureTypeStyle>
 <Rule>
 <TextSymbolizer>
   <Label>
     <ogc:PropertyName>CNTRY_NAME</ogc:PropertyName>
   </Label>
   <Font>
     <CssParameter name="font-family"><ogc:Literal>Lucida Sans</ogc:Literal></CssParameter>
     <CssParameter name="font-style"><ogc:Literal>normal</ogc:Literal></CssParameter>
     <CssParameter name="font-size"><ogc:Literal>13.0</ogc:Literal></CssParameter>
     <CssParameter name="font-weight"><ogc:Literal>bold</ogc:Literal></CssParameter>
   </Font>
 <LabelPlacement>
   <PointPlacement>
     <AnchorPoint>
       <AnchorPointX>0.5</AnchorPointX>
       <AnchorPointY>0.5</AnchorPointY>
     </AnchorPoint>
   </PointPlacement>
 </LabelPlacement>
   <Fill>
     <CssParameter name="fill">#6666FF </CssParameter>
   </Fill>
 </TextSymbolizer>
 </Rule>
     </FeatureTypeStyle>
   </UserStyle>
 </NamedLayer>
</StyledLayerDescriptor>

Layers

Add the following layers in the layers menu

Adding the country layers

Add the layers from the stores gbif:country_borders, gbif:country_fill and gbif:country_names, respectively with the names country_borders, country_fill y country_names. With the following parameters:

Data tab
  • Coordinate Reference Systems: The Native SRS is UNKNOWN and the Declared SRS is EPSG:4326.
  • Bounding Boxes: In both Native Bounding Box and Lat/Lon Bounding Box, set the following:
Min XMin YMax XMax Y
-180-9018083,623

Publishing tab
  • Default Title: Set the Default Style as the respective layer name.
Adding the tabDensityLayer layer

Add the layer tabDensityLayer from the store gbif:tab_density. With the following parameters.

Data tab
  • Coordinate Reference Systems: The Declared SRS is EPSG:4326.
  • Bounding Boxes: In both Native Bounding Box and Lat/Lon Bounding Box, set the following:
Min XMin YMax XMax Y
-180-9018090

Publishing tab
  •  Default Title: Set the Default Style as the respective layer name.
Test the layers

To test if the country layers are working well, enter to the GWC GeoWebCache, then to "A list of all the layers and automatic demos" and check the behavior of the country layers, they should work according to their names.