_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);
}
}