_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() { $type = V::get('TYPENAME', '', $_REQUEST); $typeEx = explode(':', $type); $maxFeatures = V::get('MAXFEATURES', '10000', $_REQUEST, 'int');// TODO: Set Deafult Limit $srsname = V::get('SRSNAME', '', $_REQUEST);// eg. EPSG:4326 if (count($typeEx) == 2) { return $this->getFeatures($typeEx[0], $typeEx[1], $maxFeatures, $srsname); } else { throw new HttpException("Wrong param TYPENAME", 400); } } public function getFeatures($nsPrefix, $type, $maxFeatures, $srsname) { $DBG = (V::get('DBG_GEO', '', $_GET) > 0);// TODO: Profiler $typeName = "{$nsPrefix}:{$type}"; $acl = $this->getAclFromTypeName($typeName); $fldList = $this->_getFieldListFromAcl($acl); $baseNsUri = $this->getBaseNamespaceUri(); //$wfsNs = 'p5_default_db_' . $type;//$nsPrefix; $wfsNs = 'p5_default_db';//$nsPrefix; $wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3); $featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$typeName}&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 $fldName) { if ($acl->isGeomField($fldName)) { $geomFld = $fldName; } } } $dbGeomType = $acl->getGeomFieldType($geomFld); $searchParams = array(); $searchParams['limit'] = $maxFeatures; $searchParams['order_by'] = $acl->getPrimaryKeyField(); $searchParams['order_dir'] = 'DESC'; if ($geomFld) $searchParams["f_{$geomFld}"] = 'IS NOT NULL'; if ($geomFld) $searchParams["f_{$geomFld}"] = 'GeometryType=' . strtoupper($dbGeomType); //if ($geomFld) $searchParams["f_{$geomFld}"] = 'GeometryType=LINESTRING'; if($DBG){echo 'getItems:';print_r($searchParams);echo "\n";} $items = $acl->getItems($searchParams); $dom = new DOMDocument('1.0', 'utf-8'); $dom->formatOutput = true; $dom->preserveWhiteSpace = false; $rootNode = $dom->createElementNS('http://www.opengis.net/wfs', 'wfs:FeatureCollection'); $dom->appendChild($rootNode); $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.opengis.net/wfs'); $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:wfs', 'http://www.opengis.net/wfs'); $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml'); $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri); $rootNode->setAttribute('xsi:schemaLocation', "{$wfsNsUri} {$featureTypeUri}"); if(0){// TODO: get BBOX for add features $boundedByNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:boundedBy'); $rootNode->appendChild($boundedByNode); $boxNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:Box'); $boundedByNode->appendChild($boxNode); $boxNode->setAttribute('srsName', "http://www.opengis.net/gml/srs/epsg.xml#4326");// TODO: EPSG $coordinatesNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:coordinates'); $boxNode->appendChild($coordinatesNode); $coordinatesNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml'); $coordinatesNode->setAttribute('decimal', '.'); $coordinatesNode->setAttribute('cs', ','); $coordinatesNode->setAttribute('ts', ' '); $coordinatesNode->nodeValue = '1544947.6295,4322758.105 1548002.2259,4330464.1001';// TODO: coordinates for all items? } if($DBG){echo '(geomFld: '.$geomFld.'):';print_r($acl->getFieldType($geomFld));echo "\n";} if (empty($items)) { $pKeyField = $acl->getPrimaryKeyField(); $fakeItem = new stdClass(); $fakeItem->{$pKeyField} = 0; if ('polygon' == $dbGeomType) { $fakeItem->the_geom = "POLYGON(())"; } else if ('linestring' == $dbGeomType) { $fakeItem->the_geom = "LINESTRING()"; } else if ('point' == $dbGeomType) { $fakeItem->the_geom = "POINT(0,0)"; } $items[0] = $fakeItem; } foreach ($items as $itemKey => $item) { if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld}).'):';print_r($item->{$geomFld});echo "\n";} if ($geomFld) { if (empty($item->{$geomFld})) { continue;// QGIS crash when WFS contain features with empty geom field } } $featureMemberNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:featureMember'); $rootNode->appendChild($featureMemberNode); $featureNode = $dom->createElementNS($wfsNsUri, "{$wfsNs}:{$type}"); $featureMemberNode->appendChild($featureNode); $featureNode->setAttribute('fid', "{$type}.{$itemKey}"); if(0){// TODO: get BBOX $boundedByNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:boundedBy'); $featureNode->appendChild($boundedByNode); $boxNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:Box'); $boundedByNode->appendChild($boxNode); $boxNode->setAttribute('srsName', "http://www.opengis.net/gml/srs/epsg.xml#4326");// TODO: EPSG $coordinatesNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:coordinates'); $boxNode->appendChild($coordinatesNode); $coordinatesNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml'); $coordinatesNode->setAttribute('decimal', '.'); $coordinatesNode->setAttribute('cs', ','); $coordinatesNode->setAttribute('ts', ' '); $coordinatesNode->nodeValue = '1546472.2363,4328949.5775 1548002.2259,4330464.1001';// TODO: coordinates for item? } foreach ($fldList as $fldName) { $featureFldNode = $dom->createElementNS($wfsNsUri, "{$wfsNs}:{$fldName}"); if ($acl->isGeomField($fldName)) { $geomNode = $this->_typeConverter->createGmlFromWkt($item->{$fldName}, $dom); if (!$geomNode) continue; $featureFldNode->appendChild($geomNode); } else { $featureFldNode->nodeValue = str_replace('&', '&', $item->{$fldName}); if (empty($featureFldNode->nodeValue) && '0' !== $featureFldNode->nodeValue) { continue; } } $featureNode->appendChild($featureFldNode); } } return $dom->saveXml(); } 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->getRealFieldList(); {// mv the_geom to the first place array_unshift($fldList, 'the_geom'); $fldList = array_unique($fldList); } return $fldList; } }