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:
var originalSource = new ol.source.GeoJSON({
url: '../assets/data/cluster.geojson'
});var originalLayer = new ol.layer.vector({
source: originalSource,
});layers array:var map = new ol.Map({
target: 'map',
layers: [vectorLayer, originalLayer],
view: view
});
originalLayer:var clusterSource = new ol.source.Cluster({
source: originalSource
});
var clusterLayer = new ol.layer.vector({
source: clusterSource,
});originalLayer with clusterLayer in the map's layers:var map = new ol.Map({
target: 'map',
layers: [vectorLayer, clusterLayer],
view: view
});
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 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.
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:
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:
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 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.
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:
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.
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.GeoJSONol.source.TopoJSONol.source.GMLol.source.GPXol.source.KMLol.source.OSMXMLol.source.IGCol.source.WKTEach 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.
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.
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 two JSON formats, ol.source.GeoJSON and ol.source.TopoJSON, support the two additional constructor options. These are shown in the following table:
The GPX format constructor has no additional options, but will read data from the node and doc options.
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:
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 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!