Peter Robins, his website

Using OpenLayers: OL Concepts

Map and layers

The main objective of OL is to overlay different types of geographic and cartographic data, from the same or different sources, and display them in a web browser on a monitor or, increasingly these days, mobile device. This data is placed in layers, which can be loaded separately or together, can be made visible or invisible, and can be transparent or opaque. These layers are placed in a Map object, which is the base container for OL objects (I'll use the convention of giving the Map object an initial capital letter to distinguish it from other uses of the word 'map'). So the basic procedure is to create a Map object, and then add layers to it. You then add controls to the Map to enable users to pan and zoom, to turn layers on or off, click on features for further info, and so on.

Although you can have as many layers as you like, there is a fundamental distinction, namely between baselayer(s) and overlays. I'm mainly using OL to display route lines and points of interest on topographical rasters so, in my case, the rasters form the baselayer(s) with the vector data in further overlay layers on top. You can have any number of overlay layers active at the same time, but only one baselayer. (Note that it's planned to remove this baselayer/overlay distinction in v3.)

Projections

Normally, the projection of the baselayer(s) is the same as that of the map, and the vector data coordinates are transformed into that projection before being added to the Map. If you look at Map.js, amongst the many properties you will see projection and units, with the default being 4326 (i.e. WGS84 geographical coordinates) and degrees. Though units can be set to various things, all the non-4326 projections I use are in metres. If, as I do, you are using rasters that other organisations make available, you are of course limited to whatever projections they provide.

OL provides the transforms needed for the SphericalMercator projection used by Google et al. For any other projection, you can use the Proj4js program. This needs the projection definition, which you can get from the Proj files, or from spatialreference.org. As my needs are straightforward - convert 4326 coordinates into the baselayer projection - I simply add the appropriate Proj definition to the program. Proj can then do all the calculations without me having to know anything about ellipsoids, datum or any of the other complicated geometric calculations.

Resolution(s)

Another property of the baselayer is which resolutions, i.e. which zoomlevels, are available. Also in Map.js, you will see the default maxResolution is 1.40625. Resolutions are in map units per pixel, so this corresponds to zoom level 0 on Google Maps, i.e. the entire 360° earth divided by a tile size of 256px, or 1.40625° per pixel. If you look in Layer/Google.js, you will see the resolutions property is an array of values, which correspond to the tiling setup that Google uses. You cannot change this, as Google only provides tiles of a fixed size at these resolutions/zoomlevels.

Of course, if you're fetching raster tiles from other organisations, they will probably use a different structure. The European topographical maps I use are generally by country, with each country covering only their geographical area, using their local projection. In this case, the maxResolution is determined by the geographical bounds of their area; you can also define this in OL with the maxExtent property in the Map/layer objects. In some cases, they provide fixed resolutions as Google does; you can then define this in the resolutions property as with Google layers. In others the servers can dish up any resolution subject to whatever is the minimum resolution/zoomlevel (generally, mapping agencies do not provide detailed maps below scales of 1:2,000 or so). In this case, you can either provide the minimum and maximum zoomlevel/resolution and let OL determine the intermediate levels; or (my preference) you can define a fixed array of resolutions yourself. They may also use a different tilesize. This will of course affect the maxResolution.

As stated above, the rasters I use are generally metre-based. Using WGS84/GRS80 which has an equatorical circumference of 40,075,016.686m, divided by the 256px tilesize = 156,543.03390625m. So if you look in Layer/SphericalMercator.js (the metre-based projection used by Google et al), you will see default maxResolution (set in initialize()) is 156543.0339.

Scale

To find the scale a resolution represents, you have to know how big a pixel is; OL doesn't know that for sure, but makes some reasonable assumptions. If you look at Util.js, and search for getScaleFromResolution(), you will find that it uses 2 constants, INCHES_PER_UNIT and DOTS_PER_INCH, and the calculation is "resolution * OpenLayers.INCHES_PER_UNIT[units] * OpenLayers.DOTS_PER_INCH". For degrees this is resolution*4374754*72 (314,982,288), so the maximum scale is 1:442,943,843. In metres, the maximum scale is 156543.0339*39.3701*72 (2,834.6472) or 1:443,744,273.

Events

There are 2 basic types of event which can be monitored in OL: browser events (mouseover, mouseout, mousedown, mouseup, mousemove, click, dblclick, rightclick, dblrightclick, resize, focus, blur); and map events (such as loadstart or featureadded).

The former are dealt with by handlers associated with controls; for example, if you wish to display the coordinates when the user clicks on the map, you would set up a control with a click handler, which when activated would run a function to display the coordinates. You can also prevent default click handling by creating a stop click handler; for example, with the navigation control active, double-click means 'zoom in', but you can prevent this by creating a control to stop double-click from propagating. There are examples of these in the OL examples: click.html and click-handler.html

Map events are used by map, layer and many controls; see the EVENT_TYPES property in each class for what is available. The basic procedure is to register the event, which means associating it with a function to be run when it is triggered, and possibly unregister it when no longer needed. See Events.js for examples of how these are set up, namely in the register() and unregister() method docs, and also in the on() and un() method docs. You can also pass an eventListeners option when instantiating the object. There are a couple of examples of these in the following pages.

April 2010, checked January 2012