We also have a new example using the turf.js geometry library for slicing and dicing GeoJSON map selections client-side, which can then be saved server-side into a session-based layer and be incorporated into the map itself.

Since our sample applications use both OpenLayers 3 and cesium, we've also have an XYZ tile sample that uses both thanks to the ol3-cesium integration library.

And there's many more sample applications to try out. (NOTE: The vector tile example is broken in this release, I'm looking to fix that in the next release)

Other changes in this release include:

The whitelist configuration introduced in the previous release, is now extended to cover resource service APIs as well

The selected features route can be restricted to certain property names like the other routes that return feature data

XYZ tiles (not served from a Tile Set Definition) should no longer have labels/symbology anomalies at tile boundaries as mapguide-rest now renders out "buffered" XYZ tiles and crop the result to the original 256x256 size

GeoJSON output now covers the full set of supported geometry types

I'm certain this release will be the last one before I put the final 1.0 stamp on it. Other than documentation cleanup, and some performance testing I do not see anything of a show-stopping nature that impedes me from making the next release the 1.0 final release.

The HttpPlatformHandler module for IIS allows it to do process management and request proxying for other http listeners (like Tomcat or Kestrel), making it possible for IIS to "host" Java or .net Core applications.

So regardless of whether you're on .net*, PHP or Java we now have the means to deploy and host it on both Windows and Linux.

* Yes, there's a small caveat in this idealized scenario. It requires:

Your .net MapGuide application basically has to target the .net Core profile (and not the full .net Framework) in order to take advantage of the cross-platform deployment scenario.

That we can reverse-proxy to Kestrel from Apache HTTPD. The official documentation refer to nginx as the front-facing web server, but if the ability to reverse proxy is the sole requirement, then any web server that has the capability can be the front-facing web server and not just nginx.

Tuesday, 3 November 2015

NOTE: This tip only applies to PHP that is bundled with MapGuide Open Source 2.6 and newer.

MapGuide Open Source 2.6 and newer bundles the 5.5.x series of PHP, which includes a new opcode caching feature. Opcode caching can reduce execution times by upwards of 50% (as is the case with our mapguide-rest functional test suite which usually took around 6 minutes to run, but now runs in just over 3 minutes with opcode caching enabled)

In the interest of playing it safe, we didn't activate this feature in the default php.ini that's bundled with MapGuide. So if you want to activate this feature, you'll have to edit php.ini and add the following lines:

Thursday, 8 October 2015

What this means is if you have a Feature Source that connects to a directory of SHP files, you should see dramatic performance improvements in walking schemas and class definitions of that feature source if that directory contained lots of SHP files. How does this work?

GetSchemaNames only has to return the schema name which will always be "Default". No disk I/O necessary

GetClassNames only has to return a class name list based on the file listing of the connected directory as each Feature Class name is basically the name of the SHP file (without the .shp extension). Previously, this would build the FDO logical schema from every SHP file in that directory and then return the class name list of that. Building that logical schema means connecting and inspecting every SHP file. For a directory with lots of SHP files, that takes a lot of time.

DescribeSchema with class name hint just means instead of constructing the FDO logical schema of every SHP file in that directory, we just do it for the list of SHP files indicated by the class name list (once again, because SHP class name = SHP file name)

GetClassDefinition does not require a full DescribeSchema first, as the parameters passed to it now contain enough information to know which physical SHP file to inspect and create the necessary class definition from it.

In practical terms, the performance gains will be most apparent on:

Editing SHP-based Layers in Maestro because the schema/class listing operations are now super cheap and fast.

Any code in your application or MapGuide Server that needs to access a single class definition from a feature source. In the past without these APIs supported, a full schema walk on the SHP feature source was required first in order to pluck out the necessary class definition from within it. This would be most noticeable performance wise when a request for a given class is made the first time. Subsequent times would be near instant due to caching, but for directories of many SHP files that first request could take a while.

This template is basically my dream responsive map viewer layout fully realized, which I've been trying to replicate for the longest time since I first heard of bootstrap.

A cursory glance at the repo shows that it's written in the most un-obtrusive of HTML, CSS and JavaScript which means actual integration of bootstrap-styled content should be a simple affair, and their examples already cover allthepossiblemap viewer solutions you would ever use.

Monday, 13 July 2015

Last year, I said I would be interested in attending the 2015 iteration of GovHack. Well, this time round, I almost didn't make it. I didn't get wind about the tickets for this years event being available until 5 days after the initial announcement and it seems that was enough time for tickets to be sold out. Well fortunately, one Saturday before the event, I get the email notification that I'm off the wait-list so I claimed that available ticket before it was too late and I was locked in for GovHack: Round 2.

Although I did have a idea about what to build this time round, the key materials needed to make this idea work arrived too late to realistically execute this idea of mine, so I've put that idea on ice (yes this whole preceding sentence is kept intentionally vague :)).

Compared to last year, this time round was much smoother. Team was assembled quickly, we had several potential ideas worth pursuing for the next 46 hours. In the discussions that followed it was decided that we should have an interactive map. Cue my map expertise ... :)

So armed with my brand new hackathon-grade ASUS Zenbook that I acquired a few months earlier, we set forth to build ... yet another MapGuide concoction.

Unlike last year, this time round wasn't a load-everything-into-MapGuide and house it in a Fusion application affair. This time round, we looked to build a MapGuide application geared towards modern browsers and mobile devices, using the building blocks of OpenLayers 3, Bootstrap and Knockout.

The end result, is our GovHack 2015 entry: The VET provider map.

The VET provider map allows people to look for Vocational Education and Training (VET) providers in the state of Victoria. With this map, people can search for:

VET providers

Occupations (which would then show related pathway courses and the providers that offer them)

Courses (offered by a provider, that is a pathway to a given occupation)

Unfortunately, due to time constraints the (bits that I mentioned in parentheses) could not be completed within the weekend, meaning that while you could search for courses and occupations, the crucial link to the actual providers on the map that offered such courses is not there. Still, what was implemented should convey what we are trying to achieve with this application.

The search capabilities are powered by the data publishing framework of mapguide-rest, which gave our spatial data sources ready-to-go (Geo)JSON APIs for our application to use, and also "cleaner" JSON property names (pet peeve of this hackathon: Dealing with property length limitations of the SHP file format and undesirable property/column names. Ugh!)

A modal-based legend/layer toggler that shows when you hit the "Layers" button on the map viewer.

And finally, the whole application is responsive.

But don't take the word of my gifs and screenshots, you can see the map in action for yourself from our demo site linked on our hackerspace page. Once again, the demo site is hosted on a Amazon EC2 micro instance (be gentle :)). If you're interested in the source code and data that drives this map, you can find that on our GitHub repo. Be sure to vote for our entry if you can.

Thanks to the team (Ling, Tim and Hans) for your coding, data acquiring, wrangling and video production efforts. It's been a blast!

Friday, 19 June 2015

However, this support was partial as it only targets un-tiled Map Definitions. None of the tiling mechanisms in OpenLayers 3 were compatible with the tiling scheme used by MapGuide meaning OpenLayers 3 cannot consume non-XYZ tiles from MapGuide ...

... Or so I thought.

It turns out that it is indeed possible to consume non-XYZ tiles from MapGuide, here's one such example using the just released v3.6.0 of OpenLayers.

What this means is that OpenLayers 3 is at feature parity with OpenLayers 2 in terms of MapGuide support, meaning it has the core functionality we need to build a MapGuide client mapping application out of.

Sometimes, your data has to escape the MapGuide/FDO ecosystem and be consumed from other geo-software. If the limitations of the omnipresent SHP file format leave a lot less to be desired, then the next best thing is SQLite databases.

The reason I say this is because:

SQLite files (in our context) are just regular SQLite database with some special tables so mapping software know how to read features from them. You don't need FDO to peek inside the structure of a SQLite database. Any other SQLite database tool or library can get at the data as well.

SQLite is a relational(-ish) database. So features you'd expect in an RDBMS (eg. views) are also available in SQLite. Can you say that about SHP files?

The biggest reason. There's an OGR driver for SQLite, and it understands FDO's flavor of SQLite databases, and if your mapping software isn't using FDO, it's using GDAL/OGR!

Sure, there's a few quirks here and there, but they can be worked around or fixed.

From the "I lost several hours discovering this so you don't have to" department

Today, I was tasked with producing some KML files. The spatial data was in SQL Server and it needed to be married with some CSV files I had, but I wanted it to get into a more portable format so I can do the bulk of the styling work in MapGuide without having to touch the SQL Server again.

Due to some quirks in this SQL Server database, the SQLite file that were produced from an FDO Toolbox bulk copy did not have any spatial contexts in them. This turns out to be a big problem because MapGuide has to know what coordinate system your data is in for rendering and various outputs to work, especially if coordinate system transformation is required. You can fix and/or flub such a coordinate system using the Coordinate System override section of the Feature Source, but this only works if MapGuide/FDO can read a spatial context from the data store for you to stick in a replacement coordinate system in.

This actually broke the KML support in MapGuide I was intending to use because it needs to know if your data is LL84 or transformable to it and since the SQLite file had none, MapGuide didn't do anything with the data when I wanted a KML export of it. Rather than waste time re-exporting this data in another format, I wanted to see if such files can be "fixed" in-place and be made usable again.

Since SQLite files are actual relational(-ish) databases, you can open them any SQLite database viewer^ (there's a lot of them) to take a look at the contents. When you open such a file, you'll see various tables representing each of your feature classes and some special tables:

fdo_columns

geometry_columns

spatial_ref_sys

fdo_columns contains the FDO property metadata for each column of each table. Without this table, the SQLite FDO provider will treat all columns as strings, even if your column stores numbers, dates, etc.

There are no rows in spatial_ref_sys. Each row in this table is read as a spatial context

Any rows in geometry_columns either have an srid of -1 or an srid with no match in spatial_ref_sys

So with this knowledge, to "fix" such files so MapGuide knows what coordinate system they're in:

Insert a new row into spatial_ref_sys

Update the srid column of all rows in geometry_columns to the srid of the row you inserted into spatial_ref_sys

Or if none of what I just said made sense, just run the commands in this gist in your SQLite database admin tool of choice. Once done, your SQLite database will have a spatial context which you can then put an override in your Feature Source so that MapGuide knows what coordinate system to interpret your data in.

^ Though FDO Toolbox can technically be used to admin SQLite databases, I am suggesting alternative tools as I am not sure whether the SQLite FDO provider will let you "fix" something that it has an already-open connection to, nor do I know if the SQL commands the fix this will work as intended when going through the SQLite FDO provider. Better to be safe than sorry.

Tuesday, 16 June 2015

With no real show-stopping bugs of note, I've decided to put out the first release candidate of MapGuide Open Source 3.0

RC1 rolls back a problematic change introduced in beta 2 that resulted in a feature reader from SelectFeatures query not returning all results in the reader. Other than that, this contains some minor fixes for Fusion and the SDF and SQLite FDO providers. All the details can be found the release notes below

Thursday, 11 June 2015

The main addition in this release is support for defining a "whitelist" in config.php that will restrict feature service APIs to only the specified operations and feature sources defined in the whitelist, allowing you to reduce the attack surface of your mapguide-rest install by only controlling API access to feature sources of your choosing. You can find a commented-out whitelist example in config.php that you can adapt to your own installation.

Other changes and fixes include:

Fix runtime map XML generation for versions of MapGuide that do not support CREATERUNTIMEMAP

Tuesday, 12 May 2015

One of the most apparent things you'll notice as you download this release is ... the size.

As an experiment (since we're still in beta), we've excised some USA-specific coordinate system grid files and un-used Geoid height files from our installation packages. As a result our installation packages are up to 150MB lighter than they were previously.

Our test suites indicate nothing is affected by the omission of these files except for if your spatial data uses a US-based coordinate systems based on an NSRS datum. Unless your data is based in the US and you have strict data requirements that require such a coordinate system be used for your data and maps, you will probably be unaffected by the omission of these files, so why carry an extra 150MB download burden for something you'll never use amirite?

But don't fret, these grid files are made available as a separate package for download as a supplemental package should your installation of MapGuide require them. However, if this change does break functionality in your installation (and you're not using a US-based coordinate system based on a NSRS datum), we'd like to know about it.

If things go smoothly with this change, we'll most likely extend this installer weight-loss program to the next (long overdue) 2.6.1 point release as well.

Friday, 24 April 2015

A question that gets normally asked on our mailing list is how do you get the GDAL FDO provider to work with formats like ECW or MrSID. Our normal response would be (provided you are licensed to use ECW, MrSID or any other non-standard GDAL supported format) to point you over to GIS internals and grab one of their custom windows GDAL binaries to replace the GDAL dlls in your current MapGuide installation.

The reason we ask you to do this is because when we build GDAL for use with the FDO provider, we build GDAL using only the standard profile of supported formats. That is to say any format listed here:

Where the Compiled by default option is unconditionally Yes. It is not possible for us logistically to build GDAL/OGR with the proverbial kitchen sink of raster/vector format support, so that's where GIS internals comes in as their builds of GDAL/OGR have greater raster/vector format support. As long as you grab the same release of GDAL and make sure to pick the build that is built with the same MSVC compiler used to build the release of MapGuide/FDO you're using, you should then have GDAL and OGR FDO providers with expanded vector and raster format support.

This suggestion worked up until the 2.5.2 release, where the right version of GDAL built with the right version of MSVC (2010 at the time) was available for download. But for 2.6 and the (pending) 3.0 releases, this suggestion is not applicable because that site does not offer a MSVC 2012 build of GDAL 1.10, which is what MapGuide 2.6 and 3.0 both use for their GDAL FDO provider.

So this leaves some of you in a pickle, being stuck on 2.5.2 and unable to move to 2.6 or 3.0 because you need to support one of these esoteric data formats. Well, I have partially alleviated this issue for you.

Tamas has not only made these custom GDAL binaries for download, but also the development kits used to build these binaries as well. So in these past few days, I grabbed the MSVC 2012 dev kit, paired it with our internal GDAL 1.10 source tree in FDO and made a few tweaks to some makefiles here and there and here's the end result.

A custom build of GDAL 1.10 with support for the following additional raster data formats:

Well I did say I have partially alleviated the issue and not fully alleviated it. The issue is that due to what I gather is licensing restrictions, the development kit can't bundle the necessary headers and libraries needed to build GDAL with driver support for MrSID, OCI, etc. As such the custom build of GDAL I have made available does not include support for such formats.

What can be done about this. For something like Oracle, we already have a dedicated FDO provider for that. For something like MrSID? I'm afraid you're out of luck. You'll either have to stick on the 2.5.2 release for that much longer, or just bite the bullet and gdal_translate those MrSID files to something more accessible. I've heard some good things about RasterLite. I've also heard that you could get some great performance out of carefully prepared GeoTiffs.

Any thing to liberate yourself from MrSID because you won't see the right GDAL binaries with this support built in for the foreseeable future.

One more thing before I finish that is worth re-iterating. Some formats like ECW, require you to be have a license to use ECW technology in a server environment. Other formats carry their own licensing shenanigans, so make sure you are properly licensed to use any of the the additional formats that are made available with this custom build of GDAL. The GISInternals build system repo on GitHub has all the applicable licenses in RTF format for your perusal.

Also worth pointing out is that this custom build of GDAL is not supported by me or anyone on the MapGuide development team. I only make this build available to you so you have the ability to access these additional data formats should you so choose and nothing more. There is no obligation by us to provide support for any issues that may arise as a result of using this custom GDAL release (inferred or otherwise). Use this custom build of GDAL at your own discretion.

Map Definitions using the new schema, have the option of the choice of tile source

An inline tile source will be as before, where you can define base map groups and layers within the Map Definition.

An external tile source, will replace the base map UI with a new UI that simply asks for the Tile Set Definition you want to link against.

When linking against a Tile Set Definition, it is important to note that its coordinate system will take precedence

Also important to note is that you can only link to Tile Sets using the Default tile provider. Linking against XYZ tile providers is not supported in MGOS 3.0 and Maestro will prevent such an action from taking place.

MgCooker has also been updated to support tile seeding of Tile Set Definitions.

However, only Tile Set Definitions using the Default tile provider are supported. For Tile Set Definitions using the XYZ provider, consider using other tile seeding mechanisms for now.

FDO Expression and Filter support

Maestro now supports the ability to parse FDO Expression and Filter strings in pure 100% managed .net code without needing to use FDO itself. This feat was made possible through the use of the Irony language implementation library which made implementing the grammar and appropriate parsers for the FDO expression and filter syntax a dead simple affair.

With the ability to parse FDO Expressions and Filters, our Expression Editor is enhanced as follows:

We now have the ability to validate the given filter or expression for syntax validity.

With the ability to analyse the structure of FDO filters and expressions, we can now also ensure you are referencing valid identifiers in your filter or expression. Such invalid identifiers will be caught by the validation process.

Finally, a new tool is included that lets you see the parse tree of the given filter or expression.

As a developer, this functionality is accessible in its own 100% managed .net class library (OSGeo.FDO.Expressions.dll) should you have a need to parse FDO filters and expressions in your application without using FDO itself.

Reading user input from IronPython console

The IronPython script console now supports reading user input from stdin with Python's input() and raw_input() functions. Previously, you would've had to construct your own input GUIs and display them in order to capture any user input from your IronPython scripts.

With this in place, such workarounds are no longer required and allows for more flexible Maestro automation scripts as a result.

Advanced Stylization editor improvements

We've improved the Composite Symbolization editor to better work with component symbols.

Firstly, component symbols now show the applicable geometry context.

Secondly, component symbols can be re-ordered as ordering affects how the final composite style will look, so having the ability to re-order component symbols is important.

Finally, the best bit of these improvements is that now you can export a component symbol out to its own Symbol Definition.

This promotes better re-use of Symbol Definitions within layers as you can already use an external Symbol Definition as a component symbol. This new feature helps to make this process much more streamlined.

mapguide-rest support

Maestro now includes a dedicated addin to easily author up, upload and manage restcfg.json files in mapguide-rest.

This addin takes advantage of new authoring APIs introduced in mapguide-rest 1.0 RC1, and thus this is the minimum required version of mapguide-rest that this addin will work with.

This feature deserves its own blog post so stay tuned.Other stuff

We've now moved to .net Framework 4.5. This means Maestro will no longer run on Windows XP.

From a developer perspective, we've done some major re-structuring to allow for better developer scenarios. The most pertinent example being that all the various ObjectModels assemblies have now been combined into a single assembly. Referencing this single assembly gives you the ability to work with every supported resource and schema revision from MapGuide 1.0 to MapGuide 3.0 as strongly-typed classes instead of XML.

Tuesday, 31 March 2015

If I were to pick the most compelling feature of MapGuide Open Source 3.0, it would be the one I am about to show you in this post.

Do you bemoan the fact that tiled maps are tied to a given Map Definition preventing their re-use with other Map Definitions?

There are ways to work around this problem, by using the "hack" of stacking multiple Map Definitions in a Fusion Application Definition. In this case, you would have a purely tiled Map Definition and you combine this with a purely dynamic Map Definition in your Application Definition and provided both maps are in the same coordinate system, both tiled and dynamic layers will line up.

You can then reuse this tiled map definition with other Fusion applications by mixing and matching tiled and dynamic Map Definitions together. However as already mentioned, this is a hack because it exploits an esoteric feature of Fusion: The ability to have more than one Map Definition specified in a Fusion MapGroup. This technique doesn't work with the AJAX viewer.

For the 3.0 release, we have solved this problem by introducing a new resource type to define shareable tile sets: The TileSetDefintion.

For a cliff notes summary: A TileSetDefinition is a re-usable tile cache that is effectively the BaseMapDefinition element of the Map Definition Schema separated out into its own resource. A TileSetDefinition lets you:

Define one or more base layer groups, each with 0 or more layers

Define a finite set of scales

Define the coordinate system of this tile set

Define the bounds of this tile set

Basically the same tiled layer settings you would've previously defined in a Map Definition. In addition a TileSetDefinition also lets you define additional settings that are specific to that tile set:

Tile size

Tile image format

Tile storage location

No longer are your tile sets constrained by global tile settings in serverconfig.ini and no longer are your rendered tiles always stored in a global defined tile cache directory. Each tile set can have their own tile size, format, storage location.

Here's an example of such a Tile Set Definition, notice the structural similarity to the Base Map section of the Map Definition

Finally, there's the re-usability aspect. Once a TileSetDefinition has been created, you can link to it from any Map Definition. Tile caches are now bound to the TileSetDefinition instead of the Map Definition. When a Map Definition links to a TileSetDefinition, it will override the following settings from the Map Definition:

Coordinate System

Map Extents

The reason we do this is because dynamic map layers can be re-projected, but tiles cannot. So in the event that the Map Definition has a different coordinate system from the one in the linked tile set, the linked tile set "wins" and all the dynamic layers in the Map Definition will be re-projected to the coordinate system of the tile set, ensuring that both dynamic and tiled layers will line up properly.

And the best thing about this is that both AJAX and Fusion viewers support shareable tile sets*. The above multiple map hack is no longer needed.

* For this release, this will only work with shareable tile sets using the "Default" tile provider. Why? Read on below.

XYZ Tile Support

The TileSetDefinition schema allows tile set settings to be defined in a key/value fashion like you would in a Feature Source. This schema design is intentional as it allows us to define a FDO-style provider model behind the scenes for tile access. Through this provider model, we are able to add support for different tile access schemes, one of which is XYZ tiles. This means you no longer need mapguide-rest to serve XYZ tiles. MapGuide 3.0 will have this support natively.

Here's an example of a Tile Set Definition using the XYZ tile provider

Notice that the XYZ tile set definition does not specify a coordinate system. This is because XYZ tile sets are always in WGS84.PseudoMercator (aka. EPSG:3857), so there is no need to specify this. The extents describe the bounds of this tile set in EPSG:3857 coordinates.

You'll notice in both examples, that we have the concept of a tile provider along with a set of key/value pairs to describe settings applicable for that provider, which is similar to the how a Feature Source specifies a FDO provider and a set of key/value pairs that form the set of FDO connection properties.

And what is this %MG_TILE_CACHE_PATH%? It is a placeholder for the global server tile cache path, and just like %MG_DATA_FILE_PATH% for feature sources, you can replace this with actual physical paths or MapGuide aliases. That's right, your Tile Set Definitions can have their own defined tile storage location instead of being all under a globally defined path in serverconfig.ini

As you can see, the similarity between tile providers and FDO was quite intentional :)

This provider model is currently hard-coded for these 2 providers. There is no formal plugin model/API yet that allows for external third-party tile providers to be defined. Whether we will add such support in a future release is a discussion for another time.

The best thing about this XYZ support: No API changes required! You still use the same GETTILE requests to the mapagent, only now you pass in the actual X, Y and Z for the ROW, COL and SCALE parameters.

Now there is one limitation of the XYZ support for this release. You cannot create MgMap instances from a Map Definition that links to an XYZ tile set, and as a result you cannot load such Map Definitions in the AJAX and Fusion viewers. The main use case for XYZ tile support in this release is to enable easy consumption of XYZ tile sets in MapGuide by external clients like OpenLayers, Leaflet, etc. We'll correct this limitation for the next major release after 3.0.

With this release, there's a new sample you can check out that demonstrate how to consume XYZ tiles from OpenLayers.

When you look at the code, you'll find consuming XYZ tile sets from MapGuide is as simple as consuming OpenStreetMap and friends in your JS mapping library of choice, be it OpenLayers, Leaflet or any other library that can consume XYZ tile sets.

Now that our tile storage and access has been abstracted behind a Tile Set Definition resource, it paves the way for us to easily enhance the tiling capabilities in the future with:

Support for additional storage backends (eg. MBTiles)

Support for additional tile formats (eg. Vector tiles, UTFGrid)

Standardizing tile access (eg. WMTS)

That's not to say such items are definitely on our current roadmap, but it will make implementing such features a more realistic and feasible possibility now that the groundwork has been laid in this release.

For more information about these new Tile Service Enhancements, you can consult MapGuide RFC 140

Monday, 30 March 2015

After a month or two lost due to mucking around with packer and vagrant to get the perfect repeatable and disposable build environment for both Windows and Linux builds of MapGuide/FDO, I'm now happy to announce the availability of MapGuide Open Source 3.0 Beta 1.

Friday, 6 March 2015

I've decided that mapguide-rest has enough features to lock in the 1.0 version number.

Here's what's new in this release.

Cleaner JSON responses

If you've used JSON output from mapguide-rest or MapGuide proper, you'll notice that the JSON is ugly and cumbersome to use:

Every JSON property is an array

All property values are strings

The main reason this JSON is so ugly is because of the way that XML is converted to JSON. The conversion process knows nothing about the content model of the XML document it is trying to convert, so as a lowest-common-denominator solution, it forces all converted XML elements to JSON array properties and all XML text elements as string values. While this allows for rudimentary usage by client applications, it's not a pleasant experience.

For this release, we've set out to solve this problem. The JSON produced which would've looked like this:

Now looks like this:

How did we achieve this? Simply put, we now maintain a hard-coded list of known XML element paths (compiled from all the MapGuide XML schemas) and make note of:

Which paths must always be processed as a JSON array

Which paths have values whose data type is not a string

With this list, we now know which XML elements need to be converted to JSON arrays and which elements need to be converted to JSON property values, and the proper data type to convert such values to.

The end result is that the new JSON responses are much more natural and intuitive to work with. Not to mention these new JSON responses are smaller than their previous counterparts. Those extra [ and " characters do add up.

This is a PHP-level solution. With this release, all JSON conversion/output is now handled by mapguide-rest. While slower than doing it natively in MapGuide, it gives us more usable JSON structures and this increased usability is worth it for the slower performance.

As for the old JSON response structure, that is going away in mapguide-rest. This new structure will be used for all APIs in mapguide-rest that return JSON. If you want the old JSON structured responses, you'll have to go back to the mapagent.

In one particular case, we eschew the convert-to-JSON-from-XML approach and define a new dedicated JSON response format.

Ever tried to describe the schema of a Feature Source? This is the XML response:

Have you seen the JSON version of this monstrosity?

How on earth would any sane person know how to use this response in their applications? Yeah me neither.

So for schemas and class definitions that are returned as JSON, we introduce a more cleaner and intuitive JSON format

Isn't that a more intuitive and self-explanatory JSON response?

This new response structure is only applicable for JSON schemas and class definitions. The XML version of these schemas and class definitions will still be its same ugly and verbose self. From my perspective, XML is the "legacy" response format in mapguide-rest. JSON is the preferred response format for any client application and so we should strive to make consuming such data in this format as simple and clean as possible. With this release, hopefully we've achieved that objective.

While we're still on the subject of JSON, for certain REST APIs that previously accepted XML request bodies, such APIs now support JSON-equivalent request bodies. For example, consider this route to set resource content:

POST /rest/library/{resourcePath}/content.xml

To set resource content, you'd make a POST request to this route and include the resource XML as part of the request body.

You can now set the same resource content via its JSON representation

POST /rest/library/{resourcePath}/content.json

By making a POST request to this route and include the equivalent JSON as part of the request body. Because our JSON formats now structurally follow their XML counterparts, knowing what JSON to construct should be easy to figure out. On the server-side such JSON bodies will be converted back to its XML counterpart before passing down to the underlying MapGuide APIs (because sadly XML is still the canonical format for storage and data transfer throughout the official MapGuide APIs)

Authoring APIs for restcfg.json files

We've added a set of new APIs in the data publishing framework to allow for restcfg.json and any supporting files to be uploaded from a mapguide-rest client without needing physical access to the directory where the restcfg.json files are stored.

These authoring APIs allow you to:

Upload a restcfg.json file to a desired subdirectory within mapguide-rest based on the given URI part

Upload any supporting files to the subdirectory mapped to the given URI part

Delete any restcfg.json configuration

Delete any supporting file of a restcfg.json configuration

Because URI parts are mapped to physical subdirectories within a mapguide-rest installation, there could be a opportunities for malicious activity without proper security precautions. To this effect, we do the following:

Such APIs require Administrator or Author-level roles to be assigned to the authenticated user. The MapGuide Anonymous users will not have such roles, and thus any attempt at accessing these APIs will be denied.

Any URI parts and filename parameters are sanitized to strip off any semblance of relative paths and any other path navigation tricks that would cause mapguide-rest to save/delete a file or directory outside of its installation directory.

APIs that previously returned simple primitive values now return a XML or JSON boxed version of that value. Simply put, if an API returned a boolean value like this:

true

It will now return a boxed value, which looks like this for XML:

And looks like this for JSON:

{ "PrimitiveValue": { "Type": "Boolean", "Value": true } }

While this looks more verbose, it is simply to provide a consistent developer experience. If you have been expecting XML or JSON responses for 99% of the APIs, why make an exception for this 1% of APIs that return basic primitive values? They should be XML or JSON respectively as well and in order for that to happen, we have to box such values.

In addition many new APIs have been added to cover missing pieces and loose ends in our REST API:

Creating Feature Sources

Setting and deleting resource data items

Listing Long Transactions of a supported Feature Source

Getting the coordinate system base library

Validating Coordinate System WKT

Converting Coordinate System WKT to EPSG codes

Testing the connectivity of a Feature Source

Enumerating unmanaged (aliased) data

Getting site information status/statistics

DescribeSchema with class name hint

Setting content and header of any resource in a single request

Fusion layout authoring support APIs

Interrogating and setting the edit-ability of a Feature Source with the REST API

The data publishing framework now supports CRUD for JSON representations. The JSON representation is much more simpler and compact in its request payloads. The requests to create, update and delete features are structurally the same as the XML one (using the same XML-to-JSON pattern for most of our JSON data structures)

The existing Editable Properties example has been modified to use the JSON representation instead of the XML one. For doing CRUD through the data publishing framework, I'm sure you'll find it much easier to work with this JSON representation than the XML one.Customizable HTML representation

The HTML representation for features are now customizable and localizable as the previous bits of hardcoded HTML that were rendered out by the HTML renderer, have all been extracted out into Smarty templates, where you can customize the HTML to your own liking.MapGuide 3.0 support

From now to the final 1.0 release of mapguide-rest, it will be nothing but bug fixes and (really) minor enhancements.

After 1.0 as I've somewhat hinted, if mapguide-rest as a project should have a continued evolution, I strongly believe it should be on the ASP.net 5.0 platform. Given ASP.net 5.0 won't see light for many more months, I'll have plenty of time to play and experiment with many ideas that are possible with ASP.net 5.0