|
@@ -66,121 +66,6 @@ class Api_WfsServerBase {
|
|
|
return $acl;
|
|
return $acl;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * @param $_GET [ , POST Body - XML file ]
|
|
|
|
|
- * @return array $args
|
|
|
|
|
- * TODO: get $acl and check more restrictions
|
|
|
|
|
- */
|
|
|
|
|
- public function parseGetFeatureArgsFromRequest() {
|
|
|
|
|
- $rawArgs = $_GET;// $_REQUEST; ($_POST values not allowed, only xml in post body)
|
|
|
|
|
- $args = array();
|
|
|
|
|
- $args['xsd:type'] = null;// @from: TYPENAME, typeName (typename)
|
|
|
|
|
- $args['typePrefix'] = null;// @from: TYPENAME, typeName (typename)
|
|
|
|
|
- $args['typeName'] = null;// @from: TYPENAME, typeName (typename)
|
|
|
|
|
- $args['srsname'] = null;// @from: SRSNAME (srsname)
|
|
|
|
|
- $args['limit'] = 0;// @from: MAXFEATURES, maxFeatures, COUNT (maxfeatures, count)
|
|
|
|
|
- $args['offset'] = 0;// @from: startIndex (startindex, count)
|
|
|
|
|
- $args['ogc:filter'] = null;// @from: FILTER, Filter (filter)
|
|
|
|
|
- $args['sortBy'] = null;// @from: sortBy (sortby)
|
|
|
|
|
- $args['wfs:propertyName'] = null;// @from: propertyName (propertyname)
|
|
|
|
|
- $args['filterFields'] = array();// array of field names to show - @from: propertyName
|
|
|
|
|
- $args['resultType'] = null;// @from: resultType (resulttype)
|
|
|
|
|
- $args['bbox'] = null;// @from: BBOX (bbox)
|
|
|
|
|
- $args['wfs:featureID'] = null;// @from: featureID, featureId (featureid)
|
|
|
|
|
- $args['primaryKey'] = null;// primaryKey type - @from: featureID or $req[primaryKey]
|
|
|
|
|
- $args['xlink'] = V::get('xlink', '', $rawArgs); // xlink = "https://biuro.biall-net.pl/wfs/default_db/CRM_PROCES#PROCES.100" but with '#' replaced with '/'
|
|
|
|
|
- $args['outputBlobFormat'] = V::get('outputBlobFormat', 'base64', $rawArgs); // how to print blob fields ('base64', 'link') - default base64
|
|
|
|
|
- $args['resolve'] = V::get('resolve', '', $rawArgs);
|
|
|
|
|
- $args['resolveDepth'] = V::get('resolveDepth', 0, $rawArgs, 'int'); // TODO: if ('*' === resolveDepth) - recurse resolve
|
|
|
|
|
-
|
|
|
|
|
- $lowerArgs = array(); foreach ($rawArgs as $name => $value) $lowerArgs[ strtolower($name) ] = trim($value);
|
|
|
|
|
-
|
|
|
|
|
- $args['xsd:type'] = V::get('typename', '', $lowerArgs);
|
|
|
|
|
- $exType = explode(':', $args['xsd:type']);
|
|
|
|
|
- if (count($exType) != 2) throw new HttpException("Wrong param TYPENAME", 400);
|
|
|
|
|
- $args['typePrefix'] = $exType[0];
|
|
|
|
|
- $args['typeName'] = $exType[1];
|
|
|
|
|
-
|
|
|
|
|
- $args['srsname'] = V::get('SRSNAME', '', $lowerArgs);// eg. EPSG:4326
|
|
|
|
|
-
|
|
|
|
|
- $args['limit'] = V::get('maxfeatures', $args['limit'], $lowerArgs, 'int');
|
|
|
|
|
- $args['limit'] = V::get('count', $args['limit'], $lowerArgs, 'int');
|
|
|
|
|
- $defaultFeaturesLimit = ('biuro.biall-net.pl' == V::get('SERVER_NAME', '', $_SERVER)) ? 50000 : 10000;
|
|
|
|
|
- if ($args['limit'] <= 0) $args['limit'] = $defaultFeaturesLimit;// default limit
|
|
|
|
|
-
|
|
|
|
|
- $args['offset'] = V::get('startindex', 0, $lowerArgs, 'int');
|
|
|
|
|
-
|
|
|
|
|
- $args['ogc:filter'] = urldecode(V::get('filter', '', $lowerArgs));
|
|
|
|
|
- if (empty($args['ogc:filter'])) {// read ogc:Filter from POST body if not defined in GET
|
|
|
|
|
- $reqBody = Request::getRequestBody();
|
|
|
|
|
- if (!empty($reqBody)) {
|
|
|
|
|
- $parsedRequest = $this->parseOgcFilterRequest($reqBody);
|
|
|
|
|
- DBG::log($parsedRequest, 'array', 'parsed ogc query request');
|
|
|
|
|
- if (!empty($parsedRequest['ogc:Filter'])) $args['ogc:filter'] = $parsedRequest['ogc:Filter'];
|
|
|
|
|
- if (!empty($parsedRequest['wfs:PropertyName'])) {
|
|
|
|
|
- foreach ($parsedRequest['wfs:PropertyName'] as $fieldXpath) {
|
|
|
|
|
- $args['filterFields'][] = $fieldXpath;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } else if ($args['resolve'] && $args['resolveDepth'] > 0) {
|
|
|
|
|
- $args['filterFields'][] = '*' . str_repeat("/*", $args['resolveDepth'] - 1);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $args['sortBy'] = V::get('sortby', '', $lowerArgs);// TODO: split to array of array(fieldName, (asc | desc))
|
|
|
|
|
-
|
|
|
|
|
- $args['wfs:propertyName'] = trim(V::get('propertyname', '', $lowerArgs));// TODO: fields to show - split by ','
|
|
|
|
|
- if (strlen($args['wfs:propertyName']) > 0) {
|
|
|
|
|
- $exFields = explode(',', $args['wfs:propertyName']);
|
|
|
|
|
- foreach ($exFields as $fieldName) {
|
|
|
|
|
- $fieldName = trim($fieldName);
|
|
|
|
|
- if (!empty($fieldName)) $args['filterFields'][] = $fieldName;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $args['resultType'] = V::get('resulttype', '', $lowerArgs);
|
|
|
|
|
-
|
|
|
|
|
- $args['bbox'] = V::get('bbox', '', $lowerArgs);
|
|
|
|
|
- if (!empty($args['bbox'])) {
|
|
|
|
|
- // BBOX may have EPSG at then end - example: ",EPSG:4326"
|
|
|
|
|
- $num = "\d+.?\d*?";// "\d+(.\d+)?"
|
|
|
|
|
- if (!preg_match("/^({$num}),({$num}),({$num}),({$num})(\,EPSG:\d+)?$/", $args['bbox'], $matches)) throw new Exception("Illegal BBOX format");
|
|
|
|
|
- // QGIS send BBOX in correct order: 54.23580872176457,18.46844302390853,54.25220902538883,18.492990600812696
|
|
|
|
|
- // first number should not be smaller then second
|
|
|
|
|
- // example $matches:
|
|
|
|
|
- // [0] => 18.492990600812696,54.23580872176457,18.46844302390853,54.25220902538883
|
|
|
|
|
- // [1] => 18.492990600812696
|
|
|
|
|
- // [2] => 54.23580872176457
|
|
|
|
|
- // [3] => 18.46844302390853
|
|
|
|
|
- // [4] => 54.25220902538883
|
|
|
|
|
- // (optional) EPGS
|
|
|
|
|
- $bboxPoints = ($matches[1] > $matches[2])
|
|
|
|
|
- ? [ $matches[1], $matches[2], $matches[3], $matches[4] ]
|
|
|
|
|
- : [ $matches[2], $matches[3], $matches[4], $matches[1] ];
|
|
|
|
|
-
|
|
|
|
|
- $args['bbox'] = implode(",", $bboxPoints);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $args['wfs:featureID'] = V::get('featureid', null, $lowerArgs);// TODO: allow multiply feature id (csv)
|
|
|
|
|
- if ($args['wfs:featureID']) {
|
|
|
|
|
- $dotPos = strpos($args['wfs:featureID'], '.');
|
|
|
|
|
- if (!$dotPos) throw new Exception("Wrong param featureID");
|
|
|
|
|
- if ($args['typeName'] != substr($args['wfs:featureID'], 0, $dotPos)) throw new Exception("Wrong typeName in param featureID");
|
|
|
|
|
- $args['primaryKey'] = substr($args['wfs:featureID'], $dotPos + 1);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $pk = V::get('primarykey', '', $lowerArgs);
|
|
|
|
|
- if ($pk) {
|
|
|
|
|
- $args['primaryKey'] = $pk;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(DBG::isActive() && V::get('DBG', 0, $_GET)){ echo "\$lowerArgs:";print_r($lowerArgs); }
|
|
|
|
|
- if(DBG::isActive() && V::get('DBG', 0, $_GET)){ echo "\$args:";print_r($args); }
|
|
|
|
|
-
|
|
|
|
|
- return $args;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
public function _getXmlSchemaLocation() {
|
|
public function _getXmlSchemaLocation() {
|
|
|
$schemaLocations = array();
|
|
$schemaLocations = array();
|
|
|
//$schemaLocations[] = 'http://www.opengis.net/wfs http://webgis.regione.sardegna.it:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd';// @from http://webgis.regione.sardegna.it/geoserver/ows?service=WFS&request=GetCapabilities
|
|
//$schemaLocations[] = 'http://www.opengis.net/wfs http://webgis.regione.sardegna.it:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd';// @from http://webgis.regione.sardegna.it/geoserver/ows?service=WFS&request=GetCapabilities
|
|
@@ -1303,83 +1188,4 @@ if($DBG){echo 'L.' . __LINE__ . ' $validateConvertedTransactionXsdString:';print
|
|
|
$this->_logger->DBG($reqLog, $lineNr, $funName, $className);
|
|
$this->_logger->DBG($reqLog, $lineNr, $funName, $className);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public function parseOgcFilterRequest($requestOgcFilter) {
|
|
|
|
|
- // GetFeature: @maxFeatures, @traverseXlinkDepth, @traverseXlinkExpiry
|
|
|
|
|
- // \-- (1..) wfs:Query: @typeName
|
|
|
|
|
- // \--- (0..) ---: wfs:PropertyName
|
|
|
|
|
- // : wfs:XlinkPropertyName
|
|
|
|
|
- // : ogc:Function
|
|
|
|
|
- // ogc:Filter
|
|
|
|
|
- // ogc:SortBy
|
|
|
|
|
- // \--- (1..) ogc:SortProperty
|
|
|
|
|
- // \---: ogc:PropertyName
|
|
|
|
|
- // : ogc:SortOrder ( DESC / ASC )
|
|
|
|
|
- // <ogc:SortBy>
|
|
|
|
|
- // <ogc:SortProperty>
|
|
|
|
|
- // <ogc:PropertyName>ASTA</ogc:PropertyName>
|
|
|
|
|
- // <ogc:SortOrder>ASC</ogc:SortOrder>
|
|
|
|
|
- // </ogc:SortProperty>
|
|
|
|
|
- // </ogc:SortBy>
|
|
|
|
|
-
|
|
|
|
|
- if (empty($requestOgcFilter)) return '';
|
|
|
|
|
- $requestXml = new DOMDocument();
|
|
|
|
|
- $requestXml->loadXml($requestOgcFilter);
|
|
|
|
|
- $rootNode = $requestXml->documentElement;
|
|
|
|
|
- // if ($rootNode->getAttribute('resolve'))
|
|
|
|
|
- DBG::log([$rootNode->getAttribute('resolve'), $rootNode->getAttribute('resolveDepth')], 'array', "TODO: use wfs:GetFeature @resolve, @resolveDepth");
|
|
|
|
|
- $nodesQuery = [];
|
|
|
|
|
- foreach ($requestXml->getElementsByTagNameNS('http://www.opengis.net/wfs', 'Query') as $element) {
|
|
|
|
|
- DBG::log($element->nodeName, 'array', "main loop - wfs:Query");
|
|
|
|
|
- $nodesQuery[] = $element;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (empty($nodesQuery)) { // legacy - try to find 'ogc:Filter'
|
|
|
|
|
- $tagsFilter = [];
|
|
|
|
|
- foreach ($requestXml->getElementsByTagNameNS('http://www.opengis.net/ogc', 'Filter') as $element) {
|
|
|
|
|
- DBG::log($element->nodeName, 'array', "loop element (0 * wfs:Query)");
|
|
|
|
|
- $tagsFilter[] = $requestXml->saveXML($element);
|
|
|
|
|
- }
|
|
|
|
|
- DBG::log($tagsFilter, 'array', "\$tagsFilter (0 * wfs:Query)");
|
|
|
|
|
- return [
|
|
|
|
|
- 'ogc:Filter' => (!empty($tagsFilter))
|
|
|
|
|
- ? reset($tagsFilter) // TODO: only one ogc:Filter allowed
|
|
|
|
|
- : ''
|
|
|
|
|
- ];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (1 === count($nodesQuery)) {
|
|
|
|
|
- $tagsFilter = [];
|
|
|
|
|
- foreach ($requestXml->getElementsByTagNameNS('http://www.opengis.net/ogc', 'Filter') as $element) {
|
|
|
|
|
- // DBG::log($element->nodeName, 'array', "loop ogc:Filter (1 * wfs:Query)");
|
|
|
|
|
- $tagsFilter[] = $requestXml->saveXML($element);
|
|
|
|
|
- }
|
|
|
|
|
- DBG::log($tagsFilter, 'array', "\$tagsFilter (1 * wfs:Query)");
|
|
|
|
|
- $tagsWfsPropertyName = [];
|
|
|
|
|
- foreach ($requestXml->getElementsByTagNameNS('http://www.opengis.net/wfs', 'PropertyName') as $element) {
|
|
|
|
|
- // DBG::log($element->nodeValue, 'array', "loop wfs:PropertyName (1 * wfs:Query)");
|
|
|
|
|
- if ($element->getAttribute('resolve')) DBG::log([$element->getAttribute('resolve'), $element->getAttribute('resolveDepth'), $element->getAttribute('resolvePath')], 'array', "TODO: use wfs:PropertyName @resolve, @resolveDepth, @resolvePath");
|
|
|
|
|
- $value = $element->nodeValue;
|
|
|
|
|
- if (in_array($element->getAttribute('resolve'), ['all', 'local', 'remote'])) {
|
|
|
|
|
- $depth = $element->getAttribute('resolveDepth');
|
|
|
|
|
- if ('*' !== substr($value, -1)) { // TODO: propertyName is not regex
|
|
|
|
|
- if ('*' === $depth) $value .= "/**"; // TODO: resolveDepth="*" - resolve all
|
|
|
|
|
- else if ((int)$depth > 0) $value .= str_repeat("/*", $depth);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- $tagsWfsPropertyName[] = $value;
|
|
|
|
|
- }
|
|
|
|
|
- DBG::log($tagsWfsPropertyName, 'array', "\$tagsWfsPropertyName (1 * wfs:Query)");
|
|
|
|
|
- return array_filter([
|
|
|
|
|
- 'ogc:Filter' => (!empty($tagsFilter))
|
|
|
|
|
- ? reset($tagsFilter)
|
|
|
|
|
- : '',
|
|
|
|
|
- 'wfs:PropertyName' => (!empty($tagsWfsPropertyName))
|
|
|
|
|
- ? $tagsWfsPropertyName
|
|
|
|
|
- : '',
|
|
|
|
|
- ], function ($value) { return !empty($value); });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- throw new Exception("Not imeplemented multiple ogc:Query"); // multiple ogc:Query require ogc:Query/@typeName
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
}
|
|
}
|