WpsProcess.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. // class Type_WpsProcess
  3. // class Type_WpsProcessInput
  4. class Type_WpsProcess {
  5. var $_data = [];
  6. // @see http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd
  7. // wps:ProcessDescriptions / ProcessDescription [ @minOccurs=1, @maxOccurs=unbounded ]
  8. // ProcessDescription / ows:Identifier [ @minOccurs=1, @maxOccurs=1 ]
  9. // ProcessDescription / ows:Title [ @minOccurs=1, @maxOccurs=1 ]
  10. // ProcessDescription / ows:Abstract [ @minOccurs=0, @maxOccurs=1 ]
  11. // ProcessDescription / ows:Metadata [ @xlink:title, @xlink:type, @xlink:href, @about ]
  12. // ProcessDescription / DataInputs / Input [ @minOccurs=1, @maxOccurs=unbounded ]
  13. // ProcessDescription / ProcessOutputs / Output [ @minOccurs=1, @maxOccurs=unbounded ]
  14. // Input / ows:Identifier [ @minOccurs=1, @maxOccurs=1 ]
  15. // Input / ows:Title [ @minOccurs=1, @maxOccurs=1 ]
  16. // Input / ows:Abstract [ @minOccurs=0, @maxOccurs=1 ]
  17. // Input / ( LiteralData | ComplexData | BoundingBoxData )
  18. // Input / ( LiteralData )
  19. // Input / ( LiteralData ) / ows:DataType [ @minOccurs=0, @maxOccurs=1, @ows:reference ]
  20. // Input / ( LiteralData ) / UOMs [ @minOccurs=0, @maxOccurs=1 ]
  21. // Input / ( LiteralData ) / ( ows:AllowedValues | ows:AnyValue | ValuesReference )
  22. // Input / ( LiteralData ) / ( ows:AllowedValues )
  23. // Input / ( LiteralData ) / ( ows:AllowedValues ) / ( ows:Value | ows:Range )
  24. // Input / ( LiteralData ) / ( ows:AllowedValues ) / ( ows:Value )
  25. // Input / ( LiteralData ) / ( ows:AllowedValues ) / ( ows:Range ) / [ @ows:MinimumValue, @ows:MaximumValue, @ows:Spacing ]
  26. // Input / ( LiteralData ) / ( ows:AnyValue )
  27. // Input / ( LiteralData ) / ( ValuesReference ) / [ @ows:reference, valuesForm anyURI ]
  28. // Input / ( LiteralData ) / DefaultValue [ @minOccurs=0, @maxOccurs=1 ]
  29. // Input / ( ComplexData )
  30. // Input / ( ComplexData ) / Default / Format [ @minOccurs=1, @maxOccurs=1 ]
  31. // Input / ( ComplexData ) / Supported / Format [ @minOccurs=1, @maxOccurs=unbounded ]
  32. // Input / ( ComplexData ) / @maximumMegabytes integer
  33. // Input / ( BoundingBoxData )
  34. // Input / ( BoundingBoxData ) / Default / CRS anyURI
  35. // Input / ( BoundingBoxData ) / Supported / CRS anyURI
  36. // Output / ows:Identifier
  37. // Output / ows:Title
  38. // Output / ( ComplexOutput | LiteralOutput | BoundingBoxOutput )
  39. // Output / ( ComplexOutput )
  40. // Output / ( ComplexOutput ) / Default / Format [ @minOccurs=1, @maxOccurs=1 ]
  41. // Output / ( ComplexOutput ) / Supported / Format [ @minOccurs=1, @maxOccurs=unbounded ]
  42. // Output / ( LiteralOutput )
  43. // Output / ( LiteralOutput ) / ows:DataType [ @minOccurs=0, @maxOccurs=1 ]
  44. // Output / ( LiteralOutput ) / UOMs [ @minOccurs=0, @maxOccurs=1 ]
  45. // Output / ( BoundingBoxOutput )
  46. // Output / ( BoundingBoxData ) / Default / CRS anyURI
  47. // Output / ( BoundingBoxData ) / Supported / CRS anyURI
  48. // Format / MimeType string [ @minOccurs=1, @maxOccurs=1 ]
  49. // Format / Encoding AnyURI [ @minOccurs=0, @maxOccurs=1 ]
  50. // Format / Schema AnyURI [ @minOccurs=0, @maxOccurs=1 ]
  51. // UOMs / ( Default / ows:UOM | Supported / ows:UOM [ @minOccurs=1, @maxOccurs=unbounded ] )
  52. // ows:UOM string [ @ows:reference ]
  53. // @ows:reference - URI (local or remote) or URN (like ogc:*, xs:*)
  54. // example: Output / LiteralOutput / <ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#float">float</ows:DataType>
  55. // example: Input / LiteralData:
  56. // <ows:DataType ows:reference="xs:float">float</ows:DataType>
  57. // <ows:AnyValue/>
  58. // <DefaultValue>1.01</DefaultValue>
  59. // Type_WpsProcessOutput: [ 'MimeType' => text/xml, 'Encoding' => base64, 'Schema' => http://foo.bar/gml/3.1.0/polygon.xsd ]
  60. // supportedOutput: [ Type_WpsProcessOutput, ... ]
  61. // [ 'MimeType' => "text/xml; subtype=wfs-collection/1.0" ],
  62. // [ 'MimeType' => "text/xml; subtype=wfs-collection/1.1" ],
  63. // [ 'MimeType' => "application/json" ],
  64. // [ 'MimeType' => "application/wfs-collection-1.0" ],
  65. // [ 'MimeType' => "application/wfs-collection-1.1" ],
  66. // [ 'MimeType' => "application/zip" ],
  67. static function validate($conf) {
  68. if (empty($conf['identifier'])) throw new Exception("WpsProcess parse error - missing input identifier");
  69. if (empty($conf['title'])) throw new Exception("WpsProcess parse error - missing input title for '{$conf['identifier']}'");
  70. }
  71. static function build($conf) { // @return Type_WpsProcess or throw Exception
  72. return self::buildProcess($conf);
  73. }
  74. static function buildProcess($conf) { // @return Type_WpsProcess or throw Exception
  75. self::validate($conf);
  76. $wpsProcess = new Type_WpsProcess();
  77. $wpsProcess->identifier = $conf['identifier'];
  78. $wpsProcess->title = $conf['title'];
  79. $wpsProcess->description = $conf['description'];
  80. $wpsProcess->processVersion = V::get('processVersion', '1.0.0', $conf);
  81. $wpsProcess->dataInputs = array_map([ self, 'buildInput' ], $conf['dataInputs']);
  82. // $wpsProcess->dataInputs = array_map(function ($input) {
  83. // return ($input instanceof Type_WpsProcessInput) ? $input : Type_WpsProcessInput::build($input);
  84. $wpsProcess->defaultOutput = $conf['defaultOutput'];
  85. $wpsProcess->supportedOutput = $conf['supportedOutput'];
  86. return $wpsProcess;
  87. }
  88. static function buildInput($input) { // @return Type_WpsProcessInput or throw Exception
  89. return ($input instanceof Type_WpsProcessInput) ? $input : Type_WpsProcessInput::build($input);
  90. }
  91. function __isset($name) {
  92. return (array_key_exists($name, $this->_data));
  93. }
  94. function __get($name) {
  95. if (array_key_exists($name, $this->_data)) {
  96. return $this->_data[$name];
  97. }
  98. return null;
  99. }
  100. function __set($name, $value) {
  101. $this->_data[$name] = $value;
  102. }
  103. function toArray() {
  104. return $this->_data;
  105. }
  106. function __toString() {
  107. return str_replace('"', '',
  108. str_replace([ '{', '}', '":', ',"' ], [ '{ ', ' }', ': ', ', ' ], json_encode($this->_data))
  109. );
  110. }
  111. function toWpsJson() {
  112. return [
  113. 'processVersion' => V::get('processVersion', '1.0.0', $this->_data),
  114. 'statusSupported' => false,
  115. 'storeSupported' => false,
  116. 'identifier' => $this->_data['identifier'],
  117. 'title' => $this->_data['title'],
  118. 'abstract' => V::get('description', '', $this->_data),
  119. 'dataInputs' => array_map(function ($input) {
  120. return $input->toWpsJson();
  121. }, $this->_data['dataInputs']),
  122. 'processOutputs' => [ // TODO: multiple outputs?
  123. [
  124. 'identifier' => "result",
  125. 'title' => "result",
  126. 'defaultOutput' => $this->_data['defaultOutput'],
  127. 'supportedOutput' => $this->_data['supportedOutput'],
  128. ],
  129. ]
  130. ];
  131. // { // expected json structure:
  132. // "processVersion": "",
  133. // "statusSupported": false,
  134. // "storeSupported": false,
  135. // "identifier": "p5:selectFeature",
  136. // "title": "Select feature",
  137. // "abstract": "",
  138. // "dataInputs": [{
  139. // "maxOccurs": 1,
  140. // "minOccurs": 1,
  141. // "title": "Feature typeName",
  142. // "abstract": "Feature typeName eg. default_db/PROBLEMS",
  143. // "literalData": {
  144. // "anyValue": true
  145. // }
  146. // }, {
  147. // "maxOccurs": null,
  148. // "minOccurs": 1,
  149. // "title": "Feature primaryKey",
  150. // "abstract": "Feature primaryKey",
  151. // "literalData": {
  152. // "anyValue": true
  153. // }
  154. // }],
  155. // "processOutputs": [{
  156. // "identifier": "result",
  157. // "title": "result",
  158. // "complexOutput": {
  159. // "default": {
  160. // "formats": {
  161. // "text/xml; subtype=wfs-collection/1.0": true
  162. // }
  163. // },
  164. // "supported": {
  165. // "formats": {
  166. // "text/xml; subtype=wfs-collection/1.0": true,
  167. // "text/xml; subtype=wfs-collection/1.1": true,
  168. // "application/json": true
  169. // }
  170. // }
  171. // }
  172. // }]
  173. // }
  174. }
  175. }
  176. class Type_WpsProcessInput {
  177. var $_data = []; // $_data['dataType'] === $this->dataType
  178. // $_data['dataType']: ( 'literal' | 'complex' | 'boundingBox' )
  179. static function validate($conf) {
  180. if (empty($conf['identifier'])) throw new Exception("WpsProcessInput parse error - missing input identifier");
  181. if (empty($conf['title'])) throw new Exception("WpsProcessInput parse error - missing input title for '{$conf['identifier']}'");
  182. switch ($conf['dataType']) {
  183. case 'literal': break;
  184. case 'complex': break;
  185. case 'boundingBox': break;
  186. default: throw new Exception("WpsProcessInput parse error - missing input type for '{$conf['identifier']}'");
  187. }
  188. }
  189. static function build($conf) { // @return Type_WpsProcessInput or throw Exception
  190. return self::buildInput($conf);
  191. }
  192. static function buildInput($conf) { // @return Type_WpsProcessInput or throw Exception
  193. self::validate($conf);
  194. $input = new Type_WpsProcessInput();
  195. $input->identifier = $conf['identifier'];
  196. $input->title = $conf['title'];
  197. $input->description = V::get('description', "", $conf);
  198. $input->maxOccurs = V::get('maxOccurs', 1, $conf, 'maxOccurs');
  199. $input->minOccurs = V::get('minOccurs', 1, $conf, 'minOccurs');
  200. $input->dataType = $conf['dataType']; // 'literal' | 'complex' | 'boundingBox'
  201. $input->xsdType = V::get('xsdType', '', $conf);
  202. return $input;
  203. }
  204. function __isset($name) {
  205. return (array_key_exists($name, $this->_data));
  206. }
  207. function __get($name) {
  208. if (array_key_exists($name, $this->_data)) {
  209. return $this->_data[$name];
  210. }
  211. return null;
  212. }
  213. function __set($name, $value) {
  214. $this->_data[$name] = $value;
  215. }
  216. function toArray() {
  217. return $this->_data;
  218. }
  219. function __toString() {
  220. return str_replace('"', '',
  221. str_replace([ '{', '}', '":', ',"' ], [ '{ ', ' }', ': ', ', ' ], json_encode($this->_data))
  222. );
  223. }
  224. function toWpsJson() {
  225. return array_merge(
  226. [
  227. 'identifier' => $this->_data['identifier'],
  228. 'title' => $this->_data['title'],
  229. 'abstract' => $this->_data['description'],
  230. 'maxOccurs' => $this->_data['maxOccurs'],
  231. 'minOccurs' => $this->_data['minOccurs'],
  232. ],
  233. ('literal' === $this->dataType) ? [ 'literalData' => $this->_data['literalData'] ] : [],
  234. ('complex' === $this->dataType) ? [ 'complexData' => $this->_data['complexData'] ] : [],
  235. ('boundingBox' === $this->dataType) ? [ 'boundingBoxData' => $this->_data['boundingBoxData'] ] : []
  236. );
  237. }
  238. }