Wednesday, 29 January 2020

Announcing: vscode-map-preview 0.5.0

Having figured out the technique for seamlessly loading CSV data in mapguide-react-layout, it was clear that there was another OpenLayers-based tool of mine that could benefit as well, hence a new release of the VSCode Map Preview extension.

Here's what's new in this release.

CSV Support

Obviously!


Rather than bombard you with excessive UI prompts for what column is the X coordinate and what column is the Y coordinate, we just check for a list of common column pairs:
  • X/Y
  • Lon/Lat
  • Lng/Lat
  • Long/Lat
  • Longitude/Latitude
  • Easting/Northing
If you want to add more column pairs to search for, there is a new configuration setting to define these pairs.


Preview buttons

Having learned about VSCode menu contribution points, we now finally have buttons in the editor UI to invoke the preview commands!



Custom Projection Support

The extension now supports custom projections allowing you to preview data from projections other than 4326 or 3857. A new configuration property is available to let you define additional custom projections:


To find/register your custom projection, visit epsg.io and get the proj.4 or proj4js definition for your particular EPSG code and add a new entry with this EPSG code and definition as per the above fragment.

Because of this support, the Map Preview (with projection) command now presents a list of known projections instead of requiring you to enter the EPSG code manually


Other Changes

Vertex styling for line/polygon features can now be toggled on/off through a new configuration property.


OpenLayers has also been updated to the latest release (6.1.1) and the extension fixes some corner cases when previewing certain types of KML and GeoJSON content.

mapguide-react-layout dev diary part 24: Adding *even* more than just WMS layers

Since I introduced the revamped external layer manager, the creativity floodgates have opened as I have realised that there are many other things that we could implement on top. So for this post, I'm going to cover even more cool things you can do with the revamped external layer manager.

Revised file-loading process

The UI for loading file-based layers has been tweaked a bit. This means that the first step is picking your file as usual. Note that we've changed the "uploader" UI back to a plain blueprint-styled file input due to bundle size budget constraints that required us to drop react-dropzone


After picking the file, we now give you the ability to specify the projection of this file you just picked, which is now a number picker instead of a dropdown. If you enter an EPSG code not known to the viewer, it will now do an epsg.io lookup and register the found projection on-the-fly before adding the vector layer. The design that drives this UI has been refactored to be more modular and flexible, meaning we now can identify the "type" of the file based on the first successful driver to properly parse the file content.

This refactored design also finally allows us to add ...

CSV Support!

When looking at what types of files to support for external vector layers, CSV seemed like a no-brainer to support. Point data is after-all, commonly defined in CSV files.

The problem with CSV files is that there is no established standard as to how point coordinates are defined. The ideal solution would involve having to attempt peek and introspect the file and build the UI to allow picking the correct point coordinate columns. But this UI would complicate our 2-step UI for file-based layers. How would we know the file we're about to add is indeed a CSV file to then be able to present a UI for the user to pick the columns for point coordinate data?

In the interest of pragmatism and avoid having to answer that hard question altogether, our approach is to look for the most common column labels for point coordinates on the first line of the file we encounter:

  • X/Y
  • Lon/Lat
  • Lng/Lat
  • Longitude/Latitude
  • Easting/Northing
If the file you add has a CSV header and it contains one of the above pairs of columns and the row data referenced by these columns checks out as numbers, it will be accepted as a CSV file.

Added Layers UI Changes

The UI for added layers has been compressed to maximize screen real estate


The opacity slider took up a lot of space (relatively speaking) and toggles a setting I deem to be non-essential to overall functionality, so that slider is now hidden behind a layer options panel (toggled by the new cog icon)


Finally for WMS layers, we now register their source load events so they can contribute to the viewer busy state, meaning that we can properly communicate busy loading state for any added WMS layers.



WMS UI changes

After loading the WMS capabilities URL, for each layer we find you now have the ability to add the WMS layer in as a single-tile or tiled WMS layer.


WFS Support

It seems strange that this external layer manager supports WMS services but does not support the other major W*S service. This was a glaring omission the viewer now addresses. WFS is available as a new layer type:


Added WFS layers are vector layers and assumes the UI of added file-based layers.

Due to viewer bundle size budget constraints the WFS layer UI will only care about layers in the loaded capabilities document that offer GeoJSON output. We could add support for GML2 and GML3 (the formats commonly associated with WFS), but it is not worth blowing up our bundle size to add format drivers for such an esoteric and verbose format.

Select tool support for external layers

So now our revamped external layer manager can add data from a whole assortment of file formats and remote WFS/WMS services. But these data sources are not just for show. They generally have intelligence attached in the form of attribute data for vector data or in the case of WMS layers, APIs to get at such data (WMS GetFeatureInfo), so to put the cherry on top of this revamped external layer manager, the viewer should provide some means of interacting with these layers after adding them.

To this end, our default select tool can now select vector features from external layers and display their attributes in an overlay tooltip.


Vector features take precedence over MapGuide layers. That is to say, the select tool will now try to select vector features first (and display its attributes if found). Only when no vector feature are selected does the viewer proceed with the normal MapGuide layer selection logic.

For WMS layers, we introduce a new active tool dedicated for sending GetFeatureInfo requests against any WMS layers on the current map. The effect is still the same, click on a WMS layer and if we get data back from a WMS GetFeatureInfo response, we'll show the data in a overlay tooltip.


The choice to do WMS "selection" is done through a separate active tool instead of adding on to the default select tool behavior was because adding WMS layer selection logic to the existing select tool would complicate the control flow significantly given that WMS GetFeatureInfo requests are asynchronous and it is hard to maintain a selection priority when dealing with a map that has vector, WMS and MapGuide layers together.

In Closing

The revamped external layer manager is the last major feature for the upcoming 0.13 release. Remaining work before release will primarily be knocking off any remaining bugs and loose ends and also tidying up documentation.

Friday, 10 January 2020

mapguide-react-layout dev diary part 23: Adding more than just WMS layers

In the tail end of part 21, I did say that the next release (0.13) will have some actual new features besides some important under-the-hood updates and for this post we'll be talking about one such feature.

Way back in the 0.11 release, a new component was introduced to allow adding external WMS layers to your current map.


I knew at that point in time that this component had much more room for improvement as the wide array of formats that OpenLayers can support means we can add more than just WMS layers.

For the upcoming 0.13 release we've re-designed and re-built this component to allow adding a wider array of external layers to your map. When you bring up the external layer manager, you are now greeted with a choice of what kind of layer to add:
  1. A local file-based layer
  2. A remote URL-based layer
With a local file-based layer, simply drag a supported file type into the specified drop-zone or click the drop-zone itself to be prompted for a file to load. Once loaded, specify the projection of the data source (default will be EPSG:4326) and the layer will be added to the map.


Several things to note with local file-based layers.

Firstly, the files you pick are not uploaded to any server. The "upload" UI is merely a means to obtain a HTML5 FileReader so we can load the vector features client-side into the map directly.

Secondly, the following file formats are supported in this mode:
  • GeoJSON/TopoJSON
  • KML
  • GPX
  • IGC
Finally, the available projection list in the following dropdown:


Are built-in projections provided by the proj4js library we're using along with any additional projections registered while discovering map definitions or projections registered up-front.

The other mode is remote URL-based layers, which is how you add WMS and WFS layers through this re-designed UI.


UI for adding WFS layers is near identical, so it is not shown here.

Loaded layers can be viewed and managed through the Manage Layers tab, which itself has been re-designed as well.


Every layer in this list:
  • Can have their visibility toggled via the switch
  • Can have their opacity changed via the slider
  • Can have their draw-order (relative to the MapGuide map) changed through the up/down arrow buttons
  • Can be removed later on via the button with the trash icon
For WMS layers that support the LegendURL sub-capability, you can click the info button to show the WMS legend inline.


For added vector layers, you can zoom to the extents of that layer.


And for vector layers that aren't KML files, you can edit the style for these features. For KML files, the style is intrinsically part of the file itself, so the style is effectively "locked in" for such layers and is not editable as a result.


So in closing, the revised external layer manager now supports adding the following external data sources to your current map:
  • Local files: GeoJSON/TopoJSON, KML, GPX, IGC
  • Remote sources: WMS, WFS
We could actually add many more formats, but this revised external layer manager took a significant toll on our production bundle size and adding more formats would've blown up the bundle size to unacceptable levels. This list of formats I have determined to be a "good enough" list given our bundle size constraints.

Thanks to the storybook support, you can also see a live demo of this external layer manager here.