[mapguide-commits] r6524 - trunk/MgDev/Doc/devguide/source

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sat Feb 18 12:35:31 EST 2012


Author: jng
Date: 2012-02-18 09:35:31 -0800 (Sat, 18 Feb 2012)
New Revision: 6524

Modified:
   trunk/MgDev/Doc/devguide/source/analyzing_features.rst
   trunk/MgDev/Doc/devguide/source/custom_output.rst
   trunk/MgDev/Doc/devguide/source/digitizing_and_redlining.rst
   trunk/MgDev/Doc/devguide/source/introduction.rst
   trunk/MgDev/Doc/devguide/source/mapguide_advanced.rst
   trunk/MgDev/Doc/devguide/source/mapguide_ajax_viewer.rst
   trunk/MgDev/Doc/devguide/source/mapguide_cookbook.rst
   trunk/MgDev/Doc/devguide/source/modifying_maps_and_layers.rst
   trunk/MgDev/Doc/devguide/source/working_with_feature_data.rst
Log:
#1614: Add more .net samples (copy/pasted from the *now completed* .net devguide sample application). Also clean up page links (from page numbers to actual section links). Added some select code samples to the MapGuide Cookbook section.

Modified: trunk/MgDev/Doc/devguide/source/analyzing_features.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/analyzing_features.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/analyzing_features.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -19,6 +19,8 @@
 .. index::
     single: Geometry: Representations
 
+.. _representations-of-geometry:
+
 Representations of Geometry
 ---------------------------
 
@@ -108,12 +110,8 @@
 Comparing Geometry Objects
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. todo::
-    Update page number reference with section link
-
 The ``MgGeometry`` class contains methods for comparing different geometry
-objects. These are similar to the spatial filters described in Selecting with the
-Web API on page 39. Methods to test spatial relationships include:
+objects. These are similar to the spatial filters described in :ref:`selecting-with-web-api`. Methods to test spatial relationships include:
 
  * ``Contains()``
  * ``Crosses()``
@@ -365,9 +363,6 @@
 Temporary Feature Sources
 -------------------------
 
-.. todo::
-    Update page number reference with section link
-
 Many geometric analysis operations require creating new features and new
 feature sources. For example, drawing a buffer around a point on a map requires
 a layer to display the buffer polygon, and the layer requires a feature source.
@@ -521,7 +516,7 @@
 
 To display features from a temporary feature source in a map, create a layer
 definition that refers to the feature source. Use the techniques described in
-Modifying Maps and Layers on page 57.
+:ref:`modifying-maps-and-layers`.
 
 .. index::
     single: Features; Inserting Features
@@ -535,9 +530,6 @@
 Inserting, Deleting and Updating Features
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. todo::
-    Update page number reference with section link
-
 To change data in a feature source, create an MgFeatureCommandCollection
 object. This can contain commands to insert, delete, or update features in an
 FDO data source. The commands are executed sequentially. For FDO providers
@@ -702,7 +694,7 @@
 
 To update existing features, create an MgPropertyCollection object that
 contains the new values for the properties and a filter expression that selects
-the correct feature or features. See Querying Feature Data on page 38 for details
+the correct feature or features. See :ref:`querying-feature-data` for details
 about filter expressions.
 
 .. index::
@@ -878,11 +870,7 @@
 Example
 -------
 
-.. todo::
-    Update page number reference with section link
-
-This example builds on the example from Working With the Active Selection
-on page 48. Instead of listing the parcels in the selection, it creates a series of
+This example builds on the example from :ref:`working-with-the-active-selection`. Instead of listing the parcels in the selection, it creates a series of
 concentric buffers around the selection, showing increasing distance. The
 code sections below contain the significant additions in this example. The
 complete source code is available with the Developer's Guide samples.
@@ -936,30 +924,6 @@
     // If it does not exist, create a feature source and
     // a layer to hold the buffer.
 
-    /*
-    // Old way, pre MapGuide OS 2.0. Kept here for reference
-    try
-    {
-      $bufferLayer = $map->GetLayers()->GetItem('Buffer');
-      $bufferFeatureResId = new MgResourceIdentifier($bufferLayer->GetFeatureSourceId());
-
-      $commands = new MgFeatureCommandCollection();
-      $commands->Add(new MgDeleteFeatures('BufferClass', "ID like '%'"));
-
-      $featureService->UpdateFeatures($bufferFeatureResId, $commands, false);
-    }
-    catch (MgObjectNotFoundException $e)
-    {
-      // When an MgObjectNotFoundException is thrown, the layer
-      // does not exist and must be created.
-
-      $bufferFeatureResId = new MgResourceIdentifier("Session:" . $sessionId . "//Buffer.FeatureSource");
-      CreateBufferFeatureSource($featureService, $mapWktSrs, $bufferFeatureResId);
-      $bufferLayer = CreateBufferLayer($resourceService, $bufferFeatureResId, $sessionId);
-      $map->GetLayers()->Insert(0, $bufferLayer);
-    }
-    */
-    
     // This is how things can be done now
     $layerIndex = $map->GetLayers()->IndexOf('Buffer');
     if ($layerIndex < 0)
@@ -986,7 +950,45 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    int bufferRingSize = 100; // measured in metres
+    int bufferRingCount = 5;
 
+    // Set up some objects for coordinate conversion
+
+    String mapWktSrs = map.GetMapSRS();
+    MgAgfReaderWriter agfReaderWriter = new MgAgfReaderWriter();
+    MgWktReaderWriter wktReaderWriter = new MgWktReaderWriter();
+    MgCoordinateSystemFactory coordinateSystemFactory = new MgCoordinateSystemFactory();
+    MgCoordinateSystem srs = coordinateSystemFactory.Create(mapWktSrs);
+    MgMeasure srsMeasure = srs.GetMeasure();
+
+    BufferHelper helper = new BufferHelper(Server);
+
+    // Check for a buffer layer. If it exists, delete
+    // the current features.
+    // If it does not exist, create a feature source and
+    // a layer to hold the buffer.
+
+    MgLayer bufferLayer = null;
+    int layerIndex = map.GetLayers().IndexOf("Buffer");
+    if (layerIndex < 0)
+    {
+        // The layer does not exist and must be created.
+
+        MgResourceIdentifier bufferFeatureResId = new MgResourceIdentifier("Session:" + sessionId + "//Buffer.FeatureSource");
+        helper.CreateBufferFeatureSource(featureService, mapWktSrs, bufferFeatureResId);
+        bufferLayer = helper.CreateBufferLayer(resourceService, bufferFeatureResId, sessionId);
+        map.GetLayers().Insert(0, bufferLayer);
+    }
+    else
+    {
+        bufferLayer = (MgLayer)map.GetLayers().GetItem(layerIndex);
+        MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
+        commands.Add(new MgDeleteFeatures("BufferClass", "ID like '%'"));
+
+        bufferLayer.UpdateFeatures(commands);
+    }
+
 **Java**
     
 .. highlight:: java
@@ -1039,19 +1041,12 @@
         $commands->Add(new MgInsertFeatures('BufferClass', $properties));
     }
 
-    // Old way, pre MapGuide OS 2.0
-    //$results = $featureService->UpdateFeatures($bufferFeatureResId, $commands, false);
-    
-    // New way, post MapGuide OS 2.0
     $results = $bufferLayer->UpdateFeatures($commands);
 
     $bufferLayer->SetVisible(true);
     $bufferLayer->ForceRefresh();
     $bufferLayer->SetDisplayInLegend(true);
     
-    //If you created a MgMap using the empty constructor
-    //$map->Save($resourceService);
-    
     //If you created a MgMap with a MgSiteConnection
     $map->Save();
 
@@ -1061,7 +1056,45 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    MgGeometryCollection inputGeometries = new MgGeometryCollection();
+    while (featureReader.ReadNext())
+    {
+        MgByteReader featureGeometryData = featureReader.GetGeometry("SHPGEOM");
+        MgGeometry featureGeometry = agfReaderWriter.Read(featureGeometryData);
 
+        inputGeometries.Add(featureGeometry);
+    }
+
+    MgGeometryFactory geometryFactory = new MgGeometryFactory();
+    MgGeometry mergedGeometries = geometryFactory.CreateMultiGeometry(inputGeometries);
+
+    // Add buffer features to the temporary feature source.
+    // Create multiple concentric buffers to show area.
+    // If the stylization for the layer draws the features
+    // partially transparent, the concentric rings will be
+    // progressively darker towards the center.
+    // The stylization is set in the layer template file, which
+    // is used in function CreateBufferLayer().
+
+    MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
+    for (int bufferRing = 0; bufferRing < bufferRingCount; bufferRing++)
+    {
+        double bufferDist = srs.ConvertMetersToCoordinateSystemUnits(bufferRingSize * (bufferRing + 1));
+        MgGeometry bufferGeometry = mergedGeometries.Buffer(bufferDist, srsMeasure);
+
+        MgPropertyCollection properties = new MgPropertyCollection();
+        properties.Add(new MgGeometryProperty("BufferGeometry", agfReaderWriter.Write(bufferGeometry)));
+
+        commands.Add(new MgInsertFeatures("BufferClass", properties));
+    }
+
+    bufferLayer.UpdateFeatures(commands);
+
+    bufferLayer.SetVisible(true);
+    bufferLayer.ForceRefresh();
+    bufferLayer.SetDisplayInLegend(true);
+    map.Save();
+
 **Java**
     
 .. highlight:: java
@@ -1069,13 +1102,15 @@
 
     //This code fragment assumes you have imported the org.osgeo.mapguide namespace
     
+    //No code sample available yet.
+    
 The functions ``CreateBufferFeatureSource()`` and ``CreateBufferLayer()`` are
 in ``bufferfunctions.php``. ``CreateBufferFeatureSource()`` creates a temporary
 feature source, with a single feature class, ``BufferClass``. The feature class has
 two properties, ``ID`` and ``BufferGeometry``. ``ID`` is autogenerated, so it does not
 need to be added with a new feature. ``CreateBufferLayer()`` modifies a layer
 definition from an external file and saves it to the repository. For more details,
-see Modifying Maps and Layers on page 57.
+see :ref:`modifying-maps-and-layers`.
 
 **PHP**
 
@@ -1142,7 +1177,106 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    
+    //NOTE: This is only subset of the BufferHelper relevant to this particular chapter
+    //of the developer's guide. For the full source, see bufferfunctions.aspx from the
+    //.net Developer Guide sample.
+    
+    public class BufferHelper
+    {
+        private HttpServerUtility _server;
 
+        public BufferHelper(HttpServerUtility server) 
+        { 
+            _server = server;
+        }
+        
+        HttpServerUtility Server { get { return _server; } }
+    
+        public void CreateBufferFeatureSource(MgFeatureService featureService, String wkt, MgResourceIdentifier bufferFeatureResId)
+        {
+            MgClassDefinition bufferClass = new MgClassDefinition();
+            bufferClass.SetName("BufferClass");
+            MgPropertyDefinitionCollection properties = bufferClass.GetProperties();
+
+            MgDataPropertyDefinition idProperty = new MgDataPropertyDefinition("ID");
+            idProperty.SetDataType(MgPropertyType.Int32);
+            idProperty.SetReadOnly(true);
+            idProperty.SetNullable(false);
+            idProperty.SetAutoGeneration(true);
+            properties.Add(idProperty);
+
+            MgGeometricPropertyDefinition polygonProperty = new MgGeometricPropertyDefinition("BufferGeometry");
+            polygonProperty.SetGeometryTypes(MgFeatureGeometricType.Surface);
+            polygonProperty.SetHasElevation(false);
+            polygonProperty.SetHasMeasure(false);
+            polygonProperty.SetReadOnly(false);
+            polygonProperty.SetSpatialContextAssociation("defaultSrs");
+            properties.Add(polygonProperty);
+
+            MgPropertyDefinitionCollection idProperties = bufferClass.GetIdentityProperties();
+            idProperties.Add(idProperty);
+
+            bufferClass.SetDefaultGeometryPropertyName("BufferGeometry");
+
+            MgFeatureSchema bufferSchema = new MgFeatureSchema("BufferLayerSchema", "temporary schema to hold a buffer");
+            bufferSchema.GetClasses().Add(bufferClass);
+
+            MgCreateSdfParams sdfParams = new MgCreateSdfParams("defaultSrs", wkt, bufferSchema);
+
+            featureService.CreateFeatureSource(bufferFeatureResId, sdfParams);
+        }
+
+        public MgLayer CreateBufferLayer(MgResourceService resourceService, MgResourceIdentifier bufferFeatureResId, String sessionId)
+        {
+            // Load the layer definition template into
+            // a XmlDocument object, find the "ResourceId" element, and
+            // modify its content to reference the temporary
+            // feature source.
+
+            XmlDocument doc = new XmlDocument();
+            doc.Load(Server.MapPath("bufferlayerdefinition.xml"));
+            XmlNode featureSourceNode = doc.GetElementsByTagName("ResourceId")[0];
+            featureSourceNode.InnerText = bufferFeatureResId.ToString();
+
+            // Get the updated layer definition from the XmlDocument
+            // and save it to the session repository using the
+            // ResourceService object.
+
+            MgByteSource byteSource = null;
+            using (MemoryStream ms = new MemoryStream())
+            {
+                doc.Save(ms);
+                ms.Position = 0L;
+                
+                //Note we do this to ensure our XML content is free of any BOM characters
+                byte [] layerDefinition = ms.ToArray();
+                Encoding utf8 = Encoding.UTF8;
+                String layerDefStr = new String(utf8.GetChars(layerDefinition));
+                layerDefinition = new byte[layerDefStr.Length-1];
+                int byteCount = utf8.GetBytes(layerDefStr, 1, layerDefStr.Length-1, layerDefinition, 0);
+                
+                byteSource = new MgByteSource(layerDefinition, layerDefinition.Length);
+                byteSource.SetMimeType(MgMimeType.Xml);
+            }
+
+            MgResourceIdentifier tempLayerResId = new MgResourceIdentifier("Session:" + sessionId + "//Buffer.LayerDefinition");
+
+            resourceService.SetResource(tempLayerResId, byteSource.GetReader(), null);
+
+            // Create an MgLayer object based on the new layer definition
+            // and return it to the caller.
+
+            MgLayer bufferLayer = new MgLayer(tempLayerResId, resourceService);
+            bufferLayer.SetName("Buffer");
+            bufferLayer.SetLegendLabel("Buffer");
+            bufferLayer.SetDisplayInLegend(true);
+            bufferLayer.SetSelectable(false);
+            
+            return bufferLayer;
+        }
+    }
+
 **Java**
     
 .. highlight:: java
@@ -1150,6 +1284,8 @@
 
     //This code fragment assumes you have imported the org.osgeo.mapguide namespace
     
+    //No code sample available yet
+    
 There is an additional example in the Developer's Guide samples. It queries
 the parcels in the buffer area and selects parcels that match certain criteria.
 The selection is done using a query that combines a basic filter and a spatial
@@ -1175,14 +1311,36 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    
+    double bufferDist = srs.ConvertMetersToCoordinateSystemUnits(bufferRingSize);
+    MgGeometry bufferGeometry = mergedGeometries.Buffer(bufferDist, srsMeasure);
 
+    // Create a filter to select parcels within the buffer. Combine
+    // a basic filter and a spatial filter to select all parcels
+    // within the buffer that are of type "MFG".
+
+    queryOptions = new MgFeatureQueryOptions();
+    queryOptions.SetFilter("RTYPE = 'MFG'");
+    queryOptions.SetSpatialFilter("SHPGEOM", bufferGeometry, MgFeatureSpatialOperations.Inside);
+
 **Java**
     
 .. highlight:: java
 .. code-block:: java
 
     //This code fragment assumes you have imported the org.osgeo.mapguide namespace
+    
+    double bufferDist = srs.ConvertMetersToCoordinateSystemUnits(bufferRingSize);
+    MgGeometry bufferGeometry = mergedGeometries.Buffer(bufferDist, srsMeasure);
 
+    // Create a filter to select parcels within the buffer. Combine
+    // a basic filter and a spatial filter to select all parcels
+    // within the buffer that are of type "MFG".
+
+    queryOptions = new MgFeatureQueryOptions();
+    queryOptions.SetFilter("RTYPE = 'MFG'");
+    queryOptions.SetSpatialFilter("SHPGEOM", bufferGeometry, MgFeatureSpatialOperations.Inside);
+
 It creates an additional feature source that contains point markers for each of
 the selected parcels.
 
@@ -1215,10 +1373,6 @@
 
     if ($parcelMarkerCommands->GetCount() > 0)
     {
-        // Old way, pre MapGuide OS 2.0. Kept here for reference
-        //$featureService->UpdateFeatures($parcelFeatureResId, $parcelMarkerCommands, false);
-        
-        // New way, post MapGuide OS 2.0
         $parcelMarkerLayer->UpdateFeatures($parcelMarkerCommands);
     }
     else
@@ -1232,10 +1386,70 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    
+    // Get the features from the feature source,
+    // determine the centroid of each selected feature, and
+    // add a point to the ParcelMarker layer to mark the
+    // centroid.
+    // Collect all the points into an MgFeatureCommandCollection,
+    // so they can all be added in one operation.
+    
+    MgFeatureCommandCollection parcelMarkerCommands = new MgFeatureCommandCollection();
+    while (featureReader.ReadNext())
+    {
+        MgByteReader byteReader = featureReader.GetGeometry("SHPGEOM");
+        MgGeometry geometry = agfReaderWriter.Read(byteReader);
+        MgPoint point = geometry.GetCentroid();
 
+        // Create an insert command for this parcel.
+        MgPropertyCollection properties = new MgPropertyCollection();
+        properties.Add(new MgGeometryProperty("ParcelLocation", agfReaderWriter.Write(point)));
+        parcelMarkerCommands.Add(new MgInsertFeatures("ParcelMarkerClass", properties));
+    }
+    featureReader.Close();
+
+    if (parcelMarkerCommands.GetCount() > 0)
+    {
+        parcelMarkerLayer.UpdateFeatures(parcelMarkerCommands);
+    }
+    else
+    {
+        Response.Write("</p><p>No parcels within the buffer area match.");
+    }
+
 **Java**
     
 .. highlight:: java
 .. code-block:: java
 
-    //This code fragment assumes you have imported the org.osgeo.mapguide namespace
\ No newline at end of file
+    //This code fragment assumes you have imported the org.osgeo.mapguide namespace
+    
+    // Get the features from the feature source,
+    // determine the centroid of each selected feature, and
+    // add a point to the ParcelMarker layer to mark the
+    // centroid.
+    // Collect all the points into an MgFeatureCommandCollection,
+    // so they can all be added in one operation.
+    
+    MgFeatureCommandCollection parcelMarkerCommands = new MgFeatureCommandCollection();
+    while (featureReader.ReadNext())
+    {
+        MgByteReader byteReader = featureReader.GetGeometry("SHPGEOM");
+        MgGeometry geometry = agfReaderWriter.Read(byteReader);
+        MgPoint point = geometry.GetCentroid();
+
+        // Create an insert command for this parcel.
+        MgPropertyCollection properties = new MgPropertyCollection();
+        properties.Add(new MgGeometryProperty("ParcelLocation", agfReaderWriter.Write(point)));
+        parcelMarkerCommands.Add(new MgInsertFeatures("ParcelMarkerClass", properties));
+    }
+    featureReader.Close();
+
+    if (parcelMarkerCommands.GetCount() > 0)
+    {
+        parcelMarkerLayer.UpdateFeatures(parcelMarkerCommands);
+    }
+    else
+    {
+        response.getWriter().Write("</p><p>No parcels within the buffer area match.");
+    }
\ No newline at end of file

Modified: trunk/MgDev/Doc/devguide/source/custom_output.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/custom_output.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/custom_output.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -82,6 +82,10 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    
+    MgByteReader byteReader = renderingService.RenderMap(map, selection, envelope, imageWidth, imageHeight, color, "PNG");
+    //See common/common.aspx for implementation of Utility.OutputReaderContent()
+    Utility.OutputReaderContent(byteReader, Response);
 
 **Java**
     
@@ -89,6 +93,8 @@
 .. code-block:: java
 
     //This code fragment assumes you have imported the org.osgeo.mapguide namespace
+    
+    //Code sample not yet available
 
 .. index::
    single: Custom Output; dwf
@@ -162,10 +168,40 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    
+    MgDwfVersion dwfVersion = new MgDwfVersion("6.01", "1.2");
 
+    MgPlotSpecification plotSpec = new MgPlotSpecification(8.5f, 11.0f, MgPageUnitsType.Inches, 0.5f, 0.5f, 0.5f, 0.5f);
+
+    MgResourceIdentifier layoutRes = new MgResourceIdentifier("Library://Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout");
+    MgLayout layout =  new MgLayout(layoutRes, "City of Sheboygan", MgPageUnitsType.Inches);
+
+    MgMapPlotCollection plotCollection = new MgMapPlotCollection();
+
+    MgMapPlot plot1 = new MgMapPlot(map, plotSpec, layout);
+    plot1.SetCenterAndScale(map.GetViewCenter().GetCoordinate(), map.GetViewScale() * 2);
+    plotCollection.Add(plot1);
+
+    // Create a second map for the second sheet in the DWF. This second sheet uses the print layout
+    // to display a page title and legend.
+
+    MgMap map2 = new MgMap(siteConnection);
+    map2.Create(map.GetMapDefinition(), "Sheet 2");
+    MgMapPlot plot2 = new MgMapPlot(map2, plotSpec, layout);
+    plot2.SetCenterAndScale(map.GetViewCenter().GetCoordinate(), map.GetViewScale());
+    plotCollection.Add(plot2);
+
+    MgByteReader byteReader = mappingService.GenerateMultiPlot(plotCollection, dwfVersion);
+
+    // Now output the resulting DWF.
+    // See common/common.aspx for implementation of Utility.OutputReaderContent()
+    Utility.OutputReaderContent(byteReader, Response);
+
 **Java**
     
 .. highlight:: java
 .. code-block:: java
 
     //This code fragment assumes you have imported the org.osgeo.mapguide namespace
+    
+    //Code sample not yet available

Modified: trunk/MgDev/Doc/devguide/source/digitizing_and_redlining.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/digitizing_and_redlining.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/digitizing_and_redlining.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -168,14 +168,96 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    
+    // Create a temporary feature source to draw the lines on
 
+    // Create a feature class definition for the new feature
+    // source
+    MgClassDefinition classDefinition = new MgClassDefinition();
+    classDefinition.SetName("Lines");
+    classDefinition.SetDescription("Lines to display.");
+    String geometryPropertyName="SHPGEOM";
+    classDefinition.SetDefaultGeometryPropertyName( geometryPropertyName);
+
+    // Create an identify property
+    MgDataPropertyDefinition identityProperty = new MgDataPropertyDefinition("KEY");
+    identityProperty.SetDataType(MgPropertyType.Int32);
+    identityProperty.SetAutoGeneration(true);
+    identityProperty.SetReadOnly(true);
+    // Add the identity property to the class definition
+    classDefinition.GetIdentityProperties().Add(identityProperty);
+    classDefinition.GetProperties().Add(identityProperty);
+
+    // Create a name property
+    MgDataPropertyDefinition nameProperty = new MgDataPropertyDefinition("NAME");
+    nameProperty.SetDataType(MgPropertyType.String);
+    // Add the name property to the class definition
+    classDefinition.GetProperties().Add(nameProperty);
+
+    // Create a geometry property
+    MgGeometricPropertyDefinition geometryProperty = new MgGeometricPropertyDefinition(geometryPropertyName);
+    geometryProperty.SetGeometryTypes(MgFeatureGeometricType.Surface);
+    // Add the geometry property to the class definition
+    classDefinition.GetProperties().Add(geometryProperty);
+
+    // Create a feature schema
+    MgFeatureSchema featureSchema = new MgFeatureSchema("SHP_Schema", "Line schema");
+    // Add the feature schema to the class definition
+    featureSchema.GetClasses().Add(classDefinition);
+
+    // Create the feature source
+    String wkt = map.GetMapSRS();
+    MgCreateSdfParams sdfParams = new MgCreateSdfParams("spatial context", wkt, featureSchema);
+    featureService.CreateFeatureSource(resourceIdentifier, sdfParams);
+
 **Java**
     
 .. highlight:: java
 .. code-block:: java
 
     //This code fragment assumes you have imported the org.osgeo.mapguide namespace
+    
+    // Create a temporary feature source to draw the lines on
 
+    // Create a feature class definition for the new feature
+    // source
+    MgClassDefinition classDefinition = new MgClassDefinition();
+    classDefinition.SetName("Lines");
+    classDefinition.SetDescription("Lines to display.");
+    String geometryPropertyName="SHPGEOM";
+    classDefinition.SetDefaultGeometryPropertyName( geometryPropertyName);
+
+    // Create an identify property
+    MgDataPropertyDefinition identityProperty = new MgDataPropertyDefinition("KEY");
+    identityProperty.SetDataType(MgPropertyType.Int32);
+    identityProperty.SetAutoGeneration(true);
+    identityProperty.SetReadOnly(true);
+    // Add the identity property to the class definition
+    classDefinition.GetIdentityProperties().Add(identityProperty);
+    classDefinition.GetProperties().Add(identityProperty);
+
+    // Create a name property
+    MgDataPropertyDefinition nameProperty = new MgDataPropertyDefinition("NAME");
+    nameProperty.SetDataType(MgPropertyType.String);
+    // Add the name property to the class definition
+    classDefinition.GetProperties().Add(nameProperty);
+
+    // Create a geometry property
+    MgGeometricPropertyDefinition geometryProperty = new MgGeometricPropertyDefinition(geometryPropertyName);
+    geometryProperty.SetGeometryTypes(MgFeatureGeometricType.Surface);
+    // Add the geometry property to the class definition
+    classDefinition.GetProperties().Add(geometryProperty);
+
+    // Create a feature schema
+    MgFeatureSchema featureSchema = new MgFeatureSchema("SHP_Schema", "Line schema");
+    // Add the feature schema to the class definition
+    featureSchema.GetClasses().Add(classDefinition);
+
+    // Create the feature source
+    String wkt = map.GetMapSRS();
+    MgCreateSdfParams sdfParams = new MgCreateSdfParams("spatial context", wkt, featureSchema);
+    featureService.CreateFeatureSource(resourceIdentifier, sdfParams);
+
 .. index::
     single: Redlining; Create a Layer
 
@@ -186,4 +268,4 @@
     Update page number reference with section link
 
 The final step is to create a new layer to display the feature source, the same
-way it was done in Adding Layers To A Map on page 68.
\ No newline at end of file
+way it was done in :ref:`adding-layers-to-a-map`
\ No newline at end of file

Modified: trunk/MgDev/Doc/devguide/source/introduction.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/introduction.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/introduction.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -431,8 +431,7 @@
 
 Once the site connection and any other service connections are open, the
 page can use MapGuide Web API calls to retrieve and process data. Output
-goes to the task pane or back to the Viewer. See The MapGuide Viewer on
-page 15 for details about sending data to the Viewer.
+goes to the task pane or back to the Viewer. See :ref:`mapguide-ajax-viewer` for details about sending data to the Viewer.
 
 .. note::
 

Modified: trunk/MgDev/Doc/devguide/source/mapguide_advanced.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/mapguide_advanced.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/mapguide_advanced.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -169,12 +169,6 @@
 
     Not all data stores support the `ApplySchema` API. Check the FDO provider capabilities of the feature source to determine if such an operation is possible.
 
-Quering Data with Expressions and Filters
------------------------------------------
-
-Relationship to FDO
--------------------
-
 The Geospatial Platform and MapGuide's role in it
 -------------------------------------------------
 

Modified: trunk/MgDev/Doc/devguide/source/mapguide_ajax_viewer.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/mapguide_ajax_viewer.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/mapguide_ajax_viewer.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -1,5 +1,7 @@
 .. index::
    single: viewer
+
+.. _mapguide-ajax-viewer:
    
 The MapGuide AJAX Viewer
 ========================

Modified: trunk/MgDev/Doc/devguide/source/mapguide_cookbook.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/mapguide_cookbook.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/mapguide_cookbook.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -2,4 +2,377 @@
    single: samples
    
 MapGuide Cookbook
------------------
\ No newline at end of file
+=================
+
+This section is a select list of MapGuide code samples. See `Trac <http://trac.osgeo.org/mapguide/wiki/CodeSamples>`_ for more samples.
+
+.. _event-hooking-example:
+
+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: 
+
+.. highlight:: html
+.. code-block:: html
+
+    <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: 
+
+.. highlight:: html
+.. code-block:: html
+
+    <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: 
+
+.. highlight:: html
+.. code-block:: html
+
+    <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 (:ref:`event-hooking-example`), to make sure we can start using the Viewer API when the frames have been fully initialized.
+
+autostart.html 
+
+.. highlight:: html
+.. code-block:: 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.
+
+     http://localhost/mapguide/set_intial_view.php?x=507700&y=186000&scale=400000
+
+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
+^^^^^^^^
+
+.. highlight:: php
+.. code-block:: php
+
+    <?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;
+
+    ?>
\ No newline at end of file

Modified: trunk/MgDev/Doc/devguide/source/modifying_maps_and_layers.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/modifying_maps_and_layers.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/modifying_maps_and_layers.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -1,3 +1,5 @@
+.. _modifying-maps-and-layers:
+
 Modifying Maps and Layers
 =========================
 
@@ -16,9 +18,6 @@
 Adding An Existing Layer To A Map
 ---------------------------------
 
-.. todo::
-    Update page number reference with section link
-
 If the layer already exists in the resource repository, add it to the map by getting
 the map's layer collection and then adding the layer to that collection.
 
@@ -52,7 +51,7 @@
 By default, newly added layers are added to the bottom of the drawing order,
 so they may be obscured by other layers. If you want to specify where the layer
 appears in the drawing order, use the ``$layerCollection->Insert()`` method.
-For an example, see Adding Layers To A Map on page 68.
+For an example, see :ref:`adding-layers-to-a-map`.
 
 .. note::
 
@@ -64,9 +63,6 @@
 Creating Layers by Modifying XML
 --------------------------------
 
-.. todo::
-    Update page number reference with section link
-
 The easiest way to programmatically create new layers is to
 
  1. Build a prototype layer through the UI. To make the scripting simpler, this layer should have as many of the correct settings as can be determined in advance.
@@ -144,13 +140,59 @@
 .. code-block:: csharp
 
     //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    
+    // --------------------------------------------------//
+    // Open the map
+    MgMap map = new MgMap(siteConnection);
+    map.Open(mapName);
 
+    // ...
+    // --------------------------------------------------//
+    // Load a layer from XML, and use the DOM to change it
+
+    // Load the prototype layer definition into
+    // a PHP DOM object.
+    XmlDocument domDocument = new XmlDocument();
+    String layerDefPath = Server.MapPath("RecentlyBuilt.LayerDefinition");
+    if (!File.Exists(layerDefPath))
+    {
+        Response.Write("The layer definition 'RecentlyBuilt.LayerDefinition' could not be found.<BR>\n");
+        return;
+    }
+    domDocument.Load(layerDefPath);
+
+    // Get a list of all the <AreaRule><Filter> elements in
+    // the XML.
+    XmlNodeList nodes = domDocument.SelectNodes("//AreaRule/Filter");
+    // Find the correct node and change it
+    foreach (XmlNode node in nodes)
+    {
+        if (node.InnerText == "YRBUILT > 1950")
+        {
+            node.InnerText = "YRBUILT > 1980";
+        }
+    }
+
+    // Get a list of all the <LegendLabel> elements in the
+    // XML.
+    nodes = domDocument.SelectNodes("//LegendLabel");
+    // Find the correct node and change it
+    foreach (XmlNode node in nodes)
+    {
+        if (node.InnerText == "Built after 1950")
+        {
+            node.InnerText = "Built after 1980";
+        }
+    }
+
 **Java**
     
 .. highlight:: java
 .. code-block:: java
 
     //This code fragment assumes you have imported the org.osgeo.mapguide namespace
+    
+    //Code sample not yet available
 
 .. note::
 
@@ -158,7 +200,7 @@
     be considered as one way for modifying XML. By no means is this the **definitive** way.
 
 The page then goes on to save the XML to a resource and loads that resource
-into the map, as described in Adding Layers To A Map on page 68.
+into the map, as described in :ref:`adding-layers-to-a-map`.
 
 If you wish to modify an existing layer that is visible in other users' maps,
 without affecting those maps:
@@ -167,7 +209,7 @@
  2. Modify the layer and save it back to the session repository.
  3. Change the user's map to refer to the modified layer.
 
-See Adding Layers To A Map on page 68.
+See :ref:`adding-layers-to-a-map`
 
 .. index::
     single: LayerDefinitionFactory
@@ -192,7 +234,7 @@
 The ``layerdefinitionfactory`` is only available for PHP. For development using
 ASP.NET, a good alternative is to use the Visual Studio tool ``xsd.exe`` to generate
 .NET classes for the LayerDefinition schema, or to use the strongly-typed resource classes
-in the Maestro API
+in the :ref:`maestroapi`
 
 ``CreateLayerDefinition($resourceId, $featureClass, $geometry, $featureClassRange)``
 
@@ -260,9 +302,6 @@
 Example: Creating a layer that users Area Rules
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. todo::
-    Update page number reference with section link
-
 .. note::
     
     This example specifically uses the ``LayerDefinitionFactory`` class which is not available for .net and Java
@@ -298,7 +337,7 @@
     // ...
     
 The script then saves the XML to a resource and loads that resource into the
-map. See Adding Layers To A Map on page 68.
+map. See :ref:`adding-layers-to-a-map`.
 
 .. index::
     single: LayerDefinitionFactory; Line Rules
@@ -394,6 +433,8 @@
 .. index::
     single: MgMap; Adding Layers
 
+.. _adding-layers-to-a-map:
+
 Adding Layers to a Map
 ----------------------
 

Modified: trunk/MgDev/Doc/devguide/source/working_with_feature_data.rst
===================================================================
--- trunk/MgDev/Doc/devguide/source/working_with_feature_data.rst	2012-02-18 15:24:50 UTC (rev 6523)
+++ trunk/MgDev/Doc/devguide/source/working_with_feature_data.rst	2012-02-18 17:35:31 UTC (rev 6524)
@@ -51,6 +51,8 @@
 .. index::
     single: Features; Querying
 
+.. _querying-feature-data:
+
 Querying Feature Data
 ---------------------
 
@@ -64,15 +66,12 @@
 Feature Readers
 ^^^^^^^^^^^^^^^
 
-.. todo::
-    Update page number reference with section link
-
 A *feature reader*, represented by an ``MgFeatureReader`` object, is used to iterate
 through a list of features. Typically, the feature reader is created by selecting
 features from a feature source.
 
 To create a feature reader, use the ``MgFeatureService::SelectFeatures()``
-method. See Selecting with the Web API on page 39 for details about selection.
+method. See :ref:`selecting-with-web-api` details about selection.
 
 To process the features in a feature reader, use the
 ``MgFeatureReader::ReadNext()`` method. You must call this method before
@@ -105,6 +104,8 @@
 .. index::
     single: Selections
 
+.. _selecting-with-web-api:
+
 Selecting with the Web API
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -262,16 +263,13 @@
 Spatial Filters
 """""""""""""""
 
-.. todo::
-    Update page number reference with section link
-
 With spatial filters, you can do comparisons using geometric properties. For
 example, you can select all features that are inside an area on the map, or that
 intersect an area.
 
 .. note::
 
-    For more information about geometry, see Representation of Geometry on page 73.
+    For more information about geometry, see :ref:`representations-of-geometry`.
 
 There are two ways of using spatial filters:
 
@@ -460,6 +458,8 @@
 .. index::
     single: Selections; Listing Properties
 
+.. _example-selection:
+
 Example: Selection
 ^^^^^^^^^^^^^^^^^^
 
@@ -685,9 +685,6 @@
 Additional Parameters to an Invoke URL Command
 """"""""""""""""""""""""""""""""""""""""""""""
 
-.. todo:
-    Update page number references to section links
-
 With this release of MapGuide, the current selection is the only variable that
 can be passed as part of an Invoke URL command.
 
@@ -725,7 +722,7 @@
 
 gets the current selection, in XML format.
 
-See Working With the Active Selection on page 48 for details about using the
+See :ref:`working-with-the-active-selection` for details about using the
 XML data.
 
 .. note::
@@ -803,6 +800,8 @@
 .. index::
     single: Active Selection; Manipulating the Active Selection
 
+.. _working-with-the-active-selection:
+
 Working with the Active Selection
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -967,25 +966,18 @@
 Setting the Active Selection with the Web API
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. todo::
-    Update page number reference with section link
-
 To set the run-time map selection using a query, perform the following steps:
 
- * Create a selection as described in Selecting with the Web API on page 39. This creates a feature reader containing the selected features.
+ * Create a selection as described in `selecting-with-the-web-api`. This creates a feature reader containing the selected features.
  * Create an ``MgSelection`` object to hold the features in the feature reader.
  * Send the selection to the Viewer, along with a call to the Viewer API function ``SetSelectionXML()``.
 
 Example: Setting the Active Selection
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. todo::
-    Update page number reference with section link
-
 The following example combines the pieces needed to create a selection using
 the Web API and pass it back to the Viewer where it becomes the active
-selection for the map. It is an extension of the example shown in Example:
-Selection on page 43.
+selection for the map. It is an extension of the example shown :ref:`example-selection`.
 
 The PHP code in this example creates the selection XML. Following that is a
 JavaScript function that calls the ``SetSelectionXML()`` function with the
@@ -1053,7 +1045,7 @@
         }
         catch (MgException $e)
         {
-            echo $e->GetMessage();
+            echo $e->GetExceptionMessage();
             echo $e->GetDetails();
         }
         ?>
@@ -1067,6 +1059,7 @@
         function OnPageLoad()
         {
             selectionXml = '<?php echo $selectionXml; ?>';
+            parent.parent.SetSelectionXML(selectionXml);
         }
     </script>
 
@@ -1075,11 +1068,100 @@
 .. highlight:: csharp
 .. code-block:: csharp
 
-    //This code fragment assumes you have imported the OSGeo.MapGuide namespace
+    <!-- This code fragment assumes you have imported the OSGeo.MapGuide namespace -->
+    <body class="AppFrame" onLoad="OnPageLoad()">
+     
+        <h1 class="AppHeading">Select features</h1>
 
+    <%
+
+    sessionId = Request.Params["SESSION"];
+    mapName = Request.Params["MAPNAME"];
+
+    try
+    {
+
+      // Initialize the Web Extensions and connect to the Server using
+      // the Web Extensions session identifier stored in PHP session state.
+
+      MapGuideApi.MgInitializeWebTier (Constants.WebConfigPath);
+
+      MgUserInformation userInfo = new MgUserInformation(sessionId);
+      MgSiteConnection siteConnection = new MgSiteConnection();
+      siteConnection.Open(userInfo);
+
+      MgMap map = new MgMap(siteConnection);
+      map.Open(mapName);
+
+      // Get the geometry for the boundaries of District 1
+
+      MgFeatureQueryOptions districtQuery = new MgFeatureQueryOptions();
+      districtQuery.SetFilter("Autogenerated_SDF_ID = 1");
+
+      MgLayerBase layer = map.GetLayers().GetItem("Districts");
+      MgFeatureReader featureReader = layer.SelectFeatures(districtQuery);
+      MgByteReader districtGeometryData = null;
+      try {
+        featureReader.ReadNext();
+        districtGeometryData = featureReader.GetGeometry("Data");
+      } finally { //Ensures the reader is closed regardless
+        featureReader.Close();
+      }
+
+      // Convert the AGF binary data to MgGeometry.
+
+      MgAgfReaderWriter agfReaderWriter = new MgAgfReaderWriter();
+      MgGeometry districtGeometry = agfReaderWriter.Read(districtGeometryData);
+
+      // Create a filter to select the desired features. Combine
+      // a basic filter and a spatial filter.
+
+      MgFeatureQueryOptions queryOptions = new MgFeatureQueryOptions();
+      queryOptions.SetFilter("RNAME LIKE 'SCHMITT%'");
+      queryOptions.SetSpatialFilter("SHPGEOM", districtGeometry, MgFeatureSpatialOperations.Inside);
+
+      // Get the features from the feature source,
+      // turn it into a selection, then save the selection as XML.
+
+      layer = map.GetLayers().GetItem("Parcels");
+      featureReader = layer.SelectFeatures(queryOptions);
+
+      MgSelection selection = new MgSelection(map);
+      selection.AddFeatures(layer, featureReader, 0);
+      selectionXml = selection.ToXml();
+
+      Response.Write("Selecting parcels owned by Schmitt in District&nbsp;1");
+    }
+    catch (MgException e)
+    {
+      Response.Write(e.GetExceptionMessage());
+      Response.Write(e.GetDetails());
+    }
+    %>
+
+  </body>
+
+  <script language="javascript">
+
+    <!-- Emit this function and assocate it with the onLoad event for the -.
+    <!-- page so that it gets executed when this page loads in the        -.
+    <!-- browser. The function calls the SetSelectionXML method on the    -.
+    <!-- Viewer Frame, which updates the current selection on the viewer  -.
+    <!-- and the server.                                                  -.
+
+    function OnPageLoad()
+    {
+      selectionXml = '<%= selectionXml %>';
+      parent.parent.SetSelectionXML(selectionXml);
+    }
+
+  </script>
+
 **Java**
     
 .. highlight:: java
 .. code-block:: java
 
-    //This code fragment assumes you have imported the org.osgeo.mapguide namespace
\ No newline at end of file
+    //This code fragment assumes you have imported the org.osgeo.mapguide namespace
+    
+    //Code sample currently not available
\ No newline at end of file



More information about the mapguide-commits mailing list