UK Ordnance Survey Map With Draggable Features

OpenLayers Version

This demo uses the version of OpenLayers API current at the time of writing, .

The former OL2 demo is still working, and is here: UKOSOpenLayers2.shtml.

You can also load an Open Street Map using OpenLayers.

Help

This section describes how some of the less obvious aspects of the demo work.

There are two interactions that select objects, and one that drags them.

You can select objects using either an ol.interaction.Select or an ol.interaction.DragSelect, the former being unaltered from the OL original, the latter being a custom extension of ol.interaction.DragBox.  The former has the multi option enabled, which means that you can select multiple objects by Shift clicking.  The latter is invoked by Shift dragging.  The former selection is cancelled by clicking anywhere in the map outside of a feature, the latter by Shift dragging anywhere in the map outside of a feature.  It's important to understand that the collections of features so selected are now properties of the interaction objects themselves, not of the layer or the map, and consequently are different selections.  This can get sufficiently confusing to the user that an end-programmer may decide that, although both are included here for demonstration purposes, only one or the other should be used in production, not both.

Features are dragged by an ol.interaction.DragVector, which is an extension of ol.interaction.Pointer.  Where no objects are selected as above, a simple drag drags just one feature, but if Shift is applied all features beneath the start point of the drag are dragged together, while if objects are selected as above and Alt is applied, both the above selections will be dragged.  This latter is achieved by the above two interaction objects being parameters to the drag interaction's constructor.

OpenLayers' API

This section describes some aspects of the current OpenLayers API

This author hasn't liked any OL version since and including 3, because even the most basic, fundamental objects either disappeared or changed radically in name and properties between OL2 and OL3, necessitating a wearisome rewrite of one's entire codebase, and, although fundamental aspects of the coding, such as encapsulation, are markedly improved, there are more aspects of it that either prevent or make very tedious the coding of some things that were fairly easy to do in v2  such as the lack of a layer-switcher control, and there is no easy way to get the mouse position control to display the map centre when the mouse is outside of the map  while the tendency with each new version to create unwelcome 'features', aka bugs, apparently still remains.  For example, just in writing this demo, I found the following bugs in the then current operational version:

  1. One certain bug, one probable one, and a further inconsistency in the attribution control   the first is the hard-coding of a spelling mistake in the '-collapse' class name suffix, the second is that a layer's source getAttributions function returns not the attributions themselves as one would naturally expect, but another function that itself returns them, the third is an inconsistency in image handling, in that, as demonstrated below by the OS Branding examples, in some places an image is specified as HTML text which is then passed to OL, while in others it must be created as a DOM element and then passed to OL.
  2. One in the z-order styling of the zoom-slider control, such that when the mouse pointer is moved over the track, the increase in its opacity overlays the button. 
  3. Depending on which version you use, the MousePosition control is just as inflexible as it used to be in v3, in that it is still impossible to have it reliably display the centre of the map when the mouse pointer is outside of it.  You can do it in v6.5.0, but the initial display on loading is blank because, in the constructor, the element is drawn before all the relevant options that could affect its appearance have been read from the option parameters, and further the only way to make it display anything on mouseout is by directly stuffing the value into undefinedHTML_while in v6.9.0, the map will display its centre correctly on loading, but thereafter will always display that initial value for the centre whenever the mouse is outside of it, regardless of how the map has been moved since, and debugging the code reveals that, despite the placeholder property supposedly being a settable option, it is name-mangled in this version, and there is no way provided of updating it once the control has been created.

The coding of this demo contains workarounds for those that easily can be fixed, the others need proper code bug fixes.

The end-programmer must ensure not to rely on serendipitous discoveries from examining the debug code, because, as we have already seen with the mouse position control, subsequent testing may show failure with the live script, where many of the property and method names are mangled.

OL since 3 is more highly compressed code.  While this has some advantages, for example, a reduction in overall code size, it also has some serious disadvantages, the most notable of which, the name-mangling, has already been highlighted, but besides the points already made, sometimes also this has negative consequences for the bug-fixing, extensibility, and the open exchange of techniques that should arise from Open Source software.

We seem to have lost the behaviour of the v2 scaleline control in giving both m/km and ft/mi scalelines, which is perhaps regrettable.  It would be a good idea to provide this as an option, say triggered by the units option being given as a comma separated list.

Ordnance Survey's API

This section describes some aspects of the latest Ordnance Survey API

The first thing to note is that the latest free version is quite restricted in access compared with its pedecessor OpenSpace©; particularly, we can no longer access leisure maps at useful zoom levels, and, although the paid up version does offer a free quota before charges start to apply, amateurs like myself probably won't want to run the risk of being charged at all, and this severely restricts the usefulness to us of the current OS API in a way that OpenSpace did not.

Ordnance Survey Branding

This only covers particular issues relating to branding, for fuller and up-to-date information of this important consideration, see:
  Ornance Survey's Own Site
  Ordnance Survey on GitHub

The problems programming the OpenLayers attributions control described above may be a partial reason why the Ordnance Survey have chosen to ignore OL coding and instead supply their own CSS and script to display their branding, which if loaded, they are not here, would appear in a page's HTML as follows …
  <link rel="stylesheet" href="https://labs.os.uk/public/os-api-branding/v0.3.0/os-api-branding.css">
  <script src="https://labs.os.uk/public/os-api-branding/v0.2.0/os-api-branding.js"></script>
… but both the above and their own examples on their own site contravene their own branding guidelines document from GitHub above, if the rules in the latter are strictly applied, and further the above coding breaks when the map doesn't fill the whole viewport!  Note particularly also that the guidelines mention that their copyright statement should contain a link to their site, but which link is not given, and, as neither their own examples nor the coding loaded as above include one to copy, there is none here either.

If so many professionals can get it wrong, how can we mere end users, with least pain, get the OS's branding to appear correctly?  Sadly, the simple truth is that OS's so-called 'guidelines' are too unnecessarily restrictive to be called that, and we can't follow them exactly without moving other OpenLayers controls around the map to leave spaces where the OS want their branding to appear.  Rather than be bothered with that, as this is merely a free non-commercial demo, I dare to offer two compromises avoiding this need, both of which satisfy the OS's branding guidelines as long as they are viewed merely as guidelines, not strict rules, but commercial enterprises may wish to check with OS before using either.  Both require obtaining & using their branding logos directly from the links at the start of this section, and both display the branding using the OpenLayers attribution control in the default location for it, the bottom RH corner.  Note also the inconsistency in image handling already noted previously, in that one version merely passes it to OL as HTML, while the other requires it to be created as a DOM element before passing it to OL:

  1. This version just displays statically the OS copyright statement and logo. Its simplest version listed below may well be good enough, but this page itself enhances it somewhat to reduce of the area of the map covered by the semi-opaque background, and to ensure that the OS's attributions are not reduced in size by OpenLayers' default styling for the Attribution control, which it achieves by defining its own styling for it.  See the comments in this page's style coding for further details of how to do this:

    UKOS.BCopy  = "Contains OS data &copy; Crown copyright and database rights " + new Date().getFullYear();
    UKOS.BLogo  = "os-logo-maps", // os-logo-maps | os-logo-maps-white
    UKOS.BImg   = "<img
          src='/Resources/Images/" + UKOS.BLogo + ".svg'
          class='attrL'
          alt='Ordnance Survey Logo'
          title='" + UKOS.BCopy + "'/>";
    UKOS.BAttr  = UKOS.BImg + "<p class='attrC'>" + UKOS.BCopy + "</p>";
    // ...
    var source     = new ol.source.WMTS( options );
    // Note: Function must return function that returns attributions = probable bug
    source.getAttributions = function(){ return function(){return [UKOS.BAttr];}; };
    // ...
    var theMap    = new ol.Map({
          controls: ol.control.defaults
               ({
               attributionOptions: { collapsible: false /* optionally also: className: "attr" */ }
               }).extend([optional further controls here]),
          // ...
    });
  2. This version turns the OS logo into a button, which has a hovertip containing the full text, and the clicking of which toggles display of the full text.  The collapsed option given determines the initial state of the attribution, true (just the button) or false (button & text, as chosen here):

    <style type="text/css">
      <!--
        .ol-attribution button, .ol-attribution-expand button, .ol-attribution-collapse button
            { height:24px; width:90px; }
      -->
    </style>
    // ...
    var UKOS.BCopy  = "Contains OS data &copy; Crown copyright and database rights " + new Date().getFullYear();
    var buttonImg1 = document.createElement( "img" );
    buttonImg1.id  = "Logo1";
    buttonImg1.src = "<path>/os-logo-maps.svg";
    var buttonImg2 = document.createElement( "img" );
    buttonImg2.id  = "Logo2";
    buttonImg2.src = "<path>/os-logo-maps-white.svg";
    // ...
    var source     = new ol.source.WMTS( options );
    // Note: Function must return function that returns attributions = probable bug
    source.getAttributions = function(){ return function(){return [UKOS.BCopy];}; };
    // ...
    var theMap    = new ol.Map({
          controls: ol.control.defaults
               ({
               attributionOptions:
                    {
                    collapsible:       true,
                    collapsed:         false,
                    label:             buttonImg1,
                    collapseLabel:     buttonImg2,
                    tipLabel:          UKOS.BCopy.replace( "\&copy;", "(c)" ),
                    // Fix hard-coded spelling error in OL attribution code!
                    collapseClassName: "ol-attribution-collapse"
                    }
               }).extend([optional further controls here]),
          // ...
    });
Updated Description
Late 2016 Page first created.
08/01/2017 Fixed OL3 version to 3.8.2 loaded from own server as later releases have proved highly unreliable.  Added CSS styling for ol.interaction.DragSelect for upward compatibility with later versions.  Corrected typos.
08/12/2021 Fixed to work with new Ordnance Survey Mapping and OpenLayers 6.9.0.  Updated notes accordingly.
03/03/2022 Updated to work with OS OAuth2 API.  Created replacement mouse position control and found styling method to remove its background when there is no text being displayed.  Improved display of OS attributions.