Table of Contents for
Mastering OpenLayers 3

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Mastering OpenLayers 3 by Gábor Farkas Published by Packt Publishing, 2016
  1. Cover
  2. Table of Contents
  3. Mastering OpenLayers 3
  4. Mastering OpenLayers 3
  5. Credits
  6. About the Author
  7. About the Reviewer
  8. www.PacktPub.com
  9. Preface
  10. What you need for this book
  11. Who this book is for
  12. Conventions
  13. Reader feedback
  14. Customer support
  15. 1. Creating Simple Maps with OpenLayers 3
  16. Structure of OpenLayers 3
  17. Building the layout
  18. Using the API documentation
  19. Debugging the code
  20. Summary
  21. 2. Applying Custom Styles
  22. Customizing the default appearance
  23. Styling vector layers
  24. Customizing the appearance with JavaScript
  25. Creating a WebGIS client layout
  26. Summary
  27. 3. Working with Layers
  28. Building a layer tree
  29. Adding layers dynamically
  30. Adding vector layers with the File API
  31. Adding vector layers with a library
  32. Removing layers dynamically
  33. Changing layer attributes
  34. Changing the layer order with the Drag and Drop API
  35. Clearing the message bar
  36. Summary
  37. 4. Using Vector Data
  38. Accessing attributes
  39. Setting attributes
  40. Validating attributes
  41. Creating thematic layers
  42. Saving vector data
  43. Saving with WFS-T
  44. Modifying the geometry
  45. Summary
  46. 5. Creating Responsive Applications with Interactions and Controls
  47. Building the toolbar
  48. Mapping interactions to controls
  49. Building a set of feature selection controls
  50. Adding new vector layers
  51. Building a set of drawing tools
  52. Modifying and snapping to features
  53. Creating new interactions
  54. Building a measuring control
  55. Summary
  56. 6. Controlling the Map – View and Projection
  57. Customizing a view
  58. Constraining a view
  59. Creating a navigation history
  60. Working with extents
  61. Rotating a view
  62. Changing the map's projection
  63. Creating custom animations
  64. Summary
  65. 7. Mastering Renderers
  66. Using different renderers
  67. Creating a WebGL map
  68. Drawing lines and polygons with WebGL
  69. Blending layers
  70. Clipping layers
  71. Exporting a map
  72. Creating a raster calculator
  73. Creating a convolution matrix
  74. Clipping a layer with WebGL
  75. Summary
  76. 8. OpenLayers 3 for Mobile
  77. Responsive styling with CSS
  78. Generating geocaches
  79. Adding device-dependent controls
  80. Vectorizing the mobile version
  81. Making the mobile application interactive
  82. Summary
  83. 9. Tools of the Trade – Integrating Third-Party Applications
  84. Exporting a QGIS project
  85. Importing shapefiles
  86. Spatial analysis with Turf
  87. Spatial analysis with JSTS
  88. 3D rendering with Cesium
  89. Summary
  90. 10. Compiling Custom Builds with Closure
  91. Configuring Node JS
  92. Compiling OpenLayers 3
  93. Bundling an application with OpenLayers 3
  94. Extending OpenLayers 3
  95. Creating rich documentation with JSDoc
  96. Summary
  97. Index

Working with extents

In a WebGIS application, it is especially feasible to have controls to zoom into various extents. Users are used to the luxury of zooming in to a layer or a feature to the maximum extent with a single click. In this example, called ch06_extent, we will implement such zooming capabilities. We will create a tool to zoom into the validity extent of the current projection, one for zooming into the selected layer, and the other to zoom into the selected feature. First, let's make some CSS rules for our new tools:

.toolbar .ol-zoom-extent button {
    background-image: url(../../res/button_zoom_extent.png);
}
.toolbar .ol-zoom-layer button {
    background-image: url(../../res/button_zoom_layer.png);
}
.toolbar .ol-zoom-selected button {
    background-image: url(../../res/button_zoom_selected.png);
}

Creating a zoom control

There is a built-in control in OpenLayers 3 to zoom into various extents. However, the main weakness of ol.control.ZoomToExtent lies in its static nature. We can define an arbitrary extent on construction and cannot change it afterwards. There is one strength of this control, however. If we do not provide an extent, it reads the current projection's validity extent. This spark of dynamism makes this control suitable for our first use case. For the rest of the tools, we make our own zoom control, which accepts a function, rather than a static extent, and zooms into the return value of that function:

ol.control.ZoomTo = function (opt_options) {
    var options = opt_options || {};
    var _this = this;
    var controlDiv = document.createElement('div');
    controlDiv.className = options.class || 'ol-unselectable ol-control';
    var controlButton = document.createElement('button');
    controlButton.textContent = options.label || '';
    controlButton.title = options.tipLabel || 'Zoom to extent';
    controlButton.addEventListener('click', function (evt) {
        var zoomCandidate = _this.get('extentFunction')();
        if (zoomCandidate instanceof ol.geom.SimpleGeometry ||
            (Object.prototype.toString.call(zoomCandidate) === '[object Array]' && zoomCandidate.length === 4)) {
            _this.getMap().getView().fit(zoomCandidate, _this.getMap().getSize());
        }
    });
    controlDiv.appendChild(controlButton);
    ol.control.Control.call(this, {
        element: controlDiv,
        target: options.target
    });
    this.set('extentFunction', options.zoomFunction);
};
ol.inherits(ol.control.ZoomTo, ol.control.Control);

As the view object's fit method can only receive a simple geometry or an extent besides a mandatory size argument, we will check whether the return value of the provided function fits this criteria. Note that we only check this if the returned extent is an array has exactly four members. For a more general control, further checks should be considered.

Note

If you played with JavaScript's typeof method, you may know that only primitives are distinguishable from it. Arrays are considered as objects. However, objects have subtypes, which can be extracted by calling Object.prototype.toString with an object. Be careful, though. This method is not protected; therefore, any library can overwrite it.

Extending the toolbar

Next, we extend our toolbar with a method, which creates three extent controls:

toolBar.prototype.addExtentControls = function () {
    var _this = this;
    var zoomFull = new ol.control.ZoomToExtent({
        label: ' ',
        tipLabel: 'Zoom to full extent'
    });
    var zoomToLayer = new ol.control.ZoomTo({
        class: 'ol-zoom-layer ol-unselectable ol-control',
        tipLabel: 'Zoom to layer extent',
        extentFunction: function () {
            var source = _this.layertree.getLayerById(_this.layertree.selectedLayer.id).getSource();
            if (source.getExtent()) {
                return source.getExtent();
            }
            return false;
        }
    });

The first two controls are very simple. For the full extent control, we use OpenLayers 3's mechanism, while for the layer extent control, we provide a function, calling the getExtent method of the layer's source.

Tip

Only vector sources have a factory method to get their extent. However, you can create such a method for any layer with the same functionality. Just make sure that you store the extent of the layer in its source object. For WMS layers, you can parse their extent from their GetCapabilities response.

Next, we create the selection extent control, which is a little more complicated, and close our method appropriately:

    var zoomToSelected = new ol.control.ZoomTo({
        class: 'ol-zoom-selected ol-unselectable ol-control',
        tipLabel: 'Zoom to selected feature',
        extentFunction: function () {
            var features = _this.selectInteraction.getFeatures();
            if (features.getLength() === 1) {
                var geom = features.item(0).getGeometry();
                if (geom instanceof ol.geom.SimpleGeometry) {
                    return geom;
                }
                return geom.getExtent();
            }
            return false;
        }
    });
    this.addControl(zoomFull).addControl(zoomToLayer).addControl(zoomToSelected);
    return this;
};

We only accept one feature in this scenario, as allowing more features requires extra calculations. If the feature is a single part, we return it, avoiding unnecessary operations, while if it's multipart, we calculate its extent and return this instead. Finally, we add the new controls to the toolbar:

tools.addExtentControls().addSelectControls().addEditingToolBar();

If you save the code and run it in your browser, you will see our extent controls up and running:

Extending the toolbar