OpenLayers Tutorial - Part 2: Layers

OpenLayers
Posted on Feb 2nd, 2010

Layers are, basically, OpenLayer's way of showing different map services. The term may seem confusing when combined with an individual map service's layer term. The broadest explanation I can provide for the moment is that an OpenLayer Layer is an object inside OpenLayers that contains a single map service. This is going to be a rather in depth tutorial. Here's how it's set up

Part A - URL Calls (Emphasis on WMS)
Part B - Layer Class

Part A - OpenLayers URL Calls


In essence, OpenLayers basically provides a nice way to automatically call other map services, get back a lot of results, and piece them together to form a map. Now, for a map service like Google Maps or a vector layer the logic is a bit different, but for the WMS service and other map services that accept a URL this is the basic process. This may seem a bit abstract, so let's look at how OpenLayers makes a map using a WMS layer.
OpenLayers Layer - WMS Process
OpenLayers is basically calling the URL you provide, adding parameters to the URL that act as GET variables (based off the parameters you pass in when you define the layer), getting back an image, and placing all the images together coherently as to form a large map image.

To clarify - If you have a map div that is 500pixels x 500pixels big, OpenLayers would make four separate calls to the URL you provide to get back four different images and place the four images side by side to form the 500 x 500 map. (You could also just tell it to get back an image 500 x 500 pixels big, along with telling it to get back more images outside the viewing area so the panning around is more seamless, etc. We will cover this later)
So, with that in mind, let's start taking a look at a WMS URL. http://labs.metacarta.com/wms/vmap0?request=getCapabilities&service=WMS
This is the url to get an XML that contains detailed information about the WMS service. The first part of the url, http://labs.metacarta.com/wms/vmap0 contains the actual URL you pass into the OpenLayers Layer url parameter.
Next we have a ? followed by a key = value pair of variables. If you go to the url without passing ?request=getCapabilities&service=WMS you won't see much. But, by passing the a request of getCapabilities AND (&) a service variable with the value WMS you will get an XML file with a bunch of useful information in it (e.g., a list of layers you can use).

For a service like WMS, many layers can be specified in the WMS parameter calls, but OpenLayers considers the entire WMS service -one- layer (even though the request itself may ask for multiple layers). The WMS Layer is one of the more popular layers used, so I'll first spend a moment discussing it.

To elucidate this further, here's some example code that shows

1. A single OpenLayers WMS Layer object with only one WMS layer parameter specified
map = new OpenLayers.Map('map');

    var wms = new OpenLayers.Layer.WMS(

    "OpenLayers WMS",

    "http://labs.metacarta.com/wms/vmap0",

        {layers: 'basic'}

    );
Take note of the {layers: 'basic'} code. This sets the "layers" parameter of the OpenLayers WMS Layer to "basic"

2. A single OpenLayers WMS Layer object with two WMS layer parameters specified

map = new OpenLayers.Map('map');

    var wms = new OpenLayers.Layer.WMS(

    "OpenLayers WMS",

    "http://labs.metacarta.com/wms/vmap0",

        {layers: 'basic, ground_01'}

    );
Notice the "layers" parameter is set to 'basic,ground_01'. This means that the WMS service will return an image that has both the 'basic' and 'ground_01' layers turned on. Those two WMS layers are grouped into the OpenLayer Layer and are considered one OpenLayer Layer.
What exactly is happening here though? Well, the parameters you define (explained later) such as layers: 'basic' are passed into the URL for the layer (in this case, http://labs.metacarta.com/wms/vmap0). Thus, a url is generated from the layer definition you provide in OpenLayers. Here's what one piece of the map looks like from the first example (you can test this yourself by opening the example map you created from part I and using the firebug addon for firefox to inspect the map element and get the img that is generated and copying the URL).
http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256
If you copy and paste the above URL into your browser, you should see a map image of the Americas and Antartica. OpenLayers makes numerous calls to the URL and gets numerous images like this back, pieces them together, and lets you manipulate them through the interface with controls (which is the topic of the next tutorial). Don't get overwhelmed yet though. Let's break apart the URL.

http://labs.metacarta.com/wms/vmap0
- This is the base URL that is defined in the OpenLayers Layer definition. Everything after this is generated by OpenLayers based on the parameters you specify in the Layer definition.
?
- This is a question mark which signifies everything after it will be a attribute=value pair. These are GET variables (what you're doing here is basically giving the server information through the URl. For example, a GET call could look like http://server.com?username=Foo. By calling that specific URL, you're passing in the username of 'Foo' to the server. Multiple pairs are separated by &. E.g., http://server.com?username=Foo&password=Bar)
LAYERS=basic
- Look familiar? The LAYERS parameter gets it value from the {layers: 'basic'} in the OpenLayers Layer definition.
&SERVICE=WMS
- The service is WMS. OpenLayers knows this because the Layer definition is a OpenLayers.Layer.WMS object.

The rest of the GET variables are automatically generated for you using default values. You can, however, override them.
Let's skip a couple of attribute=value pairs and find the BBOX value.
&BBOX=-180,-90,0,90
- This is where you tell the service what part of the map you want to look at. This is where OpenLayers does a lot of its magic too. Imagine you have a map that is composed of two images. Now, with this example it'd be trivial to determine what two URL calls you need to make to get those two images (that two URL calls would be identical except for the BBOX parameter, where one would be -180,90,0,90 and the other would be 0, -90, 180, 90. You can try this yourself by going to
http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256
and changing the BBOX parameters to see how the image is affected).

So, pulling two images and piecing them together yourself is trivial. But now imagine a more realistic situation where you map is composed of 10 of these images. This would be a bit harder to do - but now imagine that the user zooms in, or pans the map around. You would have to recalculate the BBOX parameters for every interaction. OpenLayers does this automatically.

Go ahead and play with the parameters of
http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256
Remember, these parameters will correspond to the ones you define in the OpenLayers Layer definition.

Part B - Layer Class

The OpenLayers Layer class is what we use to specify the layers on the map. OpenLayers provides support for a multitude of mapping services, including WMS, WFS, Google Maps, Bing Maps, even a Vector layer that supports KML and various other formats. There's even an image layer that allows you to use an image as a map - e.g., you could use a high res picture of an antique map, an image of a map of a video game, or an image of something that's not a map at all.

Let's take a look at OpenLayer's extensive documentation. http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Layer-js.html This is the place to go to find out information about what a specific function or class supports. We're taking a look specifically at the Layer class here though.

Notice that there's a summary of the properties, constraints, properties, and functions that are part of the Layer class. On the left hand side of the page, there's a Layer dropdown that provide even more specific information for the Layer service of your choice. This part will focus on the base Layer class though, and the next part of the tutorial will cover the specific Layer classes.

Generally, the Layer class is defined with the following structure
Title, URL of WMS service, {Params}, {Properties}

A concrete example would be, as we've seen before:

var wms = new OpenLayers.Layer.WMS(

    "OpenLayers WMS",

    "http://labs.metacarta.com/wms/vmap0",

        {layers: 'basic'}

    );
Let's first go through this line by line. Now, keep in mind that code is specific for the WMS Layer class. WMS Layer Doc for a complete class description.

var wms = new OpenLayers.Layer.WMS(
var wms - will be an OpenLayer.Layer.WMS object. i.e., wms is an instantiated object based on the Layer.WMS class. (If you are unfamiliar with object oriented programming, the basic idea is that a class is similar to a blueprint of a house and an object is the actual house created based on the blueprint. We interact with objects that are generated from classes.) new OpenLayers.Layer.WMS - this creates a new object using the OpenLayers.Layer.WMS class. ( - Here we begin passing in parameters

"OpenLayers WMS", - This is the title of the layer. The title what is displayed on the layer switcher control (which we'll cover in the next tutorial) and is completely arbitrary, you can call it whatever you'd like.
http://labs.metacarta.com/wms/vmap0", - this is the URL we'll be using for the layer
{layers: 'basic'} - Now we start passing in params (parameters). We pass in key: value pairs separated by commas. e.g., { layers: 'basic', transparent: 'true' }. The params represent the GetMap url string discussed above. The GetMap call will provide you with parameters you can define.
); - finish the call

Notice we did not specify any properties in this layer. We'll get to that in a moment.

Now I'm going to shamelessly plug my Google Summer of Code 08 project, OpenLayers Architect. I'll be using it occasionally to demonstrate various things. You can reach it at OLArchitect.com. Now, if you select a layer from the drop down list and hit "create" further options will appear on the left hand side. These are all the properties available for that layer that were in place as late 2008 with a prior version of OpenLayers. Almost all, if not all, the properties should still work. If you save the layer then click the save and create map button the right hand side of the page, code will be generated. You can play around with it to see how it generate code based on your input.

Now, let's take a look at some more WMS layer code

layer0 = new OpenLayers.Layer.WMS( 'Layer Name', 

    'http://labs.metacarta.com/wms/vmap0?',

        {layers: 'basic'},

        {projection: new OpenLayers.Projection('4362')}

    );
The code is the same as before but notice the new projection attribute.

Properties

We have neglected to mention properties yet. They are, however, pretty important. By default, most properties are inherited from the map - e.g., the projection. Params and Properties of the WMS layer refer to different settings.

Params
, the first dictionary object ( which in Javascript looks like a set of brackets { }'s with key:value pairs) corresponds to the parameters for the WMS service itself. These params not be usable for a Google map layer or most other layers.
Properties
, the optional second dictionary object, contains OpenLayers Layer settings.

Let's look at some code.
{projection: new OpenLayers.Projection('4362')}
This is the properties object which in this case specifies the current layer's projection.

Let's go back to the OpenLayers API docs OpenLayers docs. Notice the list of properties. These are the properties you can use in that properties object in the OpenLayer Layer definition. Again, these are separated by commas and are key: value pairs. E.g., the properties object might look like

{ buffer:2, gutter: '1', isBaseLayer: 'True' }
The specific properties are described within the linked doc.
buffer
is basically how many tiles the map will draw outside the viewing area so navigation is more seamless.
isBaseLayer
determines if the map is considered a base or overlay layer. The difference is subtle and the concept will pop up when we discuss the layer switcher control.
The main concept is that an base layer is used for what it sounds like - being the base layer. If the isBaseLayer is not defined, it will be on or by default, depending on the layer service and how many layers are in the map. If there are two WMS layers, you could have one layer be the base layer, e.g., a map of the earth, and the second layer be toggle-able layer of weather data.

Conclusion

There will be more tutorials about specific Layer Classes - such as Google Maps and Vector Layers, but each are broken into their own post. The next general tutorial will be OpenLayers Tutorial Part III - Controls. We'll discuss what a control is, how to implement them, and how to customize them.

Ready for the next post? Continue to OpenLayers Tutorial - Part 3 - Controls
NEXT | OpenLayers Tutorial - Part 3: Controls
PREVIOUS | OpenLayers Tutorial - Part 1: Introduction
All Posts

Engage

Comments