WPSClient and WPSProcess for convenient WPS interaction.
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<title>OpenLayers WPS Client Example</title>
|
||||||
|
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="style.css" type="text/css">
|
||||||
|
<script src="../lib/OpenLayers.js"></script>
|
||||||
|
<script src="wps-client.js"></script>
|
||||||
|
</head>
|
||||||
|
<body onload="init()">
|
||||||
|
<h1 id="title">WPS Client Example</h1>
|
||||||
|
|
||||||
|
<div id="tags">
|
||||||
|
wps
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="shortdesc">Shows the usage of the WPS Client</div>
|
||||||
|
|
||||||
|
<div id="map" class="smallmap"></div>
|
||||||
|
|
||||||
|
<div id="docs">
|
||||||
|
<p>This example shows how simple it is to use the WPS Client. See
|
||||||
|
<a href="wps-client.js">wps-client.js</a> to see how this is done.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
var map, client, process;
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
map = new OpenLayers.Map('map', {
|
||||||
|
allOverlays: true,
|
||||||
|
center: [114, 16],
|
||||||
|
zoom: 4,
|
||||||
|
layers: [new OpenLayers.Layer.Vector()]
|
||||||
|
});
|
||||||
|
|
||||||
|
var features = [new OpenLayers.Format.WKT().read(
|
||||||
|
'LINESTRING(117 22,112 18,118 13, 115 8)'
|
||||||
|
)];
|
||||||
|
var geometry = (new OpenLayers.Format.WKT().read(
|
||||||
|
'POLYGON((110 20,120 20,120 10,110 10,110 20),(112 17,118 18,118 16,112 15,112 17))'
|
||||||
|
)).geometry;
|
||||||
|
|
||||||
|
map.baseLayer.addFeatures(features);
|
||||||
|
map.baseLayer.addFeatures([new OpenLayers.Feature.Vector(geometry)]);
|
||||||
|
|
||||||
|
client = new OpenLayers.WPSClient({
|
||||||
|
servers: {
|
||||||
|
local: "/geoserver/wps"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a process and execute it
|
||||||
|
process = client.getProcess("local", "JTS:intersection");
|
||||||
|
process.execute({
|
||||||
|
// spatial input can be a feature or a geometry or an array of
|
||||||
|
// features or geometries
|
||||||
|
inputs: {
|
||||||
|
a: features,
|
||||||
|
b: geometry
|
||||||
|
},
|
||||||
|
success: function(outputs) {
|
||||||
|
// outputs.result is a feature or an array of features for spatial
|
||||||
|
// processes.
|
||||||
|
map.baseLayer.addFeatures(outputs.result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Instead of creating a process and executing it, we could call execute on
|
||||||
|
// the client directly if we are only dealing with a single process:
|
||||||
|
/*
|
||||||
|
client.execute({
|
||||||
|
server: "local",
|
||||||
|
process: "JTS:intersection",
|
||||||
|
// spatial input can be a feature or a geometry or an array of
|
||||||
|
// features or geometries
|
||||||
|
inputs: {
|
||||||
|
a: features,
|
||||||
|
b: geometry
|
||||||
|
},
|
||||||
|
success: function(outputs) {
|
||||||
|
// outputs.result is a feature or an array of features for spatial
|
||||||
|
// processes.
|
||||||
|
map.baseLayer.addFeatures(outputs.result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
+3
-1
@@ -394,7 +394,9 @@
|
|||||||
"OpenLayers/Symbolizer/Raster.js",
|
"OpenLayers/Symbolizer/Raster.js",
|
||||||
"OpenLayers/Lang.js",
|
"OpenLayers/Lang.js",
|
||||||
"OpenLayers/Lang/en.js",
|
"OpenLayers/Lang/en.js",
|
||||||
"OpenLayers/Spherical.js"
|
"OpenLayers/Spherical.js",
|
||||||
|
"OpenLayers/WPSClient.js",
|
||||||
|
"OpenLayers/WPSProcess.js"
|
||||||
]; // etc.
|
]; // etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
|
||||||
|
* full list of contributors). Published under the 2-clause BSD license.
|
||||||
|
* See license.txt in the OpenLayers distribution or repository for the
|
||||||
|
* full text of the license.
|
||||||
|
*
|
||||||
|
* @requires OpenLayers/SingleFile.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: OpenLayers.WPSClient
|
||||||
|
*/
|
||||||
|
OpenLayers.WPSClient = OpenLayers.Class({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: servers
|
||||||
|
* {Object} Service metadata, keyed by a local identifier.
|
||||||
|
*
|
||||||
|
* Properties:
|
||||||
|
* url - {String} the url of the server
|
||||||
|
* knownProcesses: {Object} Cache of DescribeProcess responses, keyed by
|
||||||
|
* process identifier.
|
||||||
|
*/
|
||||||
|
servers: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: lazy
|
||||||
|
* {Boolean} Should the DescribeProcess be deferred until a process is
|
||||||
|
* fully configured? Default is false.
|
||||||
|
*/
|
||||||
|
lazy: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor: OpenLayers.WPSClient
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* options - {Object} Object whose properties will be set on the instance.
|
||||||
|
*
|
||||||
|
* Avaliable options:
|
||||||
|
* servers - {Object} Mandatory. Service metadata, keyed by a local
|
||||||
|
* identifier. Can either be a string with the service url or an
|
||||||
|
* object literal with additional metadata:
|
||||||
|
*
|
||||||
|
* (code)
|
||||||
|
* servers: {
|
||||||
|
* local: '/geoserver/wps'
|
||||||
|
* }, {
|
||||||
|
* opengeo: {
|
||||||
|
* url: 'http://demo.opengeo.org/geoserver/wps',
|
||||||
|
* version: '1.0.0'
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* lazy - {Boolean} Optional. Set to true if DescribeProcess should not be
|
||||||
|
* requested until a process is fully configured. Default is false.
|
||||||
|
*/
|
||||||
|
initialize: function(options) {
|
||||||
|
OpenLayers.Util.extend(this, options);
|
||||||
|
this.servers = {};
|
||||||
|
for (var s in options.servers) {
|
||||||
|
this.servers[s] = typeof options.servers[s] == 'string' ? {
|
||||||
|
url: options.servers[s],
|
||||||
|
version: '1.0.0'
|
||||||
|
} : options.servers[s];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIMethod: execute
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* options - {Object} Options for the execute operation.
|
||||||
|
*
|
||||||
|
* Available options:
|
||||||
|
* server - {String} Mandatory. One of the local identifiers of the
|
||||||
|
* configured servers.
|
||||||
|
* process - {String} Mandatory. A process identifier known to the
|
||||||
|
* server.
|
||||||
|
* inputs - {Object} The inputs for the process, keyed by input identifier.
|
||||||
|
* For spatial data inputs, the value of an input is usually an
|
||||||
|
* <OpenLayers.Geometry>, an <OpenLayers.Feature.Vector> or an array of
|
||||||
|
* geometries or features.
|
||||||
|
* success - {Function} Callback to call when the process is complete.
|
||||||
|
* This function is called with an outputs object as argument, which
|
||||||
|
* will have a 'result' property. For processes that generate spatial
|
||||||
|
* output, this will either be a single <OpenLayers.Feature.Vector> or
|
||||||
|
* an array of features.
|
||||||
|
* scope - {Object} Optional scope for the success callback.
|
||||||
|
*/
|
||||||
|
execute: function(options) {
|
||||||
|
var process = this.getProcess(options.server, options.process);
|
||||||
|
process.execute({
|
||||||
|
inputs: options.inputs,
|
||||||
|
success: options.success,
|
||||||
|
scope: options.scope
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIMethod: getProcess
|
||||||
|
* Creates an <OpenLayers.WPSProcess>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* server - {String} Local identifier from the servers that this instance
|
||||||
|
* was constructed with.
|
||||||
|
* identifier - {String} Process identifier known to the server.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {<OpenLayers.WPSProcess>}
|
||||||
|
*/
|
||||||
|
getProcess: function(server, identifier) {
|
||||||
|
var process = new OpenLayers.WPSProcess({
|
||||||
|
client: this,
|
||||||
|
server: server,
|
||||||
|
identifier: identifier
|
||||||
|
});
|
||||||
|
if (!this.lazy) {
|
||||||
|
process.describe();
|
||||||
|
}
|
||||||
|
return process;
|
||||||
|
},
|
||||||
|
|
||||||
|
CLASS_NAME: 'OpenLayers.WPSClient'
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
|
||||||
|
* full list of contributors). Published under the 2-clause BSD license.
|
||||||
|
* See license.txt in the OpenLayers distribution or repository for the
|
||||||
|
* full text of the license.
|
||||||
|
*
|
||||||
|
* @requires OpenLayers/SingleFile.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires OpenLayers/Events.js
|
||||||
|
* @requires OpenLayers/Geometry.js
|
||||||
|
* @requires OpenLayers/Feature/Vector.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: OpenLayers.WPSProces
|
||||||
|
*/
|
||||||
|
OpenLayers.WPSProcess = OpenLayers.Class({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProperty: events
|
||||||
|
* {<OpenLayers.Events>}
|
||||||
|
*
|
||||||
|
* Supported event types:
|
||||||
|
* describeprocess - fires when the process description is available
|
||||||
|
*/
|
||||||
|
events: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: client
|
||||||
|
* {<OpenLayers.WPSClient>} The client that manages this process.
|
||||||
|
*/
|
||||||
|
client: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: server
|
||||||
|
* {String} Local client identifier for this process's server.
|
||||||
|
*/
|
||||||
|
server: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: identifier
|
||||||
|
* {String} Process identifier known to the server.
|
||||||
|
*/
|
||||||
|
identifier: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: description
|
||||||
|
* {Object} DescribeProcess response for this process.
|
||||||
|
*/
|
||||||
|
description: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: formats
|
||||||
|
* {Object} OpenLayers.Format instances keyed by mimetype.
|
||||||
|
*/
|
||||||
|
formats: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor: OpenLayers.WPSProcess
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* options - {Object} Object whose properties will be set on the instance.
|
||||||
|
*
|
||||||
|
* Avaliable options:
|
||||||
|
* client - {<OpenLayers.WPSClient} Mandatory. Client that manages this
|
||||||
|
* process.
|
||||||
|
* server - {String} Mandatory. Local client identifier of this process's
|
||||||
|
* server.
|
||||||
|
* identifier - {String} Mandatory. Process identifier known to the server.
|
||||||
|
*/
|
||||||
|
initialize: function(options) {
|
||||||
|
OpenLayers.Util.extend(this, options);
|
||||||
|
|
||||||
|
this.events = new OpenLayers.Events(this);
|
||||||
|
|
||||||
|
this.formats = {
|
||||||
|
'application/wkt': new OpenLayers.Format.WKT(),
|
||||||
|
'application/json': new OpenLayers.Format.GeoJSON()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: describe
|
||||||
|
* Issues a DescribeProcess request asynchronously and fires the
|
||||||
|
* 'describeProcess' event as soon as the response is available in
|
||||||
|
* <description>.
|
||||||
|
*/
|
||||||
|
describe: function() {
|
||||||
|
if (this._describePending || this.description) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._describePending = true;
|
||||||
|
var server = this.client.servers[this.server];
|
||||||
|
OpenLayers.Request.GET({
|
||||||
|
url: server.url,
|
||||||
|
params: {
|
||||||
|
SERVICE: 'WPS',
|
||||||
|
VERSION: server.version,
|
||||||
|
REQUEST: 'DescribeProcess',
|
||||||
|
IDENTIFIER: this.identifier
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
this.description = new OpenLayers.Format.WPSDescribeProcess()
|
||||||
|
.read(response.responseText)
|
||||||
|
.processDescriptions[this.identifier];
|
||||||
|
delete this._describePending;
|
||||||
|
this.events.triggerEvent('describeprocess');
|
||||||
|
},
|
||||||
|
scope: this
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIMethod: execute
|
||||||
|
* Executes the process
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* options - {Object}
|
||||||
|
*
|
||||||
|
* Available options:
|
||||||
|
* inputs - {Object} The inputs for the process, keyed by input identifier.
|
||||||
|
* For spatial data inputs, the value of an input is usually an
|
||||||
|
* <OpenLayers.Geometry>, an <OpenLayers.Feature.Vector> or an array of
|
||||||
|
* geometries or features.
|
||||||
|
* success - {Function} Callback to call when the process is complete.
|
||||||
|
* This function is called with an outputs object as argument, which
|
||||||
|
* will have a 'result' property. For processes that generate spatial
|
||||||
|
* output, this will either be a single <OpenLayers.Feature.Vector> or
|
||||||
|
* an array of features.
|
||||||
|
* scope - {Object} Optional scope for the success callback.
|
||||||
|
*/
|
||||||
|
execute: function(options) {
|
||||||
|
if (!this.description) {
|
||||||
|
this.events.register('describeprocess', this, function execute() {
|
||||||
|
this.events.unregister('describeprocess', this, execute);
|
||||||
|
this.execute(options);
|
||||||
|
});
|
||||||
|
this.describe();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var description = this.description,
|
||||||
|
inputs = options.inputs,
|
||||||
|
input, i, ii;
|
||||||
|
for (i=0, ii=description.dataInputs.length; i<ii; ++i) {
|
||||||
|
input = description.dataInputs[i];
|
||||||
|
this.setInputData(input, inputs[input.identifier]);
|
||||||
|
}
|
||||||
|
//TODO For now we only handle responseForm with a single output
|
||||||
|
this.setResponseForm();
|
||||||
|
OpenLayers.Request.POST({
|
||||||
|
url: this.client.servers[this.server].url,
|
||||||
|
data: new OpenLayers.Format.WPSExecute().write(this.description),
|
||||||
|
success: function(response) {
|
||||||
|
var mimeType = this.findMimeType(this.description.processOutputs[0].complexOutput);
|
||||||
|
var features = this.formats[mimeType].read(response.responseText);
|
||||||
|
if (options.success) {
|
||||||
|
options.success.call(options.scope, {
|
||||||
|
result: features
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scope: this
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: setInputData
|
||||||
|
* Sets the data for a single input
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* input - {Object} An entry from the dataInputs array of the process
|
||||||
|
* description.
|
||||||
|
* data - {Mixed} For spatial data inputs, this is usually an
|
||||||
|
* <OpenLayers.Geometry>, an <OpenLayers.Feature.Vector> or an array of
|
||||||
|
* geometries or features.
|
||||||
|
*/
|
||||||
|
setInputData: function(input, data) {
|
||||||
|
// clear any previous data
|
||||||
|
input.data = {};
|
||||||
|
if (data) {
|
||||||
|
var complexData = input.complexData;
|
||||||
|
if (complexData) {
|
||||||
|
var format = this.findMimeType(complexData);
|
||||||
|
input.data.complexData = {
|
||||||
|
mimeType: format,
|
||||||
|
value: this.formats[format].write(this.toFeatures(data))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: setResponseForm
|
||||||
|
* Sets the responseForm property of the <execute> payload.
|
||||||
|
*/
|
||||||
|
setResponseForm: function() {
|
||||||
|
output = this.description.processOutputs[0];
|
||||||
|
this.description.responseForm = {
|
||||||
|
rawDataOutput: {
|
||||||
|
identifier: output.identifier,
|
||||||
|
mimeType: this.findMimeType(output.complexOutput)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: toFeatures
|
||||||
|
* Converts spatial input into features so it can be processed by
|
||||||
|
* <OpenLayers.Format> instances.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* source - {Mixed} An <OpenLayers.Geometry>, an
|
||||||
|
* <OpenLayers.Feature.Vector>, or an array of geometries or features
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {Array(<OpenLayers.Feature.Vector>)}
|
||||||
|
*/
|
||||||
|
toFeatures: function(source) {
|
||||||
|
var isArray = OpenLayers.Util.isArray(source);
|
||||||
|
if (!isArray) {
|
||||||
|
source = [source];
|
||||||
|
}
|
||||||
|
var target = new Array(source.length),
|
||||||
|
current;
|
||||||
|
for (var i=0, ii=source.length; i<ii; ++i) {
|
||||||
|
current = source[i];
|
||||||
|
target[i] = current instanceof OpenLayers.Feature.Vector ?
|
||||||
|
current : new OpenLayers.Feature.Vector(current);
|
||||||
|
}
|
||||||
|
return isArray ? target : target[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: findMimeType
|
||||||
|
* Finds a supported mime type.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* complex - {Object} A complexData or complexOutput object from the
|
||||||
|
* process description.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {String} A supported mime type.
|
||||||
|
*/
|
||||||
|
findMimeType: function(complex) {
|
||||||
|
var formats = complex.supported.formats;
|
||||||
|
for (var f in formats) {
|
||||||
|
if (f in this.formats) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
CLASS_NAME: "OpenLayers.WPSProcess"
|
||||||
|
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user