We've been using feature objects throughout the chapter so far without really talking about the Feature class itself. We also hinted at the Geometry class, but we haven't gone into any detail so far. This section will cover both classes in a bit more detail so that you can gain a bit more confidence working with them. Don't worry—it's easy, you've already been exposed to both classes.
Before we get into the Feature class, we should go over the Geometry class, as it's used to create the actual geometry objects that make up a feature object.
Although it is perfectly valid to create features without geometries, they can't be represented on a map. Therefore, the Geometry class is, from the map's point of view, the foundation of the feature object. The Feature class uses the Geometry class to store geometry information about the feature.
However, what exactly is the Geometry class? In a nutshell, it stores geographic information in the form of one or more coordinate pairs. Remember the examples from The feature formats section of this chapter where we added features using the Format subclasses? We briefly saw geometries while reprojecting the features into the map view's projection:
for (var i = 0, ii = features.length; i < ii; ++i) {
var feature = features[i];
var geometry = feature.getGeometry();
geometry.applyTransform(transform);
}In this example, we will transform the feature's geometry from its original projection into the map view's projection so that the loaded feature will align with the raster base map correctly. This is just one part of what we can do with geometries.
When working with the Geometry class, we always use one of its subclass. What do we mean? Think about the Format classes we've used earlier in this chapter—we've talked about format but actually used subclasses of the base Format class the entire time (ol.format.GeoJSON, ol.format.KML, and so on are all subclasses of the ol.format.Format class).
We mentioned before that a geometry object stores geographic information as coordinate pairs. A coordinate pair is simply an array of two, three, or four numbers (we'll get to this in a moment) representing a single location on the earth in a given projection. You're already familiar with coordinates, it's the value that we use to set the center of a view in all of the examples. In the OpenLayers documentation, you'll see coordinates represented with the type ol.Coordinate. This looks like a classname, but really it's a type definition specifying an array of numbers representing a location. There are four different ways, called layouts, of representing a coordinate:
To get maximum performance, OpenLayers' Geometry classes store coordinates in so-called flat arrays, meaning all the values of all the coordinates are stored in a single array of numbers. Because the individual coordinates can have two, three, or four values, all the Geometry classes need to know the layout of the coordinates they are storing.
Before we cover the subclasses, let's quickly go over some of the methods available to all of the subclasses via the base Geometry class. All these methods are available to any Geometry subclass, as all the subclasses inherit from the Geometry class:
There are two direct subclasses of ol.geom.Geometry—ol.geom.SimpleGeometry and ol.geom.GeometryCollection. The GeometryCollection class, as the name suggests, treats several geometries as a single geometry object. The SimpleGeometry class is the base class for geometries we can actually use to represent specific shapes—points, lines, polygons, and so on. Let's look at the SimpleGeometry class and its subclasses first.
We don't use the SimpleGeometry class directly, but it is the base class for all the basic geometry types that OpenLayers understands. We'll look first at the methods provided by SimpleGeometry to all the subclasses, then look at the subclasses themselves:
|
Method |
Parameters |
Description |
|---|---|---|
|
|
| |
|
|
| |
|
|
|
This returns the layout (XY, XYZ, XYM, or XYZM) of the geometry. |
The Point class represents a single point, and MultiPoint is a collection of points. A Circle class is a special case of the Point class that includes a radius property. All take coordinates as the first argument to the constructor. Both Point and Circle expect a single coordinate, while MultiPoint expects an array of coordinates. A Circle takes a second argument, the radius. All take an optional final argument, the layout, which defaults to XY. Here are some examples of creating each type:
var point = new ol.geom.Point([1, 2]); var multipoint = new ol.geom.MultiPoint( [ [1,2], [2,3] ]); var circle = new ol.geom.Circle([1,2], 2);
The LineString class represents a sequence of two or more coordinates that are connected to form a line. As with MultiPoint, MultiLineString is a collection of lines. A LineString is constructed with an array of coordinates, while MultiLineString is created with an array of arrays of coordinates. Both take the layout as an optional final argument, the layout, which defaults to XY. Here are some examples of each:
var line = new ol.geom.Line([ [1, 2],[2,3],[3,4] ]); var multipoint = new ol.geom.MultiPoint([ [ [1,2],[2,3],[3,4], [ [4,5],[5,6] ] ]);
The Polygon class is composed of one or more LinearRing classes. A linear ring is a sequence of three or more coordinates that forms a closed ring, that is, the last coordinate is the same as the first coordinate. When a polygon contains multiple linear rings, the first is called the outer ring and the rest are interior rings. Interior rings define holes in the polygon. And as you might expect, a MultiPolygon is a collection of polygons. Let's see how to make a linear ring and polygon. As with the other geometry types, the layout can be specified as an optional last argument:
var linearRing = new ol.geom.LinearRing([ [1,2],[2,3],[3,4],[1,2]); var polygon = new ol.geom.Polygon([ [ [-20,-20],[-20,20],[20,20],[20,-20],[-20,-20] ] ]);