Friday 27 May 2011

Introducing the (re-vamped) Maestro API: Part 1

MapGuide Maestro may seem to be just an authoring application for MapGuide Open Source, but behind the scenes, it uses a set of core libraries that can do so much more. These libraries represent the Maestro API.

Before I talk about the Maestro API, I want to talk about the official MapGuide API that you should be familiar with by now.

The official MapGuide API that you use to create your MapGuide applications is a set of language wrappers (PHP/Java/.net) around the native MapGuide API as shown in the diagram below.



The MapGuide server has a large set of functionality that handles authoring and managing maps and spatial data. This functionality is only exposed through a few methods that allow reading and writing of Xml. The C++ classes communicate with the MapGuide server through dedicated TCP/IP ports.

This means that it is only possible to interact with servers on the local intranet (opening the port is not recommended for security reasons) and is the main reason why most applications using the official MapGuide API are either Web Applications or applications that reside on the MapGuide Web Tier.

So what is the Maestro API? To answer that I will need the assistance of a few diagrams.

Here's a diagram which may be familiar to some of you



Each client-tier application shown utilises services provided by the MapGuide Web Server Extensions.
  • Autodesk MapGuide Studio: Resource and Feature Service.
  • Google Earth: KML Service
  • AJAX Viewer / Fusion: Rendering, Tile and Mapping Services
As you can see from the diagram, MapGuide Maestro is a just another client-tier application consuming and utilising services exposed by the MapGuide Web Extensions.

What kind of services? Does this page look familiar to you?



This is the test pages for the mapagent. Every one of those links represents an element of the MapGuide API exposed over the web as a service operation by the MapGuide Web Extensions. You can invoke these operations by issuing standard HTTP GET and POST requests to the mapagent url.

Because invocation is done via HTTP and not via some custom or proprietary protocol, you can use any library that can send HTTP requests to talk to the MapGuide Web Extensions and thus create your own MapGuide client applications.

Before the Maestro API, writing a MapGuide client application would've taken lots of work to do even the basic things. Doing a simple GETRESOURCECONTENT operation would look something like this:

 string sessionId;
string url = ""http://localhost/mapguide/mapagent/mapagent.fcgi?OPERATION=GETRESOURCECONTENT&VERSION=1.0.0&SESSION=" + sessionId + "&RESOURCEID=Library://Samples/Sheboygan/Data/Parcels.FeatureSource";
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
using(Stream st = resp.GetResponseStream())
{
//Read and process XML content inside this stream
}

A lot of boilerplate is required, from setting up the request/response, processing the response stream into a readable form and then more boilerplate with System.Xml.* classes to parse and process the XML content.

Enter the Maestro API, which abstracts away all of that boilerplate so you can do something like this instead.
 string username = ...;
string password = ...;
IServerConnection conn = ConnectionProviderRegistry.CreateConnection("Maestro.Http",
"Url", "http://localhost/mapguide/mapagent/mapagent.fcgi",
"Username", username,
"Password", password);
IFeatureSource res = (IFeatureSource)conn.ResourceService.GetResource("Library://Samples/Sheboygan/Data/Parcels.FeatureSource);

The MaestroAPI conveniently exposes all the XML response structures in the MapGuide server as managed .Net classes and interfaces (notice how instead of a XML stream that needs manual processing, we get a strongly typed IFeatureSource interface).

The Maestro API reads and writes .net native streams and classes (so instead of an MgByteReader objects, you get System.IO.Stream objects or deserialized classes/interfaces). For example, this makes things like processing the result of a Rendering Service API much easier as a System.IO.Stream can be fed directly into a System.Drawing.Image object for display, whereas an MgByteReader requires manual extraction of its binary content that then has to be converted to a .net native form.

So in summary, the Maestro API is a class library wrapper for the mapagent that allows you to communicate with a MapGuide Server over the web using well-defined classes and interfaces. Because we only communicate over the web via HTTP, the Maestro API is also a 100% managed .net library using all the .net constructs and classes available to us, unlike the official MapGuide API which is a managed wrapper to native (C++) code. It is this quality of being pure managed code that makes the Maestro API usable in Mono and a reason why MapGuide Maestro also works in Linux and MacOSX.

All these features makes development of MapGuide Client Applications using the Maestro API incredibly easy and simple! If it's exposed in the mapagent, you can do it with the Maestro API!

Stay tuned for part 2, where I delve into the design of Maestro API and introduce the main classes in this API.