Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Expert GeoServer
Expert GeoServer

Expert GeoServer: Build and secure advanced interfaces and interactive maps

eBook
S$12.99 S$35.99
Paperback
S$44.99
Subscription
Free Trial

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Expert GeoServer

Developing a Spatial Analysis Platform with WPS

In this chapter, you'll learn how to use the Web Processing Service (WPS) to run geospatial processing on your data and return the results to your web app. We'll start out by installing the WPS plugin on your GeoServer instance, and you'll learn how it works. Then you'll use the WPS request builder to create some simple WPS requests. You'll explore the process chaining technique with a more complex example, and finally, we'll integrate the complex WPS request into OpenLayers.

In this chapter, we will cover the following topics:

  • Installing and learning the basics of WPS
  • WPS request builder
  • Process chaining
  • OpenLayers integration

Installing and learning the basics of WPS

Let's get started by installing and learning the basics of WPS. We'll start by installing the plugin and noticing changes in the web administration interface within GeoServer. You'll learn about the WPS standard and basic structure, and finally, we'll look at a simple WPS request.

WPS is an interface standard, similar to WMS and WFS; however, the data output by WPS is dynamically created by a process or set of processes run by the WPS server; in our case, GeoServer. Like WFS, a request can be sent synchronously or asynchronously via HTTP POST or HTTP GET. The WPS standard defines the format of the expected input and output of the processes it interfaces with, so the data that you send in needs to match the expected data format of the service.

An example of this could be a buffer process that takes, as an input, a geographical coordinate expressed as JSON, and produces a polygon overlay that is perhaps produced as GML, and then that is displayed on a map in a web app, as shown in the following diagram:

First we need to install the WPS plugin with GeoServer, as this capability is not available in GeoServer without the plugin. The way that you do that is the same as for other plugins and GeoServer. You go to the released download page (http://geoserver.org/release/stable/), and the Extensions section is at the bottom. You download the WPS services zip archive, and expand it, and then pull it into the WEB-INF plugins directory. WPS can be used with HTTP GET and HTTP POST.

The following is an HTTP GET WPS request:

http://localhost:8080/geoserver/ows?service=wps&version=1.0.0&request=GetCapabilities

After we've installed the WPS plugin, we can now send a WPS request to GeoServer, and, through this URL, we're using the get capabilities operation within WPS which, like WFS or WMS, just gives us an XML representation of all of the processes that the WPS server supports.

And you can see, here we have many processes, such as this envelope process, which you may recognize from other GIS packages you might have used, as shown in the following code snippet:

<wps:Process wps:processVersion="1.0.0">
<ows:Identifier>geo:envelope</ows:Identifier>
<ows:Title>Envelope</ows:Title>
<ows:Abstract>
Returns the smallest bounding box polygon that contains a geometry.
For a point geometry, returns the same point.
</ows:Abstract>
</wps:Process>

Here's a polygon extraction process, as shown in the following code snippet, and these are namespaces that correspond to the underlying code that's used to create the WPS service:

<wps:Process wps:processVersion="1.0.0">
<ows:Identifier>ras:PolygonExtraction</ows:Identifier>
<ows:Title>Polygon Extraction</ows:Title>
<ows:Abstract>
Extracts vector polygons from a raster, based on regions which are
equal or in given ranges
</ows:Abstract>
</wps:Process>

This is created before we install the plugin. It's more or less outside of our control, unless we want to do coding in Java, I guess. So, there are some different namespaces here, such as ras:PolygonExtraction, vec:VectorZonalStatistics, and so on. These are not something you'll be modifying, really, but it's good to know that there are different operations within different namespaces in WPS.

After we've installed the WPS plugin, we also have some additional options in our GeoServer instance. This process status is connected to WPS. We have a WPS Settings area, and a Security area, and in our Demos we now have the ability to create requests with a WPS request builder and Demo requests.

Just a word about WPS syntax: the syntax, similarly to when we were using WFS and WMS, is defined on a specification, and you can get the details of the specification if you go through the documentation. Open Geospatial (http://docs.opengeospatial.org/is/14-065/14-065.html#15) is the best place to look for that. You can see that this execution type request (WPS GetCapabilities request), as shown in the following diagram, will be the main operation that we'll be using to run different kinds of processes:

The processes are those geometric operations that we noticed, and they get a capabilities document response. And you'll get a better example of how an execute operation is defined in the WPS XML, but I will mention that you'll see the identifier or come up a lot, which can be used to identify a process or identify a reference, which will be usually some kind of external data. We'll also see some kind of XML about the response and how to format that.

So, let's take a look at a simple WPMS, or WPS request, through the Demo requests area of GeoServer. We've used this in the past with WFST, and we have these WPS options now, after installing WPS, as shown in the following screenshot:

Let's try to check out a WPS request. The following code will be sent as a HTTP POST request via the following XML:

<?xml version="1.0" encoding="UTF-8"?><wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" 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:wcs="http://www.opengis.net/wcs/1.1.1" 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>gs:Aggregate</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>features</ows:Identifier>
<wps:Reference mimeType="text/xml"
xlink:href="http://geoserver/wfs" method="POST">
<wps:Body>
<wfs:GetFeature service="WFS" version="1.0.0"
outputFormat="GML2"
xmlns:sf="http://www.openplans.org/spearfish">
<wfs:Query typeName="topp:states"/>
</wfs:GetFeature>
</wps:Body>
</wps:Reference>
</wps:Input>
<wps:Input>
<ows:Identifier>aggregationAttribute</ows:Identifier>
<wps:Data>
<wps:LiteralData>PERSONS</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>function</ows:Identifier>
<wps:Data>
<wps:LiteralData>Count</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>function</ows:Identifier>
<wps:Data>
<wps:LiteralData>Average</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>function</ows:Identifier>
<wps:Data>
<wps:LiteralData>Sum</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>function</ows:Identifier>
<wps:Data>
<wps:LiteralData>Min</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>function</ows:Identifier>
<wps:Data>
<wps:LiteralData>Max</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>singlePass</ows:Identifier>
<wps:Data>
<wps:LiteralData>false</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="application/json">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>

You can see Identifier identifying the Aggregate operation or process, and gs is the namespace. This just means that this is a GeoServer-specific WPS process, and there will be some features that are given as input into this process. In this case, the features are coming from the WFS service on the GeoServer, and there are a couple of other parameters that are defined here in input and identifier areas, along with literal data. Here you can see the output format; the raw data output will be expressed as JSON. So now, if we Submit this request, in return we will get the aggregation results expressed in JSON, which is as follows:

This is aggregating some information about states and population. So now, you've seen a simple WPS request. In the next section, you'll see how to create a WPS request with a request builder.

WPS request builder

In the previous section, you installed and learned the basics of WPS. In this section, you'll learn about the GeoServer WPS request builder tool in the web administration interface, and how you can use it to generate requests based on WPS processes and parameters. Throughout this section, we'll create a single request in the builder. We'll look at processes and select process. Next, we'll consider and select inputs, layer, reference, text, and subprocess, and view the constructed XML request. Finally, we'll select a format for output and examine the results. As discussed in the previous section, the request builder is accessed from the demos page. The first step is to choose a process, just as shown in the following screenshot:

JTS refers to the Java Topology Suite namespace, I believe, and this area process is just a process that happens to be attached to that package; it's part of GeoServer. JTS:area returns the area of a geometry, in the units of the geometry, as shown in the preceding screenshot, so the input here is a geometry.

The geometry can be directly input as XML, GML, or any of the following formats:

Another option would be to REFERENCE the geometry. You can get it from GeoServer, as follows:

You just need to put a URL in there to get the correct geometry.

With all of these different options, it's best to break the problem down into smaller units, so you can test and make sure you're getting the output that you're expecting.

There's an option in here, SUBPROCESS, which I've found to not work. Theoretically, you could use some kind of process chaining in here; for example, you could use gs:CollectGeometries, which turns a collection into a geometry, and then the geometry would be useful for that area process. Unfortunately, I have not had any success with this, so I'm not going to get into using that subprocess here to create process chaining in the builder, but I will say that you can select a subprocess and, sometimes, you can get some kind of XML output.

One of my favorite things to do with the request builder is to just get XML output. For instance, we can see what the actual request would look like as created by the request builder, as shown in the following code, and then copy and paste that into an XML document, edit it, and make it actually work:

<?xml version="1.0" encoding="UTF-8"?><wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" 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:wcs="http://www.opengis.net/wcs/1.1.1" 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>JTS:area</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>geom</ows:Identifier>
<wps:Data>
<wps:ComplexData mimeType="text/xml;
subtype=gml/3.1.1"><![CDATA[Some text]]>
</wps:ComplexData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput>
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>

Let's try that gs:CollectGeometries process under the Choose process dropdown, because I know that we can use an existing GeoServer layer there, and we can view the output. Select tiger:giant_polygon from the Process inputs dropdown.

There are a couple of different options for output; let's get it in JSON by selecting application/json from the Process outputs dropdown.

Select the Execute process button, and you can see successful output, as shown in the following screenshot:

So, this is useful as a kind of testing tool to build up parts of your process if you're creating a complex process with process chaining, which we'll be learning about in the next section. If you want to preview the GeoJSON, one nice site to do it at is http://geojsonlint.com/, and you just paste in your GeoJSON. If it's valid, it'll show up on the map, as shown in the following screenshot; if it's not, it'll give you a pretty good error message about why it's not working:

Also, QGIS is always helpful when you're going through a process and are able to preview data output.

In this section, you learned about building a WPS request with request builder, and about some of the parts of a WPS request, especially input formats. In the next section, you'll learn more about building a complex request with process chaining, and we can bring some of the XML we created with our request builder into the more complex process-chained WPS request.

Process chaining

In the previous section, you learned about creating WPS requests with WPS request builder. In this section, you'll learn how to make more complex WPS requests with process chaining. First, we'll take a look at a chain process request in plain XML. Next, we'll create an even more complex request. Finally, we'll add this request to a minimal OpenLayers web app to test the results of POST.

Here is our first process-chained XML, and you can see that the first WPS process is started here with this wps:Execute operation. The identifier is gs:CollectGeometries, so it's the gs:CollectGeometries process that we're running here, as shown in the following code:

<?xml version="1.0" encoding="UTF-8"?>
<wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" 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:wcs="http://www.opengis.net/wcs/1.1.1" 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>gs:CollectGeometries</ows:Identifier>
<wps:DataInputs>
...
// Full code in the code bundle
</wps:ResponseForm>
</wps:Execute>

But the interesting thing is that when you look at wps:Input of CollectGeometries, you can see it's getting the features parameter from wps:Reference. So, this is not wps:Execute, yet it still is wps:Reference, but it's referencing a text/xml type that includes an wps:Execute operation in it, which is a little bit convoluted, but that's just how it's set up. And this is usually how you're going to refer to process-chained processes, with XML inside of other processes.

So, we have our second wps:Execute operation here, inside a wps:Body section, and this is using the BufferFeatureCollection process, which also has a features input parameter:

<wps:Body>
<wps:Execute version="1.0.0" service="WPS">
<ows:Identifier>gs:BufferFeatureCollection</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>features</ows:Identifier>
<wps:Reference mimeType="text/xml" xlink:href="http://geoserver/wfs" method="POST">
<wps:Body>
<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2" xmlns:learning-geoserver="http://packtpub.com/learning-geoserver">
<wfs:Query srsName="EPSG:2272" typeName="learning-geoserver:pois"/>
</wfs:GetFeature>
</wps:Body>
</wps:Reference>
</wps:Input>

Here, for features, we're also using wps:Reference, but rather than having an additional WPS request or WPS section inside of wps:Reference, we're using wfs. This section in here is actually just a valid wfs defined by the WFS standard:

<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2" xmlns:learning-geoserver="http://packtpub.com/learning-geoserver">
<wfs:Query srsName="EPSG:2272" typeName="learning-geoserver:pois"/>
</wfs:GetFeature>

So anything that you would put, for example, in a wfs:Query section on WFS would be valid, and in this section of this XML. We're just using a regular wfs:Query, getting all of the points of interest in the learning-geoserver:pois workspace. Some things to be aware of here are, again, data types, so we're going to be outputting the following little portion as text XML-based wfs-collection:

<wps:RawDataOutput mimeType="text/xml; subtype=wfs-collection/1.0">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>

That is just the way this buffer features collection process returns data, and, of course, gs:CollectGeometries will turn that collection into geometries. So, be aware of data formats. You'll be using a lot of different formats through a process-chained operation. A lot of the time, you'll be changing between different formats, so of course, the spatial reference will be important. In this case, we'd have trouble doing some of these operations if we're not using a linear spatial reference, and we end up having to change or reproject the spatial reference into a different system later on, which you'll see in the next section, with OpenLayers.

The namespaces are also very important. Because this is just a feature of XML, you have to explain what your tag is referring to so that all the different data types appear in their own way. If you are using XML namespaces correctly, it separates out portions of the XML in the correct way so that the services you're feeding it to understand how to read the data.

You can see many namespaces are defined up here; not all of them are necessary, but you can see that wfs is there, defining this little section and the syntax for this section, which comes from a WFS standard:

<wps:Reference mimeType="text/xml" xlink:href="http://geoserver/wfs" method="POST">
<wps:Body>
<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2" xmlns:learning-geoserver="http://packtpub.com/learning-geoserver">
<wfs:Query srsName="EPSG:2272" typeName="learning-geoserver:pois"/>
</wfs:GetFeature>
</wps:Body>
</wps:Reference>

Here is the result of this as GML:

<wps:RawDataOutput mimeType="text/xml; subtype=gml/3.1.1">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>

So, that's our first XML example of a WPS request. Let's look at our second example, as follows:

<ows:Identifier>JTS:difference</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>a</ows:Identifier>
<wps:Reference mimeType="text/xml; subtype=gml/3.1.1" xlink:href="http://geoserver/wps" method="POST">
<wps:Body>
<wps:Execute version="1.0.0" service="WPS">
<ows:Identifier>gs:CollectGeometries</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>features</ows:Identifier>
<wps:Reference mimeType="text/xml" xlink:href="http://geoserver/wps" method="POST">

This is our second WPS request, and it will be even more complex than the last one, with process chaining. In the last process chain, we look at this gs:CollectGeometries section and everything below it. In this process-chained operation, we're using this difference process, which is based on a JTS namespace, and this takes two wps:Input parameters:

<ows:Identifier>JTS:difference</ows:Identifier>

Each of these inputs gives geometry in GML, and this process will take the difference of these geometries and give us that as a separate geometry feature collection or single geometry in GeoJSON format:

<wps:RawDataOutput mimeType="application/json">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>

Now I'm moving over into OpenLayers. We can run a very simple WPS request as follows:

<!DOCTYPE html>
<html lang="en">
<head>
<title>WPS-Request Example</title><!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content=
"width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- OL stylesheet -->
<link rel="stylesheet" href="https://openlayers.org/en/v4.4.2/css/ol.css" type="text/css">
</head>
<body>
<h1>WPS-Request Example</h1>

<!-- OpenLayers JS dependency, debug build -->
<script type="text/javascript" src="https://openlayers.org/en/v4.4.2/build/ol-debug.js"></script>
<!-- Begin wps-request Javascript -->
<script type="text/javascript">

The preceding code is based on a stripped-down OpenLayers app, which sends an HTTP POST request with XML. We can start with this, doing incremental testing to build up a chained WPS request in the OpenLayers code. So, it's pretty stripped down; there's not a whole lot going on there. We just have our postData with all of the WPS text XML body, which is as follows:

postData = '<?xml version="1.0" encoding="UTF-8"?><wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" 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:wcs="http://www.opengis.net/wcs/1.1.1" 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>gs:Aggregate</ows:Identifier><wps:DataInputs><wps:Input><ows:Identifier>features</ows:Identifier><wps:Reference mimeType="text/xml" xlink:href="http://geoserver/wfs" method="POST"><wps:Body><wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2" xmlns:sf="http://www.openplans.org/spearfish"><wfs:Query typeName="topp:states"/></wfs:GetFeature></wps:Body></wps:Reference></wps:Input><wps:Input><ows:Identifier>aggregationAttribute</ows:Identifier><wps:Data><wps:LiteralData>PERSONS</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>function</ows:Identifier><wps:Data><wps:LiteralData>Count</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>function</ows:Identifier><wps:Data><wps:LiteralData>Average</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>function</ows:Identifier><wps:Data><wps:LiteralData>Sum</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>function</ows:Identifier><wps:Data><wps:LiteralData>Min</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>function</ows:Identifier><wps:Data><wps:LiteralData>Max</wps:LiteralData></wps:Data></wps:Input><wps:Input><ows:Identifier>singlePass</ows:Identifier><wps:Data><wps:LiteralData>false</wps:LiteralData></wps:Data></wps:Input></wps:DataInputs><wps:ResponseForm><wps:RawDataOutput mimeType="application/json"><ows:Identifier>result</ows:Identifier></wps:RawDataOutput></wps:ResponseForm></wps:Execute>';

Then, postData is sent via this XML HTTP request object posted to GeoServer. Then we'll get a response in as an alert, which can be achieved with the following code:

url = 'http://localhost:8080/geoserver/wps';
var req = new XMLHttpRequest();
req.open("POST", url, true);
req.setRequestHeader('Content-type', 'text/xml');
req.onreadystatechange = function() {
if (req.readyState != 4) return;
if (req.status != 200 && req.status != 304) {
alert('HTTP error ' + req.status);
return;
}
alert(req.responseText);
if (req.readyState == 4) return;
};
req.send(postData);

So, we can test that out, and you can see the following result of that operation, which is in JSON; it's the data corresponding to the request:

Taking that one step further, we just add the XML from the more complex chained operation that we showed in the second example XML previously. Now, if we run this process-chained POST request, running this more complex process-chained POST request will sometimes require some time before it returns a result. Here you can see the result as GeoJSON:

Again, the spatial reference system is linear, so we're seeing much longer coordinates than we would normally see, but we're getting a successful result from our complex process-chained operation.

You've seen now how to create a complex process-chained operation. In the next section, we'll look at full integration of that WPS request into OpenLayers, as well as the result.

OpenLayers integration

In the previous section, you learned how to create and test complex WPS requests. In this section, you'll round off your understanding of WPS by fully integrating requests and responses with OpenLayers. We'll be using the example of determining where to plant apple trees on a farm using some of the data that we've worked with in previous sections. We will first cover the GeoJSON OpenLayers class, and then we'll look at how the WPS response is read into OpenLayers with that. Then we'll cover reprojection of the data with Proj4JS in particular, and finally, we'll view the result. You can refer to the following documentation for more information:

http://openlayers.org/en/latest/apidoc/module-ol_format_GeoJSON-GeoJSON.html#writeFeatureObject

We're going to use the GeoJSON class to read data into our OpenLayers app, and it's useful here to take a look at some of the methods that are available, such as readFeature and readFeatures. That distinction is important, since readFeatures takes an array of OpenLayers features that consists of multiple features:

readFeatures(source, opt_options) -> {Array.<module:ol/Feature~Feature>}

On the other hand, readFeature only takes a single feature:

readFeature(source, opt_options) -> {module:ol/Feature~Feature}

You might want to check out some of these other methods as well. Let's take a look at the code. We have our app example that we were working with in the previous section, and we've now added a dependency for Proj4JS by adding the following line:

<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js"></script>

PROJ, by the way, is the standards-based, open source-based way of doing projections by reprojecting data, and it's used by many different software packages. This Proj4JS, of course, is the JavaScript version of PROJ, and since we're working with EPSG 2272 data in our WPS operation so that we can do some linear-based operations, we need to reproject that data as EPSG: 4326, compatible with OpenLayers.

The first thing we need to do is tell PROJ how to handle this data format, and you can find a proj4 string at http://spatialreference.org/, which is a great source, but a PROJ string is a standardized way where PROJ can know some details of the coordinate system or projection system, and that way, it can translate between different projections and coordinate systems:

proj4.defs('EPSG:2272', '+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs');
var proj2272 = ol.proj.get('EPSG:2272');

So, we've taken care of some PROJ details here, creating this new variable, which is our PROJ-defined projection system. Our view is using EPSG: 4326:

var view = new ol.View({
center: [-77.163785, 39.7641],
zoom: 19,
projection: new ol.proj.Projection({
code: 'EPSG:4326',
units: 'degrees',
axisOrientation: 'neu',
global: true
})
});

If we don't use 4326 or 3857, we won't be able to use the OpenStreetMap source-based map. We're also pulling in a WMS from our GeoServer instance, which is the points of interest that we worked with previously, and that'll give us a bit of a reference for the result of this WPS operation:

var wms = new ol.layer.Image({
//extent: [-13884991, 2870341, -7455066, 6338219],
source: new ol.source.ImageWMS({
url: host + '/wms',
params: {'LAYERS': 'learning-geoserver:pois'},
ratio: 1,
serverType: 'geoserver'
})
});

var map = new ol.Map({
target: "map",
layers: [osm, wms],
view: view
});

The user will click on a button, which will go to the submit function, and so it will submit the WPS request, which is what we covered in the previous section. It's in XML format, and it will be posted to the server. Upon return, with our response, it will be reading that into a GeoJSON object. Importantly, here, you can see that dataProjection is in this proj2272 system, while we want it to be projected into EPSG:4326. So, there'll be a coordinate system translation going on there:

  url = host + '/wps';
var req = new XMLHttpRequest();
req.open("POST", url, true);
req.setRequestHeader('Content-type', 'text/xml');

req.onreadystatechange = function() {
if (req.readyState != 4) return;
if (req.status != 200 && req.status != 304) {
alert('HTTP error ' + req.status);
return;
}

var format = new ol.format.GeoJSON();
response = req.response;

var feature = (format.readFeatures(response, {
dataProjection: proj2272,
featureProjection: 'EPSG:4326'
}));

var vectorSource = new ol.source.Vector({
features: feature
});

var vectorLayer = new ol.layer.Vector({
source: vectorSource
});

// console.log((new ol.format.GeoJSON()).writeFeatures(vectorLayer.getSource().getFeatures()));

map.addLayer(vectorLayer);

if (req.readyState == 4) return;
};
req.send(postData);
}

We're just doing normal OpenLayers stuff in the preceding code, creating a vectorSource and a vectorLayer objects with our source set there. We've commented out this console.log line, but it's useful to do things like this for debugging. This will write the features of that GeoJSON object as GeoJSON, and we can use GeoJSON lint or QGIS to test and look at the result. The most important thing here is to notice whether the coordinates have been successfully reproductive, and then finally, with the map object, we'll just use the addLayer method to add vectorLayer to our map. So, let's take a look at this in action:

When you first bring up the app, you'll just see the points of interest and the base map. Now, to POST the WPS request, click the Find Apple Optimal Planning Locations button:

We want to find where the best place to plant apple trees is. Some of these trees are black walnut trees, which are not beneficial to apple trees and, in fact, may harm them, while some of these other trees are other apple trees, which we want to have close to the new apple trees for pollination purposes. And with WPS, we get this response, based on the location of the apple trees and the black walnut trees, of an area in which we can plant new apple trees.

Summary

In this chapter, we learned to use WPS to run geospatial processing on your data and return the results to our web app. We installed the WPS plugin on our GeoServer instance, and learned how it works. We used the WPS request builder to create some simple WPS requests. We also explored the process-chaining technique with a more complex example, and integrated the complex WPS request into OpenLayers.

In the next chapter, you'll learn about the technique of tile caching, and how you can harness tile caching to improve the performance of your app.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Resolve bottlenecks, optimize data stores, and cluster server resources
  • Use identity management and authentication for a user-specific, secure web application
  • Go beyond traditional web hosting to explore the full range of hosting options in the cloud

Description

GeoServer is open source, server-side software written in Java that allows users to share and edit geospatial data. In this book, you'll start by learning how to develop a spatial analysis platform with web processing services. Then you'll see how to develop an algorithm by chaining together geospatial analysis processes, which you can share with anyone in the world. Next you'll delve into a very important technique to improve the speed of your map application—tile caching. Here, you'll understand how tile caching works, how to develop an effective tile cache-supported web service, and how to leverage tile caching in your OpenLayers web application. Further on, you'll explore important tweaks to produce a performant GeoServer-backed web mapping application. Moving on, you'll enable authentication on the frontend and backend to protect sensitive map data, and deliver sensitive data to your end user. Finally, you'll see how to put your web application into production in a secure and user-friendly way. You'll go beyond traditional web hosting to explore the full range of hosting options in the cloud, and maintain a reliable server instance.

Who is this book for?

This book is for anyone who wants to learn about advanced interfaces, security, and troubleshooting techniques in GeoServer. A basic understanding of GeoServer is required

What you will learn

  • Develop a WPS-processing service to allow web-based geospatial data processing
  • Get to know important techniques to improve the speed of your web map application—tile caching, raster data optimization, and server clustering
  • Find out which GeoServer settings resolve bottlenecks
  • Develop an algorithm by chaining geospatial analysis processes together
  • Put your application into production with hosting, monitoring, and automated backup and recovery
  • Understand how to develop an effective tile cache-supported web service
  • Master techniques that ensure resilient server deployment
Estimated delivery fee Deliver to Singapore

Standard delivery 10 - 13 business days

S$11.95

Premium delivery 5 - 8 business days

S$54.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jul 31, 2018
Length: 134 pages
Edition : 1st
Language : English
ISBN-13 : 9781789538601
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Singapore

Standard delivery 10 - 13 business days

S$11.95

Premium delivery 5 - 8 business days

S$54.95
(Includes tracking information)

Product Details

Publication date : Jul 31, 2018
Length: 134 pages
Edition : 1st
Language : English
ISBN-13 : 9781789538601
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just S$6 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just S$6 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total S$ 194.97
PostGIS Cookbook
S$74.99
GeoServer Beginner's Guide
S$74.99
Expert GeoServer
S$44.99
Total S$ 194.97 Stars icon
Banner background image

Table of Contents

6 Chapters
Developing a Spatial Analysis Platform with WPS Chevron down icon Chevron up icon
Speed Up Your App with Tile Caching Chevron down icon Chevron up icon
Optimizing GeoServer Chevron down icon Chevron up icon
Secure Authentication Chevron down icon Chevron up icon
Putting it into Production Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
(1 Ratings)
5 star 0%
4 star 0%
3 star 0%
2 star 0%
1 star 100%
R. L. Hore Oct 13, 2018
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
I was expecting more from this book than I can find easily on the web with a simple search. Very dissapointing
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela