Wednesday, 11 September 2013

Maestro tip: Editing session resources

So ... You know about that resource ID "address bar" which I've introduced to MapGuide Maestro 5.0 since beta 4?

That thing also takes session-based resource IDs. Thus, assuming you connected as an Administrator you can use this address bar to also open session-based resources and view/edit them. A nice way to debug any code you have that works with session-based resources.


Now sadly there's currently no way to open a resource ID from the "address bar" using the Generic XML editor. So for the next release we're going to fix that, by letting you choose which editor you want to open the resource with: The designated one or the Generic XML editor



Credit to Crispin Hoult for the original discovery.

EDIT: Correction. It seems you can only view session resources at the moment with this technique and not be able to edit them as saving will prompt you to save back into the site repository. We're gonna have to do something about that.

Saturday, 7 September 2013

Fresh from the lab

I'm sure we all agree that software releases are generally marketed like a bunch of bullet points.

I think I found one such bullet point for the next post-5.0 release of Maestro!



Tuesday, 3 September 2013

Maestro tip: Re-organizing editor windows

Sometimes, this author himself discovers something useful about the application he built that he himself didn't know was possible but with some reflection and hindsight, it was obviously clear such a thing could be possible due to some important decisions made in the choice of libraries, components and design.

In this particular case: the decision to use the DockPanel Suite library for MapGuide Maestro 5.0.

DockPanel Suite allows Maestro to lay out its top-level UI elements in a flexible manner akin to Visual Studio. So what this means is that if you have a bunch of open editors like this



You can drag one of the editor tabs and pull it out. You'll get a nice visual indicator of where you want to drop the editor tab just like in Visual Studio.


Release the mouse at the desired drop location and presto!


Very useful if you ever want to see 2 or more open resources side-by-side for basic comparison. Something nice to remember if you have a lot of screen real estate to play with

Monday, 2 September 2013

MapGuide tidbits: Coordinate System support in mg-desktop

Here's a quick tidbit about Coordinate Systems in mg-desktop.

Whether you're using the zip distribution of mg-desktop or you installed the cs-map-dictionaries NuGet package, your mg-desktop application will not be supporting the full set of several-thousand-odd coordinate systems that any other application using CS-Map does.

The reason for this is simply: size.

NuGet has a 30mb limit on its package files, so the decision was made to have a stripped-down set of coordinate system dictionary files to support the NuGet user story. Similarly, the zip distribution of mg-desktop contains a stripped-down subset for the same reason: If you're building an mg-desktop application, you probably don't need to support all 4000+ coordinate systems and chances are the coordinate system you're working with will be in this stripped-down subset.

So what coordinate system files did we strip out for mg-desktop? All the country-specific grid files have been stripped out.



So now the question becomes: How can I use a coordinate system that's in one of these country grid files in my mg-desktop application?

The answer is to simply take a copy of the grid file(s) from an equivalent installation of MapGuide Open Source (ie. A MapGuide with the same major.minor version number as your version of mg-desktop). If you don't have MGOS installed, you can take a copy of the grid file(s) from the equivalent MapGuide InstantSetup bundle.

Drop one or more of these folders into your mg-desktop application's Dictionaries folder and your mg-desktop application should now support the coordinate systems defined in this grid files as well.

Monday, 26 August 2013

MapGuide 2.6 feature showcase: New code samples

If you're uncertain how the new CREATERUNTIMEMAP and QUERYMAPFEATURES can help you, then have no fear: For 2.6, we've bundled a whole bunch of new code samples to show you how using everyone's favourite web mapping library: OpenLayers.

When you install the 2.6 preview release, make sure that the OpenLayers Samples feature is enabled.



After installation, load in the Sheboygan sample package using Maestro or the MapGuide Site Administrator and then go to the new samples landing page link on the start menu.



To simplify the installer, all the code samples have been aggregated into this single landing page. Just be aware that some of these links might be broken if you didn't choose to install the respective samples from the installer.

If you look at the bottom of the page you'll see a whole bunch of new samples demonstrating OpenLayers integration with MapGuide. The key thing to note with all these new samples is that none of them involve any .net/Java/PHP code using the MapGuide API. They are all pure client-side HTML/JavaScript communicating with the mapagent.


Have a play around and you may be surprised what you can do with just OpenLayers and jQuery in MapGuide 2.6. Note that mixed map and the Google/OSM examples won't work out of the box.


This is because these samples work with a Map Definition that is not part of the Sheboygan dataset. You can find the required Map Definition XML document in the directory where the sample is actually physically located


Load this document into the specified resource id via Maestro or the mapagent test pages. Reload the sample page and it should now work.


These samples aren't set in stone yet. We could probably automate/simplify this process of setting up example data files somehow.

Nevertheless, hopefully these new samples give you some ideas and/or inspiration.

MapGuide 2.6 feature showcase: QUERYMAPFEATURES improved

For this post, I will be talking about another useful enhancement to the mapagent: An improved QUERYMAPFEATURES operation.

To understand the motivation for this. Open up your Firebug or Chrome DevTools on the AJAX/Fusion viewer of your current stable/production installation of MapGuide/AIMS and make a selection on the map.

You probably see something like this for the AJAX viewer


And for Fusion, you probably see something even noisier


From a performance standpoint, firing off 3 and 5 requests respectively for a single selection smells of inefficiency. What is the actual root cause of such inefficiency? The answer is simply: QUERYMAPFEATURES

In its current form, the QUERYMAPFEATURES operation in the mapagent is simply inadequate for fulfilling the needs of our current suite of client-side map viewers.
  1. Select and give me back attributes of all the selected features? Not possible. That's why the AJAX viewer before RFC 71 could only show a number of selected features. Though RFC 71 introduced a getselectedfeatures.[php/jsp/aspx] to fetch this attribute information, it still needed an additional request to do it. It's also why Fusion has to make several extra requests through various PHP backend scripts to get this information.
  2. When you make a selection, the viewer then has to make an additional GETDYNAMICMAPOVERLAYIMAGE to retrieve the selection image.
  3. QUERYMAPFEATURES is also used for tooltip requests, but the response carries extra unnecessary baggage like selected feature attributes.
For 2.6, we introduce a more powerful and flexible QUERYMAPFEATURES operation that can handle all of the above scenarios, being an efficient one-stop shop for all viewer selection/tooltip needs. We can achieve this by using the same technique as the new CREATERUNTIMEMAP operation: The client application requests the pieces of information they are interested in, and the QUERYMAPFEATURES operation returns the appropriate information in the response.
  1. The application can fire off a QUERYMAPFEATURES request to include attributes of all selected features. This avoids the need for a request to getselectedfeatures.[php/jsp/aspx] in the AJAX Viewer (in fact, the introduction of this operation has rendered getselectedfeatures.[php/jsp/aspx] obsolete). In Fusion this avoids the need to call into the various PHP scripts for the same information
  2. The application can also request an inline base64 selection image as part of the QUERYMAPFEATURES response. Through the magic of data URIs, the AJAX viewer can directly set the selection image without needing to fire off an additional GETDYNAMICOVERLAYIMAGE request. However, for Fusion it still needs to do this because the OpenLayers.Layer.MapGuide instance doesn't support plugging in base64 selection images directly yet.
  3. The application can fire off a QUERYMAPFEATURES request and only ask for tooltip/hyperlink information.
All the above cases demonstrate the capabilities of the new QUERYMAPFEATURES operation:
  • Attributes of all selected features are included (if requested). AJAX viewer no longer needs getselectedfeatures.[php/jsp/aspx]. Fusion no longer needs to call the various PHP scripts to assemble this information.
  • Inline selection images are included (if requested) as data URIs. No need for an additional GETDYNAMICMAPOVERLAYIMAGE request for the selection image.
  • You only get what you ask for. No extra unnecessary information traveling down the wire.
So how does the request chatter look like with this new operation in place?

Here's the new request chain for the AJAX viewer. A single request to the enhanced QUERYMAPFEATURES operation asking for the kitchen sink. No need for an additional GETDYNAMICOVERLAYIMAGE because QUERYMAPFEATURES includes an inline base64 image that the viewer can insert as a data URI. No need to call getselectedfeatures.[php/jsp/aspx] because the response contains the attributes of all selected features.


Here's the new request chain for the Fusion viewer. I suspect the SaveSelection.php request is somewhat redundant here because QUERYMAPFEATURES already supports modifying the selection set.


Combine this enhanced QUERYMAPFEATURES with the new CREATERUNTIMEMAP/DESCRIBERUNTIMEMAP that I already talked about and you have a powerful set of out-of-the-box functionality for building your own map viewer without needing any .net/PHP/Java assistance.

For more information about this new feature, you can have a look at the RFC that introduced it: RFC 126.

MapGuide 2.6 feature showcase: CREATERUNTIMEMAP and DESCRIBERUNTIMEMAP

For this post, I will be introducing one of my new favourite features of MapGuide Open Source 2.6 that I've been hinting in some previous posts.

2.6 introduces new operations in the mapagent to allow for creating new MgMap instances and describing key information about the MgMap such as their layer/group structure, map name, coordinate system, etc without the need to write any .net/Java/PHP web extensions glue code to do this:
  • CREATERUNTIMEMAP - To create a new MgMap instance and return information about this instance
  • DESCRIBERUNTIMEMAP - Returns information about a MgMap instance, given a map name and session ID.
Both operations return the same XML/JSON structure, except they take different input parameters:
  • CREATERUNTIMEMAP requires a Map Definition ID and a session ID or MapGuide user credentials
  • DESCRIBERUNTIMEMAP requires a Map Name and a session ID
The motivation for implementing this feature was looking at the MapGuide example for OpenLayers. It was clear that to consume MapGuide from OpenLayers, key information that we needed to make a OpenLayers.Layer.MapGuide instance was missing from the mapagent, and to fill in this information you needed to write a glue layer in .net/Java/PHP that can tap into the MapGuide API to return this missing information.

Fusion which uses OpenLayers can get away with this because it calls into PHP code to bootstrap the application with the required information. However, if you were making a pure OpenLayers application, this was not possible. CREATERUNTIMEMAP/DESCRIBERUNTIMEMAP addresses this shortcoming.

These operations are made to be scalable depending on the needs of the client application.

You could ask for the bare-minimal information, which will give a response like this: This minimal response is enough to run the MapGuide example for OpenLayers without any assistance from .net/Java/PHP web tier glue code.

Or you could request the whole kitchen sink, which will return a response like this (useful if you wanted to build your own client-side map legend / layer toggling component):
Both operations also support JSON output, albeit with the same quirk that affects other JSON responses in the mapagent where all JSON properties a generally arrays (because the XML to JSON conversion code has no current way to infer cardinality of elements to be converted)

This new feature not only allows for new client application possibilities, Fusion has also been modified to take advantage of these new operations. Using CREATERUNTIMEMAP bypasses the request chain of LoadMap.php and LoadScaleRanges.php which returns the same information. Similarly, DESCRIBERUNTIMEMAP is used when a layer/group structure needs to be refreshed. Not only are less requests required as a result. the actual response payload and round-trip time is smaller and faster as well.

Here's a sample load time of the Sheboygan dataset in Fusion using the current LoadMap.php/LoadScaleRanges.php approach


Here's the same dataset loaded by Fusion using CREATERUNTIMEMAP


As you can see, not only does CREATERUNTIMEMAP gives smaller responses. The time/latency is also smaller as well. You'll be glad to know that as the map you're loading gets bigger, so do the size/time/latency savings. And the rub of all this? This is the first cut implementation. There are still unexplored caching opportunities on the server side that could make these response times even faster!

So even if you're not building your own custom map viewer, if you're using Fusion you should still see the benefits introduced with these new operations.

If you want to find out more about these new operations, check out the MapGuide RFCs: