Displayer raster result from Geoserver WPS in Openlayers4

842 views Asked by At

For an interactive web application I use Openlayers 4.6.5 with Geoserver 2.13.0.

want to enable dynamic processing of user-selected input data points by using Geoserver WPS. I have extended the WPS functionality with the statistics package from SourceForge and want to run a KernelDensity analysis on a collection of selected points. The result of the KernelDensity process shall be displayed as raster layer in my map.

I am using the Javascript's fetch functionality for sending an XML request to the WPS.:

<wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd"><ows:Identifier>statistics:KernelDensity</ows:Identifier><wps:DataInputs><wps:Input><ows:Identifier>inputFeatures</ows:Identifier><wps:Data><wps:ComplexData mimeType="application/json"><![CDATA[{"type":"FeatureCollection","totalFeatures":2,"features":[{"type":"Feature","id":"alllocations.fid-57f369ef_1636c6c3947_-5ddb","geometry":{"type":"Point","coordinates":[100.330936,5.41626549]},"geometry_name":"geom","properties":{"idstorylocation":344,"idstory":27,"story":"HOUN","idlocation":203,"location_role":"reference","actions":"The walking stick left behind by young Dr Mortimer is of the sort which is called \"Penang Lawyer\".","name":"Penang ","country_today":"Malaysia","reference_to":"city","reality":"real","certainty":"good","accuracy":"high","county":"","state_country":"","city":"Penang","idcountry":298,"idpoints":99,"idperson":40,"initial":null,"lastname":"Mortimer","firstname":"James","nationality":null}},{"type":"Feature","id":"alllocations.fid-57f369ef_1636c6c3947_-5dda","geometry":{"type":"Point","coordinates":[100.330936,5.41626549]},"geometry_name":"geom","properties":{"idstorylocation":1519,"idstory":15,"story":"SILV","idlocation":203,"location_role":"reference","actions":"The stick of Fitzroy Simpson, which was a Penang-lawyer weighted with lead, was was just such a weapon as might, by repeated blows, have inflicted the terrible injuries to which the trainer had succumbed. ","name":"Penang ","country_today":"Malaysia","reference_to":"city","reality":"real","certainty":"good","accuracy":"high","county":"","state_country":"","city":"Penang","idcountry":298,"idpoints":99,"idperson":0,"initial":null,"lastname":null,"firstname":null,"nationality":null}}],"crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG::4326"}}}]]></wps:ComplexData></wps:Data></wps:Input><wps:Input><ows:Identifier>kernelType</ows:Identifier><wps:Data><LiteralData>Quadratic</LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>populationField</ows:Identifier><wps:Data><wps:LiteralData>icount</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>searchRadius</ows:Identifier><wps:Data><wps:LiteralData>5</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>cellSize</ows:Identifier><wps:Data><wps:LiteralData>20</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>extent</ows:Identifier><wps:Data><wps:BoundingBoxData crs="EPSG:4326" dimension="2"><ows:LowerCorner>-180.0 -90.0</ows:LowerCorner><ows:UpperCorner>180.0 90.0</ows:UpperCorner></wps:BoundingBoxData></wps:Data></wps:Input></wps:DataInputs><wps:ResponseForm><wps:RawDataOutput mimeType="image/tiff"><ows:Identifier>result</ows:Identifier></wps:RawDataOutput></wps:ResponseForm></wps:Execute>

Input jsonstring are collected events from selected point data, output should be image/tiff.

However, I am at a loss at how to get a) a raster from the response and b) the raster as layer into my map.

function calculateKernelDensity(jsonstring){

xml = createKernelDensityRequest(jsonstring);

fetch('http://localhost:8080/geoserver/Sherlock/wps', {
    method: 'POST',
    body: xml
})
// tried my luck with blob to use it later on as image layer
.then(function(response){
    var blob = response.blob(); 
    return blob;
})
.then(function(blob){
    console.log(blob.size + " " + blob.type);
});
// something here to put it as layer into the map...
};  

I did a very similar thing for the vector-based requests (collectEvents, convexHull) and added the response.json as vector features to the map, which works out fine:

function collectEvents(jsonstring){

xml = createCollectEventsRequest(jsonstring);

fetch('http://localhost:8080/geoserver/Sherlock/wps',{
    method: 'POST',
    body: xml
})
.then(function(response){
    jsonresults = response.json();
    return jsonresults;
})
.then(function(jsonresults){
    jsonstring = JSON.stringify(jsonresults);
    results = new ol.format.GeoJSON({geometryName:'geom'}).readFeatures(jsonresults,{
        dataProjection: 'EPSG:4326',
        featureProjection: 'EPSG:3857'
    });
    vectorSource.clear(results);
    vectorSource.addFeatures(results);
});
};

I fail to find any good documentation on OpenLayers 4 and how to use it with Geoserver WPS. API docs on the use of Raster and Image sources is not really of any help either. I do know about ol.source.ImageWMS, but as I am trying to dynamically generate and display a raster and not retrieve a raster from the WMS, this is no option here.

Is there a way to get the generated raster image from the WPS and display it in the OpenLayers map?

1

There are 1 answers

0
Ian Turton On

Judging by answers to this question it is not possible to directly display a GeoTiff in OpenLayers as it uses the browser's native display capabilities to do the displaying.

One option that may work for you is to save the WPS output to the GeoServer and then fetch the results using a WMS request. There is an example of how to do this in the GeoSolution's WPS training. This answer also mentions the StoreCoverage process for this purpose, but I can't find any other reference to it.