Showing posts with label MapGuide. Show all posts
Showing posts with label MapGuide. Show all posts

Sunday, 12 October 2025

Announcing: MapGuide Open Source 4.0 Final (yes, you read it right!)

I am pleased to announce to final release of MapGuide Open Source 4.0!

It has been 6 years, 6 months and 14 days since the last major stable release (3.1.2). What started as something that was supposed to be the 3.3 release stretched out to what is now the 4.0 release. Maybe some things could've been done better to not make this release gap so big, but things transpired the way they did and what's done is done.

Download

Wednesday, 10 September 2025

Announcing: MapGuide Open Source 4.0 RC1 and MapGuide Portable

We're on the home stretch now!

The first (and hopefully only) release candidate of MapGuide Open Source 4.0 is now available.

Changes since Beta 3

This release has the following changes since Beta 3:

  • A new .net repository admin tool that replaces the existing series of PHP scripts that required a super-ancient PHP binary.
  • Apache httpd updated to 2.4.65
  • PHP updated to 8.3.25
  • Tomcat updated to 9.0.108
  • Plugged a memory leak in selection processing if it throws an FDO exception
  • The .net bindings now have experimental support for Linux

New nuget packages

As a test run for the final release, the .net bindings have also been published to nuget.
To get started building a .net MapGuide application for 4.0 RC1, install the above packages (ver 4.0.0.10185) via the nuget package manager or via the dotnet CLI.

Need an idea or example of how to build a MapGuide application using these packages in modern asp.net core? Have a look at the mvc core sample.

As already stated, these bindings also have experimental support for Linux, meaning you can publish your .net application to run on Linux as opposed to Windows. Here's a screenshot of the mvc core sample application published to and running on Linux, talking to a MapGuide Server also on Linux being contacted from a web browser on Windows.


MapGuide Portable

The sub-project formerly known as mg-desktop is now known as MapGuide Portable (or mg-portable).

Why the name change? The "desktop" moniker felt too constricting. You're not exclusively tied to building just desktop applications. You could build "headless" console applications or maybe even MapGuide Server-free web applications with this library. As such, "portable" is the better moniker as it is a MapGuide Platform that goes with your application, in effect being portable.

Why are we mentioning MapGuide Portable in a 4.0 RC1 announcement? Because our extensive work on generating API bindings with vanilla SWIG had some minor splash damage. As MapGuide Portable builds on top of the shared Foundation/Geometry/PlatformBase series of libraries, we'd be leaving this in the lurch if we got these new fancy .net bindings for MapGuide proper, but still had to resort to the old crufty legacy bindings for MapGuide Portable, so extra effort was spent to get the .net bindings for MapGuide Portable to not only be generated through vanilla SWIG as well, but also retain package modularity by being able to depend on the new Foundation/Geometry/PlatformBase nuget packages.

The end result is a new series of nuget packages that you can use either in a legacy .net Framework 4.8 WinForms application or a WinForms application in the new modern .net!


Unlike the proper MapGuide API nuget packages, the MapGuide Portable packages are still Windows-only (since WinForms is tied to Windows). The new MapGuide Portable packages are:
The older mg-desktop-* packages on nuget should be considered deprecated and you should move over to these new MapGuide Portable nuget packages as these packages support modern .net while the mg-desktop-* packages can only be used in legacy .net Framework.

The final stretch

Between RC1 and the Final release I will be primarily focusing on an API documentation sweep, getting functional API documentation up and ready. Only bugs of a show-stopping nature will be addressed and only if such bugs have easy means of reproducing (I can only do so much). I am allowing for up to a month for this development window before the Final release, so that we can wrap things up before Windows 10 reaches end of life, just over a month from now.

This long and arduous journey is almost at an end!

Friday, 6 June 2025

Announcing: MapGuide Open Source 4.0 Beta 3

A new beta release of MapGuide Open Source 4.0 is now available.

The main driver for this release is updating an assortment of bundled components:

  • PHP updated to 8.3.20
  • Apache httpd updated to 2.4.63
  • Tomcat updated to 9.0.104
Sticking with PHP 8.1 would've meant that come November this year we would be bundling something that would've been end-of-life. Updating our bundled PHP to 8.3 gives us the maximum possible runway in terms of support (on the PHP side) as its end-of-life is 2.5 years from now.

This release also plugs an assortment of memory leaks found in:
  • The King Oracle FDO provider
  • Rendering of tiles from tile sets
  • Rendering of watermarks
  • In-memory feature joins
  • Render profiling

Thursday, 16 January 2025

Announcing: mapguide-react-layout 0.14.10 and MapGuide Maestro 6.0m13

We start the new year with a double-header release of:

  • MapGuide Maestro 6.0m13
  • mapguide-react-layout 0.14.10
What prompted these new releases other than (it's long overdue)?

Namely, it is to do with a notification I received about the coming deprecation (and eventual shutdown) of the epsg.io service that both pieces of software use to do proj4 projection lookups for any given EPSG code. This service will shutdown in Feburary (next month) and transition over to the MapTiler coordinates API. This new API requires an API key to use their services.

In the context of these 2 projects, the API key requirement introduces too much friction.
  • If I take up the offer to use MapTiler, I have to register and bake my API key into both Maestro and mapguide-react-layout and am now responsible for API usage/monitoring under this key from users I have no control over. Last thing I want to deal with is bug reports from users because, let's say for example: proj4 lookup is broken because the API is no longer accessible for my API key due to quota exceeded. I just don't want to deal with such a scenario.
  • Which means the alternative is to change the code to the extent that users can "bring their own API key", taking such API key usage/monitoring concerns out of my hands. This too is also too much hassle. I just want to do EPSG code to proj4 lookups nothing more nothing less!
If I was building a bespoke/custom mapping application for a client with EPSG > proj4 lookup functionality, then this API key requirement would not have been an issue, but this is not the case here.

So in light of these concerns, instead of moving to MapTiler coordinates. Instead I have opted to use spatialreference.org to do EPSG -> proj4 lookups. No API keys are required there.

So since this was the main driver for needing to put out new releases of MapGuide Maestro and mapguide-react-layout, we might as well take this opportunity to lump in some other fixes and minor changes, which are detailed below.

mapguide-react-layout changes

(reworked) Stamen and (new) StadiaMaps support

Stamen tiled layer support was broken for some time since it was taken over by Stadia Maps. I had already taken care of this in the VSCode map preview extension which had the same problem. But for mapguide-react-layout, the fix was a bit different due to it not using the latest version of OpenLayers and it is too much work right now to update to the latest OpenLayers in mapguide-react-layout.

So what was done for mapguide-react-layout instead is to create these Stamen tile layers as XYZ layers  instead of using the (now broken for that OL release) Stamen tile source. This works because Stamen tiles are ultimately tilesets using the XYZ web mercator scheme. The only other changes is that a Stadia Maps API key is required. So if your appdef defines one or more Stamen tile layers and you didn't specify an API key, you'll get the same startup warning you get when you have Bing Maps layers and didn't specify a Bing Maps API key


But if you do provide a Stadia Maps API key, you'll get the Stamen layers you've seen before.


Since a Stadia Maps API key is now required, we've also added support for other tilesets provided by Stadia Maps, like:

Alidade Smooth


Alidade Smooth Dark


Alidade Satellite


Outdoors


So if you are loading your mapguide-react-layout viewer from a Flexible Layout document, where do you need to specify this new Stadia Maps API key?

That's where the new release of MapGuide Maestro comes in to help!

MapGuide Maestro Changes

Stamen Maps (changed) and Stadia Maps (new) support

The Fusion Editor has reworked Stamen Maps support and added support for Stadia Maps


You'll notice that Stamen and Stadia Maps have 2 variants for every layer.
  • A specialized version
  • An XYZ layer variant ("... as XYZ")
What is the deal with this?

This was done so that if you are still authoring Flexible Layouts for Fusion instead of mapguide-react-layout, you can still view Stamen and Stadia Maps layers in Fusion through the existing XYZ layer support that is available in Fusion as demonstrated in the screenshot below, using the Stadia Maps alidade_smooth_dark tileset + API key.


So depending on the context:

If you are authoring a Flexible Layout for Fusion, choose the "... as XYZ" version and enter the Stadia Maps API key when prompted.

Otherwise, if you are authoring a Flexible Layout for mapguide-react-layout, choose the specialized version and enter the Stadia Maps API key in the provided field


This release of mapguide-react-layout will read the Stadia Maps API key from this new setting in the Flexible Layout when initializing with Stamen and Stadia Maps tile layers.

Using spatialreference.org for EPSG > proj4 lookups

As stated above, the projection management dialog of the Fusion Editor now uses spatialreference.org for resolving proj4 strings from EPSG codes


Other changes

  • WMS Feature Source Editor: Improved the responsiveness and usability of the Advanced Configuration Dialog
  • You can finally copy (ctrl-c) content in the IronPython console!!! You can now truly iterate on automation scripts by finally being able to copy the snippets of working Python code you just entered and eval-ed.

Download

Thursday, 15 August 2024

Announcing: MapGuide Open Source 4.0 Beta 2

This took way longer than expected, but the 2nd beta release of MapGuide Open Source is now available.

The main driver for this release is to update our various web tier components to their latest respective versions:

  • PHP 8.1.29
  • Apache httpd 2.4.62
  • Apache Tomcat 9.0.89
In addition to that, the Beta 2 release includes the following changes:

  • Installer
    • Newer libpq.dll (PostgreSQL 16.3) bundled with Windows installer
  • Server Tier
    • Fix instability on Linux due to criss-crossed resolution of sqlite3 and geos symbols to our shared libraries instead of the distro-provided versions
    • Repository admin tools have been momentarily pulled from this and future beta releases until the admin scripts have been updated and/or rewritten. As a workaround, use MapGuide Package files to backup/restore repository content
    • Removed immature MVT tile rendering support. If you want to produce Mapbox Vector Tiles, use any tool from this list
  • Web Tier
    • Fix QUERYMAPFEATURES SelectionKey containing a newline char, breaking client-side reconciliation of selected features
    • More PHP8 compatibility fixes in PHP AJAX Viewer
    • Fix bad instanceof exception checks in PHP AJAX Viewer
    • More PHP8 compatibility fixes in Site Administrator
    • Buffer overflow fixes in WMS/WFS service layer
    • New optional --bind-to parameter for MgDevHttpServer
  • InstantSetup
    • Fix crash if no setup log path specified when configuring
  • Samples
    • Fix bad extents in SheboyganXYZ tileset
So with this release out the door, what is next? Well unfortunately, there is still lots of work to do on the API binding and API documentation front, and so in the interests of not having you wait another year between releases, I am now adopting the policy of "however many beta/rc releases required" which implies more frequent beta/rc releases. As one of the major remaining items is completed and/or newer versions of any of our web tier components are available, that will be the trigger for a new beta/rc release.

Download

Note: Trac is a bit flaky right now, so the release notes page may not display. If that happens just retry with browser refreshes. Failing that, you can find all the necessary download links in my release announcement email

Thursday, 21 March 2024

Avalonia UI Test Drive

As the title implies, this blog post is about my experience test driving Avalonia UI.

So why am I doing this?

I've been getting growing questions lately about whether MapGuide Maestro works on Linux via Mono

Sadly I no longer emphasize anything regarding Mono compatibility because.

  • WinForms support (in legacy .net Framework 4.x) on Mono is pretty much a hack.
  • And since we've moved away from legacy .net Framework to .net 6.0, the combination of WinForms + .net 6.0 is probably an unsupported combination (you don't use Mono to run .net core/5.0+ applications, you use Microsoft's official SDK/runtime). I'm also not too keen to waste time and resources to test and find out.
The best and practical approach for a multi-platform MapGuide Maestro would be to at a minimum to rewrite the UI in a library/framework where support on non-Windows platforms is a first-class citizen.

And in terms of .net multi-platform UI frameworks, there's only one logical choice: Avalonia UI

While it is not in my immediate plans to rewrite MapGuide Maestro's UI in Avalonia, I wanted to at least explore the feasibility of building such a UI even if all the actual functionality is mocked up, just to see how easy or difficult the whole process is.

Hence the motivation for this post.

So why Avalonia?

Avalonia is effectively the "spiritual successor" to WPF, and adopts most of the same patterns and practices when building UIs for Avalonia.

I had first heard about Avalonia when it was formerly known as Perspex and at the time, from the screenshots of example Perspex applications on Windows and non-Windows platforms, it was clear at that point in time the range of possible applications one can build with Perspex was quite limited and building an application like Maestro on top of Perspex was not feasible.

Just recently, I had heard about the framework now known as Avalonia again and this time round there was a lot more positive buzz around it, so I gave it another look and was much more impressed at its capabilities and richer suite of UI controls to build applications with.

Our objective 

My objective with this Avalonia learning exercise was to build a minimal multi-document interface skeleton application, mimicking the primary functionality (UI-wise) of MapGuide Maestro.

  • Being able to present a login UI to connect to a MapGuide Server
  • Present MapGuide Server resources in a tree view
  • Open resources in a region of tabbed editor panels and being able to close them.
This is a crude wireframe of the kind of UI I wanted to build.
If this kind of UI looks familiar, yes it's basically the UI for tools like:
MapGuide Maestro is an IDE-like application (in terms of UI), so my first instinct is to look for a Visual Studio like docking library for Avalonia. However, I've been using Visual Studio Code more often than full Visual Studio as my daily driver for coding and the VSCode UI has become my default UI that I want to replicate for any IDE-like application with a multi-document interface.

The benefit of such a UI, is that it doesn't require an explicit VS-style window docking control like I have for the current WinForms-based MapGuide Maestro. I can already see the controls needed to build such a UI

Any UI toolkit worth its salt should to able to provide these basic controls.

This is a proof-of-concept, so we won't be using the existing Maestro API to talk to actual MapGuide Servers. Instead such functionality will be mocked up for this application. The main purpose of this exercise is to see if Avalonia provides enough of the base UI elements to build a hypothetical version of MapGuide Maestro on top of.

It turns out this exercise was fraught with several challenges

Challenge #1: Getting familiar with Avalonia concepts

The first challenge was simply getting familiar with Avalonia concepts. Being someone who did .net desktop app development primarily in Windows Forms, I skipped over WPF, and its XAML-based variants/successors like Silverlight, Xamarin Forms, UWP, and MAUI, and Avalonia being a "spiritual successor" to WPF meant that I didn't have a potential conceptual head start on Avalonia that one might have if they already had experience with WPF and its XAML-based derivatives.

However, I was familiar with the MVVM pattern and data-binding, which is used heavily in Avalonia. I already had experience in knockout.js building/maintaining some of our web apps in my day job, and these concepts learned from knockout.js mostly translate cleanly 1:1 to Avalonia.

The other Avalonia concepts I'll have to figure out as we go along.

Challenge #2: WebAssembly (WASM) support

Before I begin, I must take the MapGuide-knowledgable readers of this post back in time, way back to when MapGuide Open Source 1.0 was released.

Do you remember how this new (at the time), re-invented version of MapGuide was released, but the only authoring option at the time was to buy a license of Autodesk MapGuide Studio? Not a pretty look if you are offering a free and open source web map GIS server, but the authoring tools are not?

Some members of the MapGuide community were aware of this glaring discrepancy and created a web-based equivalent of MapGuide Studio called Web Studio built fully with HTML/JS/CSS. Unfortunately, Web Studio was really bare-bones in terms of authoring capabilities and the code being written in the pre-historic era of javascript (this was circa 2006-2007) which did not make it conductive to external contribution. React, TypeScript and friends weren't around then, so trying to enhance Web Studio with new features was extremely challenging. I once tried to add at least a generic XML text editor fallback for Web Studio so you had something to edit various resources where Web Studio did not provide a dedicated editor UI for, but alas this was just too challenging for me and I gave up on such an idea.

But eventually another user of the MapGuide community solved this problem more directly by developing and releasing a v1.0 of a windows .net desktop application that you all know as MapGuide Maestro. As an aside, I am not the original author of MapGuide Maestro in case you're wondering, I merely took over development and maintenance of Maestro from the 2.1 release onwards.

Anyways, back to the topic at hand, when I created the new Avalonia application with the provided project template, I was most surprised to see that the generated solution came with a project that compiled to WebAssembly (WASM) that was ready to run in your web browser!

This was a mind-blowing revelation for me from a conceptual standpoint. It means our hypothetical MapGuide Maestro built on Avalonia could not only exist as a regular desktop application, but the WASM build of this application could be dropped in the the wwwroot of a MapGuide Web tier installation and you would now have a modern version of Web Studio, but much more powerful and capable, because it is just MapGuide Maestro ... now in your web browser!

Since our starter project template includes a functioning WASM browser target. I now had a strong incentive to keep this target active and working, because the prospect of being able to run MapGuide Maestro in a web browser is a very tempting proposition. Therefore, the choice of libraries and APIs I use is constrained by my new requirement of being able to work in a browser/WASM environment.

For example, I originally wanted to use MVVMDialogs to simplify working with dialogs (Maestro has lots of dialogs, so I figure such a library could be useful), but I couldn't get this library to work in a WASM environment with some of my testing dialogs, so this was a no-go. Since this was just a proof-of-concept, there wasn't a need to have working dialog system, but it does mean if this were to go beyond a proof-of-concept and into an actual application where we will inevitably have to present a dialog of some sort, I'd have to come with a paradigm that can work in both desktop and browsers.

Another problem with this WASM target is that I can't seem to debug it in Visual Studio. You can launch the WASM target in the debugger and spawn a new browser window to launch your app, but any breakpoints you stick in your C# code are not being hit. I'm not sure if this a shortcoming or a broken feature, but it is somewhat concerning if we were to go full steam ahead with support WASM as a compilation/deployment target.

Challenge #3: "Large scale" MVVM

Although I already knew the MVVM pattern from knockout.js, my scope of usage was mostly limited to using knockout.js to building "islands" of interactive client-side content on primarily server-generated web pages. So I didn't really have an idea of how to apply such a pattern on a full blown Single Page Application (SPA), which is pretty much what we're trying to achieve (conceptually) in Avalonia. By the time I was building SPAs proper, I had moved on the popular stuff like React, which is how I gained the knowledge needed to build a modern replacement map viewer for MapGuide and my usage of knockout.js fell by the wayside as a result, so I never figured out the answer for how to do large scale MVVM.

The main problem was that in a large scale MVVM, how do view models communicate with each other without a tight parent-child coupling?

I deduced that for starters, we definitely need to use dependency injection. Various view models will need to access different services and if we had a root view model with explicit nested child view models (each with their own service requirements), it would be an absolute pain to have to setup these various view models. Using a DI container means we can offload this concern to it and we can focus on just asking the DI container for a particular view model and it will setup all the required services for it for us provided we register everything properly with the DI container.

For better WASM support, I wanted a dependency injection container that is not driven by reflection to make the code more friendlier to app trimming. We want to be able to app trim on publish so that we can eliminate unused code and reduce the final binary size. This is most desirable for the WASM target as app trimming means smaller binaries, which means smaller payloads to download in a web browser. StrongInject was chosen for this reason as it was a "compile-time" DI container that can verify all your dependencies are registered properly before running the application through the magic of source generators, generating all the necessary registration and validation code for you.

Finally, to be able to communicate between view models without necessary parent-child coupling, the messenger facility of the MVVM toolkit can be used. With this messenger facility, we simply:
  • Have select view models be recipients of certain messages
  • Have our application services (that various view model commands call) send these messages.
  • Relevant recipients get notified and update themselves (and their bound UIs) accordingly as a result.
I don't know if this is the proper usage of MVVM pattern in a "large scale" application, but it makes sense internally in my mind.

Challenge #4: TabControl binding of heterogenous/polymorphic content

Our proof-of-concept app has a main tab region where tabs of various document content are shown. I figured out easily that their TabControl component is supposed to be data-bound to an observable collection of view models, but what really stumped me was how bind this control to an observable collection of polymorphic editor view models?

The reason is because the tab content we want to show is not homogenous. One open editor tab could be for a layer, one for a map, one for a feature source, etc, etc. So we need to be able to show different tabs on the same tab control. 

Avalonia documentation is pretty scant on this topic. All examples I found assume homogenous series of tab content, which is not our case.

Just for laughs, since AI has been hyped for soon taking away everyone's jobs (even us devs), I figured I'd ask huggingface chat (as a guest), how would you solve this problem?


Unfortunately, the provided code sample does not work out of the box. It clearly assumed Avalonia = WPF and gave me a WPF-based solution. The giveaway was the Avalonia TabControl does not have an ItemTemplateSelector, but the WPF TabControl does.

But Avalonia sharing many conceptual similarities with WPF meant that although the answer provided wasn't correct, parts of the answer were applicable and did lead me down to further avenues of inquiry and eventually I found the solution: It was to define a data template for every possible derived tab view model class in the same UserControl where the TabControl was specified.

Final challenge: Avalonia VS designer

This wasn't so much a challenge, rather an annoyance. The Avalonia designer in Visual Studio has some teething issues
  • Intellisense/autocomplete is somewhat flaky when writing binding expressions and when you're doing a lot of data-binding, having the editor giving you and incomplete or outdated list of properties you can bind to becomes annoying. A full project build generally fixes this, but it is annoying having to do this every time I add new observable properties or commands to an existing view model class.
  • It's also not rename-aware, so observable property or command renames will result in stale binding expressions, causing havoc with the designer and have to be manually fixed up in the XAML. Choose your observable property names wisely I suppose, because renaming them afterwards is painful.

The end result and overall thoughts

A week later from that post, after addressing and/or navigating around these various challenges, we have a functional skeleton application!





And if these screenshots don't convince you, thanks to being able to deploy as a WASM target, I deployed a copy to GitHub pages, so you can see this app for yourself right in your WASM-enabled web browser!


The source code for this app can be found here. One day this may form the basis of a new (true) multi-platform version of MapGuide Maestro, but for now this lies as a potentially useful starting point for building a tabbed-multi-document editor application with Avalonia.

So what did I think of Avalonia from this little experiment? 
  • I like it mostly. My pre-existing experience on knockout.js helped greatly with picking up MVVM and data-binding. My initial prediction of a VSCode-style UI layout being buildable turned out to be true.
  • I like the default (project template provided) choice of MVVM Toolkit for applying the MVVM pattern. I like their heavy use of source generators to make adding new observable properties and commands to a view model being a simple case of tacking [ObservableProperty] on a field or tacking [RelayCommand] to a private method and having the source generator generate all of the boilerplate code for you (and it's a lot of boilerplate!).
  • The revelation that Avalonia has a WASM deployment target was both exciting and "cramping my style". It meant that certain libraries I wanted to use (eg. The MVVM dialogs library) could not be used and it wasn't clear what would work in a WASM browser environment and what wouldn't. Which leads to ...
  • Documentation is lacking in some areas. What really stumped me for a while was how do a TabControl bound to a collection of polymorphic or heterogenous tab view models. Their provided examples completely failed to tell me how to do this. I suppose if I came into this with existing WPF experience, this wouldn't have been so difficult as most of the concepts and patterns seem to be mostly transferable, but I happened to have skipped WPF and its bajillion XAML-based derivatives, so I didn't have this pre-existing knowledge to fall back on. Through perseverance and looking at the source code for many existing Avalonia applications on GitHub, I was finally able to determine that data templates was the solution.
So all-in-all, this was a fun and useful exercise and you get a useful starting point app from this effort!

Now I better get back onto this MapGuide/FDO work.

Monday, 18 December 2023

Minor change of plans

There will be a slight change of plans in the MapGuide Open Source 4.0 release timeline.

Namely, the next release will not be the Release Candidate, but rather a 2nd beta release.

The main driver behind this decision is because of my intention to remove the recently introduced support for Mapbox Vector Tiles. While I initially had high hopes with this implementation, additional testing with data outside of the example Sheboygan dataset has revealed rendering issues I do not have the capability to address. Rather than ship a half-baked implementation that may never bake fully, I'd rather bow out while we still can, remove this immature implementation, and leave MVT tile generation to dedicated external tools.

A 2nd beta release will also mean that the other changes I want to get in will also have some time to bake before the Release Candidate stage.

I am hoping the 2nd beta release will be out late January in the new year.

Saturday, 12 August 2023

MapGuide Maestro 6.0m12 nuget packages now available on nuget.org

nuget.org support finally provided a resolution on my account issue and I was able to regenerate my publishing keys.

As a result, the 6.0m12 release (6.0.0-pre500) nuget packages are now finally available on nuget.org

We now return to your regularly scheduled programming ...

Monday, 7 August 2023

Where's the new Maestro API nuget packages?

There were a few things I left out of the previous announcement that I'll use this post to address.

Firstly, the 6.0m12 release of MapGuide Maestro formally drops all Fusion editor support for integration with Google Maps tiles and services. We no longer support Google Maps integration in Fusion and the editor in previous releases gave the false impression that this is still possible. That is no longer the case with this release.

Secondly, the more important thing (and the subject of this post) is that if you are using the Maestro API and consume this through nuget packages from nuget.org you may be wondering why there are no new versions?

The answer to that one is simply: My nuget package publishing keys have expired and something in the nuget.org website or something with my nuget.org account is preventing me from regenerating these keys or to generate a fresh set. As a result, I currently cannot upload any new nuget packages to nuget.org

But do not fret, because there is an alternative solution.

As part of the MapGuide Maestro release on GitHub, the nuget .nupkg files are also included


From here, you can set up a local directory-based nuget package source, drop the .nupkg files into it and the this version of the package is available to install in your Visual Studio solution.

If/when I get a resolution on this publishing key matter, I will upload the .nupkg files for this release and make another announcement. Until then, this local package source is a suitable workaround.

Wednesday, 2 August 2023

Announcing: MapGuide Maestro 6.0m12

Next stop on the tour: A new release of MapGuide Maestro

This release includes the following notable changes.

Improved MapGuide Open Source 4.0 authoring support

This release improves the MapGuide Open Source 4.0 authoring experience with support for the new label justification setting for basic stylization labels.


This setting is part of the new v4.0.0 Layer Definition XML schema, whose .xsd file is now also included with this release (so XML validation against this schema will work)

Fusion editor enhancements for mapguide-react-layout features

This release includes several enhancements to the Fusion Flexible Layout editor to support various features that can be taken advantage of when loaded into a mapguide-react-layout viewer. These new enhancements are accessible from the layout settings panel and require the latest release of mapguide-react-layout to leverage these new features.


The Manage Custom Projections button opens up a new dialog that lets you manage and pre-register custom proj4 definitions for your application. By pre-registering these definitions in the Flexible Layout document itself, you can avoid needing to perform a epsg.io lookup for any projections found in the viewer init process that is not EPSG:4326 or EPSG:3857

The Manage Settings button opens up a different dialog that lets you managed the app settings in the Flexible Layout document. These are arbitrary key/value pairs that your mapguide-react-layout viewer will be initialized with and your viewer code can read such settings at runtime to control and drive whatever custom functionality you may have.


Other Changes

  • Improved layer editor UI responsiveness when layer points to a feature source with a really large schema
  • Increased schema walk/describe timeout to handle really large schemas
  • Fix: Connection error dialog buttons are no longer cut off
  • Fix: Transactional package drag-and-drop loading works again
  • Fix: Broken rest addin due to missing RestSharp dependency
  • Fix: Fill/line pattern dropdowns in layer editor are working again
  • Fix: MgTileSeeder will now accept bounding boxes outside the [-90, -180, 90, 180] lat/long domain by clamping any outside coordinates to be within this domain.
Now onto the next stop: Finally giving mapguide-rest some long deserved attention!

Wednesday, 19 July 2023

Announcing: mapguide-react-layout 0.14.9

Our journey needed to make a temporary detour, with another release of mapguide-react-layout.

This release has the following notable changes

Legend layer and group customization support

This release provides a new viewer init option to allow layer and group elements of the Legend component to be augmented with additional HTML content. For example, we can use this to add a download link for specific layers (how to actually implement the download link is an exercise left to you the reader)



See this comment for an example of how to customize the layer and group elements.

Reduced excessive re-rendering

In the process of implementing the above feature, we discovered that some components (the Legend component in particular) did a lot of pointless re-rendering which contributes to sluggishness in viewer performance.

For this release, great efforts were made to ensure that component re-rendering is the result of legitimate changes to component state and not from pointless re-rendering from bogus shallow state "changes"

Removed IE-specific polyfills and workarounds

Internet Explorer ceased to be a supported browser by Microsoft for some time now. This release formally removes our various IE-specific workarounds and polyfills that were only there to support this ancient browser.

Other changes

  • The urlPropsIgnore setting is now considered when the viewer updates the URL state
  • The viewer bundle patches OpenLayers to log a console warning and abort rendering when attempting to render a map overlay image with a width/height/scale/dpi of 0
  • Fixed an issue where no map images are rendered if the browser zoom is below 100%

Friday, 2 June 2023

Announcing: mapguide-react-layout 0.14.8

We've arrived at the next stop on the tour, a new release of mapguide-react-layout

This release has the following notable changes

Map Definition with XYZ tileset restriction lifted

MapGuide Open Source 4.0 removed the restriction that Map Definitions cannot link to a XYZ tileset definition. This release of mapguide-react-layout takes advantage of this removed restriction by now supporting loading of a Map Definition that links to a XYZ tileset.

Support for loading custom projections and app settings from an Application Definition

The beauty of the Extension element in an Application Definition document (and why its XML schema has not required a revision since its introduction) is that we can put any content in there.

With this release, we are taking advantage of this fact by supporting the ability to read custom projections and app settings from an Application Definition if the right elements are present in the root Extension element of the Application Definition.

By registering custom projections in the Application Definitions, we can register custom projections with the viewer without requiring an epsg.io lookup.

The next release of Maestro (the next stop on this tour) will have dedicated editors for specifying custom projections and app settings. So stay tuned to see how this feature can be used.

Modal dialog size/positioning now preserved

The redux state around modal dialogs has been reworked so that size/positioning is now preserved. This means that if you close a modal dialog and re-open it later on, it will retain the previous size/positioning it had previously, as demonstrated in this video.


MapGuide Base Layers now has its own opacity

Previously the opacity of MapGuide Base Layers was coupled to the opacity of the MapGuide Map. With this release, MapGuide Base Layers now has its own opacity setting.



Other Changes

  • OpenLayers updated to 6.15.1
  • Support disabling custom cursors through a new DISABLE_CURSORS app setting (1 to enable, 0 to disable)
  • Fix potential stale legend state from dispatched update action
  • Fix epsg.io lookup
  • Support Coordinate Tracker with only one projection specified
  • Un-break viewer API drawing example
  • Restore selection appending while holding down SHIFT key
  • Fix viewer state not pushing to url


Download


Friday, 5 May 2023

The "I haven't forgotten about you $PROJECT" tour

As I said near the end of my MGOS 4.0 Beta 1 announcement, I will be momentarily stepping away from MapGuide development/maintenance to give some of my sibling projects in the MapGuide/FDO space some long-overdue attention.

So for the next few weeks, I will be embarking on the "I haven't forgotten about you $PROJECT" tour with stopovers at the following projects:

mapguide-react-layout

Next Release: 0.14.8

Objectives: This will be the last release in the 0.14.x series and the last release to officially support Internet Explorer.

MapGuide Maestro

Next Release: 6.0m12

Primary Objective: This release will have authoring parity with MapGuide Open Source 4.0 Beta 1
Secondary Objective: Assorted fixes and minor enhancements

FDO Toolbox

Next Release: 1.5.3

Objective: Some fixes for bugs and usability problems reported since 1.5.2

mapguide-rest

Next Release: 1.0 RC6

Yes! I am finally giving this project some very-overdue attention!

Primary Objective: Make sure it is compatible with PHP 8.1 that is bundled with MapGuide Open Source 4.0 Beta 1. Also doubles as a secondary sanity test of the new vanilla SWIG-generated PHP bindings, which is my main motivator for revisiting this project.

Secondary Objective: See if we can do this will still being able to support older PHP versions bundled with older MapGuide versions. If this is not tenable, we may need to branch codebases and make separate releases. I hope that this is not the case.


When I finish this tour, then I will be returning to get MapGuide Open Source 4.0 to the final release finish line



Wednesday, 5 April 2023

Announcing: MapGuide Open Source 4.0 Beta 1

Due to real life priorities and commitments, this release look longer than expected to finally come to fruition, but that's all in the past because we're finally here! The first (and probably only) beta release of MapGuide Open Source 4.0 is finally available for the following platforms:

  • Windows
  • Ubuntu Linux 22.04
  • CentOS Linux 7.0
Some notable changes / improvements over the previous Preview 4 release are detailed below.

GeoJSON output improvements

The GeoJSON output support has several improvements in this release:
  • Where possible, the GeoJSON will now always include the crs property (if the source data's coordinate system has an EPSG code representation), allowing for the GeoJSON content to self-identify its coordinate system.
  • GeoJSON from WFS GetFeature requests will now properly transform feature data if a different SRS/CRS is specified in the query parameters
  • Such requests that return GeoJSON content now properly return a application/json mime type

Additional security options for mapagent hardening

Currently, an Anonymous (guest) user or session can read any resource in a MapGuide Server's repository via the mapagent HTTP endpoint. While this capability is required for certain client applications to work properly (for example, mapguide-react-layout needs to be able to read WebLayout/ApplicationDefinition/MapDefinition resources as part of viewer initialization), it doesn't mean that *every* resource should be allowed to be read by anonymous users/sessions.

In particular, Feature Sources rarely need to be read by anonymous users/sessions and it may be considered a security risk to some that connection settings in such Feature Sources (especially ones that connect to relational databases) can be read by anonymous users/sessions, exposing names of internal db servers in the process.

The current resource permission model in MapGuide does allow for read access certain resources to be denied (in their resource headers), but this model is a sledgehammer approach. (ie. It will break rendering operations that need to query data from a feature source you just denied access to in their resource header).

We need a more fine-grained approach where we can deny direct resource API access operations to things like feature sources, but still allow resource API access operations to such resources in the context of things like map rendering.

This release introduces several new webconfig.ini properties to help reduce the attack surface of the mapagent in this regard.
  • AnonymousDenyGetResourceContent
  • AnonymousDenyGetResourceData
  • AnonymousDenyGetResourceHeader
These properties accept a comma-delimited list of resource ids or resource id prefixes and when set, if an anonymous user/session attempts a GETRESOURCECONTENT, GETRESOURCEHEADER or GETRESOURCEDATA with a resource id that matches any id or prefix specified, the mapagent will deny them access to that resource.

With this feature, you can reduce the attack surface of your mapagent by reducing anonymous resource access to only resources needed for a MapGuide client application to function.

Please note that this feature only covers the mapagent and not your custom application code.

Web Tier Component updates

This release bundles updated web tier components:
  • PHP 8.1.17
  • Apache httpd 2.4.56
  • Apache Tomcat 9.0.73

Some long-standing bugs/limitations finally fixed!

A 14-year old bug where un-formatted WebLayout XML cannot be loaded has finally been fixed.

Another 14-year old limitation where labels under basic stylization is always left-justified has been addressed with new options in the 4.0.0 Layer Definition schema allowing you to control the feature label justification.

Sorry for the long turnaround on such issues. Sadly, one person can only do so much.

What's next?

Before we begin the journey to Release Candidate (and then Final release). I will be stepping away from MapGuide development/maintenance work for a few weeks to give some of the surrounding projects like Maestro and mapguide-react-layout some long needed attention, and I expect new releases of MapGuide Maestro and mapguide-react-layout during this period as a result.

Once that is out of the way, then it is back onto the 4.0 release train, driving it to its final destination.

Friday, 4 November 2022

Announcing: MapGuide Open Source 4.0 Preview 4

After a long an arduous development journey, it is finally here! The 4th preview release of MapGuide Open Source 4.0 is now available for the following platforms:

  • Windows
  • Ubuntu Linux 22.04
  • CentOS Linux 7.0
The main feature new to the preview 4 release is the one feature that took the longest time to finish, but was something that needed to be done: We have overhauled all of our MapGuide API language bindings to now be generated with the official version of SWIG instead of our ancient and heavily modified version.

It is through this work that are finally able to drop PHP 5.6 and bundle a newer version of PHP, which for this release is PHP 8.1.11.

On the .net front, this release now offers the .net bindings as a series of netstandard2.0 nuget packages. These packages can be found in the Web/nuget directory of your preview 4 installation. Come the final release of MapGuide Open Source 4.0, we will publish these packages to the official NuGet gallery and will replace the existing MapGuide API nuget package going forward.

On the Java front, we no longer ship MapGuideJavaApi.jar (the "crufty" wrapper) and MapGuideJavaApiEx.jar (the "non-crufty" wrapper) together. We now just ship a single MapGuideJavaApi.jar, which is based on the "non-crufty" wrapper. If your Java MapGuide application has been working against MapGuideJavaApiEx.jar, then migration back to MapGuideJavaApi.jar  is 99.9% seamless.

While this release is not deemed production ready, you should use this release as a means to start getting your MapGuide applications ready for the 4.0 final release. For all 3 languages, refer to the RFC for an overview of what migration you will need to perform on your codebase.

After this release, I'm not intending to introduce or implement any new features in the 4.0 timeframe. It will be all bug fixes and library updates (where required) going forward, so I'm expecting a relatively short Beta > RC > Final cycle.

Saturday, 10 September 2022

MapGuide dev diary: It is done!

In the previous installment, we had gotten a test MapGuide installation with bundled PHP 8.1 up and running, and we were able to successfully produce a PHP error when hitting the Site Administrator.

This PHP error referenced previously was a milestone because it meant that our PHP 8.1 setup (FastCGI on Apache via mod_fcgid) was working, our PHP code was actually running and so the actual errors is the result of the vast swaths of our current PHP web tier applications needing to be migrated across to work against this new PHP 8.1 binding for the MapGuide API.

And so for the next few months I did just that, not just for PHP, but also for Java and .net. You can consider this post to be a preview of what you'll need to do yourself if you want to migrate your PHP/Java/.net MapGuide applications to MGOS 4.0.

PHP Migration Overview

The PHP binding was the one I expect to be the most work because besides finally supporting PHP 8.1, the major feature of this new PHP binding is that constants.php is no longer required! This is because with vanilla SWIG we now can bake all the constants of the MapGuide API into the PHP binding extension itself! So I expect a lot of  "include 'constants.php'" references needing to be removed.

Once all the constants.php references are removed, we found the prime issue with this new PHP binding. PHP didn't like some of our C++ classes had overloaded methods whose signatures did not exist in the parent class. This manifested in the form of fatal PHP errors like the following:

PHP Fatal error:  Declaration of MgCoordinateSystemMeasure::GetDistance(MgCoordinate|float|null $arg1, MgCoordinate|float|null $arg2, float $arg3, float $arg4): float must be compatible with MgMeasure::GetDistance(?MgCoordinate $arg1, ?MgCoordinate $arg2): float in Unknown on line 0

In this case, our MgMeasure class has a GetDistance method of the following signature:

double GetDistance(MgCoordinate* coord1, MgCoordinate* coord2)

In the derived MgCoordinateSystemMeasure, it has a new overload of GetDistance that has this signature:

double GetDistance(double x1, double y1, double x2, double y2)

However, when this converted to PHP proxy classes by SWIG, PHP doesn't like this class setup because under its inheritance model, it is expecting the GetDistance overload with 4 double parameters to also exist in the base MgMeasure class. This is not the case, and thus PHP throws the above fatal error.

To workaround this problem, we had to use the SWIG %rename directive to rename the conflicting overload signature in MgCoordinateSystemMeasure in PHP to the following:

double GetDistanceSimple(double x1, double y1, double x2, double y2)

With this rename, there is no longer a signature conflict in the generated proxy class and PHP no longer throws a fatal error. Fortunately, only 2 classes in the MapGuide API have this problem, so the amount of method renaming is minimal.

Once this issue was addressed, I tried firing up the PHP implementation of the AJAX viewer and I got an interactive map! Everything seemed to be working until I tried to generate a map plot, and found my second problem. I was getting PHP fatal errors like this:

PHP Fatal error:  Uncaught TypeError: No matching function for overloaded 'MgRenderingService_RenderMap' in quickplotgeneratepicture.php:115

Fortunately, this one was easier to explain and fix. In PHP 8.1 (maybe even earlier in the PHP 7.x series), the type checking became more stricter which meant int parameters must take integers, double parameters must take doubles, etc, etc, you couldn't pass ints as doubles or vice versa, and for a method like RenderMap of MgRenderingService, there are lots of overloads that take many different combinations of int and double parameters.

Our map plotting code was passing in strings where int/double parameters were expected. In PHP 5.6 this was allowed because the type checking was evidently more lax. Now such cases cause the above PHP fatal error. This was easy enough to fix, we just use the intval and doubleval functions to make sure ints are being passed into int parameters and doubles are being passed into double parameters.

And with that, the rest of the changes involving fixing up our exception handling code due to a major change with how MapGuide applications should be handling exceptions from the MapGuide API. As part of this SWIG binding work, we've flattened the MapGuide exception hierarchy into a single MgException class, and introduced a new exception code property to allow handling MapGuide exceptions on a case-by-case basis.

So if you were handling specific MapGuide exceptions like this:

1
2
3
4
5
6
7
8
try
{
   //Some code that could throw
} 
catch (MgUnauthorizedAccessException $e) 
{
    ...
}

You would now rewrite them like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
try
{
   //Some code that could throw
} 
catch (MgException $e) 
{
    if ($e->GetExceptionCode() == MgExceptionCodes::MgUnauthorizedAccessException) {
        ...
    }
}

The reason for flattening the exception hierarchy was:

  • To make wrapping exceptions simpler (we now only need to wrap the sole MgException class in SWIG) and not have to handle exception class inheritance chains in a consistent manner across all 3 language bindings.
  • Most of the example MapGuide API code pretty much only caught MgException anyways and rarely catches any of its derived exception classes (and I imagine that this is the case in your MapGuide applications as well). Any code that cared to handle specific exception cases, we can just include the relevant sub-classification as a property of MgException itself as the above code example shows.
Once this final change was made, the AJAX viewer was fully functional. Porting Fusion to PHP 8 was a similar process.

Java Migration Overview

This migration I expect to be a cakewalk because although this binding is now also being generated by vanilla SWIG, it is 99% identical to the existing MapGuideJavaApiEx.jar that we have been generating and shipping for many releases of MapGuide.

So all I expect is just to:
  • Fix up references to MapGuideJavaApiEx and rename them to MapGuideJavaApi
  • Update exception handling blocks to take action based on the captured exception code in the caught MgException instead of catching for specific subclasses of MgException
  • Replace MapGuideApiEx.jar with MapGuideApi.jar (we're using the old jar name for the new binding) in our MG installation (and effectively, going back full circle to the way things were for Java in MapGuide)
And ... it went just exactly what I said above! This was by far the easiest migration effort of the lot.

.net Migration Overview

This migration was the one I had been dreading the most. Not because I feared this binding was going to be fragile, because we already had an exhaustive test suite which this binding passed with flying colors.

But rather, I had been dreading this one because all of our .net code that is going to use this binding (AJAX viewer, code samples, etc) are all legacy pre-historic aspx webforms and I wasn't sure if such code would accept the brand new .net development story I had planned for it.

Consider the current .net development story.

  1. You would reference the 5 OSGeo.MapGuide.* assemblies from mapviewernet/bin in your MapGuide application.
  2. You would then have to manually copy the remaining dlls from mapviewernet/bin to your MapGuide application's output directory so that the .net MapGuide API binding doesn't fail due to missing native dll dependencies
The alternative to this is to use the NuGet package, which make this story more seamless, but the process to build this NuGet package was a bespoke affair, with hand-crafted powershell scripts that trigger on nuget package installation to set up the necessary project build events to copy the native dlls needed by the OSGeo.MapGuide.* assemblies to the right location. Such functionality is tightly-coupled to Visual Studio, so if you were installing this NuGet package and building your MapGuide application outside of Visual Studio, none of the required post-build events would fire and the result is a broken MapGuide .net application because the native dll dependencies were not being copied to your application's output directory.

For this new .net binding, we build each OSGeo.MapGuide.* assembly as a separate SDK-style csproj project files. This new csproj file format has several benefits:
  • You don't have to reference individual C# source files that need to be compiled. Any C# source fil in the same directory as the csproj file is implied to be compiled as part of the project. This is great because it means we can run SWIG to generate the .cs files straight into the project and build that project straight away afterwards.
  • This csproj file format supports NuGet packages as first-class project output
  • The NuGet packages produced have first-class support for native dependencies. This is the real killer feature because it means in terms of packaging, we just have to include these native dlls in a well known location and they will be bundled up automatically as part of NuGet package creation. Such a package when consumed will have its native dependencies automatically copied to the right place and loaded from the right spot without any custom post-build events to set this stuff up!
  • And finally, it means instead of targeting .net Framework, we can target netstandard2.0

What does netstandard2.0 support imply? It implies your MapGuide application using these packages can work on all of these platforms. Now practically speaking, despite now being netstandard2.0 packages, these packages will only work on platforms where the underlying OS is Windows and (maybe) Linux as those are the platforms where we can actually compile the underlying supporting native libraries needed by these nuget packages. So no Mac OSX, no Xamarin, etc. 

In practical terms, it means you are no longer shackled to legacy .net framework for building MapGuide .net applications. You can now use .net core from its earliest netstandard2.0-supported iterations all the way to the latest .net 6.0 (as of this post). 

That's great and all, but going back to the original issue: Can the current suite of aspx webforms code accept this new way of consuming the .net MapGuide API and come along for the ride? I hope so! Because the alternative is to rewrite all of this code with more modern .net web technologies (razor pages maybe?), and while such a rewrite has merit and probably warranted, it is not warranted right now because that would add many more months of dev work to my already time-poor schedule. We have bigger fish to fry! We just hope this current codebase will cooperate with our new .net packaging paradigm with minimal effort.

So let's start with the basic facts.

  • MapGuide's .net integration requires IIS and .net framework to already be installed
  • We can assume that for the purpose of being able to use this netstandard2.0 library, that the installed .net framework version must .net framework 4.8. Building your own MapGuide applications for .net core and .net 5.0+ is something you can opt-in to, but it is not something to be demanded by our existing .net web tier code.
With these facts established we have our first hurdle, and it is one of setup/deployment.

The AJAX viewer and sample code have no Visual Studio solution/project files! How do these things ever get built?

The AJAX viewer for .net is a series of raw .aspx files, will be "compiled" to .net assemblies on first request to IIS. As part of this compilation, it will check its respective "bin" directory for any references. That's why the mapviewernet/bin has the OSGeo.MapGuide.* assemblies in there because that is what is being referenced when the .aspx files get compiled. The .net sample code also follows the same pattern.

So we have a bunch of folders of .aspx files and we need to get the correct set of dlls from inside our brand new shiny nuget packages into these folders. How would we go about this without needing to disruptively set up solution/project files for them?

Here's my approach. We setup a stub SDK-style project that targets net4.8 and references the 5 OSGeo.MapGuide.* nuget packages produced from our new .net binding project setup.

As part of the main build, we perform a framework-dependent publish of this project. Because of the first-class native dependency support, the publish output of this project would be the project's assembly, the 5 OSGeo.MapGuide.* assemblies and (importantly) all of their native dll dependencies in one single output directory. Once we done the framework-dependent publish, we can then copy all the dll files in this publish output folder (except for the stub project) into the bin directory of our AJAX viewer and sample directories.

It turns out this approach does result in a functional .net AJAX viewer and code samples. What was needed in addition to using a stub project to setup the required dll file list, is that the .net AJAX viewer and code samples need a web.config file that references the netstandard assembly due to our OSGeo.MapGuide.* assemblies now target netstandard2.0

Is this a complete and utter hack? Totally!

But this approach gives us a functional .net AJAX viewer and code samples. Considering the alternative solutions and my current timelines, this is a workable approach and sometimes ...


So that was the ugly setup/deployment aspect, but what about the code itself? Well that was relatively simple. Like PHP and Java before it, we only needed to fix up the exception handling code to match to our new pattern of checking for specific exception codes in the caught MgException to handle for certain error cases.

Getting this to work on Linux

With the bindings now all being generated by vanilla SWIG and all working on Windows, it was a case of getting the build system fully working again on Linux with these new bindings and updated web tier components.

Fortunately, on the binding front, most of the CMake configurations added in the initial phases of this work only needed minor adjustments, so the bulk of the work was actually building PHP 8.1 and  integrating this into the Apache httpd server, which we are also building from source and updating our various httpd/php config file templates to work with this new version of PHP.

Where we stand now

We now finally have MapGuide API bindings generated with vanilla, unmodified SWIG that work on both Windows and Linux. This has been a long and arduous journey and I can finally see the light at the end of this tunnel!

A new RFC has been posted for PSC discussion/voting. I hope there isn't strong opposition/dissent on these changes, because I truly believe that this work is absolutely necessary for MapGuide going forward. Newer versions of .net/Java/PHP will always get released and inevitably we will need our MapGuide API bindings to work on these newer versions. Our current infrastructure to keep up with newer .net/Java/PHP versions is just not maintainable or tenable.

If/when this RFC is adopted, the long overdue Preview 4 release should drop not too long after!