Tuesday, 3 September 2019

MapGuide 4.0 showcase: Supercharged tile sets

As promised, this is the first (of many) blog posts showcasing the new features of the just released MapGuide Open Source 4.0 Preview 1. Before we dive in, here's a little recap for some extra context.

Way back in MapGuide Open Source 3.0, we introduced the concept of a Tile Set Definition, a new resource type that allows one to define a shareable, re-usable tile set that was free of (most) server-imposed global default settings and is decoupled from any particular map or application. Before the introduction of shareable tile sets, a tile cache could only be defined within a Map Definition and was thus coupled to any application consuming this particular map. This setup also made the respective tile cache extremely prone to invalidation upon any minute changes to the Map Definition. Tile settings like size and image format were global (in serverconfig.ini) making it impossible to have tile sets of various sizes and image formats.

With the introduction of shareable tile sets, it means that tile sets no longer need to be defined on the Map Definition. Instead, it can be defined in an external Tile Set Definition resource and linked into any Map Definition (hence the shareable aspect). Being a linked resource, also means any changes to a Map Definition will not errantly flush cached tiles for the associated tile set as we have solid guarantees that editing a Map Definition that links to a tile set would not alter or compromise the layer/group structure of a tile set being linked that would normally necessitate invalidating the tile cache by deleting all previously cached tile images.

Because tile sets are now their own separate resources, it also opens up a design space that allows us to do things with these tiles that were previously not possible. Each Tile Set Definition can:
  • Specify their own tile sizes
  • Specify their own image formats
  • Specify their own storage location (internally managed by MapGuide or an explicit directory)
  • ... and much more
Tile Set Definitions also support a mini-FDO-style provider model that allows us to support different tile access semantics. This is how we're able to support XYZ tiles, while retaining the same method of accessing such tiles without any API changes.

For MapGuide 4.0, we've expanded the "...and much more" bullet point above by building on top of the shareable tile set foundation with new capabilities.

UTFGrid Tile Support

UTFGrid is a specification for rasterized interaction data. UTFGrid allows us to pre-render tooltip interaction data into tiles of textual content, which when superimposed on top of your existing map, allows us to have rich tooltips without having to send a single mapagent request for tooltip data! 

If you installed 4.0 Preview 1 with samples, there is a new sample demonstrating UTFGrid tiles in action. Notice the distinct lack of mapagent requests (beyond the requests for viewer assets, tile images and UTFGrid tiles).

UTFGrid files follow the XYZ tile access scheme, and thus are supported in Tile Set Definitions using the XYZ Tile Provider with the new tile output format of UTFGRID

With the introduction of UTFGrid tiles, the 4.0 preview 1 release opens up a new viable and potent interactive web mapping combination that was previously not possible.
  • Base map imagery provided by XYZ tiles (whether from an XYZ tile set served from MapGuide or from external services like OpenStreetMap)
  • Overlaid with tooltip interaction data provided by UTFGrid tiles served from another MapGuide XYZ tile set.
This combination requires zero MapGuide sessions to operate. If you recall my now-somewhat-ancient thoughts on scalability in MapGuide, session repositories (and their creation/maintenance/teardown) is a main contributing factor to load in a MapGuide Server.

You can pre-cache all the required content up-front through stateless tile request APIs. You can also choose to output generated tiles to a custom directory of your choosing (by editing the TilePath setting) and front that tile cache directory as a source of static file content in a HTTP web server of your choosing for even more scalability/cacheability. If your mapping interactivity requirements are simple, this new combination of XYZ + UTFGrid tiles served from MapGuide may be a viable combination for you.

(...and it just occurred to me in the process of writing the above blocks of text that this combination opens up brand new map publishing workflows and capabilities that were previously not possible! Here's one such idea I'm brewing for a future release of MapGuide Maestro)

Beyond the provided sample, there is nothing out of the box in the Preview 1 release that currently takes advantage of UTFGrid tile support. UTFGrid support exists in OpenLayers, both in:
So it is possible for some kind of out-of-the-box viewer support for UTFGrid tiles to appear in a future 4.0 preview release (no promises right now!)

Meta-Tiling Support

Meta-tiling is the process of rendering a bigger tile and slicing it down into sub-tiles of the original requested size. Here's a visual explanation:

By rendering bigger tiles and slicing the result down to sub-tiles for tile cache storage, we improve tile generation throughput via:
  • Less queries for feature data (because we're rendering for bigger tiles)
  • Requesting 1 tile and getting 2^n cached tiles for free for other requests because we cache those other sliced sub-tiles as well.
Meta-tiling was a feature that was actually implemented many years ago in a sandbox branch, but it was never merged back into trunk to be made available in a future release. With the advent of shareable tile sets introduced in MGOS 3.0, it was somewhat impractical to merge this work back into trunk as-is, so the existing meta-tiling support was refactored by yours truly to make it easy to retrofit into the new shareable tile set infrastructure.

As a result, in the 4.0 preview 1 release, meta-tiling support is available for Tile Set Definitions in both the Default and XYZ tile providers through 2 new properties:
  • MetaTileFactor
  • MetaTileLockMethod
The MetaTileFactor is a value > 1 that indicates how big our meta-tile to render should be. The specified value will be the multiple of the size of the tile we're requesting. For example, if we're requesting a 256x256 tile from a tile set with a MetaTileFactor of 2, MapGuide will render a 512x512 tile for division into four 256x256 tiles.

The MetaTileLockMethod is an optional setting that controls the locking behavior during this whole process.

  • 1 - Uses a mutex to ensure thread-safe tile writing
  • 0 or unset - Uses a file-based lock for the same effect
Generally speaking, this is a setting you don't really need to tweak and can leave as unset.

Hi-DPI (Retina) tiles

For Tile Set Definitions using the XYZ provider, a new RetinaScale property is available that allows you to generate Retina tiles. Retina tiles are (256 * n) x (256 * n) tiles where n is the specified RetinaScale value. Such tiles provide higher visual fidelity on high-resolution devices such as iPhones, iPads and high-end Android devices.

Our current out-of-the-box viewer offerings do not take advantage of Retina tiles and there is no plans to add such support. This feature is made available primarily for custom viewer offerings (like mapguide-react-layout) to take advantage of.

Other Loose Ends

The previously global TileExtentOffset property can now be configured on a per-tileset basis through a tile set property of the same name. This value is used to internally "buffer" a tile by a certain amount to be rendered to allow label placement algorithms more "breathing space" when determining optimal label placement.

We've also removed the previous restriction that you cannot create a new MgMap from a Map Definition that links to a XYZ tile set (NOTE: Maestro still enforces this restriction in the UI, but this restriction will be removed if we're connecting to a 4.0 server). To see what removing this restriction can give you, there's a new code sample that demonstrates that we can now view any conceivable Map Definition or Tile Set Definition.

No comments: