Table of Contents for
OpenLayers 3 : Beginner's Guide

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition OpenLayers 3 : Beginner's Guide by Erik Hazzard Published by Packt Publishing, 2015
  1. Cover
  2. Table of Contents
  3. OpenLayers 3 Beginner's Guide
  4. OpenLayers 3 Beginner's Guide
  5. Credits
  6. About the Authors
  7. About the Reviewers
  8. www.PacktPub.com
  9. Preface
  10. What you need for this book
  11. Who this book is for
  12. Sections
  13. Time for action – heading
  14. Conventions
  15. Reader feedback
  16. Customer support
  17. 1. Getting Started with OpenLayers
  18. Advantages of using OpenLayers
  19. What, technically, is OpenLayers?
  20. Anatomy of a web mapping application
  21. Connecting to Google, Bing Maps, and other mapping APIs
  22. Time for action – downloading OpenLayers
  23. Time for action – creating your first map
  24. Where to go for help
  25. OpenLayers issues
  26. OpenLayers source code repository
  27. Getting live news from RSS and social networks
  28. Summary
  29. 2. Key Concepts in OpenLayers
  30. Time for action – creating a map
  31. Time for action – using the JavaScript console
  32. Time for action – overlaying information
  33. OpenLayers' super classes
  34. Key-Value Observing with the Object class
  35. Time for action – using bindTo
  36. Working with collections
  37. Summary
  38. 3. Charting the Map Class
  39. Time for action – creating a map
  40. Map renderers
  41. Time for action – rendering a masterpiece
  42. Map properties
  43. Time for action – target practice
  44. Map methods
  45. Time for action – creating animated maps
  46. Events
  47. Views
  48. Time for action – linking two views
  49. Summary
  50. 4. Interacting with Raster Data Source
  51. Layers in OpenLayers 3
  52. Common operations on layers
  53. Time for action – changing layer properties
  54. Tiled versus untiled layers
  55. Types of raster sources
  56. Tiled images' layers and their sources
  57. Time for action – creating a Stamen layer
  58. Time for action – creating a Bing Maps layer
  59. Time for action – creating tiles and adding Zoomify layer
  60. Image layers and their sources
  61. Using Spherical Mercator raster data with other layers
  62. Time For action – playing with various sources and layers together
  63. Time For action – applying Zoomify sample knowledge to a single raw image
  64. Summary
  65. 5. Using Vector Layers
  66. Time for action – creating a vector layer
  67. How the vector layer works
  68. The vector layer class
  69. Vector sources
  70. Time for action – using the cluster source
  71. Time for action – creating a loader function
  72. Time for action – working with the TileVector source
  73. Time for action – a drag and drop viewer for vector files
  74. Features and geometries
  75. Time for action – geometries in action
  76. Time for action – interacting with features
  77. Summary
  78. 6. Styling Vector Layers
  79. Time for action – basic styling
  80. The style class
  81. Time for action – using the icon style
  82. Have a go hero – using the circle style
  83. Multiple styles
  84. Time for action – using multiple styles
  85. Style functions
  86. Time for action – using properties to style features
  87. Interactive styles
  88. Time for action – creating interactive styles
  89. Summary
  90. 7. Wrapping Our Heads Around Projections
  91. Time for action – using different projection codes
  92. Time for action – determining coordinates
  93. OpenLayers projection class
  94. Transforming coordinates
  95. Time for action – coordinate transforms
  96. Time for action – setting up Proj4js.org
  97. Time for action – reprojecting extent
  98. Time for action – using custom projection with WMS sources
  99. Time for action – reprojecting geometries in vector layers
  100. Summary
  101. 8. Interacting with Your Map
  102. Time for action – converting your local or national authorities data into web mapping formats
  103. Time for action – testing the use cases for ol.interaction.Select
  104. Time for action – more options with ol.interaction.Select
  105. Introducing methods to get information from your map
  106. Time for action – understanding the forEachFeatureAtPixel method
  107. Time for action – understanding the getGetFeatureInfoUrl method
  108. Adding a pop-up on your map
  109. Time for action – introducing ol.Overlay with a static example
  110. Time for action – using ol.Overlay dynamically with layers information
  111. Time for action – using ol.interaction.Draw to share new information on the Web
  112. Time for action – using ol.interaction.Modify to update drawing
  113. Understanding interactions and their architecture
  114. Time for action – configuring default interactions
  115. Discovering the other interactions
  116. Time for action – using ol.interaction.DragRotateAndZoom
  117. Time for action – making rectangle export to GeoJSON with ol.interaction.DragBox
  118. Summary
  119. 9. Taking Control of Controls
  120. Adding controls to your map
  121. Time for action – starting with the default controls
  122. Controls overview
  123. Time for action – changing the default attribution styles
  124. Time for action – finding your mouse position
  125. Time for action – configuring ZoomToExtent and manipulate controls
  126. Creating a custom control
  127. Time for action – extending ol.control.Control to make your own control
  128. Summary
  129. 10. OpenLayers Goes Mobile
  130. Using a web server
  131. Time for action – go mobile!
  132. The Geolocation class
  133. Time for action – location, location, location
  134. The DeviceOrientation class
  135. Time for action – a sense of direction
  136. Debugging mobile web applications
  137. Debugging on iOS
  138. Debugging on Android
  139. Going offline
  140. Time for action – MANIFEST destiny
  141. Going native with web applications
  142. Time for action – track me
  143. Summary
  144. 11. Creating Web Map Apps
  145. Using geospatial data from Flickr
  146. Time for action – getting Flickr data
  147. A simple application
  148. Time for Action – adding data to your map
  149. Styling the features
  150. Time for action – creating a style function
  151. Creating a thumbnail style
  152. Time for action – switching to JSON data
  153. Time for action – creating a thumbnail style
  154. Turning our example into an application
  155. Time for action – adding the select interaction
  156. Time for action – handling selection events
  157. Time for action – displaying photo information
  158. Using real time data
  159. Time for action – getting dynamic data
  160. Wrapping up the application
  161. Time for action – adding dynamic tags to your map
  162. Deploying an application
  163. Creating custom builds
  164. Creating a combined build
  165. Time for action – creating a combined build
  166. Creating a separate build
  167. Time for action – creating a separate build
  168. Summary
  169. A. Object-oriented Programming – Introduction and Concepts
  170. Going further
  171. B. More details on Closure Tools and Code Optimization Techniques
  172. Introducing Closure Library, yet another JavaScript library
  173. Time for action – first steps with Closure Library
  174. Making custom build for optimizing performance
  175. Time for action – playing with Closure Compiler
  176. Applying your knowledge to the OpenLayers case
  177. Time for action - running official examples with the internal OpenLayers toolkit
  178. Time for action - building your custom OpenLayers library
  179. Syntax and styles
  180. Time for action – using Closure Linter to fix JavaScript
  181. Summary
  182. C. Squashing Bugs with Web Debuggers
  183. Time for action – opening Chrome Developer Tools
  184. Explaining Chrome Developer debugging controls
  185. Time for action – using DOM manipulation with OpenStreetMap map images
  186. Time for action – using breakpoints to explore your code
  187. Time for action – playing with zoom button and map copyrights
  188. Using the Console panel
  189. Time for action – executing code in the Console
  190. Time for action – creating object literals
  191. Time for action – interacting with a map
  192. Improving Chrome and Developer Tools with extensions
  193. Debugging in other browsers
  194. Summary
  195. D. Pop Quiz Answers
  196. Chapter 5, Using Vector Layers
  197. Chapter 7, Wrapping Our Heads Around Projections
  198. Chapter 8, Interacting with Your Map
  199. Chapter 9, Taking Control of Controls
  200. Chapter 10, OpenLayers Goes Mobile
  201. Appendix B, More details on Closure Tools and Code Optimization Techniques
  202. Appendix C, Squashing Bugs with Web Debuggers
  203. Index

Time for action – using the cluster source

The cluster source may be used with any type of feature, but it is typically used with a set of point features. This example illustrates using the cluster source with some randomly generated points that are included with the sample files for this project in assets / data / cluster.geojson. We'll first show the original data, then modify the example to use the cluster source. The following are the steps:

  1. Starting from the previous example, we will add a new vector source that loads the sample data:
    var originalSource = new ol.source.GeoJSON({
      url: '../assets/data/cluster.geojson'
    });
  2. Next, we will create a cluster source to cluster these features:
    var originalLayer = new ol.layer.vector({
      source: originalSource,
    });
  3. Then, add the new layer to the map's layers array:
    var map = new ol.Map({
      target: 'map',
      layers: [vectorLayer, originalLayer],
      view: view
    });
  4. Load this in your browser and take a look:
    Time for action – using the cluster source
  5. That's a lot of points—about 5000 actually. If these represented real data, it will be very hard to see individual points until we zoom way in. Now, let's see what the cluster source does with these features. Create a new source and layer after the originalLayer:
    var clusterSource = new ol.source.Cluster({
      source: originalSource
    });
    var clusterLayer = new ol.layer.vector({
      source: clusterSource,
    });
  6. And replace originalLayer with clusterLayer in the map's layers:
    var map = new ol.Map({
      target: 'map',
      layers: [vectorLayer, clusterLayer],
      view: view
    });
  7. Reload to see the effect of the cluster source. Try zooming in and out.
    Time for action – using the cluster source

What just happened?

In this example, we discovered how the cluster source works. First, we created a vector layer containing about 5000 points and displayed it on the map. As we saw, it's very hard to see these points when zoomed out. Next, we added a cluster source and a new layer based on the cluster source. Now the number of points displayed on the map changes dynamically as we zoom in and out, and the number of points on the map at any one time is much more manageable.

Typically, when displaying a cluster of features, we would represent the cluster differently depending on how many features are in the cluster—perhaps by adding a text label or changing the size of the point. We'll revisit this example in the next chapter and deal with the styling options then.

The format sources

The other direct subclass of the vector source is the FormatVector source. This class cannot be directly created, rather it is an abstract class that adds a single method, readFeatures, to the API of all its concrete subclasses. This means that all the other source classes provide a readFeatures method that gets features from some data structure such as a string, array, or JavaScript object. The type of the data structure is determined by the format.

What are formats?

A feature format is responsible for reading features from a structured format that organizes spatial features in a structured way. Each feature format is based on a recognized specification document that defines how that format represents the geospatial data it contains. The feature formats are organized into three distinct groups:

  • JSON-based formats, which use the JavaScript Object Notation format
  • XML-based formats, which use the Extensible Markup Language format
  • Text formats, which do not rely on another markup language but rather define their own structure

The JSON formats

There are two JSON-based formats, GeoJSON and TopoJSON. The GeoJSON format defines a schema used to represent spatial data as JSON data. JSON looks a lot like JavaScript object literals, but it has specific rules for formatting. The main differences between JSON and JavaScript object literals are:

  • JSON strings, including object property keys, must be wrapped with the double quote character
  • Property values in JSON may only be JSON objects, arrays, strings, numbers, and Boolean values
  • JSON may only contain one top-level thing and it must be either an object or an array

To find out more about the JSON format, see http://www.json.org.

A GeoJSON file may contain either a Feature or FeatureCollection. A Feature is represented in JSON as an object with three keys: type, geometry, and properties. The type is always "Feature". The geometry is an object with a type and coordinates, where the type can be one of "Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon", or "GeometryCollection", and the coordinates are an array containing the coordinates in a structure dependency on the type. The properties key is an object that contains keys and values representing nonspatial data associated with the feature.

A FeatureCollection is represented as an object containing two keys: type and features. The type is always "FeatureCollection" and features is an array of GeoJSON features structured as in the preceding paragraph.

An example of a Feature looks like the following:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}

A FeatureCollection looks like the following:

{ "type": "FeatureCollection",
  "features": [
  { "type": "Feature",
    "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
    "properties": {"prop0": "value0"}
  },
  { "type": "Feature",
    "geometry": {
      "type": "LineString",
      "coordinates": [ [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] ]
    },
    "properties": {
      "prop0": "value0",
      "prop1": 0.0
    }
  },
  { "type": "Feature",
    "geometry": {
      "type": "Polygon",
      "coordinates": [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],[100.0, 1.0], [100.0, 0.0] ] ]
    },
    "properties": {
      "prop0": "value0",
      "prop1": {"this": "that"}
    }
  }
  ]
}

As you might imagine, this structure is quite easy to use with JavaScript applications and GeoJSON is a popular format for web mapping applications. Read more about this format at http://geojson.org.

The TopoJSON format is an extension of the GeoJSON format that encodes topology. A discussion of topology is beyond the scope of this book; briefly, topology defines rules for representing spatial features in a region. The most common example of this is adjacent polygons sharing a common border. Topological rules require two adjacent polygons sharing a common boundary will share the points that define the common boundary between them such that moving one point changes the boundary of both polygons simultaneously. You can find out more about the TopoJSON format at https://github.com/mbostock/topojson.

The XML formats

The XML formats are based on XML, a metalanguage that describes structured content using tags denoted by the < and > signs. HTML, which we've seen many times in this book already, looks like XML, and the tags in HTML instruct a web browser how to render the page.

Note

Most HTML is not valid XML. HTML does not follow the strict formatting rules required by XML— particularly, there are many tags in HTML that do not require a closing tag. The <img> tag is an example of this. There is a variant of HTML, called XHTML, that defines a valid XML schema for HTML. While there are some advantages to using XHTML, it has not gained widespread adoption because it is more work for developers to ensure a valid document and the perceived benefits are low.

Structured documents based on XML have a specific set of tags and a set of rules on tag content and nesting. Collectively, the tags and rules are called a schema. There are several geospatial formats based on XML and each defines a specific schema. The schema allows developers to write code to parse the spatial information out of the structured document in the same way that the GeoJSON format proscribes a specific JSON object structure.

The XML-based formats are GML, GPX, KML, OSM XML, and WFS. Let's describe each briefly:

  • GML (Geography Markup Language): This is based on a standard published by the Open Geospatial Consortium. This standard was developed in collaboration with many companies that were interested in developing a standard format for describing geospatial information to facilitate exchange of data between different proprietary and open source systems. While GML is very expressive and represents a wide range of geospatial data, it is also quite complicated to support consuming GML as there are several versions and vendor-specific extensions to the schema.
  • GPX (GPS Exchange Format): This is a schema supported by many GPS vendors as a common format for representing data generated by GPS devices. Its primary purpose is to describe routes, tracks, and waypoints in a vendor-neutral way. In addition to geographic locations, it can store time, speed, and elevation data.
  • KML (Keyhole Markup Language): This was popularized by Google as the format for representing spatial data rendered in Google Earth. It is less expressive than GML, but contains additional information about how to view the data it represents.
  • OSM XML (OpenStreetMap XML): This schema is used for representing the core data structures in the OpenStreetMap system, particularly nodes, ways, and relations.

The text formats

While all the formats we've discussed so far can be represented in a plain text file, the text formats differ in that they are not based on standard representation. Rather, they define their own unique structure. There are currently two text formats supported by OpenLayers—IGC and WKT.

  • ICG (International Gliding Commission): This format is a specification produced for recording glider flight information. Unless you are part of the gliding community, you probably won't have much need for this format. It is part of OpenLayers, partly because someone had an interest in it and contributed the code, and partly as an example of implementing support for text-based formats. There is an sample IGC file included in assets/data if you are interested.
  • WKT (Well Known Text): This is a standard first developed by the Open Geospatial Consortium. It has since been expanded and included in ISO (International Standards Organisation) 13249-3:2011. The WKT format is well supported by many open source and commercial GIS applications.

The StaticVector source

Now, we know something about formats, let's look at the next class in the vector source hierarchy—StaticVector. OpenLayers provides the StaticVector source and some format-specific subclasses designed to simplify loading vector features from the supported formats. They are as follows:

  • ol.source.GeoJSON
  • ol.source.TopoJSON
  • ol.source.GML
  • ol.source.GPX
  • ol.source.KML
  • ol.source.OSMXML
  • ol.source.IGC
  • ol.source.WKT

Each of these is a vector source that works in exactly the same way, the only difference between them is the format they use internally to read features.

The StaticVector source, as the name suggests, loads a set of vector features from a source that does not change. This means the features are loaded, and parsed, just once, The actual features in the source never change in response to panning or zooming. In all other respects, the StaticVector source works in the same way as the other vector sources.

You can create an instance of StaticVector directly and pass it a format and a source of data, or you can use one of the format-specific subclasses. Let's look first at creating StaticVector instance. Note that several of the options only apply for particular formats, as noted in the description.

Note

It is worth emphasizing at this point that for all the OpenLayers formats, the data stored in files are actually text files. Loading these files in a browser will result in the data being loaded as a JavaScript string. Some libraries will automatically convert data from its text-based representation into another type of object for you. For instance, loading XML data from a text file will often give you a reference to a Document Object after it is loaded. In OpenLayers, every format supports loading data from a string value, but the string must contain data that is in the structure expected by the format.

Name

Type

Description

attributions

Array.<ol.Attribution>

As with ol.source.vector, this is an optional array of attributions to display when features from this source are displayed on the map.

doc

Document | undefined

This is a browser Document Object, typically returned from parsing an XML document. This option is used by the GML, GPX, KML, and OSMXML formats.

format

ol.format.Format

This is the format to use for extracting features from the provided data. The option that provides the data for the format depends on the type of the format, as noted in the relevant options.

logo

string | olx.LogoOptions | undefined

This is a logo to display when features from this source are displayed on the map.

node

Node | undefined

This is a browser node object, typically returned by querying the browser's document or a document parsed from an XML string. This option is used by the GML, GPX, KML, and OSMXML formats.

object

Object | undefined

This is a JavaScript object, typically obtained by programmatically creating an object using object literal syntax or by parsing a JSON string. This option is used by the GeoJSON and TopoJSON formats.

projection

ol.proj.ProjectionLike

This is the projection for feature geometries after parsing. Some formats support identifying the projection of the data, or have a default projection. If a projection is passed to the StaticVector constructor and it is different from the projection of the features coming from the format, the geometries of the features will be transformed into this projection.

text

string | undefined

This is a string representing the data to load. All formats support reading from a string as long as it is properly structured for that format.

url

string | undefined

This is an optional URL to load the data from. If provided, then OpenLayers will attempt to load the URL and parse it using the source's format. The actual format of the data when loaded must match what the format expects. For instance, if the format is ol.format.GeoJSON, then the URL must return valid JSON when loaded.

urls

Array.<string> | undefined

These are multiple URLs to load data from. These are treated the same way as the url option, and data will be loaded from each URL in turn.

The actual format-specific source classes generally work the same way and support only those options that make sense from the StaticVector class. However, there are some important differences that are worth noting. All the following source constructors support the attributions, logo, text, url, and urls options listed in the preceding table. For the sake of brevity, these options have been omitted from the following tables.

The JSON formats

The two JSON formats, ol.source.GeoJSON and ol.source.TopoJSON, support the two additional constructor options. These are shown in the following table:

Name

Type

Description

defaultProjection

ol.proj.ProjectionLike | undefined

This is the GeoJSON format specification. This indicates that data is, by default, in the EPSG:4326 projection. Newer versions of the specification allow you to identify the projection of the data as something other than EPSG:4326. If the data is not in EPSG:4326 and the projection is not stored with the data, this option allows you to override the default value.

object

Object | undefined

This is a JavaScript object containing the data, usually parsed from a JSON string using the JSON.parse method.

ol.source.GPX

The GPX format constructor has no additional options, but will read data from the node and doc options.

ol.source.IGC

The IGC format constructor supports one additional option. Refer to the following table:

Name

Type

Description

altitudeMode

ol.format.IGCZ | undefined

This is the mode to use for altitude measurements when parsing data. Possible values are barometric, gps, and none. The default is value is none.

ol.source.KML

The KML format specification requires that the geometry data for features be represented in EPSG:4326. In addition to supporting the node and doc options, the KML format supports two other options. Refer to the following table:

Name

Type

Description

defaultStyle

Array.<ol.style.Style>

The default style to use for features that do not have embedded style information, or if extraction of styles is disabled.

extractStyles

boolean

KML documents contain embedded style information. If this option is set to true (the default value), then OpenLayers will attempt to extract style information from the KML document for each feature.

ol.source.OSMXML

The GPX format constructor has no additional options, but will read data from the node and doc options.

Have a go hero

Time to put our new knowledge into action. There are sample files included with the book's code samples in assets / data in each of the formats discussed earlier. Try adding each of them to a map. Remember, you will need to create an appropriate source and a vector layer, and add the vector layer to the map. As with earlier examples, you should be able to use the url option to load the data without having to load and parse it yourself.

The ServerVector source

The ServerVector source requests features from a server by sending the geographic coordinates of some region it needs features for to a server. As you might imagine, there are many different ways of doing this based on what a particular server understands. Each server has its own unique language for requesting features. Many servers implement a common language based on an open standard called WFS (Web Feature Service) that can simplify the job. Even so, there are different versions and different flavours of WFS that make it difficult to support them all. To avoid this problem, OpenLayers provides a generic mechanism for requesting features for the ServerVector source; specifically it requires that you implement the loader function yourself!