Thursday, 26 September 2019

MapGuide 4.0 Showcase: Transform all the things!

Did you know that MapGuide uses CS-Map, a coordinate system transformation library with support for many thousands of coordinate systems out of the box? No matter how esoteric the map projection your data is in, MapGuide can re-project geospatial data in and out of it thanks to this library.

So it is quite a shame that for the longest time, MapGuide's powerful coordinate system transformation capabilities has zero representation in any part of the mapagent (the HTTP API provided by MapGuide).

To use MgCooordinateSystem and friends (the classes that wrap the CS-Map library) requires building a your own MapGuide application using the MapGuide Web API in one of our supported languages (.net, Java or PHP) and having your client application call into your own MapGuide application. There is nothing out of the box in the mapagent for a client map viewer application to do a basic HTTP request for transforming coordinates or requesting feature data to be transformed to a certain coordinate system.

For MapGuide 4.0, we've exposed the coordinate system transformation capabilities in APIs where it makes sense. Such as our SELECTFEATURES APIs for returning feature data. In my previous showcase post, I've shown how appending VERSION=4.0.0 and CLEAN=1 now gives you an intuitive GeoJSON result for this API.



The coordinates are based on the coordinate system of the data source it comes from. In the above screenshot, this is latitude/longitudes (code: LL84, epsg: 4326).

Suppose you want this data in web mercator (code: WGS84.PseudoMercator, epsg: 3857) so you can easily plonk this GeoJSON onto a slippy map with OpenStreetMap or your own XYZ tiles, which would also be in web mercator. With MapGuide 4.0, you can now also include a TRANSFORMTO=WGS84.PseudoMercator parameter to your HTTP request and that GeoJSON data will be transformed to web mercator.


The other major capability gap is that the mapagent offers no API over the mapagent for transforming a series of coordinates from one coordinate system to another. For MapGuide 4.0, there's now a dedicated API for doing this: The CS.TRANSFORMCOORDINATES operation.

With this operation, simply feed it:

  • A comma-separated list of space-separated coordinate pairs (COORDINATES)
  • The CS-Map code of the source coordinate system the above coordinates are in (SOURCE)
  • The CS-Map code of the target coordinate system to transform to (TARGET)
  • Your desired output format of JSON or XML (FORMAT)
  • If you want JSON, whether you want the pretty JSON version (CLEAN)
Invoking the operation will give you back a collection of transformed coordinates.



A place where this new API is sorely needed is MapGuide Maestro, which previously required kludgy workarounds for transforming bounding boxes in Map Definitions (when adding layers in different coordinate systems, or re-computing extents):
The next milestone of MapGuide Maestro will now take advantage of this new API for transformation when connected to a MapGuide 4.0 or newer server.

Tuesday, 24 September 2019

Now *THIS* is progress!

So in my previous post, it turns out I had mis-configured the tile grid property of the OL vector tile source in this example, namely the tile size. Is it not the default 256x256, but 4096x4096.

Once I fixed the tile size, everything beautifully snaps into place!





It is still progress

Even if the mapbox vector tiles are completely out of alignment, progress is still progress.

I'm seeing stuff!


Saturday, 21 September 2019

MapGuide 4.0 showcase: JSON that's easier to work with.

If you've ever worked with the HTTP-based mapagent API, you should be aware that most of the APIs responses in the mapagent generally come back in 2 forms:

  • XML
  • JSON
However, if you ever look at the JSON responses, you'll be accustomed to dealing with ugly monstrosities like this (eg. A JSON version of a Layer Definition):



Or heaven forbid, you want to explore the structure of a Feature Source and so you need the JSON version of a FDO feature schema:



Good luck trying to parse and comprehend that!

Why is the JSON so horrible? The answer is XML is the canonical response format for all non-image/binary mapagent operations (MapGuide Open Source's inception was in 2004 after all, when XML was king and JSON probably didn't exist yet), so the JSON version is a literal translation of whatever its XML form would be. While there is nothing wrong with that, the way this JSON translation was done is the most lowest-common-denominator approach:
  • Treat every XML element as a JSON array.
  • Treat every XML element text body as a JSON string.
As a result, as evidenced by the above screenshots that means that all JSON responses are nothing but a series of JSON arrays (of possible more JSON arrays) of strings.

But there is a reason for such laziness. The JSON translation knows nothing about the content model of whatever XML it's trying to translate, so it really has no choice in the matter. Such content models are defined in the various XML schemas that are shipped with MapGuide. But working with XML schemas in C++ sounds like a nightmare in and of itself, so there is another way to determine the content model: Just manually hard-code the list of all possible XML xpaths that are:
  • Repeating (ie. Should be converted to actual JSON arrays)
  • Not a string
Using the existing XML schemas as the reference, this list only required a one-off painstaking translation of this xpath list. The end result isn't exactly pretty, but it gets the job done. With this hard-coded list now in our JSON converter, it means we now have the means to output JSON that is much easier to comprehend and intuitive! 

For MGOS 4.0, for any mapagent operation that returns JSON, if you specify VERSION=4.0.0 and CLEAN=1 in the request parameters you will now get a JSON format that actually makes sense!



Now for some mapagent operations, finally having a "clean" JSON version still isn't enough because the clean JSON response is still mostly clunky and unusable. Consider the FDO feature schema example. The original JSON version is an unworkable monstrosity, and the "clean" version would've just been lipstick on a pig because at the end of the day, it is still a literal JSON translation of an XML schema! 



So as a result, for this set of APIs, a new simpler XML response format is introduced for schema and class definitions by including SIMPLE=1 to your VERSION=4.0.0 request:



From which its JSON equivalent (I hope you'll agree) is much more easier to comprehend!



There is another class of operations that have received a similar treatment. Operations that return geometric/feature data. Consider the XML form of selecting features (the ugly schema section collapsed for brevity):



This is what the "ugly" JSON version would've looked like (schema parts again collapsed for brevity). 



Even if we prettied this up with content-model-aware conversion, the JSON is still mostly unremarkable. Because, if we're serving JSON feature data out to clients, then there's really only one format we should care about supporting:


GeoJSON is the de-facto format for serving out JSON-based feature data, and is universally supported by any mapping/GIS product/tool/library/viewer worth a damn, so if we have the opportunity for MapGuide to return clean JSON data for geometries/features, forget about the literal conversion from XML approach! Just go ahead and make GeoJSON output a first-class citizen

So for MGOS 4.0, if you run any mapagent operation that returns geometry/feature data and you ask for VERSION=4.0.0 and CLEAN=1 you will now get GeoJSON!



Which (due to GeoJSON's ubiquity) can be plugged directly into your web mapping library of choice for display if you so choose.

If you are building your own server-side MapGuide applications with the MapGuide Web API, there's a new MgGeoJsonWriter class is available for you to convert MgFeatureReaders to GeoJSON data.

With MapGuide Open Source 4.0, JSON support is no longer an afterthought, it's actually usable!

Friday, 20 September 2019

Announcing: mapguide-react-layout 0.12.2

This bugfix release plugs remaining localization gaps in the measurement tool and tooltips for various OpenLayers controls we are using.

Project Home Page
Download
mapguide-react-layout on npm

Sunday, 15 September 2019

Announcing: mapguide-react-layout 0.12.1

This bug fix release fixes the broken WMS layer manager that was discovered after making the 0.12 release and also refines the selection sub-highlighting capability check to exclude 4.0 preview 1 and older servers as the 4.0 preview 1 release had a broken implementation of QUERYMAPFEATURES 4.0.0.

Project Home Page
Download
mapguide-react-layout on npm

Announcing: mapguide-react-layout 0.12.0

As promised, here's the long overdue new release of mapguide-react-layout.

As stated in my revised plans, this release marks the point where this project will go on a short development hiatus as I give MapGuide Open Source maximum development priority for the next few months. I may put out a bugfix release or two if the need arises.

Here's what's new and notable in this release.

Support for XYZ tile sets in Flexible Layouts

Fusion in MapGuide was recently able to finally support XYZ tile sets defined in a Flexible Layout (aka. Application Definition) document. That same support has been extended to this release

XYZ tile sets can come from many different sources. It could be your own XYZ tile set definitions or a custom OSM flavor tile set, or Here Maps (as shown below)


Or many more!

Selections now live through browser refreshes

Map selection state is now stashed into browser local storage and recovered from on startup upon a browser refresh


Sub-selection highlighting now only enabled for MapGuide Open Source 4.0 (and newer) servers

Our neat little trick of sub-selecting selected features actually has a major flaw. It is built on the erroneous assumption that selection keys and selection attributes in a QUERYMAPFEATURES response are rendered in the same order (we used the current index of the selected feature's attributes to pick up the selection key at the same index to request a sub-selection for). This turned out to be sadly not the case.

Rectifying this required a new version of the QUERYMAPFEATURES API that will also render selection keys alongside attributes (to avoid the same-index selection key lookup). This has been implemented for the MGOS 4.0 preview 1 release.

But what that means is that sadly we have to disable sub-selection highlighting for older MapGuide Servers. This feature is now only enabled for MGOS 4.0 preview 1 (and newer) servers.

Share Link To View component can now copy to clipboard

This component now includes a button to copy the link to the clipboard, saving you the need to select the URL and copy yourself.


NOTE: This component will not include the map selection if another user opens the shared link on another browser/computer as that selection state lives in the user's browser local storage and is too big to reliably encode into the URL itself for sharing.

Smaller JS bundle size

The viewer JS bundle previously bundled all the necessary CSS within the JS. For this release, that CSS has been extracted out to a separate viewer.css file. This has 2 benefits.

  1. The JS bundle is now smaller
  2. The viewer CSS can be modified if you so please.

Compare the bundle size of the previous 0.l1.2 release

Against this 0.12 release

Other Changes
  • Plug remaining i18n holes in measure and WMS layer manager components.
  • Don't word wrap layer/group node labels in Legend component and provide tooltips for these labels
  • Remove non-geodesic measure option as it is mostly inaccurate.
  • Fix init failure if appdef has an empty widget container
  • Fix line measurement total showing units in m^2
  • Fix measure tool starting measuring when switching measurement type
  • Fix memory leak due to dangling measure components being held on by the measure context after unmount
  • Various components updated to use componentDidUpdate instead of componentWillReceiveProps
  • Made redux actions more strongly-typed
  • Updated Blueprint to 1.40.0
  • Updated TypeScript to 3.6.3
  • Updated React to 16.9.0
  • Replaced query-string module with qs
  • Now built with webpack 4.x

Project Home Page
Download
mapguide-react-layout on npm