_parseTransactionXmlStruct($reqContent, $tags); } throw new Api_WfsException("TODO ... L." . __LINE__, 501); $xml = new SimpleXMLElement($reqContent); $namespaces = $xml->getNameSpaces(true); if ('Transaction' == $xml->getName()) { $this->_parseTransactionXml($xml); } else { throw new Api_WfsException("Not Implemented " . htmlspecialchars($xml->getName()), 501); } } public function getFeatureAction() { $args = $this->parseGetFeatureArgsFromRequest(); // TODO: if ('hits' == $args['resultType']) ... return $this->getFeatures($args); } public function getFeatures($args) { $DBG = (V::get('DBG_GEO', '', $_GET) > 0);// TODO: Profiler $type = $args['typeName']; $acl = $this->getAclFromTypeName($args['xsd:type']); $fldList = $this->_getFieldListFromAcl($acl); $baseNsUri = Api_WfsNs::getBaseWfsUri(); $wfsNs = 'p5_default_db';//$args['typePrefix']; $wfsNsUri = "{$baseNsUri}/" . substr($args['typePrefix'], 3); $featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$args['xsd:type']}&REQUEST=DescribeFeatureType"; // https://biuro.biall-net.pl/dev-pl/se-master/wfs-qgis.php/default_db/ // https://biuro.biall-net.pl/dev-pl/se-master/wfs-data.php/default_db/TEST_PERMS/?SERVICE=WFS&VERSION=1.0.0&TYPENAME=p5_default_db:TEST_PERMS&REQUEST=DescribeFeatureType // get BBox from geom_field (only one geom fld is allowed) $geomFld = null; { foreach ($fldList as $idZasob => $fldName) { if ($acl->isGeomField($fldName)) { $geomFld = $fldName; } } } $dbGeomType = $acl->getGeomFieldType($geomFld); $searchParams = array(); $searchParams['limit'] = $args['limit']; $searchParams['order_by'] = $acl->getPrimaryKeyField(); $searchParams['order_dir'] = 'DESC'; if (!empty($args['bbox'])) $searchParams['f_the_geom'] = "BBOX:{$args['bbox']}"; if (!empty($args['primaryKey'])) $searchParams['primaryKey'] = $args['primaryKey']; //if ($geomFld) $searchParams["f_{$geomFld}"] = 'IS NOT NULL'; //if ($geomFld) $searchParams["f_{$geomFld}"] = 'GeometryType=' . strtoupper($dbGeomType); $geomType = strtoupper($dbGeomType); if ($geomFld) $searchParams["ogc:Filter"] = << {$geomFld} {$geomFld} {$geomType} OGC_FILTER; if($DBG){echo 'args:';print_r($args);echo "\n";} if($DBG){echo 'getItems(params) \$params:';print_r($searchParams);echo "\n";} $this->DBG("getItems:" . json_encode($searchParams), __LINE__, __FUNCTION__, __CLASS__); $items = $acl->getItems($searchParams); $this->DBG("items(" . count($items) . ")", __LINE__, __FUNCTION__, __CLASS__); header('Content-type: application/xml; charset=utf-8'); $xmlWriter = new XMLWriter(); $xmlWriter->openUri('php://output'); // $xmlWriter->openMemory();// DBG $xmlWriter->setIndent(true); if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404); $xmlWriter->startDocument('1.0','UTF-8'); //$xmlWriter->startElementNS('wfs', 'FeatureCollection', 'http://www.opengis.net/wfs'); $xmlWriter->startElement('wfs:FeatureCollection'); // $xmlWriter->writeAttributeNS('xmlns', 'wfs', 'http://www.w3.org/2000/xmlns/', 'http://www.opengis.net/wfs'); $xmlWriter->writeAttribute('xmlns:wfs', 'http://www.opengis.net/wfs'); $xmlWriter->writeAttribute('xmlns', 'http://www.opengis.net/wfs'); // $xmlWriter->writeAttributeNS('xmlns', 'gml', 'http://www.w3.org/2000/xmlns/', 'http://www.opengis.net/gml'); // $xmlWriter->writeAttributeNS('xmlns', 'xsi', 'http://www.w3.org/2000/xmlns/', 'http://www.w3.org/2001/XMLSchema-instance'); // $xmlWriter->writeAttributeNS('xmlns', $wfsNs, 'http://www.w3.org/2000/xmlns/', $wfsNsUri); $xmlWriter->writeAttribute('xmlns:gml', 'http://www.opengis.net/gml'); $xmlWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $xmlWriter->writeAttribute("xmlns:{$wfsNs}", $wfsNsUri); $xmlWriter->writeAttribute('xsi:schemaLocation', "{$wfsNsUri} {$featureTypeUri}"); if($DBG){echo '(geomFld: '.$geomFld.'):';print_r($acl->getFieldType($geomFld));echo "\n";} $dbgLoop = 0; $this->DBG("before loop...", __LINE__, __FUNCTION__, __CLASS__); foreach ($items as $itemKey => $item) { $item = (array)$item; if (0 == (++$dbgLoop) % 500) $this->DBG("items loop:{$dbgLoop}", __LINE__, __FUNCTION__, __CLASS__); if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item[$geomFld]).'):' . var_export($item[$geomFld], true) . "\n";} if ($geomFld) { if (empty($item[$geomFld])) { continue;// QGIS crash when WFS contain features with empty geom field } } $xmlWriter->startElement('gml:featureMember'); $xmlWriter->startElement("{$wfsNs}:{$type}"); $xmlWriter->writeAttribute('fid', "{$type}.{$itemKey}"); foreach ($fldList as $idZasob => $fldName) { // if (!$acl->isAllowed($idZasob, 'R', $item)) {echo '';} if (!$acl->canReadObjectField($fldName, (object)$item)) continue; // if ($acl->isGeomField($fldName)) // BUG: wolno if ($geomFld != null && $fldName == $geomFld) { $xmlWriter->startElement("{$wfsNs}:{$fldName}"); $this->_typeConverter->createGmlFromWkt_xmlWriter($item[$fldName], $xmlWriter); $xmlWriter->endElement();// {$wfsNs}:{$fldName} } else if (is_array($item[$fldName])) {// TODO: by struct - REF field // if($DBG_DS){echo">>> TODO({$fldName}) REF item[{$itemKey}][{$fldName}]: ";print_r($item[$fldName]);echo "\n";} } else { $value = str_replace('&', '&', $item[$fldName]); if (empty($value) && '0' !== $value) { continue; } else { $xmlWriter->startElement("{$wfsNs}:{$fldName}"); $xmlWriter->text($value); $xmlWriter->endElement();// {$wfsNs}:{$fldName} } } } $xmlWriter->endElement();// {$wfsNs}:{$type} $xmlWriter->endElement();// gml:featureMember } $xmlWriter->endElement();// wfs:FeatureCollection $xmlWriter->endDocument(); $this->DBG("items loop END", __LINE__, __FUNCTION__, __CLASS__); exit; } public function describeFeatureTypeAction() { $type = V::get('TYPENAME', '', $_REQUEST); if (empty($type)) { $reqContent = Request::getRequestBody(); if (!empty($reqContent)) { return $this->_parseDescribeFeatureTypeRequest($reqContent); } else { return $this->_getDescribeFeatureAllTypes(); } //throw new HttpException("Wrong param TYPENAME", 400); } $typeEx = explode(':', $type); if (count($typeEx) != 2) { throw new HttpException("Wrong param TYPENAME", 400); } return $this->_getDescribeFeatureType($typeEx[0], $typeEx[1]); } public function getCapabilitiesAction() { $wfsServerUrl = $this->getBaseUri(); $serviceTitle = "Web Feature Service for QGIS"; $serviceDescription = "This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction."; //header('Content-type: application/xml; charset="utf-8"'); header('Content-type: application/xml'); $this->_getCapabilities($wfsServerUrl, $serviceTitle, $serviceDescription); exit; } public function _getTableAclList() {// Use only Tables from default_db with the_geom field $tblAclList = array(); $db = DB::getDB(); $idDefaultDB = $db->_zasob_id; $fullTblAclList = $this->_usrAcl->getTablesAcl(); foreach ($fullTblAclList as $tblAcl) { $dataSourceName = 'default_db';// TODO: getSourceName $tblName = $tblAcl->getName(); if ($idDefaultDB != $tblAcl->getDB()) {// hide non default_db tables continue; } try { $acl = $this->getAclFromTypeName($typeName = "p5_{$dataSourceName}:{$tblName}"); } catch (Exception $e) { // TODO: error log $e->getMessage(); } if (!$acl) { // TODO: error log msg continue; } $fldList = $acl->getRealFieldList(); if (!in_array('the_geom', $fldList)) { continue; } $tblAclList[] = $tblAcl; } return $tblAclList; } public function _getFieldListFromAcl($acl) { $fldList = $acl->getRealFieldListByIdZasob(); // mv the_geom to the first place $orderedFldList = array(); foreach ($fldList as $idZasob => $fldName) { if ('the_geom' == $fldName) $orderedFldList[$idZasob] = $fldName; } foreach ($fldList as $idZasob => $fldName) { if ('the_geom' == $fldName) continue; $orderedFldList[$idZasob] = $fldName; } return $orderedFldList; } }