[Mapbender-commits] r3512 - in trunk/mapbender/http: classes php

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Tue Feb 3 10:52:15 EST 2009


Author: christoph
Date: 2009-02-03 10:52:15 -0500 (Tue, 03 Feb 2009)
New Revision: 3512

Modified:
   trunk/mapbender/http/classes/class_gml_2_factory.php
   trunk/mapbender/http/classes/class_gml_3_factory.php
   trunk/mapbender/http/classes/class_gml_factory.php
   trunk/mapbender/http/classes/class_universal_gml_factory.php
   trunk/mapbender/http/php/mod_loadwfs.php
   trunk/mapbender/http/php/mod_wfs_result.php
Log:
basic GML3 support

Modified: trunk/mapbender/http/classes/class_gml_2_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_2_factory.php	2009-02-03 10:49:32 UTC (rev 3511)
+++ trunk/mapbender/http/classes/class_gml_2_factory.php	2009-02-03 15:52:15 UTC (rev 3512)
@@ -220,21 +220,13 @@
 	 * @param $domNode DOMNodeObject the feature tag of the GML 
 	 * 								(<gml:featureMember> in the above example)
 	 */
-	private function parseFeature($domNode, $feature) {
+	protected function parseFeature($domNode, $feature) {
 		if (func_num_args() == 3) {
 			$feature->geomFeaturetypeElement = func_get_arg(2);
 		}
 
 		$currentSibling = $domNode->firstChild;
 
-		//
-		// There had been a bug with whitespaces in the XML document.
-		// These whitespace had been interpreted as text nodes
-		//
-		if ($currentSibling instanceof DOMText) {
-			return;
-		}
-		
 		$feature->fid = $currentSibling->getAttribute("fid");
 		
 		$currentSibling = $currentSibling->firstChild;
@@ -299,50 +291,12 @@
 	 * @param $xml String
 	 */
 	public function createFromXml ($xml) {
-		try {
-			$gml2 = new Gml_2();
-			
-			if (func_num_args() == 2) {
-				$gml2->geomFeaturetypeElement = func_get_arg(1);
-			}
-
-			$xml = $this->removeWhiteSpace($xml);
-			$gmlDoc = new SimpleXMLElement($xml);
-			
-			$gmlDoc->registerXPathNamespace('xls', 'http://www.opengis.net/xls');
-			$gmlDoc->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs');
-			$gmlDoc->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
-			
-			// build feature collection
-			$gml2->featureCollection = new FeatureCollection();
-			
-			// segments of the featzreCollection
-			$gmlFeatureMembers = $gmlDoc->xpath("//gml:featureMember");
-			
-			if(count($gmlFeatureMembers)>0){
-				$cnt=0;
-				foreach ($gmlFeatureMembers as $gmlFeatureMember) {
-					$featureMember_dom = dom_import_simplexml($gmlFeatureMember);
-					
-					$feature = new Feature();
-					if ($this->geomFeaturetypeElement != null) {
-						$this->parseFeature($featureMember_dom, $feature, $this->geomFeaturetypeElement);
-					}
-					else {
-						$this->parseFeature($featureMember_dom, $feature);
-					}
-					if (isset($feature->geometry)) {
-						$gml2->featureCollection->addFeature($feature);
-					}
-					$cnt++;
-				}
-			}
-			return $gml2;
+		$gml2 = new Gml_2();
+		
+		if (func_num_args() == 2) {
+			$gml2->geomFeaturetypeElement = func_get_arg(1);
 		}
-		catch (Exception $e) {
-			$e = new mb_exception($e);
-			return null;
-		}
-	}
+		return parent::createFromXml($xml, $gml2);
+	}	
 }
 ?>
\ No newline at end of file

Modified: trunk/mapbender/http/classes/class_gml_3_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_3_factory.php	2009-02-03 10:49:32 UTC (rev 3511)
+++ trunk/mapbender/http/classes/class_gml_3_factory.php	2009-02-03 15:52:15 UTC (rev 3512)
@@ -37,21 +37,293 @@
 	 * @param $xml String
 	 */
 	public function createFromXml ($xml) {
-		try {
-			$gml3 = new Gml_3();
+		$gml3 = new Gml_3();
+		
+		if (func_num_args() == 2) {
+			$gml3->geomFeaturetypeElement = func_get_arg(1);
+		}
+		return parent::createFromXml($xml, $gml3);
+	}	
+
+	
+	
+	function findNameSpace($s){
+		list($ns,$FeaturePropertyName) = split(":",$s);
+		$nodeName = array('ns' => $ns, 'value' => $FeaturePropertyName);
+		return $nodeName;
+	}
+
+	private function parsePoint ($domNode, $gmlPoint) {
+		$currentSibling = $domNode->firstChild;
+		while ($currentSibling) {
+			list($x, $y, $z) = explode(",", $currentSibling->nodeValue);
+			$gmlPoint->setPoint($x, $y);
+			$currentSibling = $currentSibling->nextSibling;
+		}
+	}
+
+	private function parseLine ($domNode, $gmlLine) {
+		$currentSibling = $domNode->firstChild;
+		while ($currentSibling) {
 			
-			if (func_num_args() == 2) {
-				$gml3->geomFeaturetypeElement = func_get_arg(1);
+			foreach(explode(' ',$currentSibling->nodeValue) as $cords){
+				list($x,$y,$z) = explode(',',$cords);
+				$gmlLine->addPoint($x, $y);
 			}
+			$currentSibling = $currentSibling->nextSibling;
+		}
+	}
 
-			$xml = $this->removeWhiteSpace($xml);
-			$gmlDoc = new SimpleXMLElement($xml);
+	public function parsePolygon ($domNode, $gmlPolygon) {
+		$simpleXMLNode = simplexml_import_dom($domNode);
+
+		$simpleXMLNode->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
+		
+		$allCoords = $simpleXMLNode->xpath("gml:exterior/gml:LinearRing/gml:posList");
 			
+		$cnt=0;
+		foreach ($allCoords as $Coords) {
+			$coordsDom = dom_import_simplexml($Coords);
+				
+			$dim = $coordsDom->getAttribute("srsDimension");
+			if ($dim == "2") {
+				$coordArray = explode(' ', trim($coordsDom->nodeValue));
+				for ($i = 0; $i < count($coordArray); $i += 2) {
+					$x = $coordArray[$i];
+					$y = $coordArray[$i+1];
+					$gmlPolygon->addPoint($x, $y);
+				}
+			}		
+			$cnt++;
 		}
-		catch (Exception $e) {
-			$e = new mb_exception($e);
-			return null;
+		
+		$innerRingNodeArray = $simpleXMLNode->xpath("gml:innerBoundaryIs/gml:LinearRing");
+		if ($innerRingNodeArray) {
+			$ringCount = 0;
+			foreach ($innerRingNodeArray as $ringNode) {
+				$coordinates = $ringNode->xpath("gml:coordinates");
+				foreach ($coordinates as $coordinate) {
+					$coordsDom = dom_import_simplexml($coordinate);
+						
+					$dim = $coordsDom->getAttribute("srsDimension");
+					if ($dim == "2") {
+						$coordArray = explode(' ', trim($coordsDom->nodeValue));
+						for ($i = 0; $i < count($coordArray); $i += 2) {
+							$x = $coordArray[$i];
+							$y = $coordArray[$i+1];
+							$gmlPolygon->addPointToRing($ringCount, $x, $y);
+						}
+					}
+				}
+				$ringCount++;
+			}
 		}
 	}
+
+	public function parseMultiLine ($domNode, $gmlMultiLine) {
+		$simpleXMLNode = simplexml_import_dom($domNode);
+
+		$simpleXMLNode->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
+		
+		$allCoords = $simpleXMLNode->xpath("gml:lineStringMember/gml:LineString/gml:coordinates");
+			
+		$cnt=0;
+		foreach ($allCoords as $Coords) {
+			
+			$gmlMultiLine->lineArray[$cnt] = array();
+			
+			$coordsDom = dom_import_simplexml($Coords);
+				
+//			$name = $coordsDom->nodeName;
+//			$value = $coordsDom->nodeValue;				
+//			echo "===> name: ".$name. ", Value: ".$value."<br>";
+			
+			foreach(explode(' ',$coordsDom->nodeValue) as $pointCoords){
+				list($x,$y,$z) = explode(',',$pointCoords);
+				$gmlMultiLine->addPoint($x, $y, $cnt);
+				}
+			
+			$cnt++;
+		}
+	}		
+	
+	public function parseMultiPolygon ($domNode, $gmlMultiPolygon) {
+//		echo $domNode->nodeName."<br>";
+		$simpleXMLNode = simplexml_import_dom($domNode);
+
+		$simpleXMLNode->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
+
+		$allPolygons = $simpleXMLNode->xpath("gml:surfaceMembers/gml:Polygon");
+		
+		$cnt=0;
+		foreach ($allPolygons as $polygon) {
+			$allCoords = $polygon->xpath("gml:exterior/gml:LinearRing/gml:posList");
+				
+			$gmlMultiPolygon->polygonArray[$cnt] = array();
+			foreach ($allCoords as $Coords) {
+				
+				$coordsDom = dom_import_simplexml($Coords);
+				$dim = $coordsDom->getAttribute("srsDimension");
+				if ($dim == "2") {
+					$coordArray = explode(' ', trim($coordsDom->nodeValue));
+					for ($i = 0; $i < count($coordArray); $i += 2) {
+						$x = $coordArray[$i];
+						$y = $coordArray[$i+1];
+						$gmlMultiPolygon->addPoint($x, $y, $cnt);
+					}
+				}
+				// assume $dim == "3"
+				else {
+					$e = new mb_exception("GML with three-dimensional coordinates are not supported.");
+				}	
+			}
+			
+			$gmlMultiPolygon->innerRingArray[$cnt] = array();
+			$innerRingNodeArray = $polygon->xpath("gml:interior");
+			if ($innerRingNodeArray) {
+				$ringCount = 0;
+				foreach ($innerRingNodeArray as $ringNode) {
+					$currentRingNode = $ringNode->xpath("gml:LinearRing");
+					foreach ($currentRingNode as $node) {
+						$coordinates = $node->xpath("gml:posList");
+						foreach ($coordinates as $coordinate) {
+							$coordsDom = dom_import_simplexml($coordinate);
+								
+							$dim = $coordsDom->getAttribute("srsDimension");
+							if ($dim == "2") {
+								$coordArray = explode(' ', trim($coordsDom->nodeValue));
+								for ($i = 0; $i < count($coordArray); $i += 2) {
+									$x = $coordArray[$i];
+									$y = $coordArray[$i+1];
+									$gmlMultiPolygon->addPointToRing($cnt, $ringCount, $x, $y);
+								}
+							}
+							// assume $dim == "3"
+							else {
+								$e = new mb_exception("GML with three-dimensional coordinates are not supported.");
+							}
+						}
+						$ringCount++;
+						
+					}
+				}
+			}
+			$cnt++;
+//			new mb_exception("create multipolygon " . serialize($gmlMultiPolygon->innerRingArray));
+		}		
+	}
+	
+	/**
+	 * Parses the feature segment of a GML and stores the geometry in the
+	 * $geometry variable of the class.
+	 * 	
+	 * Example of a feature segment of a GML. 
+	 * 
+	 * <gml:featureMember>
+	 * 	<ms:my_polygons gml:id="my_polygons.624">
+	 * 		<gml:boundedBy>
+	 * 			<gml:Envelope srsName="epsg:4326">
+	 * 				<gml:lowerCorner>39.700000 29.400000</gml:lowerCorner>
+	 * 				<gml:upperCorner>46.400000 35.400000</gml:upperCorner>
+	 * 			</gml:Envelope>
+	 * 		</gml:boundedBy>
+	 * 		<ms:the_geom>
+	 * 			<gml:MultiSurface srsName="epsg:4326">
+	 * 				<gml:surfaceMembers>
+	 * 					<gml:Polygon>
+	 * 						<gml:exterior>
+	 * 							<gml:LinearRing>
+	 * 								<gml:posList srsDimension="2">
+	 * 									43.200000 35.400000 
+	 * 									46.400000 31.700000 
+	 * 									44.100000 31.000000 
+	 * 									41.700000 29.400000 
+	 * 									39.700000 31.400000 
+	 * 									43.300000 32.300000 
+	 * 									43.200000 35.400000 
+	 * 								</gml:posList>
+	 * 							</gml:LinearRing>
+	 * 						</gml:exterior>
+	 * 					</gml:Polygon>
+	 * 				</gml:surfaceMembers>
+	 * 			</gml:MultiSurface>
+	 * 		</ms:the_geom>
+	 * 		<ms:oid>16752039</ms:oid>
+	 * 		<ms:gid>624</ms:gid>
+	 * 		<ms:name>inter_08</ms:name>
+	 * 		<ms:angle/>
+	 * 		<ms:annotation/>
+	 * 		<ms:style>3</ms:style>
+	 * 		</ms:my_polygons>
+	 * 	</gml:featureMember>
+	 * 
+	 * @return void
+	 * @param $domNode DOMNodeObject the feature tag of the GML 
+	 * 								(<gml:featureMember> in the above example)
+	 */
+	protected function parseFeature($domNode, $feature) {
+		if (func_num_args() == 3) {
+			$feature->geomFeaturetypeElement = func_get_arg(2);
+		}
+
+		$currentSibling = $domNode->firstChild;
+
+		$feature->fid = $currentSibling->getAttribute("gml:id");
+		
+		$currentSibling = $currentSibling->firstChild;
+		
+		while ($currentSibling) {
+		
+			$name = $currentSibling->nodeName;
+			$value = $currentSibling->nodeValue;
+			
+			$namespace = $this->findNameSpace($name);
+			$ns = $namespace['ns'];
+			$columnName = $namespace['value'];
+			$isGeomColumn = ($feature->geomFeaturetypeElement == null || $columnName == $feature->geomFeaturetypeElement);
+			
+			// check if this node is a geometry node.
+			// however, even if it is a property node, 
+			// it has a child node, the text node!
+			// So we might need to do something more 
+			// sophisticated here...
+			if ($currentSibling->hasChildNodes() && $isGeomColumn){
+				$geomNode = $currentSibling->firstChild; 
+					$geomType = $geomNode->nodeName;
+					switch ($geomType) {
+						case "gml:Polygon" :
+							$feature->geometry = new GMLPolygon();
+							$this->parsePolygon($geomNode, $feature->geometry);
+							break;
+						case "gml:LineString" :
+							$feature->geometry = new GMLLine();
+							$this->parseLine($geomNode, $feature->geometry);
+							break;
+						case "gml:Point" :
+							$feature->geometry = new GMLPoint();
+							$this->parsePoint($geomNode, $feature->geometry);
+							break;
+						case "gml:MultiCurve" :
+							$feature->geometry = new GMLMultiLine();
+							$this->parseMultiLine($geomNode, $feature->geometry);
+							break;
+						case "gml:MultiSurface" :
+							$feature->geometry = new GMLMultiPolygon();
+							$this->parseMultiPolygon($geomNode, $feature->geometry);
+							break;
+						default:
+							$feature->properties[$columnName] = $value;
+							break;
+					}
+			} 
+			else {
+					$feature->properties[$columnName] = $value;
+			}
+			
+			$currentSibling = $currentSibling->nextSibling;
+		}
+	}
+	
+	
 }
 ?>
\ No newline at end of file

Modified: trunk/mapbender/http/classes/class_gml_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_factory.php	2009-02-03 10:49:32 UTC (rev 3511)
+++ trunk/mapbender/http/classes/class_gml_factory.php	2009-02-03 15:52:15 UTC (rev 3512)
@@ -26,7 +26,7 @@
  * 
  * @return Gml
  */
-class GmlFactory {
+abstract class GmlFactory {
 
 	public function removeWhiteSpace ($string) {
 		return preg_replace("/\>(\s)+\</", "><", trim($string));
@@ -38,7 +38,45 @@
 	 * @return Gml
 	 * @param $xml String
 	 */
-	public function createFromXml ($xml) {
-	}
+	public function createFromXml ($xml, $gml) {
+		try {
+			$xml = $this->removeWhiteSpace($xml);
+			$gmlDoc = new SimpleXMLElement($xml);
+			
+			$gmlDoc->registerXPathNamespace('xls', 'http://www.opengis.net/xls');
+			$gmlDoc->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs');
+			$gmlDoc->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
+			
+			// build feature collection
+			$gml->featureCollection = new FeatureCollection();
+			
+			// segments of the featureCollection
+			$gmlFeatureMembers = $gmlDoc->xpath("//gml:featureMember");
+			
+			if(count($gmlFeatureMembers)>0){
+				$cnt=0;
+				foreach ($gmlFeatureMembers as $gmlFeatureMember) {
+					$featureMember_dom = dom_import_simplexml($gmlFeatureMember);
+					
+					$feature = new Feature();
+					if ($this->geomFeaturetypeElement != null) {
+						$this->parseFeature($featureMember_dom, $feature, $this->geomFeaturetypeElement);
+					}
+					else {
+						$this->parseFeature($featureMember_dom, $feature);
+					}
+					if (isset($feature->geometry)) {
+						$gml->featureCollection->addFeature($feature);
+					}
+					$cnt++;
+				}
+			}
+			return $gml;
+		}
+		catch (Exception $e) {
+			$e = new mb_exception($e);
+			return null;
+		}
+	}	
 }
 ?>
\ No newline at end of file

Modified: trunk/mapbender/http/classes/class_universal_gml_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_universal_gml_factory.php	2009-02-03 10:49:32 UTC (rev 3511)
+++ trunk/mapbender/http/classes/class_universal_gml_factory.php	2009-02-03 15:52:15 UTC (rev 3512)
@@ -27,10 +27,26 @@
 
 class UniversalGmlFactory extends GmlFactory {
 
+	/**
+	 * This function checks if the XML contains a tag "gml:posList"
+	 * If yes, the xml is considered to be a GML3 document,
+	 * otherwise GML2.
+	 * 
+	 * This has to be done another way; it is just a quick hack.
+	 * 
+	 * @return Boolean
+	 * @param $xml String
+	 */
 	private function getVersionFromXml ($xml) {
-
+		$simpleXml = simplexml_load_string($xml);
+		$simpleXml->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
+		
+		$nodeArray = $simpleXml->xpath("gml:featureMember//gml:posList");
+		if (count($nodeArray) > 0 ) {
+			return "3";
+		}
 		return "2";
-		throw new Exception("WFS version could not be determined from XML.");
+		throw new Exception("GML version could not be determined from XML.");
 	}
 
 	/**

Modified: trunk/mapbender/http/php/mod_loadwfs.php
===================================================================
--- trunk/mapbender/http/php/mod_loadwfs.php	2009-02-03 10:49:32 UTC (rev 3511)
+++ trunk/mapbender/http/php/mod_loadwfs.php	2009-02-03 15:52:15 UTC (rev 3512)
@@ -32,6 +32,9 @@
 $myWfsFactory = new UniversalWfsFactory();
 $myWfs = $myWfsFactory->createFromUrl($url);      
 
+if ($myWfs == null) {
+	echo "WFS could not be uploaded.";
+}
 $myWfs->insertOrUpdate();
 
 // link WFS to GUIs in $guiList

Modified: trunk/mapbender/http/php/mod_wfs_result.php
===================================================================
--- trunk/mapbender/http/php/mod_wfs_result.php	2009-02-03 10:49:32 UTC (rev 3511)
+++ trunk/mapbender/http/php/mod_wfs_result.php	2009-02-03 15:52:15 UTC (rev 3512)
@@ -29,16 +29,6 @@
 $db_wfs_conf_id = $_REQUEST["db_wfs_conf_id"];
 $typename = $_REQUEST["typename"];
 
-function sepNameSpace($s){
-	$c = mb_strpos($s,":"); 
-	if ($c > 0){
-		return mb_substr($s,$c+1);
-	}
-	else{
-		return $s;
-	}		
-}
-
 /**
  * checks if a variable name is valid.
  * Currently a valid name would be sth. like $_SESSION["mb_user_id"]
@@ -99,6 +89,8 @@
 
 if ($data === null) die('{}');
 
+//echo $data; die;
+
 $geomColumn = WfsConf::getGeomColumnNameByConfId($db_wfs_conf_id);
 
 $gmlFactory = new UniversalGmlFactory();



More information about the Mapbender_commits mailing list