From 81b67db10165491dcc3209b3c7962bafe80e342d Mon Sep 17 00:00:00 2001 From: ahocevar Date: Wed, 14 Mar 2012 17:12:06 +0100 Subject: [PATCH] Patch from http://trac.osgeo.org/openlayers/ticket/3307. Uses a remote GeoServer now, which is added to the allowed hosts for proxy.cgi. --- examples/proxy.cgi | 6 +- examples/wps.html | 77 ++++++++++++ examples/wps.js | 289 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 369 insertions(+), 3 deletions(-) create mode 100644 examples/wps.html create mode 100644 examples/wps.js diff --git a/examples/proxy.cgi b/examples/proxy.cgi index 4358e2ca03..3ec43195d3 100755 --- a/examples/proxy.cgi +++ b/examples/proxy.cgi @@ -20,9 +20,9 @@ allowedHosts = ['www.openlayers.org', 'openlayers.org', 'prototype.openmnnd.org', 'geo.openplans.org', 'sigma.openplans.org', 'demo.opengeo.org', 'www.openstreetmap.org', 'sample.azavea.com', - 'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080', - 'vmap0.tiles.osgeo.org', 'www.openrouteservice.org', - 'maps.wien.gv.at'] + 'suite.opengeo.org', 'v2.suite.opengeo.org', + 'v-swe.uni-muenster.de:8080', 'vmap0.tiles.osgeo.org', + 'www.openrouteservice.org', 'maps.wien.gv.at'] method = os.environ["REQUEST_METHOD"] diff --git a/examples/wps.html b/examples/wps.html new file mode 100644 index 0000000000..11f297d97d --- /dev/null +++ b/examples/wps.html @@ -0,0 +1,77 @@ + + + + + + + OpenLayers WPS Builder Example + + + + + +

WPS Builder Example

+ +
+ wps, process +
+ +
Using WPS formats to interact with WPS
+ +
+ +
+

This example shows WPS in action by using the WPSCapabilities, + WPSDescribeProcess and WPSExecute formats. See + wps.js for the + source code.

+
+
+
    +
  1. Select a process from the list below. The list is populated + with the result of a WPS GetCapabilities request, parsed using + OpenLayers.Format.WPSCapabilities::read.
  2. +
  3. Fill out the Input form. Hover over fields to get a description. + To use a geometry from the map as input, select the geometry on the + map (using the pen symbol on the left of the toolbar) and just + click the field. The form is generated from the object returned by + OpenLayers.Format.WPSDescribeProcess::read
  4. +
  5. Click "Execute" and examine the result in the result text area. + If the result can be parsed as features, it will be displayed on + the map as well. The process data is sent to the server with the + serialized XML from OpenLayers.Format.WPSExecute::write, + which can use a modified + OpenLayers.Format.WPSDescribeProcess result object as + input.
  6. +
+ +

+
+
+
+ + + + diff --git a/examples/wps.js b/examples/wps.js new file mode 100644 index 0000000000..0fa213b4c7 --- /dev/null +++ b/examples/wps.js @@ -0,0 +1,289 @@ +OpenLayers.ProxyHost = "proxy.cgi?url="; + +var capabilities, // the capabilities, read by Format.WPSCapabilities::read + process; // the process description from Format.WPSDescribeProcess::read + +// get some capabilities +getCapabilities(); + +// create the UI +var layer = new OpenLayers.Layer.Vector("Scratchpad", { + isBaseLayer: true +}); +var toolbar = new OpenLayers.Control.EditingToolbar(layer); +toolbar.addControls([new OpenLayers.Control.ModifyFeature(layer, { + title: "Select feature" +})]); +var map = new OpenLayers.Map('map', { + controls: [ + toolbar, + new OpenLayers.Control.ZoomPanel(), + new OpenLayers.Control.PanPanel() + ], + layers: [layer] +}); +map.zoomToMaxExtent(); + +// add behavior to html elements +document.getElementById("processes").onchange = describeProcess; + +// using OpenLayers.Format.WPSCapabilities to read the capabilities +function getCapabilities() { + OpenLayers.Request.GET({ + url: "http://suite.opengeo.org/geoserver/wps/", + params: { + "SERVICE": "wps", + "REQUEST": "GetCapabilities" + }, + success: function(response){ + capabilities = new OpenLayers.Format.WPSCapabilities().read( + response.responseText + ); + var dropdown = document.getElementById("processes"); + var offerings = capabilities.processOfferings, option; + // populate the dropdown + for (var p in offerings) { + option = document.createElement("option"); + option.innerHTML = offerings[p].identifier; + option.value = p; + dropdown.appendChild(option); + } + } + }); +} + +// using OpenLayers.Format.WPSDescribeProcess to get information about a +// process +function describeProcess() { + var selection = this.options[this.selectedIndex].value; + OpenLayers.Request.GET({ + url: "http://suite.opengeo.org/geoserver/wps/", + params: { + "SERVICE": "wps", + "REQUEST": "DescribeProcess", + "VERSION": capabilities.version, + "IDENTIFIER": selection + }, + success: function(response) { + process = new OpenLayers.Format.WPSDescribeProcess().read( + response.responseText + ).processDescriptions[selection]; + buildForm(); + } + }); +} + +// dynamically create a form from the process description +function buildForm() { + document.getElementById("abstract").innerHTML = process["abstract"]; + document.getElementById("input").innerHTML = "

Input:

"; + document.getElementById("output").innerHTML = ""; + + var inputs = process.dataInputs, supported = true; + var input; + for (var i=0,ii=inputs.length; i"; + } +} + +// helper function to dynamically create a textarea for geometry (WKT) data +// input +function addWKTInput(input, previousSibling) { + var name = input.identifier; + var container = document.getElementById("input"); + var label = document.createElement("label"); + label["for"] = name; + label.title = input["abstract"]; + label.innerHTML = name + " (select feature, then click field):"; + previousSibling && previousSibling.nextSibling ? + container.insertBefore(label, previousSibling.nextSibling) : + container.appendChild(label); + var field = document.createElement("textarea"); + field.onclick = function () { + if (layer.selectedFeatures.length) { + this.innerHTML = new OpenLayers.Format.WKT().write( + layer.selectedFeatures[0] + ); + } + createCopy(input, this, addWKTInput); + }; + field.onblur = function() { + input.data = field.value ? { + complexData: { + mimeType: "application/wkt", + value: this.value + } + } : undefined; + }; + field.title = input["abstract"]; + field.id = name; + previousSibling && previousSibling.nextSibling ? + container.insertBefore(field, previousSibling.nextSibling.nextSibling) : + container.appendChild(field); +} + +// helper function to dynamically create a WFS collection reference input +function addWFSCollectionInput(input) { + var name = input.identifier; + var field = document.createElement("input"); + field.title = input["abstract"]; + field.value = name + " (layer on demo server)"; + addValueHandlers(field, function() { + input.reference = field.value ? { + mimeType: "text/xml; subtype=wfs-collection/1.0", + href: "http://geoserver/wfs", + method: "POST", + body: { + wfs: { + version: "1.0.0", + outputFormat: "GML2", + featureType: field.value + } + } + } : undefined; + }); + document.getElementById("input").appendChild(field); +} + +// helper function to create a literal input textfield or dropdown +function addLiteralInput(input, previousSibling) { + var name = input.identifier; + var container = document.getElementById("input"); + var anyValue = input.literalData.anyValue; + // anyValue means textfield, otherwise we create a dropdown + var field = document.createElement(anyValue ? "input" : "select"); + field.id = name; + field.title = input["abstract"]; + previousSibling && previousSibling.nextSibling ? + container.insertBefore(field, previousSibling.nextSibling) : + container.appendChild(field); + if (anyValue) { + var dataType = input.literalData.dataType; + field.value = name + (dataType ? " (" + dataType + ")" : ""); + addValueHandlers(field, function() { + input.data = field.value ? { + literalData: { + value: field.value + } + } : undefined; + }); + } else { + var option; + option = document.createElement("option"); + option.innerHTML = name; + field.appendChild(option); + for (var v in input.literalData.allowedValues) { + option = document.createElement("option"); + option.value = v; + option.innerHTML = v; + field.appendChild(option); + } + field.onchange = function() { + createCopy(input, field, addLiteralInput); + input.data = this.selectedIndex ? { + literalData: { + value: this.options[this.selectedIndex].value + } + } : undefined; + }; + } +} + +// if maxOccurs is > 1, this will add a copy of the field +function createCopy(input, field, fn) { + if (input.maxOccurs && input.maxOccurs > 1 && !field.userSelected) { + // add another copy of the field - we don't check maxOccurs + field.userSelected = true; + var newInput = OpenLayers.Util.extend({}, input); + // we recognize copies by the occurrence property + newInput.occurrence = (input.occurrence || 0) + 1; + process.dataInputs.push(newInput); + fn(newInput, field); + } +} + +// helper function for adding events to form fields +function addValueHandlers(field, onblur) { + field.onclick = function() { + if (!this.initialValue) { + this.initialValue = this.value; + this.value = ""; + } + }; + field.onblur = function() { + if (!this.value) { + this.value = this.initialValue; + delete this.initialValue; + } + onblur.apply(this, arguments); + }; +} + +// execute the process +function execute() { + var output = process.processOutputs[0]; + var input; + // remove occurrences that the user has not filled out + for (var i=process.dataInputs.length-1; i>=0; --i) { + input = process.dataInputs[i]; + if (input.occurrence && !input.data && !input.reference) { + OpenLayers.Util.removeItem(process.dataInputs, input); + } + } + process.responseForm = { + rawDataOutput: { + identifier: output.identifier + } + }; + if (output.complexOutput && output.complexOutput.supported.formats["application/wkt"]) { + process.responseForm.rawDataOutput.mimeType = "application/wkt"; + } + OpenLayers.Request.POST({ + url: "http://suite.opengeo.org/geoserver/wps", + data: new OpenLayers.Format.WPSExecute().write(process), + success: showOutput + }); +} + +// add the process's output to the page +function showOutput(response) { + var result = document.getElementById("output"); + result.innerHTML = "

Output:

"; + var features; + var contentType = response.getResponseHeader("Content-Type"); + if (contentType == "application/wkt") { + features = new OpenLayers.Format.WKT().read(response.responseText); + } else if (contentType == "text/xml; subtype=wfs-collection/1.0") { + features = new OpenLayers.Format.WFST.v1_0_0().read(response.responseText); + } + if (features && (features instanceof OpenLayers.Feature.Vector || features.length)) { + layer.addFeatures(features); + result.innerHTML += "The result should also be visible on the map."; + } + result.innerHTML += ""; +} \ No newline at end of file