_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 = $acl->getRealFieldList(); $baseNsUri = $this->getBaseNamespaceUri(); $wfsNs = 'p5_default_db_' . $type;//$nsPrefix; $wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3) . '/' . $type; // 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', 'http://www.opengis.net/wfs');// TODO: add DescribeFeatureType xsd uri 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($item->ID == 19)continue; 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)) { continue; } } $featureNode->appendChild($featureFldNode); } } return $dom->saveXml(); } public function describeFeatureTypeAction() { $type = V::get('TYPENAME', '', $_REQUEST); if (empty($type)) { 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 getDescribeFeatureType($nsPrefix, $type) { $typeName = "{$nsPrefix}:{$type}"; $acl = $this->getAclFromTypeName($typeName); $baseNsUri = $this->getBaseNamespaceUri(); $wfsNs = 'p5_default_db_' . $type;//$nsPrefix; $wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3) . '/' . $type; if (empty($type)) { throw new HttpException("Feature Type Name not defined", 400); } if (!$this->isAllowedFeatureType($nsPrefix, $type)) { throw new Api_WfsException("Could not find type: " . htmlspecialchars($type)); } $typeName = $type . 'Type'; $fldList = $acl->getRealFieldList(); header('Content-type: application/xml'); // // $dom = new DOMDocument('1.0', 'utf-8'); $dom->formatOutput = true; $dom->preserveWhiteSpace = false; $rootNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:schema'); $dom->appendChild($rootNode); $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml'); $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri); $rootNode->setAttribute('elementFormDefault', 'qualified'); $rootNode->setAttribute('targetNamespace', $wfsNsUri); $cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType'); $rootNode->appendChild($cTypeNode); $cTypeNode->setAttribute('name', $typeName); $cConNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexContent'); $cTypeNode->appendChild($cConNode); $extNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:extension'); $cConNode->appendChild($extNode); $extNode->setAttribute('base', 'gml:AbstractFeatureType'); $seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:sequence'); $extNode->appendChild($seqNode); // $pKeyField = $acl->getPrimaryKeyField(); foreach ($fldList as $fldName) { $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $seqNode->appendChild($elNode); $elNode->setAttribute('name', $fldName); $minOccurs = 0; if ($pKeyField == $fldName) { $minOccurs = '1'; } else { $minOccurs = '0'; } $elNode->setAttribute('minOccurs', $minOccurs); if ($acl->isIntegerField($fldName)) { $fldType = 'xsd:integer'; } else if ($acl->isDecimalField($fldName)) { $fldType = 'xsd:decimal'; } else if ($acl->isDateField($fldName)) { $fldType = 'xsd:date'; } else if ($acl->isDateTimeField($fldName)) { $fldType = 'xsd:dateTime'; } else if ($acl->isGeomField($fldName)) { $fldType = 'gml:GeometryPropertyType'; //$fldType = 'gml:Polygon';// nie działa musi być gml:GeometryPropertyType } else { $fldType = 'xsd:string'; } $elNode->setAttribute('type', $fldType); $elNode->setAttribute('nillable', 'true'); } $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $rootNode->appendChild($elNode); $elNode->setAttribute('name', $type); $elNode->setAttribute('type', $wfsNs . ':' . $typeName); echo $dom->saveXML(); } 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); } }