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

Creating a WebGIS client layout

Now that we are quite familiar with the possibilities of styling our maps with CSS and the inner methods, the next step is to create the layout of a WebGIS application. This step requires us to rethink our design patterns. The goal of this chapter is to create an application-specific design that doesn't prevent future developers from using the default options. This way, we can create a general wrapper API, which extends the capabilities of the library in a developer-friendly way.

Building the HTML

First, let's extend the HTML part of our application. For a proper WebGIS client, the map canvas is only a part of the complete application. As mentioned in the beginning, for now, we only build the tool bar and the notification bar. We extend the HTML like in the example named ch02_webgis.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Chapter 2 - Preparing a WebGIS Application</title>
        <link href="../../js/ol3-3.9.0/ol.css" rel="stylesheet">
        <link href="ch02_webgis.css" rel="stylesheet">
        <script type="text/javascript" src="../../js/ol3-3.9.0/ol.js"></script>
        <script type="text/javascript" src="ch02_webgis.js"></script>
    </head>
    <body>
        <div class="map-container">
            <div id="toolbar" class="toolbar"></div>
            <div id="map" class="map">
                <div class="nosupport">Your browser doesn't seem to support this application. Please, update it.</div>
            </div>
            <div class="notification-bar">
                <div id="messageBar" class="message-bar"></div>
                <div id="coordinates"></div>
            </div>
        </div>
    </body>
</html>

Now we put everything in a map container. The sizes of the element are relative to the container. We also put a built-in error message in the HTML, which will be covered up by the map if the browser can load it.

Tip

Note that, in a good API, every element is created dynamically with JavaScript. Hard coding the HTML elements is a bad practice. We only do this for the sake of simplicity. Creating an API with JavaScript is out of the scope of this book.

Styling the layout

As you have noticed, we created our HTML by defining simple elements with class names. We style these elements in a separate CSS file with class-based rules. Firstly, we style the map container element with the error message:

body {
    margin: 0px;
}
.map-container {
    width: 100%;
    height: 100%; /*Fallback*/
    height: 100vh;
}
.map {
    width: 100%;
    height: calc(100% - 3.5em);
}
.nosupport {
    position: absolute;
    width: 100%;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
}

Note

In Web design, horizontal alignment goes smoothly, but vertical alignment can be painful. In the nosupport class, you can see the most typical hack. The absolute positioning allows you to manually align the element with the parent. Setting the top attribute to 50% pushes down the element's top-side to the middle of the parent element. Giving it a -50% vertical transformation with translateY pulls back the element by 50% of its height.

Next, we style the notification bar. It has two parts, one for the mouse position control and one for the messages that the application will communicate. Now, we only style the coordinate indicator:

.notification-bar {
    width: 100%;
    height: 1.5em;
    display: table;
}
.notification-bar > div {
    height: 100%;
    display: table-cell;
    border: 1px solid grey;
    width: 34%;
    box-sizing: border-box;
    vertical-align: middle;
}
.notification-bar .message-bar {
    width: 66%;
}
.notification-bar .ol-mouse-position {
    font-family: monospace;
    text-align: center;
    position: static;
}

Regardless of using the div elements, we style the notification bar to render table-like. This way, we can vertically align the text messages that the application will output in an easy manner. It needs a parent element with the table display and child elements with the table-cell display (at least in Internet Explorer).

Note

In an HTML document, every visible element is rendered as a box. Every box has four edges: content, padding, border, and margin. By default, browsers use a content-box model, which applies the computed size only to the content. As we use a 100% width for the element, but we apply a 1 pixel border, the resulting box will exceed the maximum width of the screen by 4 pixels. This is why we use a border-box model, which includes the padding, and the border to the computed size of the box.

Finally, we style the tool bar for the controls. For now, it can only handle one line of buttons, but it can be expanded if more controls are needed:

.toolbar {
    height: 2em;
    display: table;
    padding-left: .2em;
}
.toolbar .ol-control {
    position: static;
    display: table-cell;
    vertical-align: middle;
    padding: 0;
}
.toolbar .ol-control button {
    border-radius: 2px;
    background-color: rgba(219,63,63,.5);
    width: 2em;
    display: inline-block;
}
.toolbar .ol-control button:hover {
    background-color: rgba(219,63,63,1);
}

As before, the styling of the control buttons are basically the same. The only difference is that we give them an inline-block display if they are in the tool bar. This way, the zoom controls, which are vertically stacked by default, become horizontally aligned. We vertically center the elements of the tool bar with the table method described above.

Note

By specifying the style of the controls under our custom classes, they will always overwrite the default declarations. However, our styles are only applied if the controls are placed in the appropriate containers. If they are targeted at the map canvas, they won't be affected by our rules.

Writing the code

With the CSS rules and the HTML elements in place, the final task is to write the code part of the example. The code will be based on the previous example; however, we will strip it down to only contain the most necessary parts:

var map = new ol.Map({
    target: 'map',
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        }),
        new ol.layer.Vector({
            source: new ol.source.Vector({
                format: new ol.format.GeoJSON({
                    defaultDataProjection: 'EPSG:4326'
                }),
                url: '../../res/world_capitals.geojson',
                attributions: [
                    new ol.Attribution({
                        html: 'World Capitals © Natural Earth'
                    })
                ]
            })
        })
    ],
    controls: [
        new ol.control.Zoom({
            target: 'toolbar'
        }),
        new ol.control.MousePosition({
            coordinateFormat: function(coordinates) {
                var coord_x = coordinates[0].toFixed(3);
                var coord_y = coordinates[1].toFixed(3);
                return coord_x + ', ' + coord_y;
            },
            target: 'coordinates'
        })
    ],
    view: new ol.View({
        center: [0, 0],
        zoom: 2
    })
});

We cut out the entire interactions part. This way, we don't have to save the vector layer into a separate variable. We keep the base layer and the vector layer to have something for our map to display. We cut out most of the controls and only define the zoom buttons and the mouse position controls. As we do not extend the default set of controls, but instead define some, the default ones won't be present in our map, unless we add them manually.

The main extension to the previous examples is the placement of the controls. We can specify where OpenLayers 3 should place a control with the target parameter. We can provide a DOM element, or just simply the id of our element of choice. We place our controls according to our design in the tool bar and the coordinate container. If you save the complete example and open it up, you will see our application:

Writing the code