wps.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. //OpenLayers.ProxyHost = "proxy.cgi?url=";
  2. OpenLayers.ProxyHost = "index.php?FUNCTION_INIT=OPEN_LAYERS_WPS&HEADER_NOT_INIT=YES&_url=";
  3. var wps = "http://demo.opengeo.org/geoserver/wps",
  4. capabilities, // the capabilities, read by Format.WPSCapabilities::read
  5. process; // the process description from Format.WPSDescribeProcess::read
  6. // get some capabilities
  7. getCapabilities();
  8. // create the UI
  9. var layer = new OpenLayers.Layer.Vector("Scratchpad");
  10. var toolbar = new OpenLayers.Control.EditingToolbar(layer);
  11. toolbar.addControls([new OpenLayers.Control.ModifyFeature(layer, {
  12. title: "Select feature"
  13. })]);
  14. var map = new OpenLayers.Map('map', {
  15. controls: [
  16. toolbar,
  17. new OpenLayers.Control.ZoomPanel(),
  18. new OpenLayers.Control.PanPanel()
  19. ],
  20. layers: [
  21. new OpenLayers.Layer.WMS(
  22. "OSM", "http://maps.opengeo.org/geowebcache/service/wms",
  23. {layers: "openstreetmap", format: "image/png"}
  24. ), layer
  25. ]
  26. });
  27. map.zoomToMaxExtent();
  28. // add behavior to html elements
  29. document.getElementById("processes").onchange = describeProcess;
  30. // using OpenLayers.Format.WPSCapabilities to read the capabilities
  31. function getCapabilities() {
  32. OpenLayers.Request.GET({
  33. url: wps,
  34. params: {
  35. "SERVICE": "WPS",
  36. "REQUEST": "GetCapabilities"
  37. },
  38. success: function(response){
  39. capabilities = new OpenLayers.Format.WPSCapabilities().read(
  40. response.responseText
  41. );
  42. var dropdown = document.getElementById("processes");
  43. var offerings = capabilities.processOfferings, option;
  44. // populate the dropdown
  45. for (var p in offerings) {
  46. option = document.createElement("option");
  47. option.innerHTML = offerings[p].identifier;
  48. option.value = p;
  49. dropdown.appendChild(option);
  50. }
  51. }
  52. });
  53. }
  54. // using OpenLayers.Format.WPSDescribeProcess to get information about a
  55. // process
  56. function describeProcess() {
  57. var selection = this.options[this.selectedIndex].value;
  58. OpenLayers.Request.GET({
  59. url: wps,
  60. params: {
  61. "SERVICE": "WPS",
  62. "REQUEST": "DescribeProcess",
  63. "VERSION": capabilities.version,
  64. "IDENTIFIER": selection
  65. },
  66. success: function(response) {
  67. process = new OpenLayers.Format.WPSDescribeProcess().read(
  68. response.responseText
  69. ).processDescriptions[selection];
  70. buildForm();
  71. }
  72. });
  73. }
  74. // dynamically create a form from the process description
  75. function buildForm() {
  76. document.getElementById("abstract").innerHTML = process["abstract"];
  77. document.getElementById("input").innerHTML = "<h3>Input:</h3>";
  78. document.getElementById("output").innerHTML = "";
  79. var inputs = process.dataInputs, supported = true,
  80. sld = "text/xml; subtype=sld/1.0.0",
  81. input;
  82. for (var i=0,ii=inputs.length; i<ii; ++i) {
  83. input = inputs[i];
  84. if (input.complexData) {
  85. var formats = input.complexData.supported.formats;
  86. if (formats["application/wkt"]) {
  87. addWKTInput(input);
  88. } else if (formats["text/xml; subtype=wfs-collection/1.0"]) {
  89. addWFSCollectionInput(input);
  90. } else if (formats["image/tiff"]) {
  91. addRasterInput(input);
  92. } else if (formats[sld]) {
  93. addXMLInput(input, sld);
  94. } else {
  95. supported = false;
  96. }
  97. } else if (input.boundingBoxData) {
  98. addBoundingBoxInput(input);
  99. } else if (input.literalData) {
  100. addLiteralInput(input);
  101. } else {
  102. supported = false;
  103. }
  104. if (input.minOccurs > 0) {
  105. document.getElementById("input").appendChild(document.createTextNode("* "));
  106. }
  107. }
  108. if (supported) {
  109. var executeButton = document.createElement("button");
  110. executeButton.innerHTML = "Execute";
  111. document.getElementById("input").appendChild(executeButton);
  112. executeButton.onclick = execute;
  113. } else {
  114. document.getElementById("input").innerHTML = '<span class="notsupported">' +
  115. "Sorry, the WPS builder does not support the selected process." +
  116. "</span>";
  117. }
  118. }
  119. // helper function to dynamically create a textarea for geometry (WKT) data
  120. // input
  121. function addWKTInput(input, previousSibling) {
  122. var name = input.identifier;
  123. var container = document.getElementById("input");
  124. var label = document.createElement("label");
  125. label["for"] = name;
  126. label.title = input["abstract"];
  127. label.innerHTML = name + " (select feature, then click field):";
  128. previousSibling && previousSibling.nextSibling ?
  129. container.insertBefore(label, previousSibling.nextSibling) :
  130. container.appendChild(label);
  131. var field = document.createElement("textarea");
  132. field.onclick = function () {
  133. if (layer.selectedFeatures.length) {
  134. this.innerHTML = new OpenLayers.Format.WKT().write(
  135. layer.selectedFeatures[0]
  136. );
  137. }
  138. createCopy(input, this, addWKTInput);
  139. };
  140. field.onblur = function() {
  141. input.data = field.value ? {
  142. complexData: {
  143. mimeType: "application/wkt",
  144. value: this.value
  145. }
  146. } : undefined;
  147. };
  148. field.title = input["abstract"];
  149. field.id = name;
  150. previousSibling && previousSibling.nextSibling ?
  151. container.insertBefore(field, previousSibling.nextSibling.nextSibling) :
  152. container.appendChild(field);
  153. }
  154. // helper function for xml input
  155. function addXMLInput(input, type) {
  156. var name = input.identifier;
  157. var field = document.createElement("input");
  158. field.title = input["abstract"];
  159. field.value = name + " (" + type + ")";
  160. field.onblur = function() {
  161. input.data = field.value ? {
  162. complexData: {
  163. mimeType: type,
  164. value: this.value
  165. }
  166. } : undefined;
  167. };
  168. document.getElementById("input").appendChild(field);
  169. }
  170. // helper function to dynamically create a WFS collection reference input
  171. function addWFSCollectionInput(input) {
  172. var name = input.identifier;
  173. var field = document.createElement("input");
  174. field.title = input["abstract"];
  175. field.value = name + " (layer on demo server)";
  176. addValueHandlers(field, function() {
  177. input.reference = field.value ? {
  178. mimeType: "text/xml; subtype=wfs-collection/1.0",
  179. href: "http://geoserver/wfs",
  180. method: "POST",
  181. body: {
  182. wfs: {
  183. version: "1.0.0",
  184. outputFormat: "GML2",
  185. featureType: field.value
  186. }
  187. }
  188. } : undefined;
  189. });
  190. document.getElementById("input").appendChild(field);
  191. }
  192. // helper function to dynamically create a raster (GeoTIFF) url input
  193. function addRasterInput(input) {
  194. var name = input.identifier;
  195. var field = document.createElement("input");
  196. field.title = input["abstract"];
  197. var url = window.location.href.split("?")[0];
  198. field.value = url.substr(0, url.lastIndexOf("/")+1) + "data/tazdem.tiff";
  199. document.getElementById("input").appendChild(field);
  200. (field.onblur = function() {
  201. input.reference = {
  202. mimeType: "image/tiff",
  203. href: field.value,
  204. method: "GET"
  205. };
  206. })();
  207. }
  208. // helper function to dynamically create a bounding box input
  209. function addBoundingBoxInput(input) {
  210. var name = input.identifier;
  211. var field = document.createElement("input");
  212. field.title = input["abstract"];
  213. field.value = "left,bottom,right,top (EPSG:4326)";
  214. document.getElementById("input").appendChild(field);
  215. addValueHandlers(field, function() {
  216. input.boundingBoxData = {
  217. projection: "EPSG:4326",
  218. bounds: OpenLayers.Bounds.fromString(field.value)
  219. };
  220. });
  221. }
  222. // helper function to create a literal input textfield or dropdown
  223. function addLiteralInput(input, previousSibling) {
  224. var name = input.identifier;
  225. var container = document.getElementById("input");
  226. var anyValue = input.literalData.anyValue;
  227. // anyValue means textfield, otherwise we create a dropdown
  228. var field = document.createElement(anyValue ? "input" : "select");
  229. field.id = name;
  230. field.title = input["abstract"];
  231. previousSibling && previousSibling.nextSibling ?
  232. container.insertBefore(field, previousSibling.nextSibling) :
  233. container.appendChild(field);
  234. if (anyValue) {
  235. var dataType = input.literalData.dataType;
  236. field.value = name + (dataType ? " (" + dataType + ")" : "");
  237. addValueHandlers(field, function() {
  238. input.data = field.value ? {
  239. literalData: {
  240. value: field.value
  241. }
  242. } : undefined;
  243. createCopy(input, field, addLiteralInput);
  244. });
  245. } else {
  246. var option;
  247. option = document.createElement("option");
  248. option.innerHTML = name;
  249. field.appendChild(option);
  250. for (var v in input.literalData.allowedValues) {
  251. option = document.createElement("option");
  252. option.value = v;
  253. option.innerHTML = v;
  254. field.appendChild(option);
  255. }
  256. field.onchange = function() {
  257. createCopy(input, field, addLiteralInput);
  258. input.data = this.selectedIndex ? {
  259. literalData: {
  260. value: this.options[this.selectedIndex].value
  261. }
  262. } : undefined;
  263. };
  264. }
  265. }
  266. // if maxOccurs is > 1, this will add a copy of the field
  267. function createCopy(input, field, fn) {
  268. if (input.maxOccurs && input.maxOccurs > 1 && !field.userSelected) {
  269. // add another copy of the field - we don't check maxOccurs
  270. field.userSelected = true;
  271. var newInput = OpenLayers.Util.extend({}, input);
  272. // we recognize copies by the occurrence property
  273. newInput.occurrence = (input.occurrence || 0) + 1;
  274. process.dataInputs.push(newInput);
  275. fn(newInput, field);
  276. }
  277. }
  278. // helper function for adding events to form fields
  279. function addValueHandlers(field, onblur) {
  280. field.onclick = function() {
  281. if (!this.initialValue) {
  282. this.initialValue = this.value;
  283. this.value = "";
  284. }
  285. };
  286. field.onblur = function() {
  287. if (!this.value) {
  288. this.value = this.initialValue;
  289. delete this.initialValue;
  290. }
  291. onblur.apply(this, arguments);
  292. };
  293. }
  294. // execute the process
  295. function execute() {
  296. var output = process.processOutputs[0];
  297. var input;
  298. // remove occurrences that the user has not filled out
  299. for (var i=process.dataInputs.length-1; i>=0; --i) {
  300. input = process.dataInputs[i];
  301. if ((input.minOccurs === 0 || input.occurrence) && !input.data && !input.reference) {
  302. OpenLayers.Util.removeItem(process.dataInputs, input);
  303. }
  304. }
  305. process.responseForm = {
  306. rawDataOutput: {
  307. identifier: output.identifier
  308. }
  309. };
  310. if (output.complexOutput && output.complexOutput.supported.formats["application/wkt"]) {
  311. process.responseForm.rawDataOutput.mimeType = "application/wkt";
  312. }
  313. OpenLayers.Request.POST({
  314. url: wps,
  315. data: new OpenLayers.Format.WPSExecute().write(process),
  316. success: showOutput
  317. });
  318. }
  319. // add the process's output to the page
  320. function showOutput(response) {
  321. var result = document.getElementById("output");
  322. result.innerHTML = "<h3>Output:</h3>";
  323. var features;
  324. var contentType = response.getResponseHeader("Content-Type");
  325. if (contentType == "application/wkt") {
  326. features = new OpenLayers.Format.WKT().read(response.responseText);
  327. } else if (contentType == "text/xml; subtype=wfs-collection/1.0") {
  328. features = new OpenLayers.Format.WFST.v1_0_0().read(response.responseText);
  329. }
  330. if (features && (features instanceof OpenLayers.Feature.Vector || features.length)) {
  331. layer.addFeatures(features);
  332. result.innerHTML += "The result should also be visible on the map.";
  333. }
  334. result.innerHTML += "<textarea>" + response.responseText + "</textarea>";
  335. }