Skip to content
robertd99 edited this page Aug 7, 2020 · 104 revisions

Geoserver for OHDM

GeoServer is an open source server for sharing geospatial data. This Wiki is a guide on how to set up your database, configure Geoserver and OpenLayers for use with time sensitive rendering and cacheing for OHDM.

Since the native Geoserver styles used for rendering are not able to work with time sensitive data, this project uses CSS-Styles provided by Geosolutions. These CSS-Styles allow for time sensitive rendering and cacheing via valid_since and valid_until columns. Those Styles require a certain Database-structure. In this guide we will integrate these CSS-Files, convert the OHDM-Database into a for the CSS-Styles usable Database and configure Geoserver and OpenLayers correctly.

Requirements

Setting up the DB

These steps are needed to create a database out of osm files with which we can work with. We recommend putting all files in the same directory. For further information visit https://github.com/OpenHistoricalDataMap/OSMImportUpdate/wiki .

  1. Create the schemas "intermediate", "ohdm" and "geoserverrendering" in your PostGIS database[you can name them however you want but for demonstration purposes we use those].

  2. Download the latest Version of the OSMImportUpdate Tool https://github.com/OpenHistoricalDataMap/OSMImportUpdate

  3. Download any OpenStreetMap File which you want to convert. The OSMImportUpdate Tool converts yourmap.osm files into the required databases.

  4. Create the files "intermediate_parameter.txt", "ohdm_parameter.txt" and "geoserverrendering_parameter.txt". These files are needed for the OSMImportUpdate Tool to establish a connection to your database and convert the data. Each file contains the individual connection parameters to your DB and the specific schema required for each of the steps in "6.".

  5. Configurate each of the parameter files as shown:

    servername: yourServername
    portnumber: yourPGportnumber
    username: yourPGusername
    pwd: yourPGpassword
    dbname: yourDBname
    schema: yourSchemaname

    Example for ohdm_parameter.txt:

    servername: 127.0.0.1
    portnumber: 5432
    username: postgres
    pwd: 1234
    dbname: berlin
    schema: ohdm

  6. Run the following commands in this exact order:

  • java -classpath <yourJDBCdriver.jar> -jar OSMImportUpdate.jar -o <yourOSMfile.osm> -i intermediate_parameter.txt converts your OSM file into a Intermediate DB
  • java -classpath <yourJDBCdriver.jar> -jar OSMImportUpdate.jar -i intermediate_parameter.txt -d ohdm_parameter.txt converts your intermediate DB into a OHDM DB
  • java -classpath <yourJDBCdriver.jar> -jar OSMImportUpdate.jar -d ohdm_parameter.txt -g geoserverrendering_parameter.txt converts your OHDM DB into the for the CSS Styles usable Geoserverrendering DB

The geoserverrendering schema should now be filled with 12 Tables. Your directory should now have 2 more Folders named css and symbols. If these folders were not created or are empty you can download them seperately https://github.com/OpenHistoricalDataMap/OSMImportUpdate/tree/master/src/ohdm2geoserverrendering/resources.
Note: for the folders to be filled correctly the jar is required to have the name OSMImportUpdate.jar. Otherwise the programm can not find the css and symbols to copy that into the corresponding folders.

Setting up Geoserver

Installing Geoserver

  1. Download the latest Geoserver Platform Independent Binary http://geoserver.org/release/stable/
  2. Unzip the archive
  3. Set the JAVA_HOME variable to JRE (not JDK) 1.8 (at least Java 8)
  4. Navigate to your Geoserver directory
  5. Get your Geoserver directory path with echo "$PWD"
  6. Set your GEOSERVER_HOME variable to your Geoserver directory path with export GEOSERVER_HOME=<yourGeoserverPath>
    you may need to make yourself the owner of the directory with sudo chown -R USER_NAME <yourGeoserverPath>
  7. Navigate to the /bin folder
  8. Use the command sh startup.sh to start the server

Note: If the "Address is already in use" Exception is thrown the standard Jetty port 8080 is already in use. Change it by navigating to the /geoserverver directory and edit the start.ini file with nano start.ini. Now search the Port 8080 and change it to a open Port.

Installing the Geoserver CSS extension

Geoserver can't natively render with CSS styles, which in this project define the rendering of the data. This step will add the CSS extension to our Geoserver.

  1. Download the Geoserver CSS extension https://build.geoserver.org/geoserver/master/ext-latest/geoserver-2.18-SNAPSHOT-css-plugin.zip
    Verify that the version number in the filename corresponds to the version of Geoserver you are running
  2. Extract the contents of the archive into the WEB-INF/lib directory in Geoserver. Make sure do not create any sub-directories during the extraction process.
  3. Restart Geoserver If installation was successful, you will see a new CSS entry in the Styles editor dropdown menu.

Geoserver Configuration

You could configure the Server via the files in the directory. It is advised to use the Web-Interface so we will use it instead, as much as possible. To Log in the standard username is "admin" and the standard password is "geoserver".

Create a new Workspace

Add a new DataStorage

DataStorages tell Geoserver where your Data is stored. Geoserver needs to access your Postgres Database. This step establishes the connection between those two. The Data out of the DataStorage is then associated with the workspace.

  • Click on "Data Storages" on the very left

  • Add new DataStorage

  • Choose PostGIS - PostGIS Database

  • Choose your Workspace

  • Choose any name as your DataSource

  • Set Connection Parameters as follows:

    host: yourServerURL (usually localhost)
    port: yourPGport
    database: yourDBname
    schema: yourSchemaName (it is important to use the geoserverrendering schema)
    user: yourPGusername
    passwd: yourPGpassword

  • Save the changes

Add new Styles

Styles configures how to render the Data. Since our project uses CSS Styles and Geoserver doesn't natively support them we need to add them first before we can use them. If you are accessing the Geoserver from a remote Computer and do not have acces to the CSS files you can download them onto your Computer and upload them from there:

Note: The names of the styles are always the same as the names of the tables. The only exception: The style for the table "my_housenumbers" is "addresses".

Add Layers

Layers "combine" the data stored in your workspaces DataStorage with the Styles used for rendering. We need to tell a Layer which Style uses which Data. A Layer will automatically use the Data of the workspace they are created in. A CSS-Style which only procceses "roads" will make the Layer only render roads.

  • Click on "Layer" on the very left
  • CLick "Add a new Layer"
  • Choose the Layer with Nameroom and Prefix which you want to publish
  • Choose a not yet published Style
  • In "Data" Section scroll down to "Coordinate Reference System" Section. Make sure it its EPSG:3857, if not make sure you added the correct DB in step "2. Add a new DataStorage". If it still is not showing the correct Reference System setting up the Database in step "Setting up th DB" went wrong.
  • Scroll down to "Bounding Boxes" Section. Click "Compute from SRS" (might be CRS instead). After that click "Compute from native Bounds".
  • Navigate to "Publishing" Section at the very top. Scroll down to "Layer Settings". Change the Default Style from Generics to the corresponding Style of the Layer.
  • Navigate to "Dimensions" Section at the very top. Under Time check the box "activate". Choose Attribute: valid_since, End Attribute: valid_until, Presentaion: List, Default value: Select in-built method to select the value.
  • Repeat those steps for all the Styles/Layers

Add Group-Layer

A Group-Layer simply combines multiple Layers into one. Instead of a "roads" Layer only being able to render roads and a "buildings" Layer only being able to render buildings, the Group-Layer renders all Layers within it to a single picture.

  • Click on "Group-Layer" on the very left
  • Add a new Group-Layer
  • Name it and choose your workspace
  • Add your Layers and put them in the following order:
  • Click "Generate Bounds from CRS"
  • Save changes

You should now be able to render your map. You can preview it in the "Layer-Preview" section on the very left.

Configuring OpenLayers

To integrate the rendered pictures into your OpenLayers application and activate time sensitive rendering you need to make sure

  • your map has the correct projection: add projection: 'EPSG:3857' to your ol.Map and ol.View
  • configure your Layer Tile as follows:
var your_tile_name = new ol.layer.Tile({
	source: new ol.source.TileWMS({
		url: 'http://yourServerURL/geoserver/yourWorskspace/wms',
		params: {
			'LAYERS': 'yourWorkspace:yourGroupLayer',
			'FORMAT': 'image/png',
			'VERSION': '1.1.1',
			'TIME': time,
			'TRANSPARENT': 'true'	
		},
		serverType: 'geoserver'
	})
});

The time parameter has to follow these rules: https://docs.geoserver.org/stable/en/user/services/wms/time.html

Activate Time Sensitive Cacheing

Create a new Gridset

  1. Navigate t Gridset Tab
  2. Add new Gridset
  3. Name it EPSG:3857
  4. Search for the Coordinate Reference System EPSG:3857
  5. Click "Compute from maximum extent of CRS"
  6. Set tile widht and height to 256
  7. Add as many Zoom Levels as you want to cache. The corresponding Zoom scale will compute itself automatically.

Limit Disk Quota

This step is optional. Cacheing time sensitive can lead to huge amounts of Data so limiting the Disk Quota is advised.

  1. Navigate to Disk Quota Tab
  2. Click "enable Disk Quota"
  3. Choose the maximum size the cache can have

Activate Cacheing in Group-Layer

  1. Navigate to your Group-Layer
  2. Navigate to Tile Caching at the very top
  3. Click "Enable direct integration with GeoServer WMS"
  4. Scroll down to "GridSet" Section. Add the EPSG:3857 Gridset. You can remove the others.
  5. Choose Min/Max for published and cached Zoom levels
  6. To add Time filter press on "Add Filter", choose TIME and Regular expression
  7. For standard value fill in a date which will be called if the URL had no time parameter (it has to follow the TIME parameter rules)
  8. For the Regular expression fill in the following expression: [0-9]{4}\-[0-9]{1,2}\-[0-9]{1,2}[T]{1}[0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\.[0-9]{1,3}[Z]{1} it is a simple expression which allows simple time request with yyyy-MM-ddThh:mm:ss.SSSZpattern

Note: The Cache is now activated. The Layer Preview integrated in Geoserver is not able to make use of it. To make valid calls so the GeoWebCache responds you need to configure your own OpenLayers application. You can however already see and Seed your via the URL: http://yourServer/geoserver/gwc/demo . The cache is located in your /geoserver/data_dir/gwc/yourWorkspace directory. You can also check the Response-Headers via "curl"(Windows). irst time loading the page shoudl respons with MISS, another request should respond with a HIT.

Configuring OpenLayers

To allow for cacheing and accesing the cache with a request, the GridSets of your OpenLayers and the Cache have to align. We configured the cache to have a height x width of 256x256 with the Gridset EPSG:3857. To make sure the OpenLayer request aligns with that configuration we create our own GridSet with the wanted amount of ZoomLevels. Add the following lines of code to your ol.Tile script:

var projExtent = ol.proj.get('EPSG:3857').getExtent();
var startResolution = ol.extent.getWidth(projExtent) / 256; 
	console.log("startResolution:", startResolution);
var resolutions = new Array(18); // 18 is the count of our Zoomlevels, might be different for you
for (var i = 0, ii = resolutions.length; i < ii; ++i) {
    resolutions[i] = startResolution / Math.pow(2, i);
}
var tileGrid = new ol.tilegrid.TileGrid({        
	extent: projExtent,
    resolutions: resolutions.slice(1),
    tileSize: [256, 256]
});

The Tile now has to implement the Gridset and Extent we just defined. To tell Geoserver that you want to use the cache you NEED TO INCLUDE 'TILED':'TRUE' Parameter. How it should look like:
var your_tile_name = new ol.layer.Tile({
	source: new ol.source.TileWMS({
		url: 'http://yourServerUrl/geoserver/yourWorkspace/wms',
		params: {
			'TILED':'TRUE',
			'LAYERS': 'yourWorkspace:yourGroupLayer',
			'FORMAT': 'image/png',
			'VERSION': '1.1.1',
			'TIME': time,
			'TRANSPARENT': 'true'		
		},
		serverType: 'geoserver',
		tileGrid : tileGrid
	}),
	extent: projExtent
});

If the request URL made by OpenLayers is not 256 x 256 in width in height although you configured your own Gridset like above, OpenLayers is trying to have a higher or lower PixelRatio depending on the device you are using the Application on. This results in a missalignment of the corresponding BBOX and pixel tile size with the Cached GridSet. To make sure OpenLayers makes the correct sized tile request add pixelRatio: 1 to your ol.Map. Make sure that for every included parameter in the URL request there is a corresponding Parameter Filter. For further Troubleshooting check: https://docs.geoserver.org/stable/en/user/geowebcache/troubleshooting.html

If everything works you should now receive Responses with further information. Your Response-Header geowebcache-cache-result: tells you if your Tile was processed by the WebCache. A HIT means the tile was processed by the cache. A MISS without a reason means the tile had to be rendered.The tile is now cached and if you make the same request again the request should respond with a HIT. A MISS with a reason should help you and give information to fix the issue.