MapGuide Layer Modifikation


MapGuide wechsel fdo providerMapGuide Open Source legt alle seine Layerdefinitionen im XML-Format ab. Normalerweise muss man sich darum nicht kümmern, denn mit MapGuide Maestro steht eine mittlerweile komfortable GUI zur Verfügung. Damit kann alles eingestellt werden, was für jeden Layer nötig ist. Für jeden Layer einzeln.

Aufwändig wird es, wenn man Änderungen vornehmen möchte, die alle MapGuide Layer betreffen. Das ist unter anderem der Fall, wenn man den FDO-Provider wechselt. In diesem Fall könnte man jeden einzelnen Layer anfassen und die Datenquelle (feature resource) ändern. Bei nur wenigen Layern ist das schnell getan. Wer jedoch mit mehreren hundert Layern arbeitet, kann recht schnell zur Verzweiflung getrieben werden.

Um diese Arbeit zu beschleunigen möchten wir Ihnen hier ein kleines PHP Script zeigen, was die Arbeit bedeutend erleichtert. Im konkreten Beispiel sollen die Inhalte verschiedener XML Tag’s wegen des Umstiegs von MySQL auf PostGIS geändert werden. Die <ResourceId> soll von
<ResourceId>Library://datenbankverbindung/mysql.FeatureSource</ResourceId>
auf
<ResourceId>Library://datenbankverbindung/postgis.FeatureSource</ResourceId>
modifiziert werden.

Um das zu bewerkstelligen, arbeitet das PHP Script mit 3 Arrays. $arrayTag enthält die Tag-Namen in denen gesucht wird. In unserem Beispiel also nach „//ResourceId“ (Quellcode Zeile 8). Das Array $arraySuch beinhaltet die (alten) Werte, nach denen in den Tags gesucht werden soll, also mysql.FeatureSource (Quelltext Zeile 14). Die zu ersetzenden Werte stehen in $arrayErsetz. In unserem Fall also postgis.FeatureSource (Quelltext Zeile 20). Alle anderen zu ersetzenden Werte sind analog in den drei Datenfeldern unterzubringen. Bitte beachten Sie, dass XML grundsätzlich case sensitive ist!

Nach der Definition dieser Werte folgt die MapGuide-Initialisierung und im Anschluß werden alle Werte in einer Schleife ersetzt. Wichtig ist noch die Library Angabe in  Zeile 47. Damit läßt sich die Suche auf einen Teil der Quelle reduzieren. Außerdem weisen wir noch auf die Variable $flagUpdate hin. Soll nur ein Testlauf durchegührt werden. kann man einfach den Kommentar aus Zeile 90 nehmen und so vermeiden, dass ein Update auch wirksam wird.

Das Skript selbst kann man z.B. im Aufgabenfenster eines Layouts laufen lassen und dadurch auch die einzelnen Kontroll-Echos sehen.

[codesyntax lang=“php“ lines=“normal“ lines_start=“0″ tab_width=“1″ title=“Code Beispie: MapGuide Layer Modifikation mit PHP“]

<?php
### Modifikation von Layerdefinitionen in
### MapGuide Open Source

### Tag nach dem gesucht wird
$arrayTag[0] = "//FeatureName";
$arrayTag[1] = "//Geometry";
$arrayTag[2] = "//Filter";
$arrayTag[3] = "//ResourceId";

### Alter Inhalt des Tags
$arraySuch[0] = "Fdoagmg_db";
$arraySuch[1] = "Graphik";
$arraySuch[2] = "BLName";
$arraySuch[3] = "mysql.FeatureSource";

### Neuer Inhalt des Tags
$arrayErsetz[0]= "public";
$arrayErsetz[1]= "graphik";
$arrayErsetz[2]= "blnamexx";
$arrayErsetz[3]= "postgis.FeatureSource";

//############ Start Initialisierung
$installDir='X:\OSGeo\mgos251\\';
$extensionsDir=$installDir.'Web\www\\';
$viewerDir=$extensionsDir.'mapviewerphp\\';
include $viewerDir . 'constants.php';
$mgSessionId = ($_SERVER['REQUEST_METHOD'] == "POST")
? $_POST['SESSION']: $_GET['SESSION'];
$mgMapName=($_SERVER['REQUEST_METHOD'] == "POST")
? $_POST['MAPNAME']: $_GET['MAPNAME'];
MgInitializeWebTier("$extensionsDir\webconfig.ini");
$userInfo = new MgUserInformation($mgSessionId);
$siteConnection = new MgSiteConnection();
$siteConnection->Open ($userInfo);
$resourceService = $siteConnection->CreateService(MgServiceType::ResourceService);
//############ Ende Initialisierung

echo "Initialisierung fertig<p>";

### Iteration durch durch die gesuchten Tag's
for($ia=0; $ia<count($arraySuch); $ia++)
{
	echo "#########<br>";
	echo "#Tag:$arraySuch[$ia]<br>";
	echo "#########<p>";
	//### gesucht wird in allen im Pfad $resourceID und in allen Unterpfaden
	$resourceID = new MgResourceIdentifier("Library://postgisprojekt/layer/gas/");
	$byteReader = $resourceService->EnumerateResources($resourceID, -1, "");
	$XmlSym = $byteReader->ToString();
	echo "<p>$XmlSym</p>";
	$SymDomDoc = DOMDocument::loadXML($XmlSym);
	$Spath = new DOMXPath($SymDomDoc);
	$Squery = '//ResourceDocument/ResourceId';
	$Snodes = $Spath->query($Squery);
	foreach ($Snodes as $Snode)
	{
	   	    $Sname = $Snode->nodeValue;
			echo "Nächstes element:<br>";		
		    echo "$Sname<p>";
			$resourceID = new MgResourceIdentifier($Sname);
			$byteReader = $resourceService->GetResourceContent($resourceID);
			$Xml = $byteReader->ToString();
			$LDomDoc = DOMDocument::loadXML($Xml);
			$I = -1;//zählt die gefundenen Elemente
			$xpath = new DOMXPath($LDomDoc);
			### Gesuchter Tag
			$query = $arrayTag[$ia];
			$nodes = $xpath->query($query);
			foreach ($nodes as $node )
			{
			  $Ident = $node->nodeValue;
			  echo "<p>Ident:$Ident<p>";
			  $I = $I + 1;
			  ### Update soll nur bei Änderung erfolgen
			  $flagUpdate = false;

			  //### Nach diesem TAG-Inhalt (!!!) wird gesucht
			  $posSuch = -1;
			  $posSuch = strpos($Ident,$arraySuch[$ia]);
			  echo "Position String: $posSuch<p>";
			  if($posSuch >= 0)
			  {
			   	  $Pos = $I;
				  $neuString = str_replace($arraySuch[$ia], $arrayErsetz[$ia], $Ident);
				  echo "Neustring:$neuString<p>";
				  $node->nodeValue = $neuString;
				  $flagUpdate = TRUE;
			  }//if(ident)		  
			}//foreach node
			//$flagUpdate = FALSE;
			if($flagUpdate==true)
			{
				$updatedXml = $LDomDoc->saveXML();
				$byteSource = new MgByteSource($updatedXml, strlen($updatedXml));
				$byteSource->SetMimeType(MgMimeType::Xml);
				$resourceId = new MgResourceIdentifier($Sname);
				$resourceService->SetResource($resourceId, $byteSource->GetReader(), null);
				echo "ein update erfolgt<br>";
				echo "------------<p>";
			}
	}
} // For Schleife durch Array-Tag	
echo "ganz fertig";
?>
[/codesyntax]

Für Rückfragen oder weitergehende Informationen stehen wir Ihnen gerne zur Verfügung.