Saturday 30 June 2012

Thoughts on MapGuide scalability

I've been doing some automated stress testing on the MapGuide 2.4 beta. The tool I used was Bruno Scott's scripts for the Grinder load testing tool. Running these stress tests have given me more insight into tweaking serverconfig.ini values for greater scalability, which I am sharing in this particular post.

For the record, the system I'm running the grinder test from (and where all these images in this post are sourced from) is a Quad Core desktop running 64-bit Windows 7 with 8GB RAM, which also happens to a have a Google Chrome browser with several tabs open (one for writing this post :-)), and the box isn't breaking a sweat.

Salt. Take a few grains of it


Like my post about MapGuide's undocumented expression functions, don't take my word as gospel. Most of my insights are from a 200 user automated stress test that is running as I'm writing this. Normal users do not operate like java threads following pre-determined scripts in a grinder test run, you will have a mix of heavy users, light users and users in between. Rather, consider this post as a data point from which you can extrapolate from to form your own conclusions about the optimal server configuration settings for a high volume environment.

The default settings will not cut it

Let me say off the bat that the default serverconfig.ini is definitely not optimized for serving high volumes of users. My first grinder test run simulating 50 users breached the session repository limit within 2 minutes! Gradual tweaks to serverconfig.ini has made the MapGuide Server more resilient to high volume requests. A 200 user grinder test is running as I write this post with no crashes or noticeable errors (the only errors thus far are insignificant IO errors due to the fact that I've capped the size of the request logs).

Read on to see what needs changing.


# of Session Repositories = Your "available memory"


Each time a new session is created (eg. Login with Studio/Maestro or launch the map viewer), a new session repository file is created. The SessionRepositoriesLimit setting in serverconfig.ini defines the maximum number of session repository files that can exist at any one time. If the MapGuide Server breaches this limit, it will deny any further CreateSession requests until the number of session repositories goes under this limit.

You can actually count the number of sessions that are active by looking at the Repositories/Session folder of your MapGuide Server install directory. Each session takes 2 files (a .db file and a .dbxml file), so the math is not rocket science.




How does this number go down then? Through MapGuide's session expiry mechanism. Every time a session expires, MapGuide will delete the related session repository file. So to ensure a stable MapGuide Server in a high volume environment, you need to keep this number in check, and the way to do that is to strike a fine balancing act between session creation and session expiry to ensure that this number stays steady.


This is somewhat analogous to memory allocation in a managed programming language. If you are allocating memory at a rate faster than the garbage collector can clean up, you will eventually get an out-of-memory error thrown by the runtime. Same principle here. MapGuide's session expiry is your "garbage collector"


Simply put, you will need to be more aggressive with your session expiry settings. Here's the default values in serverconfig.ini


  • SessionTimeout                     = 1200
  • SessionTimerInterval               = 400


A session is considered expired if nothing is done with that session id within 1200s (20mins) and that expiry check is done every 400s (6m40s). In the case of our automated stress test, this is way too long a period to wait to start cleaning up, which is why the grinder test was able to hit the limit in only 2 minutes. We lowered the SessionTimeout to 200s (3m20s) and the SessionTimerInterval to 60s (1min). This allowed the MapGuide Server to reclaim expired sessions at a rate that the automated stress test was creating them resulting in a steady number of active session repositories.

From a user perspective, there shouldn't be any problems with unexpected expired session errors. Maestro and the AJAX/Fusion viewers already have keep-alive mechanisms built in to ensure your session is not cleaned up due to aggressive session expiry settings.


Server memory use correlates to # of active sessions.


The memory allocation analogy for active sessions is somewhat rooted in fact. Each active session will take up memory, but each expired session will also release it. If you take a look at the task manager




The graph of memory goes in a steady up-and-down fashion in line with the session creation from the stress test (going up) and session expiry/cleanup (going down). The default session timeout settings would result in sharper drops in memory usage, but you would probably already hit the session repository limit before that happens.

Don't bother with 32-bit MapGuide

Here's the memory usage from the 200 user automated grinder test currently running as I'm writing this post



4GB like 640KB before it, was thought to be enough for everybody. But as you can see by the memory usage, a 32-bit MapGuide Server will be hitting its upper memory limit quite easily on a 32-bit system. So there is no real point in having a 32-bit MapGuide Server for a high volume environment. You should be running 64-bit MapGuide which can support and address an astronomical amount of memory (so yeah you're in a bit of a pickle if you are using or considering Linux as we still don't offer 64-bit MapGuide linux builds yet).

Conclusion (TL;DR)
  • The default serverconfig.ini will not cut it. You will have to edit this file.
  • Crank up the session repository limit as high user volume can easily breach the default limit (my stress test uses a SessionRepositoriesLimit of 4000)
  • Lower the session expiry timeout and checking interval (my stress test uses a SessionTimerInterval of 60 and a SessionTimeout of 200) to ensure expired sessions are reclaimed faster.
  • If the numbers are steady (memory usage, number of session repo files), that's a good thing!
  • Use 64-bit MapGuide. Don't bother with the 32-bit one. Throw as much RAM as you can. More users = More RAM.

Thursday 28 June 2012

New mg-desktop binaries: There can be only one thing left to do now

With this latest release of mg-desktop we are now one item short of complete feature parity with the AJAX/Fusion viewer: Support for rendering tiled maps.

Since I have still yet to figure this one out, let's just talk about what's new in this release instead:

Logging

The MapGuide Server logging infrastructure has been ported over to mg-desktop so you have the same API, trace and error logging goodness that you get with the MapGuide Server

Connection Pooling


I had a review of the connection pooling in place for mg-desktop and it turns out that I wasn't doing it right. Poolable connections that are returned to the pool are not supposed to be closed. They are only supposed to be closed when the pool is torn down or the connection is booted out. It is for this reason that you probably couldn't get Raster layers to display in the mg-desktop map viewer until now, because closing these raster connections actually wiped out their loaded configuration documents, meaning Rendering and Stylization was working off of what was essentially un-configured Feature Sources.


So with this release, not only is connection pooling working properly, but it should have better support for displaying layers from Raster feature sources (ie. GDAL and WMS)


Mouse Wheel Zoom!


The viewer control now supports zooming with the mouse wheel. Nuff said.


Legend Enhancements


The legend control now supports toggling layer selectability like the AJAX viewer.




Digitization Enhancements


The viewer control includes new digitization APIs to let you customize the digitization prompt.




As you can also see from that prompt, for digitization which consists of multiple segments (ie. Line Strings and Polygons) the viewer now supports undoing of previous segments by pressing Ctrl-Z during digitization of a Line String or Polygon




So now to figure out how to do this tiled maps thing ...

Download

Monday 25 June 2012

How to: view and monitor http traffic from the WFS and WMS FDO providers.

Fiddler is a wonderful tool for debugging http requests and responses. However if you ever tried using Fiddler to monitor http requests made by the WFS and WMS FDO providers in MapGuide or any application using FDO, you will find that Fiddler does nothing.

There's a simple trick you can do to make sure these requests show up in fiddler.

We'll use MapGuide as an example. If the MapGuide Service is running, stop it. This trick requires running the MapGuide Server as an application instead of a service. Fire up a command prompt and navigate to the server\bin directory of your MapGuide installation (eg. C:\Program Files\OSGeo\MapGuide\Server\bin)

From here type the following:

set HTTP_PROXY=localhost:8888

Then run the MapGuide Server in as an application

mgserver.exe run

Now when you interact with any WFS/WMS feature source for this session, the outbound requests will be shown in Fiddler.




Why this works is because localhost:8888 is the port that fiddler's http proxy runs on. Any web requests that go through this proxy will appear under fiddler. Secondly, HTTP_PROXY is a special environment variable that curl uses as a proxy server if it is defined. The WFS and WMS FDO providers also use the curl library to dispatch their http requests, thus this technique works for these providers as well.

Combine the two and the WFS and WMS providers will be dispatching http requests through Fiddler's proxy server, hence they will show up in fiddler if you have set the HTTP_PROXY environment variable first before running the application that uses these FDO providers.

This trick should work with any application using the curl library for doing http requests.

Wednesday 20 June 2012

MapGuide's undocumented custom aggregate functions

Deep inside MapGuide's server codebase, there is a series of expression functions which you can use for certain types of aggregate queries. I say undocumented because if you try to google for these functions and what they do, I'm sure you'll either find nothing or it will be this post, a few days after publishing :)

If you ever looked at the code for the Fusion theme widget or the theme examples for the AJAX viewer, you'll notice that there is a series of mysterious expression functions being called:
  • UNIQUE
  • EQUAL_DIST
  • STDEV_DIST
  • QUANT_DIST
  • JENK_DIST
But in actuality, there's references to even more functions in the MapGuide code:
  • MINIMUM
  • MAXIMUM
  • MEAN
  • STD_DEV
  • EXTENT
These functions do actually serve a useful purpose. Because not all FDO providers are created equal, it means that some providers are somewhat lacking in capabilities, which is critical if we want to say: Fetch a distinct set of values for theming. These functions serve to provide a somewhat level playing field for all FDO providers. It is through these functions that allow for some FDO providers to be able to do things that their actual capabilities would not be able to do.

One thing that's strange about these functions (besides that they exist :-)) is that they do not follow the normal syntax rules of your normal FDO expressions. This is probably because these functions already existed in MapGuide from the very beginning and pre-dates the introduction of the FDO expression engine and its expression syntax rules. What this means is that you can't do fancy function call chaining (eg. FunctionA(FunctionB()) ) for these particular functions, you must pass in literal values for whatever parameters are applicable.

So without further ado, here's some actual documentation. As a general note, all of these functions are called in the following fashion (PHP example):


//$featSvc is an instance of MgFeatureService

$fsId = new MgResourceIdentifier("Library://Samples/Sheboygan/Data/Parcels.FeatureSource");
$className = "Parcels";
$expr = "UNIQUE(RTYPE)"; //The expression containing the custom aggregate function
$query = new MgFeatureAggregateOptions();
$query->AddComputedProperty("RESULT", $expr);
$rdr = $featSvc->SelectAggregate($fsId, $className, $query);
while ($rdr->ReadNext())
{
    //Output the result
}
$rdr->Close();


As a second general note, do not take this blog post as the definitive fact about these functions. This post is just the result of my own observations of the MapGuide Server source code. I may have gotten a few bits incorrect here and there. But the general description and usages should be correct.

UNIQUE

The UNIQUE function returns a list of unique values for a given FDO property. Maestro and Studio both use this function to fetch a unique list of values for generating themes. It's signature is:
  • UNIQUE( property_name )
  • property_name is the FDO property which this function will return a list of unique values for
This function will return a value in the list which can be accessed through the aliased property you have mapped this function to. ReadNext() on the MgDataReader will advance to the next unique value on the list.

EQUAL_DIST


The EQUAL_DIST function returns an equal distribution of the given FDO property. The property must be a numerical property. It's signature is:
  • EQUAL_DIST( property_name, numRules, minValue, maxValue )
  • property_name is the FDO property which this function will create an equal distribution out of. This must be a string value and cannot be an FDO expression that evaluates to a string
  • numRules indicates the number of rules to create in this distribution. It must be an integer value and cannot be an FDO expression that evaluates to an integer
  • minValue indicates the minimum allowed value in this distribution. It must be a numerical value and cannot be an FDO expression that evaluates to a numeric value
  • maxValue indicates the maximum allowed value in this distribution. It must be a numerical value and cannot be an FDO expression that evaluates to a numeric value
This function will return a value in the distribution which can be accessed through the aliased property you have mapped this function to. ReadNext() on the MgDataReader will advance to the next value in the distribution. 


For reasons not known to me, this function will actually return (numRules+1)results. The theme example in the AJAX viewer samples uses this function (and other distribution functions below) to generate the themed layer definition. The 

STDEV_DIST


The STDEV_DIST function returns a standard deviation distribution of the given FDO property. The property must be a numerical property. It's signature is:
  • STDEV_DIST( property_name, numRules, minValue, maxValue )
Parameter constraints and results processing is the same as EQUAL_DIST

QUANT_DIST


The QUANT_DIST function returns a quantile distribution of the given FDO property. The property must be a numerical property. It's signature is:
  • QUANT_DIST( property_name, numRules, minValue, maxValue )
Parameter constraints and results processing is the same as EQUAL_DIST

JENK_DIST

The JENK_DIST function returns a Jenks distribution of the given FDO property. The property must be a numerical property. It's signature is:
  • JENK_DIST( property_name )
Parameter constraints and results processing is the same as EQUAL_DIST

MINIMUM


The MINIMUM function returns a smallest value of the given FDO property. It's signature is:
  • MINIMUM( property_name )
  • property_name is the FDO property which this function will find the minimum value of. This must be a string value and cannot be an FDO expression that evaluates to a string  
The function will return exactly one result containing the minimum value and can be accessed in the MgDataReader by using the aliased property that this function is mapped to.

MAXIMUM


The MAXIMUM function returns a largest value of the given FDO property. It's signature is:
  • MAXIMUM( property_name )
  • property_name is the FDO property which this function will find the maximum value of. This must be a string value and cannot be an FDO expression that evaluates to a string
The function will return exactly one result containing the maximum value and can be accessed in the MgDataReader by using the aliased property that this function is mapped to.

MEAN


The MEAN function returns a mean value of the given FDO property. It's signature is:
  • MEAN( property_name )
  • property_name is the FDO property which this function will find the mean value of. This must be a string value and cannot be an FDO expression that evaluates to a string
The function will return exactly one result containing the mean value and can be accessed in the MgDataReader by using the aliased property that this function is mapped to.

STD_DEV

The STD_DEV function returns the standard deviation of the given FDO property. It's signature is:
  • STD_DEV( property_name )
  • property_name is the FDO property which this function will find the standard deviation of. This must be a string value and cannot be an FDO expression that evaluates to a string
The function will return exactly one result containing the standard deviation value and can be accessed in the MgDataReader by using the aliased property that this function is mapped to.


EXTENT


The EXTENT function returns the bounding box of the given FDO geometry property. It's signature is:
  • EXTENT( property_name )
  • property_name is the FDO property which this function will compute the bounding box of. This must be a string value and cannot be an FDO expression that evaluates to a string
The function will return exactly one result containing the MgByteReader of the computed bounding box geometry and can be accessed in the MgDataReader by using the aliased property that this function is mapped to.

NOTE: Prior to this revision (ie. MapGuide 2.4 beta 1 and older), bad geometries will trip up this function. So if using this function throws an exception, you know you have at least one bad geometry in that data.


I've added a PHP sample here to that demonstrates the use of these functions.

Monday 18 June 2012

MapGuide Open Source 2.4: A comprehensive preview (part 2)

Last time you saw the box, now to show you what's inside.

Since we skipped the 2.3 release, (whose commerical equivalent is AIMS 2012) we might as well cover those new features as well.

Watermark Support

Watermarks was a new resource type introduced with AIMS 2012 that allows your Maps and Layers to have image or text-based watermarks associated with them, allowing for better branding of your maps, among other users for watermarks.


And yes, MapGuide Maestro has watermark support, for quite some time now too.

QuickPlot for AJAX and Fusion

Also introduced in AIMS 2012. The (really) basic print function in the AJAX/Fusion viewers has been replaced by a more flexible QuickPlot tool, which not only allows you to only capture a particular section of your current view, but also to rotate it as well.


The Fusion version of this tool now uses official MapGuide Rendering APIs instead of going through the unreliable PHP way. Still I guess the tool is called QuickPlot for a reason. Don't try to do high DPI plots with this tool unless your MapGuide Server has the memory to serve them as higher DPI plots require more memory.

For 2.4 (and AIMS 2013) the Fusion version of the QuickPlot tool can also have custom paper and scale lists plugged into the QuickPlot UI. See this thread to see how it's done. 

Profiling Support

New for MapGuide Open Source 2.4 / AIMS 2013

Straight from the horse's mouth. I don't really have much more to add. This is a useful feature for testing for layer bottlenecks in your map.

Join Support

If you're like me, you would've avoided Feature Joins for most of MapGuide Open Source's existence (and its commercial releases), mainly because the performance was absolutely horrendous. We've tackled this problem head on for 2.4 and I think we've come out the winner:
We encourage you to give Feature Joins another try. If you want an indicator of whether this improved support benefits you, here's the Feature Joins performance rule of thumb: Performance will be the best if the 2 sides you are joining on can support sorted queries

Instead of saying which FDO providers support sorted queries, let's just list the ones that don't:
  • OGR
  • WFS
  • WMS
  • SDF (before 2.4)
  • SHP (before 2.4)
SDF and SHP not being sortable before this release is the key point. Did you try to do these types of joins in the past with dismal performance?
  • SDF/SHP to ODBC (eg. MS Access database)
  • SDF/SHP to any RDBMS?
The ODBC and RDBMS sides are sortable by FDO, but because SDF/SHP was not considered sortable, you had the buggiest join algorithm chosen (Batch Sorted Block), which also performed dismally if one or both sides are considerably large since one side has to be constantly re-iterated to match all the possible results. For this release such joins will produce sorted results on both side allowing for the Sort Merge algorithm to be used. Sort Merge does not require re-iteration on either side of the join and thus the resulting merged Feature Reader will be processed the fastest.

There is one small catch for SDF and SHP feature joins. Their FDO providers can only order by a single property, meaning any joins involving SDF or SHP sources must only be done on a single property in order for these performance improvements to take effect. But multi-property Feature Joins are rare enough as it is (or single-property joins didn't phase your MapGuide Server one bit!)

Fusion

We've finally brought Fusion into "actually usable" territory. The major pain points of Fusion (Legend Performance, inability to mix tiled/untiled layers) have been addressed. Performance is now slightly behind the AJAX viewer (the more modern your browser, the better it is). You can even do new fancy tricks with your tiled maps and with commerical layers.

And as for that enhanced Redline widget? It's been improved even more for greater flexibility and productivity.

Configurable CS-Map Dictionary Path

I bring up this particular item up because by having the CS-Map dictionaries now defined in serverconfig.ini and webconfig.ini gives us the following:
  • We no longer have to use a single global environment variable (MENTOR_DICTIONARY_PATH) to tell us where these files are. Which also means ...
  • No more required reboots after installation (yes! Welcome to 2012!)
  • Enables for side-by-side installations of current/older/future versions of MapGuide. We don't currently support this scenario via the official installers, but if you have an older release and a MgInstantSetup-configured one installed, they will both peacefully co-exist because no 2 versions will no longer try to compete for the same MENTOR_DICTIONARY_PATH environment variable. Replacing MENTOR_DICTIONARY_PATH with a path from an older release is a bad thing (tm).
SVN Metadata

This feature was driven by the need to be able to seamlessly deliver web tier updates and fixes from the latest revisions of the source code without needing to build newer release or patch installers. I'm sure most readers of this blog are either developers or do write some code, so you would know about the importance of source control (or so I hope!). Source control can also function as an update delivery system if the content under source control can be used without needing to be compiled into a different form. It just so happens that most of the web tier fits this very description.

Because most of the web tier is textual content (html/js/php/css) and the entire MapGuide source code is hosted in a subversion repository, making most of the existing web tier as subversion working copies allows for easy updates through any subversion client. If we ever commit any updates or fixes, you can pull them down in this manner. No need to wait for the next major/patch release from us just for viewer/fusion/siteadmin/js/html/css updates. Win-win for everyone!


One thing to note about this particular feature is that the working copies use the SVN 1.6 working copy format. If you use a SVN 1.7 or newer client, you can  manually upgrade these directories after installation to use the 1.7 working copy format in order for your SVN 1.7 client to recognize these directories as SVN working copies. We chose the 1.6 working copy format for maximum compatibility. 1.6 and older versions will just work. 1.7 and newer versions will just require the manual working copy upgrade

Finally, this feature is completely optional, and can be turned off in the installer preferences.

Other


Besides the major new features, there's a whole bunch of little enhancements and noteworthy fixes which I'll mention here:
  • Logged map render calls to access.log now include extents
  • Better quality error messages logged to error.log
    • Null references now include the offending variable name
    • Null parameters now include the offending parameter
    • Range check failures now include the offending identifier and the range values being checked
    • FDO-related errors now include the associated feature source id where applicable
    • "The specified object was not found" in collection error? We now tell you the name whose associated object doesn't exists.
    • That useless "value cannot be less than or equal to zero" error? We now tell you what value in question it is!
  • Schema report shows associated spatial context for geometry properties and uses the Count() aggregate for counting features (this is the number used to warn you about large previews)
  • MapGuide .net assemblies are not actually versioned! (instead of being 1.0.0.1)
  • Memory leak fixes for Java API
 
So here's the gist of what you can expect for the 2.4 release. As always, if you do find defects with the current beta, be a responsible user/tester and report these problems

Sunday 17 June 2012

MapGuide Open Source 2.4 Beta 1 released

Get all the information and downloads from here

MapGuide Open Source 2.4 beta 1 comes in several flavours:

  • 32/64-bit Windows Installer
  • 32/64-bit Windows InstantSetup bundles, now as a 7zip self-extracting executable and half the size from the preview release as a result
  • 32-bit Ubuntu 12.04 deb installer
  • 32-bit CentOS 5.6 tarballs

Please note that this release does not include the ArcSDE FDO provider, because I don't have an ESRI sdk to build it. This is the problem you get for trying to support non-open geospatial data stores with non-open/non-free libraries! You could try using the ArcSDE provider dll from the FDO 3.7 beta 1 release, but this has not been tested and it is not a supported by us. You will have to wait for an official FDO 3.7 release for a newer ArcSDE provider.

Part 2 of the comprehensive overview is coming soon (it's in the draft queue)

Friday 15 June 2012

Announcing: MapGuide Maestro 5.0 beta 2

It's time for another beta release of MapGuide Maestro 5.0. Here's the main changes since the previous beta

Live Map Definition Editor


As seen previously, the Live Map Definition Editor is a new experimental way of authoring maps, though truth be told, it's actually more a test harness to exercise the capabilities of the new RuntimeMap viewer and its supporting components.




And it bears repeating that this is an experimental feature, so expect bugs and un-tested corner cases.


New XML Editor

We've taken out our vanilla XML editor, which was basically a glorified text field and replaced with something more feature-packed, proven and industrial-strength, the ICSharpCode.TextEditor component, the same text editor that was used by SharpDevelop before they moved to a WPF-based UI.

By using the ICSharpCode.TextEditor component for our XML editor, we get out-of-the-box niceties like:
  • Line Numbers
  • Syntax Highlighting
  • Whitespace Markers

With potential support for things in the future like:
  • XML element auto-completion
  • Code folding
Better support for Large Feature Sources

Ever try to work with a really large data store (that has 100s of feature classes / database tables) and Maestro just grinds to either a halt or timeout? Turns out there were many instances in the Maestro code base where we were doing a full schema walk just to list some schema names or class names, which is not only complete overkill, but is also the cause of the long waits and/or timeouts.

We've hunted down all instances where a full schema walk is performed and changed them to use GetSchemas/GetClassNames/GetClassDefinition where applicable. Using these APIs has the additional benefit of being able to tap into FDO RFC23 enhancements server-side where applicable, and in most cases the FDO providers that exhibit these problems with full schema walks (ie. RDBMS providers) implement the RFC23 enhancements that will make working with such data stores much faster.

Fixed/Enhanced ODBC configuration support


First the fix: It turns out that our configuration code was writing out bad XML, meaning your configuration documents were mostly non-functional and it was impossible to actually configure a table with X/Y/Z columns as a point feature class. This is now fixed (and backported to the 4.0.x branch), so any problematic ODBC configuration documents will have to be rebuilt.

Now for the enhancement: On a similar theme of better supporting Large Feature Sources with 100s of database tables, whenever you create an ODBC configuration document for the first time, or reset one, you will now be prompted for the list of class definitions to include in the document


This has the following benefits:
  • No more long wait to build the initial document for a 100-table database because we will only request a partial schema with only the specified classes. ODBC provider implements the FDO RFC23 APIs, so this is much faster than the full schema walk, which was done previously.
  • Because this is a schema override, any queries for the structure of this feature source will only return the classes that you specified when building the document. As mentioned previously, this is not only reduces the attack surface of your data store (by only exposing the necessary tables to MapGuide), but also improves performance
Speaking of long waits...

Background-threaded operations

Think of any operation in the past that could've taken a while and would bring up that good ol hourglass of busy-ness because Maestro's GUI thread is being clogged up by said operation. These operations are now moved into the background for better UI responsiveness.

Add-In Manager

Maestro 5.0 beta 2 includes a verbatim copy of SharpDevelop's Add-In Manager


Add-ins will definitely be a topic for a future post, but for now just understand that the infrastructure is now in place to build your own add-ins for Maestro.


And as always, beta 2 includes plenty of bug fixes from beta 1.

Wednesday 6 June 2012

Rolling your own MapGuide Mobile Viewer: Easy as 1-2-OpenLayers

Want to view your MapGuide maps on your tablet or mobile device? Don't have AIMS (and its mobile viewer extension)? No problem!

OpenLayers has made "rolling your own map viewer" a dead-simple affair. You can have something basic or you can go full blown framework with every bell and whistle under the sun. Fusion itself (and probably every web mapping framework out there for that matter) is built on top of OpenLayers, which tells you the pedigree and ubiquity of this JavaScript mapping library.

The release of OpenLayers 2.11 introduced support for HTML5 and mobile web browsers (which the soon-to-be-released 2.12 version improves upon). Put 2 and 2 together, and you'll find out that making your MapGuide maps available on Mobile Devices is actually pretty simple with OpenLayers.

How simple? Here's a mobile viewer I built using OpenLayers (2.12 RC) with Twitter Bootstrap and HTML5.


Devices shown: HP TouchPad (modded for Android 4.0), Samsung Galaxy Nexus (Left), Samsung Galaxy S2 (Middle), iPhone 3GS (Right)

In case the above photo's a bit blurry (sorry, all the good cameras were unavailable :D), here's a same viewer on a desktop machine.


This is the same viewer being shown here. A true testament to the power of OpenLayers with HTML5

The source for this mobile viewer can be found here. The viewer is very basic at the moment. Do not expect AJAX/Fusion viewer levels of features and functionality. Consider this a proof-of-concept or a starter template for your own mobile MapGuide viewer. And you know what? Someone else can take the glory and build this viewer to its full potential :-) For me this viewer was simply a learning exercise in HTML5 and Twitter Bootstrap

Logging MapGuide Web Tier requests and errors

MapGuide being a 3-tier application means there are potentially 3 places where things can go wrong, and when things go wrong, you want to make sure that there is at least some kind of logging in place to help you diagnose the what, who, when, where and why.

While Firebug and extensive logging capabilities cover the client and server tiers quite comfortably, you might be wondering, about the Web Tier, which there isn't much talk about and also happens to be the most important tier as it is the tier where all client to server and server to client communications must go through. If the Web Tier falls over, you will have no client-server communication and you sure as hell want to be able to look at any logs that can tell you why this is the case.

Fortunately, since MapGuide Open Source 2.2 the web tier has logging capabilities built in, but this is disabled by default when installed. Here's how you can enable it.

Open the webconfig.ini file in your MapGuide/AIMS installation and look for the AgentProperties section. In there, set the ErrorLogEnabled property to 1. If you want requests logged as well, set RequestLogEnabled to 1 as well


The logs will be written to the specified ErrorLogFilename and RequestLogFilename values in the directory specified by the LogsPath property.

Here's a sample of some logged requests by the web tier


And here's a sample of some logged errors by the web tier. Looks pretty much the same as the server error logs.


Once you have made your changes, save the file and restart your Apache/IIS for the web tier to be able to pick up the newly modified configuration. For IIS, an application pool recycle should be sufficient.

If this isn't mg-desktop, then what is it?

That viewer you see is the mg-desktop map viewer component refactored to work against our MaestroAPI classes instead of mg-desktop (namely the RuntimeMap class of the MaestroAPI), meaning we now have a 100% purely managed map viewer component that you can use for your own applications that use the MaestroAPI.

Or in our case, the centerpiece of a new feature coming in the next beta of Maestro: A standalone "live" Map Definition editor.


If you've played around with the mg-desktop viewer, the Maestro map viewer is 90-95% identical to the mg-desktop one in terms of functionality. It is basically a super-rich version of the AJAX viewer.

As to the editor itself, it's called a "live" editor because what you see on the map is what is currently being edited. Layers that are added to the map and any structural and draw order changes are reflected immediately in the viewer. This editor will not fire off any web browsers for previewing because you are looking at the final result! In a way, it's similar to the old MapGuide Author 6.5 and its way of authoring maps.

This viewer still currently has the same limitations as the mg-desktop one, that is: no tiled map support. If you do open a Tiled Map Definition, the editor will give you the opportunity to convert non-tiled layers to tiled ones, which you will have to then convert back with the traditional Map Definition editor when you're done. So if you primarily create and work with lots of Tiled Maps, this editor is probably not for you (for now).

Needless to say, this feature is completely experimental and full of un-tested corner cases, so put on your beta testing cap when playing with this new feature in the next beta of Maestro. And if I haven't made it clear already, this is a standalone editor. The existing Map Definition editor is not going away.

Saturday 2 June 2012

This is not mg-desktop





However, it will make the next beta of Maestro quite interesting :)