Saturday 2 October 2021

mapguide-react-layout dev diary part 26: Making the map viewer general purpose

Previously, I hinted that the future of mapguide-react-layout besides having a new name (I still haven't come up with a suitable replacement on that front) is to make the map viewer general purpose so that it can be used in contexts that do not require a dependency on a running MapGuide Server.

As I am wrapping up development on the upcoming 0.14 release, I figured it's time for a new dev diary entry that details how we have reached this goal. So strap in. This is going to be a big post with images and embedded webms galore!

MapGuide Support is now optional

To make our viewer general purpose, we have to be able to load in an Application Definition where the primary Map element does not refer to a MapGuide Map Definition, but instead refers to what I like to call a "subject layer". The "subject layer" is the layer of focus for any given map and can be:
  • A WMS layer
  • A vector layer
To demonstrate how truly de-coupled we are from requiring a running MapGuide Server, I present to you a new generic viewer template powered by this example application definition document. All the map groups in that example refer to subject layers instead of MapGuide Map Definitions and thus does not require any dependency on a running MapGuide Server.

New "generic" viewer template

The new "generic" viewer template is a minimal and opinionated viewer template geared for use in a general purpose context (without a MapGuide Server).


The template is opinionated in the following sense:
  • The commands in the vertical toolbar is pre-defined. You cannot customize the contents through the application definition. This template does offer a configurable context menu.
  • The UI is intentionally kept as minimal as possible. There is no Task Pane in this template. Invoke URL commands will load content into floating modal windows. Certain toolbar commands (like the layer manger and selection panel) will load their UI content into drawers.
Although this template is geared for use in a general purpose context, it still can be used with a MapGuide Server as demonstrated below with the Sheboygan dataset



In the MapGuide context, several extra toolbar buttons are enabled. The toolbar differences are outlined below



Supercharged External Layer Manager

For the upcoming release, the External Layer Manager gets several major enhancements.

Firstly, vector layers now have fully declarative styles with editor support in the External Layer Manager UI. With declarative style support, when adding a new file-based vector layer, you have several choices regarding how the layer is to be added.

You can now choose to create a thematic layer with a pre-defined colorbrewer ramp and optional labeling.




For point-based layers, you may choose to add it as a clustered point layer



Or alternatively, as a heatmap layer


For non-heatmap vector layers, you can view and edit the styles to your liking


General-Purpose-ing various components

There are various components that were previously MapGuide-specfic and would be somewhat pointless in a general purpose context. As some of these components are permanent fixtures in some viewer templates, we have to make them somewhat useful in a non-MapGuide context if said template is fed a non-MapGuide appdef.

The Legend component now also displays the list of external layers in its own root category, essentially acting as a compact version of the layer list from the External Layer Manager UI.


The Selection Panel component will now also display attributes of selected client-side vector features.


UTFGrid support

UTFGrid layer support was introduced in the 1st preview release of MapGuide Open Source 4.0. To better advertise this new feature, the viewer supports UTFGrid layers if specified as part of a MapGroup element in an application definition like so


With this XML fragment in place, loading the appdef into the viewer will cause a UTFGrid interaction layer to be created as part of viewer initialization and will manifest as feature tooltips that display on mouse hover.


There is one caveat with UTFGrid support in mapguide-react-layout. You must pair this up with a Map Definition that is in the WGS84.PseudoMercator (aka. EPSG:3857) coordinate system.

"Stateless" mode for MapGuide maps

UTFGrid layers go nicely with another new feature of mapguide-react-layout: Support for "stateless" mode.

In stateless mode, the viewer:
  • Does not create any session ids
  • Consequently, it does not issue any CREATERUNTIMEMAP requests on viewer startup
  • Will render maps using GETMAPIMAGE instead of GETDYNAMICMAPOVERLAYIMAGE
Because no session id is ever created, the viewer can't use commands that require a SESSION/MAPNAME pair, such as:
  • Buffer
  • Query
  • Theme
  • Redline
  • Feature Info
  • Quick Plot
  • Select Within
Such commands if present in the application definition will be permanently disabled in any toolbars and menus where they are referenced in. The viewer will log console warnings about such unsupported commands in stateless mode (as a hint for you to trim out such commands/widgets from your application definition if authoring up a stateless appdef).

Because CREATERUNTIMEMAP requests are not sent in stateless mode, we have a less rich layer/group structure to work with.

Compare the Legend for a stateful version of the Sheboygan map


Versus the stateless version


In the stateless version, we only have the basic layer group structure (computed from the Map Definition resource we fetch on startup) to work with. As a result, we do not have information such as:
  • Visible scale ranges for layers
  • Style/theme icons for layers
While technically possible, it is currently impractical to fetch all the required Layer Definitions for this information (we would be spamming our MapGuide Server for layer definition requests if loading up a really heavy Map Definition).

Why would you want to use stateless mode? If the caveats listed above are not deal breakers for the type of web map you are trying to serve, stateless mode presents a much more scalable map viewing option in MapGuide as there are zero MapGuide sessions being created or managed, reducing load/memory burden on the MapGuide Server.

Stateless mode is an opt-in feature. You can opt-in to stateless mode by adding a Stateless extension property to the Application Definition like so.


The stateless mode extension property has no effect if your appdef is general-purpose (ie. It does not reference any MapGuide Map Definitions). General-purpose appdefs are implied to be stateless already.

Other notable features/changes

Client-side vector layers are now hover-able (to better hint that they're selectable)


The fusion print command/widget is now supported. You will no longer get an error placeholder in toolbars and menus where this command/widget was referenced. This command will export the current map image out to a separate ready-to-print browser tab.


The previous WMS layer selection tool has been incorporated into the regular Select tool, making it the final one-stop-shop for selecting anything, be it MapGuide layers, WMS layers or client-side vector layers. Also when the Select tool is active, you can now still pan via middle-click mouse drag.

In Closing

Expect the 0.14 release of mapguide-react-layout to come out soon. I am just finishing up documentation aspects of this release.

No comments: