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

Spatial analysis with JSTS

Now that we are kind of familiar with Turf, let's take a look at another topological library: JSTS. In this example, called ch09_jsts, we will reproduce the first two spatial operations from the previous example with JSTS. As we would like to make the least replicated code, we will use ch09_turf as the basis for this example.

JSTS Topology Suite (JSTS) is another reasonably mature topology library out there. It is the JavaScript port of the famous desktop topology application, Java Topology Suite (JTS). The most important difference between Turf and JSTS is that JSTS is more robust but less capable of implementation. It uses an internal format to handle geometries and offers some I/O capabilities. It can traditionally read from Well-Known Text (WKT), but now it can also read from GeoJSON, OpenLayers 2, and OpenLayers 3's internal geometry formats. It can also write to these formats. As JSTS can directly read and write OpenLayers 3's geometries, the overhead of converting geometries to an exchange format is minimal. The biggest downside of JSTS is its terribly poor documentation. It is old and highly outdated; therefore, the newest features can only be explored by reading the source code or experimenting from the console.

Tip

You can download the latest release of JSTS from the GitHub repository at https://github.com/bjornharrtell/jsts/releases.

First, like in the previous examples, we will resolve the dependencies of JSTS in the HTML file. For JSTS, we have to include two JavaScript files, and as JSTS initializes itself with the other utility library, the order really matters:

<head>
    […]
    <script type="text/javascript" src="../../js/jsts-0.17.0/javascript.util.min.js"></script>
    <script type="text/javascript" src="../../js/jsts-0.17.0/jsts.min.js"></script>
</head>

Implementing operations

As we have gone through the implementing process already, we will now only discuss the changes between the previous implementation and this one. First, we initialize our control and define some variables for the buffer operation:

ol.control.JSTS = function (opt_options) {
    […]
    controlDiv.className = options.class || 'ol-jsts ol-unselectable ol-control';
    […]
    bufferButton.addEventListener('click', function (evt) {
        var layer = _this.getMap().get('selectedLayer');
        if (layer instanceof ol.layer.Vector) {
            var parser = new jsts.io.olParser();
            var features = layer.getSource().getFeatures();
            var buffered = [];

JSTS can read and write OpenLayers 3's geometries but not its features. This way, if we would like to keep the attributes of the original features, we need to clone them first and set their geometries for the result of the operation. To store these features, we initialize an empty array. Next, we iterate through the features and buffer them one by one:

            for (var i = 0; i < features.length; i += 1) {
                buffered.push(features[i].clone());
                var geom = parser.read(features[i].getGeometry());
                buffered[i].setGeometry(parser.write(geom.buffer(10000)));
            }

We create a clone of every feature, add it to our array, and override its geometries dynamically. In JSTS, we can call topological methods from the converted geometry objects. The buffer method of JSTS needs only one parameter: the radius in map units. It has two optional parameters: the number of segments that the approximation of a circular line end should be made up of and the line end (cap) style. Finally, we finish our control by creating a new layer, adding the content of our array to it, and adding it to the map:

            var bufferedLayer = new ol.layer.Vector({
                source: new ol.source.Vector({
                    features: buffered
                }),
                name: 'Buffer result'
            });
            _this.getMap().addLayer(bufferedLayer);
        }
    });

Next, we implement the merge operation. It is available in JSTS under the union method and accepts one argument: another JSTS geometry. Theoretically, it can calculate a union of a geometry collection if it is called on one without any arguments; however, in practice, it throws an error. This way, we can merge our layer by calling the union method with every feature. First, we will set up the required variables:

   […]
   mergeButton.addEventListener('click', function (evt) {
        var layer = _this.getMap().get('selectedLayer');
        if (layer instanceof ol.layer.Vector) {
            var parser = new jsts.io.olParser();
            var features = layer.getSource().getFeatures();
            var unionGeom = parser.read(features[0].getGeometry());

We initialize our operation with the first feature of the layer that's converted to a JSTS geometry. This variable will store the union of the processed features and will be extended for every iteration. Next, we create the iteration, and add a new, merged layer to the map. Note that we will only have one geometry in the end; therefore, we will lose every attribute that's associated with the original dataset:

            for (var i = 1; i < features.length; i += 1) {
                unionGeom = unionGeom.union(parser.read(features[i].getGeometry()));
            }
            var mergedLayer = new ol.layer.Vector({
                source: new ol.source.Vector({
                    features: [
                        new ol.Feature({
                            geometry: parser.write(unionGeom)
                        })
                    ]
                }),
                name: 'Merge result'
            });
            _this.getMap().addLayer(mergedLayer);
        }
    });
    […]
};
ol.inherits(ol.control.JSTS, ol.control.Control);

If you save the code and load it in your browser, you can try out the topological functions that we implemented with JSTS. Don't forget to try out buffering with the help of the polygon layer:

Implementing operations