MapGuide Cookbook¶
This section is a select list of MapGuide code samples. See Trac for more samples.
JavaScript: Hooking to events in the AJAX viewer¶
This sample will show how to do the following:
- Checking when the map has been loaded.
- Handling viewer selection.
It is assumed you know what javascript anonymous functions are and how they work.
Checking when the map has been loaded¶
Before we can hook on to events in the ajax viewer, we need to check that the DOM for the ajax viewer has been loaded. This sample shows how to do it.
Assume your viewer page looks something as follows:
<html>
<head>
<title>Viewer Sample Application</title>
</head>
<frameset rows="30,*" frameborder="no" framespacing="0">
<frame id="titleFrame" frameborder="no" marginwidth="0" marginheight="0" scrolling="no" src="title.html">
<frame id="viewerFrame" frameborder="no" marginwidth="0" marginheight="0" scrolling="no" src="[URL TO AJAX VIEWER]">
</frameset>
</html>
Insert the following script block in the head of the page:
<script type="text/javascript">
// Map loaded handler
function OnMapInitialized() {
// Map has been initialized now we're off to the races.
alert("Map has been initialized");
}
window.onload = function() {
//Timer variable
var timer;
// This is our "watch" function. What we are doing here is
// repeatedly checking the mapInit value of the Map Frame. When
// mapInit is true, then the map has been loaded.
var watch = function() {
// What we are doing here is attempting to access the mapInit
// variable of the Map frame. The reason the code is in a try-catch
// is because chances are that this code access the DOM
// of the map frame before its DOM has been initialized.
try {
var mapFrame = viewerFrame.mapFrame;
if(mapFrame.mapInit) {
// Remove the timer so this watch function stops executing
clearInterval(timer);
// Call our custom handler
OnMapInitialized();
}
}
catch(e) {
}
};
// Start the "watching" process. We basically invoke the watch function
// every 200ms until the map has been loaded.
timer = setInterval(watch, 200);
};
</script>
Handling viewer selection¶
This sample will show how to handle the selection in the ajax viewer. This assumes the html is the same as the previous example.
The code “overrides” the OnSelectionChanged function of the map frame (this is called by the map frame when selection changes) and replaces it with our own.
Insert the following script block in the head of the page:
<script type="text/javascript">
//Function variable to store the original OnSelectionChanged
var origOnSelectionChanged = null;
//Our custom selection handler
function MySelectionHandler()
{
//This is important. We don't want to replace the original function, rather
//we want to attach our code into the execution sequence. So we call the original
//function first.
origOnSelectionChanged();
//Now our code goes here. For our example, we'll just show the number of objects selected.
var count = viewerFrame.GetMapFrame().GetSelectedCount();
alert(count + " features selected");
}
window.onload = function() {
//Timer variable
var timer;
// This is our "watch" function. What we are doing here is
// repeatedly checking the mapInit value of the Map Frame. When
// mapInit is true, then the map has been loaded.
var watch = function() {
// What we are doing here is attempting to access the mapInit
// variable of the Map frame. The reason the code is in a try-catch
// is because chances are that this code access the DOM
// of the map frame before its DOM has been initialized.
try {
var mapFrame = viewerFrame.mapFrame;
if(mapFrame.mapInit) {
// Remove the timer so this watch function stops executing
clearInterval(timer);
// Replace the OnSelectionChanged function with our own function.
// It is safe to do this now because the DOM for the map frame is fully initialized.
// Store old function
origOnSelectionChanged = mapFrame.OnSelectionChanged;
// Now replace with our own.
mapFrame.OnSelectionChanged = MySelectionHandler;
}
}
catch(e) {
}
};
// Start the "watching" process. We basically invoke the watch function
// every 200ms until the map has been loaded.
timer = setInterval(watch, 200);
};
</script>
when you make a selection on the map, the code will display a dialog showing how many features were selected.
Note: Our custom handler executes when a selection has changed. So clearing the selection, for example will also call the handler even though we haven’t actually made a selection.
JavaScript: Invoke Viewer Command on startup¶
This html page can automatically invoke a named viewer command on viewer startup based on the value of a Cmd query string property. This uses the InitialTask property of the Web Layout and requires that the Task Pane is set to be visible
For example setting this initial task pane url in the Web Layout:
http://path/to/autostart.html?Cmd=Measure
Will launch the Measure command on viewer startup.
As you can see from the code below, we need to employ initialization checks just like in the example (JavaScript: Hooking to events in the AJAX viewer), to make sure we can start using the Viewer API when the frames have been fully initialized.
autostart.html
<html>
<head>
<title>Auto-start command in task pane</title>
<script type="text/javascript">
var viewerFrame = parent.parent;
function GetQueryStringValue(key)
{
key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var qs = regex.exec(window.location.href);
if(qs == null)
return "";
else
return qs[1];
}
function GetCommandIndex(name)
{
var cmds = viewerFrame.GetCommands();
for(var i = 0; i < cmds.length; i++)
{
//This command array is not sequential, there may be holes
//so we have to test element existence before testing name equality
if (cmds[i] && cmds[i].name == name)
return i;
}
return -1;
}
function OnMapInitialized()
{
var cmdName = GetQueryStringValue("Cmd");
var i = GetCommandIndex(cmdName);
if (i < 0)
alert("Command not found: " + cmdName);
else
viewerFrame.ExecuteCommand(i);
}
window.onload = function() {
//Timer variable
var timer;
// This is our "watch" function. What we are doing here is
// repeatedly checking the mapInit value of the Map Frame. When
// mapInit is true, then the map has been loaded.
var watch = function() {
// What we are doing here is attempting to access the mapInit
// variable of the Map frame. The reason the code is in a try-catch
// is because chances are that this code access the DOM
// of the map frame before its DOM has been initialized.
try {
var mapFrame = viewerFrame.mapFrame;
if(mapFrame.mapInit) {
// Remove the timer so this watch function stops executing
clearInterval(timer);
// Call our custom handler
OnMapInitialized();
}
}
catch(e) {
}
};
// Start the "watching" process. We basically invoke the watch function
// every 200ms until the map has been loaded.
timer = setInterval(watch, 200);
};
</script>
</head>
<body>
</body>
</html>
PHP: Dynamically setting initial map view and scale¶
The following script allows us to set the initial x, y and scale attributes of a map using the MapGuide Ajax Viewer. It expects the values to be passed to the script as querystring parameters, e.g.
It works by taking a copy of the WebLayout? stored in the Library repository and changing the <CenterX/>, <CenterY/> and <Scale/> elements. The updated XML is written into the Session and is used as the target when the page is ultimately redirected.
This code could easily be converted to C# (or whatever).
Things to note¶
- A side-effect of the code is that it facilitates anonymous connections
- The parameter-checking could be made a little more robust
- The $wl variable should be changed to reflect the relevant WebLayout identifier
The code¶
<?php
//
// Vital includes.
//
$viewerDir = "mapviewerphp\\";
include $viewerDir . "constants.php";
include $viewerDir . "common.php";
//
// Check and get the required parameters.
//
if (!isset($_REQUEST["x"]) || !isset($_REQUEST["y"]) || !isset($_REQUEST["scale"])) {
echo "<Error>One or more of the required arguments is missing.</Error>";
exit;
}
$x = $_REQUEST["x"];
$y = $_REQUEST["y"];
$scale = $_REQUEST["scale"];
//
// Usual initialisation step.
//
InitializeWebTier();
//
// Obtain a new session ID for this anonymous user, use it to set up
// a new site connection and use that to create a resource service.
//
$site = new MgSite();
$site->Open(new MgUserInformation("Anonymous", ""));
$sessionId = $site->CreateSession();
$siteConnection = new MgSiteConnection();
$siteConnection->Open(new MgUserInformation($sessionId));
$resourceService = $siteConnection->CreateService(MgServiceType::ResourceService);
//
// Read the web layout into an XML DOM document object.
//
$wl = "Library://WebPID/WebPID_SDF_Static.WebLayout"; // TODO Constant!
$wlResourceId = new MgResourceIdentifier($wl);
$wlReader = $resourceService->GetResourceContent($wlResourceId);
$wlXml = $wlReader->ToString();
$wlDomDoc = DOMDocument::loadXML($wlXml);
//
// Now, update the initial x, y and scale values with the desired values.
//
$nodeCenterX = $wlDomDoc->getElementsByTagName("CenterX")->item(0);
$nodeCenterX->nodeValue = "$x";
$nodeCenterY = $wlDomDoc->getElementsByTagName("CenterY")->item(0);
$nodeCenterY->nodeValue = "$y";
$nodeScale = $wlDomDoc->getElementsByTagName("Scale")->item(0);
$nodeScale->nodeValue = "$scale";
//
// Prepare the updated XML to be written out to the session.
//
$updatedXml = $wlDomDoc->saveXML();
$byteSource = new MgByteSource($updatedXml, strlen($updatedXml));
//
// Create a web layout in the session to hold the updated version
// from the library.
//
$sessionMapName = $wlResourceId->GetName();
$sessionWebLayout = "Session:$sessionId//$sessionMapName.WebLayout";
$sessionResourceId = new MgResourceIdentifier($sessionWebLayout);
//
// Write the updated web layout to the session.
//
$resourceService->SetResource($sessionResourceId, $byteSource->GetReader(), null);
//
// Redirect to the Ajax viewer pointing at the map at the desired coordinates.
//
$redirectTo = "mapguide/mapviewerajax/?SESSION=$sessionId&WEBLAYOUT=$sessionWebLayout";
$host = $_SERVER["HTTP_HOST"];
$url = "http://$host/$redirectTo";
//
// Redirect!
//
header("Location: $url");
exit;
?>