describeFeatureType .
$aWfs->getConjunctionCharacter($aWfs->describeFeatureType) .
"&SERVICE=WFS&VERSION=" . $aWfs->getVersion() .
"&REQUEST=DescribeFeatureType&TYPENAME=" . $featureTypeName;
if (isset($aWfs->auth)) {
$xml = $this->get($url, $aWfs->auth);
} else {
$xml = $this->get($url);
}
return $this->createFeatureTypeFromXml ($xml, $aWfs,$featureTypeName);
}
protected function createFeatureTypeFromXml ($xml, $myWfs, $featureTypeName) {
$newFeatureType = new WfsFeatureType($myWfs);
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXpath($doc);
$xpath->registerNamespace("xs","http://www.w3.org/2001/XMLSchema");
// populate a Namespaces Hashtable where we can use the namespace as a lookup for the prefix
// and also keep a
$namespaces = array();
$namespaceList = $xpath->query("//namespace::*");
$targetNamespace = $doc->documentElement->getAttribute("targetNamespace");
$targetNamespaceNode = null;
foreach($namespaceList as $namespaceNode){
$namespaces[$namespaceNode->nodeValue] = $namespaceNode->localName;
if($namespaceNode->nodeValue == $targetNamespace){
$targetNamespaceNode = $namespaceNode;
}
$newFeatureType->addNamespace($namespaceNode->localName, $namespaceNode->nodeValue);
}
list($ftLocalname,$ftTypePrefix) = array_reverse(explode(":",$featureTypeName));
// for the sake of simplicity we only care about top level elements. Seems to have worked so far
$query = sprintf("/xs:schema/xs:element[@name='%s']",$ftLocalname);
$elementList = $xpath->query($query);
//parse single elements - if the schema is complex, store only the DescribeFeaturetype response
$newFeatureType->schema_problem = 'f';
$newFeatureType->schema = $xml;
foreach ($elementList as $elementNode){
$elementName = $elementNode->getAttribute("name");
$elementType = $elementNode->getAttribute("type");
//if Type is empty, we assume an anonymousType, else we go looking for the anmed Type
if($elementType == ""){
//Just querying for complexTypes containing a Sequence - good enough for Simple Features
$query = "xs:complexType//xs:element";
$subElementList = $xpath->query($query,$elementNode);
} else {
// The elementType is now bound to a prefix e.g. topp:housType
// if the prefix is in the targetNamespace, changces are good it's defined in this very document
// if the prefix is not in the targetNamespace, it's likely not defined here, and we bail
list($elementTypeLocalname,$elementTypePrefix) = array_reverse(explode(":",$elementType));
$elementTypeNamespace = $doc->lookupNamespaceURI($elementTypePrefix);
if($elementTypeNamespace !== $targetNamespaceNode->nodeValue){
$e = new mb_warning("Tried to parse FeatureTypeName $featureTypeName : $elementType is not in the targetNamespace");
break;
}
// Just querying for complexTypes containing a Sequence - good enough for Simple Features
$query = sprintf("//xs:complexType[@name='%s']//xs:element",$elementTypeLocalname);
$subElementList = $xpath->query($query);
}
foreach ($subElementList as $subElement) {
// Since this is a rewrite of the old way, it reproduces it quirks
// in this case the namespace of the type was cut off for some reason
$name = $subElement->getAttribute('name');
$typeParts = explode(":",$subElement->getAttribute('type'));
//$e = new mb_exception("element: ".$name." - type: ".$typeParts[0]);
if (empty($typeParts[0])) {
$e = new mb_warning("No type attribute found in xs:element - test for integrated simpleType!");
//it maybe a simple type
/*
*/
$query = "xs:simpleType/xs:restriction";
$restriction = $xpath->query($query,$subElement);
if (gettype($restriction->item(0)) == 'object') {
$type = $restriction->item(0)->getAttribute('base');
} else {
$e = new mb_exception("classes/class_wfs_1_0_factory.php: Problem while parsing schema for featuretype ".$featureTypeName);
$newFeatureType->schema_problem = 't';
}
//TODO parse further information from xsd like maxLength: - add further column in wfs_element!
} else {
switch (count($typeParts)) {
case 1 :
$type = $typeParts[0];
break;
case 2 :
$type = $typeParts[1];
break;
}
}
$newFeatureType->addElement($name,$type);
}
}
return $newFeatureType;
}
/**
* Creates WFS 1.0 objects from a capabilities documents.
*
* @return Wfs_1_0
* @param $xml String
*/
public function createFromXml ($xml, $auth=false) {
try {
$myWfs = new Wfs_1_0();
//new for parsing with simple xml:
$admin = new administration();
$myWfs->getCapabilitiesDoc = $admin->char_encode($xml);
$myWfs->id = $this->createId();
//check for authentication
if (!$auth) {
$e = new mb_notice("class_wfs_1_0_factory.php - createFromXml - no athentication info given!");
}
$myWfs->auth = $auth; //always!
try {
$xml = str_replace('xlink:href', 'xlinkhref', $xml);
#http://forums.devshed.com/php-development-5/simplexml-namespace-attributes-problem-452278.html
#http://www.leftontheweb.com/message/A_small_SimpleXML_gotcha_with_namespaces
$wfs10Cap = new SimpleXMLElement($xml);
//$wfs10Cap = new SimpleXMLElement($xml);
if ($wfs10Cap === false) {
foreach(libxml_get_errors() as $error) {
$e = new mb_exception($error->message);
}
throw new Exception('Cannot parse WFS 1.0.0 Capabilities!');
}
}
catch (Exception $e) {
$e = new mb_exception($e->getMessage());
}
if ($wfs10Cap !== false) {
//read all relevant information an put them into the mapbender wfs object
//xmlns="http://www.opengis.net/wfs"
//Setup default namespace
$wfs10Cap->registerXPathNamespace("wfs", "http://www.opengis.net/wfs");
$wfs10Cap->registerXPathNamespace("ogc", "http://www.opengis.net/ogc");
$wfs10Cap->registerXPathNamespace("xlink", "http://www.w3.org/1999/xlink");
//some debug
//$e = new mb_notice("XML string from memory: ".$wfs10Cap->asXML());
$myWfs->version = $wfs10Cap->xpath('/wfs:WFS_Capabilities/@version');
$myWfs->version = $myWfs->version[0];
$myWfs->name = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Service/wfs:Name');
$myWfs->name = $myWfs->name[0];
$myWfs->title = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Service/wfs:Title');
$myWfs->title = $this->stripEndlineAndCarriageReturn($myWfs->title[0]);
$myWfs->summary = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Service/wfs:Abstract');
$myWfs->summary = $this->stripEndlineAndCarriageReturn($myWfs->summary[0]);
$myWfs->fees = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Service/wfs:Fees');
$myWfs->fees = $myWfs->fees[0];
$myWfs->accessconstraints = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Service/wfs:AccessConstraints');
$myWfs->accessconstraints = $myWfs->accessconstraints[0];
$myWfs->getCapabilities = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Capability/wfs:Request/wfs:GetCapabilities/wfs:DCPType/wfs:HTTP/wfs:Get/@onlineResource');
$myWfs->getCapabilities = $myWfs->getCapabilities[0];
$myWfs->describeFeatureType = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Capability/wfs:Request/wfs:DescribeFeatureType/wfs:DCPType/wfs:HTTP/wfs:Post/@onlineResource');
$myWfs->describeFeatureType = $myWfs->describeFeatureType[0];
$myWfs->getFeature = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Capability/wfs:Request/wfs:GetFeature/wfs:DCPType/wfs:HTTP/wfs:Post/@onlineResource');
$myWfs->getFeature = $myWfs->getFeature[0];
$myWfs->transaction = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:Capability/wfs:Request/wfs:Transaction/wfs:DCPType/wfs:HTTP/wfs:Post/@onlineResource');
$myWfs->transaction = $myWfs->transaction[0];
$capFeatureTypes = $wfs10Cap->xpath('/wfs:WFS_Capabilities/wfs:FeatureTypeList/wfs:FeatureType');
foreach ($capFeatureTypes as $featureType) {
$featuretype_name = $this->stripEndlineAndCarriageReturn($featureType->Name[0]);
$featuretype_title = $this->stripEndlineAndCarriageReturn($featureType->Title[0]);
$featuretype_abstract = $this->stripEndlineAndCarriageReturn($featureType->Abstract[0]);
$featuretype_srs = $featureType->SRS[0];
$LatLongBoundingBox = $featureType->LatLongBoundingBox[0];
//read bbox of featuretype
$featuretype_latlon_minx = $LatLongBoundingBox->xpath('@minx');
$featuretype_latlon_minx = $featuretype_latlon_minx[0];
$featuretype_latlon_miny = $LatLongBoundingBox->xpath('@miny');
$featuretype_latlon_miny = $featuretype_latlon_miny[0];
$featuretype_latlon_maxx = $LatLongBoundingBox->xpath('@maxx');
$featuretype_latlon_maxx = $featuretype_latlon_maxx[0];
$featuretype_latlon_maxy = $LatLongBoundingBox->xpath('@maxy');
$featuretype_latlon_maxy = $featuretype_latlon_maxy[0];
//NOTICE: for WFS 1.0.0 latlonbbox is given in featuretypes SRS and not in EPSG:4326 - it has to be reprojected ;-)
$n = new mb_notice("Calculation of BBOX for EPSG:4326");
$pointMin = new Mapbender_point($featuretype_latlon_minx, $featuretype_latlon_miny, preg_replace("/EPSG:/", "", $featuretype_srs));
$pointMax = new Mapbender_point($featuretype_latlon_maxx, $featuretype_latlon_maxy, preg_replace("/EPSG:/", "", $featuretype_srs));
$pointMin->transform("4326");
$pointMax->transform("4326");
if($pointMin->epsg != '' && $pointMin->x != '' && $pointMin->y != ''
&& $pointMax->x != '' && $pointMax->y != '') {
$featuretype_latlon_minx = $pointMin->x;
$featuretype_latlon_miny = $pointMin->y;
$featuretype_latlon_maxx = $pointMax->x;
$featuretype_latlon_maxy = $pointMax->y;
$n = new mb_notice("Calculation of BBOX for EPSG:4326 finished successful.");
}
else {
$e = new mb_exception("Could not transform BBOX from ".$featuretype_srs." to EPSG:4326.");
}
//http://www.ogccatservice.com/csw.cgi?service=CSW&version=2.0.0&request=GetRecords&constraintlanguage=CQL&constraint="recordid=urn:uuid:4ee8b2d3-9409-4a1d-b26b-6782e4fa3d59"
$metadataURLArray = $featureType->MetadataURL;
$featuretype_metadataUrl = array();
$i_mdu = 0;
foreach ($metadataURLArray as $metadataURL) {
//$e = new mb_exception("other srs: ".$otherSRS);
$featuretype_metadataUrl[$i_mdu]->href = $metadataURL;
$e = new mb_notice("metadataurl: ".$metadataURL);
$featuretype_metadataUrl[$i_mdu]->type = $metadataURL->attributes()->type;
$e = new mb_notice("type: ".$featuretype_metadataUrl[$i_mdu]->type);
$featuretype_metadataUrl[$i_mdu]->format = $metadataURL->attributes()->format;
$e = new mb_notice("format: ".$featuretype_metadataUrl[$i_mdu]->format);
$i_mdu++;
}
//do not add defective featuretypes - first request them via net
try {
$currentFeatureType = $this->createFeatureTypeFromUrl($myWfs, $featuretype_name);
if ($currentFeatureType !== null) {
$currentFeatureType->name = $featuretype_name;
$currentFeatureType->title = $featuretype_title;
$currentFeatureType->summary = $featuretype_abstract;
$currentFeatureType->srs = $featuretype_srs;
$currentFeatureType->latLonBboxArray['minx'] = $featuretype_latlon_minx;
$currentFeatureType->latLonBboxArray['miny'] = $featuretype_latlon_miny;
$currentFeatureType->latLonBboxArray['maxx'] = $featuretype_latlon_maxx;
$currentFeatureType->latLonBboxArray['maxy'] = $featuretype_latlon_maxy;
$currentFeatureType->metadataUrlArray = $featuretype_metadataUrl;
$myWfs->addFeatureType($currentFeatureType);
}
}
catch (Exception $e) {
new mb_exception("Failed to load featuretype " . $featuretype_name);
}
} //end for each featuretype
} //end of parsing wfs capabilities
return $myWfs;
}
catch (Exception $e) {
$e = new mb_exception($e);
return null;
}
}
public function createFromDb ($id) {
$myWfs = new Wfs_1_0();
return parent::createFromDb($id, $myWfs);
}
}
?>