Sie sind auf Seite 1von 13

Using the Geospatial Platform API in

AutoCAD® Map 3D and Autodesk MapGuide®


Scott McFarlane – Woolpert, Inc.

GS304-1 The AutoCAD® Map Geospatial Platform API shares many classes and methods with
Autodesk MapGuide Enterprise and MapGuide Open Source, so code written for one product can work
in another with minimal modification. This class will examine the similarities and differences in how the
API is implemented in each environment. A variety of common tasks will be demonstrated, such as
creating and modifying layer definitions, selecting features, and working with selection sets, zooming and
highlighting selected features, and performing buffer operations. We will also look at additional API
features available in AutoCAD Map, such as events and working with edit sets.

About the Speaker:


Scott is senior software engineer for the Enterprise Information Management service line at Woolpert,
Inc. He specializes in custom database applications that use Autodesk® software in the AEC, FM and
GIS industries. He has more than 25 years of programming experience, and has been integrating
databases with AutoCAD® software ever since it was possible. He is the author of AutoCAD Database
Connectivity from Autodesk Press, as well as several articles. Scott has served two two-year terms on
the AUGI® Board of Directors.

scott.mcfarlane@woolpert.com
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

Introduction
The time has come: Users of Autodesk Geospatial products can now go spatial. There are no
excuses. Rather than maintaining your maps in a DWG format, the recent releases of AutoCAD
Map 3D allow you to work directly with a variety of spatial databases, such as Oracle Spatial or
SQL Server 2008, or a spatial file format such as SHP or SDF. Your spatial data are stored in
one place – there is no import/export procedure, and none of the potential headaches of having
duplicate data. AutoCAD Map 3D 2010 makes working directly with spatial data easier than ever
by enabling the normal “CAD” tools to be used seamlessly with data from external sources.

Not only are your spatial data accessible from your desktop through AutoCAD Map 3D, your
data can also be made available to a much wider audience through the web using MapGuide
Enterprise. AutoCAD Map 3D and MapGuide Enterprise share some key elements with regard
to managing spatial data:

• Feature Data Objects (FDO) – FDO is the common data access technology used by
both products. FDO is an open source API that uses a provider-based methodology to
allow applications to read/write spatial data no matter how or where it is stored.

• XML-Based Resource Metadata – Both products use the same XML schema to
manage metadata, such as feature sources, map definitions, and layer stylization.

• API – The AutoCAD Map 3D Geospatial Platform API shares much of the same objects,
methods and properties with the MapGuide Server API.

This class will demonstrate examples of common tasks that use the Geospatial Platform API,
and show you how to maximize code re-use by separating environment-specific code into a
series of common functions. Code that uses the AutoCAD Map Geospatial Platform API can be
used with the MapGuide Server API (and vice versa) with little or no modification.

Key differences
While the signatures of these APIs are nearly identical, there are some key differences that are
important to understand.

AutoCAD Map 3D Geospatial API MapGuide Server API


Application Environment Desktop Web Server
Development Environment .NET .NET, PHP, Java
Resource Storage DWG External XML files
Resource security No Yes
Session Management No Yes
Event Handling Yes No
User Interface Desktop: AutoCAD/Windows Web: HTML/JavaScript

2
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

Using the APIs


AutoCAD Map 3D
To use the AutoCAD Map 3D Geospatial API in a Visual Studio project, you reference
Autodesk.Map.Platform.dll, found in the AutoCAD Map 3D installation folder.

In AutoCAD Map, once you add this reference, the API is ready to use.

MapGuide
In your MapGuide application, you reference MapGuideDotNetApi.dll, which is typically found
in the following location:

C:\Program Files\Autodesk\MapGuideEnterprise2010
\WebServerExtensions\www\mapviewernet\bin

Before you can start using the API in your web pages, you must include code to initialize the
MapGuide API, connect to a MapGuide server, and establish a session. Your pages will likely
contain code such as this: (C# example)

private void InitMapGuide()


{
// Initialize the MapGuide API
MapGuideApi.MgInitializeWebTier(Server.MapPath("/mapguide")
+ @"\webconfig.ini");

// Create a connection to the MapGuide site


MgSiteConnection siteConnection = new MgSiteConnection();
if (Session["SESSION"] != null)
// A session has already been established
siteConnection.Open(new MgUserInformation(Session["SESSION"].ToString()));
else
{
// Create a new session
siteConnection.Open(new MgUserInformation("Administrator", "admin"));
Session["SESSION"] = siteConnection.GetSite().CreateSession();
}
}
This code demonstrates a techique in which you store the MapGuide session ID in an HTTP
session variable called “SESSION”. The page that loads first by a client will create the new
MapGuide session, and subsequent pages can obtain that session ID from the HTTP Session
object. In a MapGuide application, it is common to use session variables to store things like the
MapGuide session ID, web layout resource identifier, and map name. Alternatively, these
variables can be passed between pages as URL parameters.

3
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

Developing a CommonFunctions Class


In order to share source code between the two environments, we will separate out the
environment-specific code into a separate class called CommonFunctions. When we’re done,
we’ll have two versions of the CommonFunctions class, one for use with our MapGuide code,
and one for our AutoCAD Map code.

Resource Service
To begin working with resources (maps, layers, etc.) you must first obtain an instance of the
MgResourceService class

AutoCAD Map 3D
For AutoCAD Map 3D, this is very easy:

public static MgResourceService ResourceService


{
get
{
return AcMapServiceFactory.GetService(MgServiceType.ResourceService)
as MgResourceService;
}
}

MapGuide
For MapGuide, you use the MgSiteConnection object you obtained with the initialization code
shown earlier.

MgResourceService resourceService =
siteConnection.CreateService(MgServiceType.ResourceService)
as MgResourceService;

Getting the Current Map


AutoCAD Map 3D
In AutoCAD Map 3D the current map is obtained using the GetCurrentMap() static method of
the AcMapMap object. It returns an instance of the AcMapMap class, which is derived from the
MgMapBase class. The following code demonstrates a static method to obtain the current map.

public static MgMapBase GetCurrentMap()


{
return AcMapMap.GetCurrentMap() as MgMapBase;
}

Note: The classes that are shared between the two APIs have the prefix Mg. The AutoCAD
Map 3D Geospatial API includes additional classes with the prefix Ac. Many of the Ac
classes extend existing Mg classes, and some provide additional functionality unique to the
AutoCAD Map environment.

4
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

MapGuide
Obtaining the current map in a MapGuide application is a bit more complex. If you want a
generic method to do this (in which the name of the map is not known) you must know the
MapGuide session ID and the Web Layout that is currently being displayed. These two pieces of
information are passed as URL parameters, SESSION and WEBLAYOUT to the page loaded
into the task pane in the AJAX viewer. If you use the “Flexible Layout” viewer, the name of the
current map is passed as the URL parameter MAPNAME.

The following code demonstrates a method that returns the current map as an MgMapBase
object. This code assumes that the session variable MAPNAME exists.

public MgMapBase GetCurrentMap()


{
// Get the MapGuide session ID from the HTTP session
string sessionId = Session["SESSION"].ToString();

// Initialize MapGuide
string webConfigIni = MapPath("/mapguide") + "\\webconfig.ini";
MapGuideApi.MgInitializeWebTier(webConfigIni);

// Open the site connection using the session ID


MgSiteConnection siteConnection = new MgSiteConnection();
siteConnection.Open(new MgUserInformation(sessionId));

// Get the current map using the MAPNAME session variable


MgMap map = new MgMap(siteConnection);
map.Open(Session["MAPNAME"].ToString());
return map as MgMapBase;
}

Common Code
Once we obtain an MgMapBase object, in either MapGuide or AutoCAD Map 3D, most things
you would do with that object can be done using the same code in either environment. For
example, the following code will populate a list box with the names of all the layers in the map.
This source code can be shared between a Map 3D .NET application, and a MapGuide
ASP.NET application.

protected void Button1_Click(object sender, EventArgs e)


{
MgMapBase map = CommonFunctions.GetCurrentMap();

if (map != null)
{
listBox1.Items.Clear();
foreach (MgLayerBase layer in map.GetLayers())
{
listBox1.Items.Add(layer.Name);
}
}

5
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

Adding a Layer to the Map


The process of adding a layer to the current map is very similar in both AutoCAD Map 3D and
MapGuide. But before you can add the layer, you must have an existing Layer Definition
resource. If you don’t have a Layer Definition resource, you must first formulate the XML to
define the layer stylization. Building the XML layer definition can be accomplished in a number
of ways, such as using the XML DOM directly, using an XML template file, or modifying an
existing layer definition resource. Diving into these techniques is beyond the scope of this class.
Once you have the XML, the code to create the resource is the same for both Map and
MapGuide:

// Store the layer resource


MgResourceIdentifier layerId =
new MgResourceIdentifier(
@"Library://Samples/Sheboygan/Layers/Soils.LayerDefinition");
content = new MgByteReader(xml, "text/xml");
CommonFunctions.ResourceService.SetResource(layerId, content, null);

The next step to adding the layer to the map is to create a new instance of the MgLayerBase
class. The code for this is slightly different depending on the environment, so we’ll create
another method in our CommonFunctions class to handle this.

AutoCAD Map 3D
In AutoCAD Map, you use the Create method of the AcMapLayer class.

public static MgLayerBase NewLayer(MgResourceIdentifier layerId)


{
return AcMapLayer.Create(layerId, ResourceService);
}

MapGuide
In MapGuide, you simply use the constructor from the MgLayer class.

public MgLayerBase NewLayer(MgResourceIdentifier layerId)


{
return new MgLayer(layerId, ResourceService) as MgLayerBase;
}

Now that we have a common function to create a new MgLayerBase instance, the code to add
the new layer to the map in either environment is as follows:

// Add the layer to the map


MgLayerBase layer = CommonFunctions.NewLayer(layerId);
layer.SetName("Soils");
layer.SetLegendLabel("Soils");
layer.SetSelectable(false);
layer.SetVisible(true);

6
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

layer.SetDisplayInLegend(true);
MgMapBase currentMap = CommonFunctions.GetCurrentMap();
currentMap.GetLayers().Add(layer);
CommonFunctions.RefreshMap(currentMap);

MapGuide
Notice that the last step in the code sequence above is a call to a RefreshMap method of our
CommonFunctions class. This is only needed for MapGuide – the AutoCAD Map 3D
implementation is empty. After a layer has been added to the map, there are two more steps
necessary for code written for MapGuide. First you must call the Save method of the MgMap
object, then you must send the necessary JavaScript code to the client to refresh the viewer.

public void RefreshMap(MgMapBase map)


{
// Make sure any changes are saved to the session
((MgMap)map).Save();

// Build the JavaScript code to refesh the map


string s = "<script language=\"javascript\">\n";
s += "window.onload = function()\n";
s += "{\n";
s += " var main = parent.parent;\n";
s += " var map = main.GetMapFrame();\n";
s += " map.Refresh();\n";
s += "}\n";
s += "</script>\n";

// Use the HttpResponse object to send this code to the client


Response.Write(s);
}

Getting the Currently Selected Features


As the user selects (highlights) features on a map, the MgSelectionBase class can be used to
work with those features. The first step is to obtain an instance of MgSelectionBase that
represents the currently selected features.

AutoCAD Map 3D
To obtain the currently selected features in AutoCAD Map 3D, use the following code:

public static MgSelectionBase GetCurrentSelection()


{
Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
PromptSelectionResult result = editor.SelectImplied();
return AcMapFeatureEntityService.GetSelection(result.Value);
}
As you can see, this method starts out by using the AutoCAD .NET API to get the current
AutoCAD “implied” selection. Once you have that, you use the GetSelection method of the

7
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

AcMapFeatureEntityService class. The AcMapFeatureEntityService class is a member of


the Autodesk.Gis.Map.Platform.Interop namespace.

MapGuide
For MapGuide, the process of obtaining the current selection is different depending on whether
you are using the AJAX viewer or the DWF viewer. If you’re using the DWF viewer, you must
pass the selection information to the server before you can use it. The AJAX viewer does this
for you, so the process is a bit easier.

To obtain the currently selected features using the AJAX viewer in a MapGuide application, use
the following code:

public MgSelectionBase GetCurrentSelection()


{
MgMap map = GetCurrentMap() as MgMap;
if (map != null)
{
MgSelection selection = new MgSelection(map);
selection.Open(ResourceService, map.Name);
return selection as MgSelectionBase;
}
return null;
}

Displaying Feature Properties


Now that we’ve got a common function to obtain the currently selected features, the process of
inspecting those features is the same for both AutoCAD Map 3D and MapGuide. The following
method populates a ListBox with the property names and values of a single feature selection.

private void ShowFeatureData(MgSelectionBase selection)


{
listBox2.Items.Clear();
MgReadOnlyLayerCollection layers = selection.GetLayers();
if (layers.Count == 1)
{
MgLayerBase layer = layers[0];
int n = selection.GetSelectedFeaturesCount(layer, layer.FeatureClassName);
if (n == 1)
{
MgFeatureReader featureReader =
selection.GetSelectedFeatures(layer, layer.FeatureClassName, false);

// Get the property definition collection from class definition


MgClassDefinition classDef = featureReader.GetClassDefinition();
MgPropertyDefinitionCollection propertyDefs = classDef.GetProperties();

while (featureReader.ReadNext())
{
foreach (MgPropertyDefinition propertyDef in propertyDefs)

8
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

{
if (propertyDef.PropertyType == MgFeaturePropertyType.DataProperty)
{
MgDataPropertyDefinition dataProp = propertyDef
as MgDataPropertyDefinition;

if (dataProp != null)
{
// Set default value.
string value = "(null)";
if (!featureReader.IsNull(propertyDef.Name))
{
// Reads the value from featureReader
// according to DataType.
switch (dataProp.GetDataType())
{
case MgPropertyType.String:
value = featureReader.GetString(propertyDef.Name);
break;
case MgPropertyType.Double:
value =
featureReader.GetDouble(propertyDef.Name).ToString();
break;
case MgPropertyType.Int16:
value =
featureReader.GetInt16(propertyDef.Name).ToString();
break;
case MgPropertyType.Int32:
value =
featureReader.GetInt32(propertyDef.Name).ToString();
break;
case MgPropertyType.Int64:
value =
featureReader.GetInt64(propertyDef.Name).ToString();
break;
case MgPropertyType.Boolean:
value =
featureReader.GetBoolean(propertyDef.Name).ToString();
break;
default:
break;
}
}

string nameValue = dataProp.Name + " = " + value;


listBox2.Items.Add(nameValue);
}
}
}
}
}
}

9
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

Setting the Active Selection


Another common development task is to display the results of some query or search operation
by highlighting features on the map display. In the previous example, you learned that the
MgSelectionBase class is used to represent a selection of features on the map. We can also
build a new MgSelectionBase object, and then use it to set the active selection. The processs
of building the MgSelectionBase object is pretty much the same whether you are developing
for AutoCAD Map 3D or MapGuide. What differs greatly between the two environments is how
you highlight the selected features on the map.

We will create a function for each environment that takes an MgSelectionBase object as an
argument, and highlights those features.

AutoCAD Map 3D
For AutoCAD Map 3D, you work with the implied selection set. First, you use the
AddFeaturesToSelectionSet method of the AcMapFeatureEntityService object to get an
AutoCAD SelectionSet object, then you use the SetImpliedSelection method of the Editor
object to highlight the objects. The following C# code demonstrates this.

public static void HighlightFeatures(MgSelectionBase selectionSet)


{
Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;

// Clear the active selection set


editor.SetImpliedSelection(new ObjectId[] { });

// Get the implied selection set


SelectionSet acadSel = editor.SelectImplied().Value;

// Add the features to the AutoCAD selection set


// This function returns a new AutoCAD selection set
SelectionSet result =
AcMapFeatureEntityService.AddFeaturesToSelectionSet(acadSel, selectionSet);

// Set the new selection set as the implied (active) selection set
editor.SetImpliedSelection(result);
}

MapGuide
For MapGuide, you use the viewer API. First, you get the XML representation of the selection
using the ToXml method of the MgSelectionBase object. Then, in your ASPX page that
processes your selection, you build the JavaScript code needed to set the active selection in the
viewer. The JavaScript code calls the SetSelectionXML function of the viewer API.

public void HighlightFeatures(MgSelectionBase selectionSet)


{
// Get the Escape any single quotes for

10
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

string xml = selectionSet.ToXml().Replace(@"'", @"\'");

// Build the JavaScript code to set the active selection


string s = "<script language=\"javascript\">\n";
s += "window.onload = function()\n";
s += "{\n";
s += " var main = parent.parent;\n";
s += " var map = main.GetMapFrame();\n";
s += " map.SetSelectionXML('" + xml + "');\n";
s += "}\n";
s += "</script>\n";

// Use the HttpResponse object to send this code to the client


Response.Write(s);
}

Common Code
The following code, which can be shared between AutoCAD Map 3D and MapGuide,
demonstrates setting the active selection.

private const string districtsId =


@"Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource";

private MgLayerBase GetLayer()


{
MgMapBase map = CommonFunctions.GetCurrentMap();
foreach (MgLayerBase layer in map.GetLayers())
if (string.Compare(layer.FeatureSourceId, districtsId, true) == 0)
return layer;

return null;
}

private void button1_Click(object sender, EventArgs e)


{
// Get an MgFeatureService object
MgFeatureService featureService = CommonFunctions.FeatureService;

// Get the resource identifier for the feature source


MgResourceIdentifier id = new MgResourceIdentifier(districtsId);

// Get the feature class for the layer


string featureClass = GetLayer().FeatureClassName;

// Set up query options


MgFeatureQueryOptions options = new MgFeatureQueryOptions();

// Query the features


MgFeatureReader reader = featureService.SelectFeatures(id, featureClass, options);

listBox1.Items.Clear();
while (reader.ReadNext())

11
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

{
listBox1.Items.Add(reader.GetString("Name"));
}
reader.Close();
}

private void button2_Click(object sender, EventArgs e)


{
// Build the filter string based on selected ListBox items
string filter = "";
foreach (string name in listBox1.SelectedItems)
{
if (filter.Length > 0)
filter += " OR ";
filter += "(Name = '" + name + "') ";
}

// Get the resource identifier for the feature source


MgResourceIdentifier fsId = new MgResourceIdentifier(districtsId);

// Get the layer


MgLayerBase layer = GetLayer();

// Get schema and feature class name


string[] schemaAndClass = layer.FeatureClassName.Split(':');

// Get the identity properties


MgFeatureService featureService = CommonFunctions.FeatureService;
MgClassDefinition classDef = featureService.GetClassDefinition(fsId,
schemaAndClass[0], schemaAndClass[1]);
MgPropertyDefinitionCollection idPropertyDefs = classDef.GetIdentityProperties();

// Set up the query options


MgFeatureQueryOptions options = new MgFeatureQueryOptions();
options.SetFilter(filter);

// Query the features


MgFeatureReader reader =
featureService.SelectFeatures(fsId, layer.FeatureClassName, options);

// Construct a selection set


MgMapBase map = CommonFunctions.GetCurrentMap();
AcMapSelection selectionSet = new AcMapSelection(map as AcMapMap);
while (reader.ReadNext())
{
int id = reader.GetInt32(idPropertyDefs[0].Name);
selectionSet.AddFeatureIdInt32(layer, layer.FeatureClassName, id);
}
reader.Close();

// Highlight the features


CommonFunctions.HighlightFeatures(selectionSet);

12
Using the Geospatial Platform API in AutoCAD® Map 3D and Autodesk MapGuide®

13

Das könnte Ihnen auch gefallen