Open Layers.2.10.Beginners.Guide

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 372 [warning: Documents this large are best viewed by clicking the View PDF Link!]

OpenLayers 2.10
Beginner's Guide
Create, opmize, and deploy stunning cross-browser web
maps with the OpenLayers JavaScript web-mapping library
Erik Hazzard
OpenLayers 2.10
Beginner's Guide
Copyright © 2011 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system,
or transmied in any form or by any means, without the prior wrien permission of the
publisher, except in the case of brief quotaons embedded in crical arcles or reviews.
Every eort has been made in the preparaon of this book to ensure the accuracy of the
informaon presented. However, the informaon contained in this book is sold without
warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers
and distributors will be held liable for any damages caused or alleged to be caused directly or
indirectly by this book.
Packt Publishing has endeavored to provide trademark informaon about all of the
companies and products menoned in this book by the appropriate use of capitals. However,
Packt Publishing cannot guarantee the accuracy of this informaon.
First published: March 2011
Producon Reference: 1110311
Published by Packt Publishing Ltd.
32 Lincoln Road
Birmingham, B27 6PA, UK.
ISBN 978-1-849514-12-5
Cover Image by Jose Argudo (
Erik Hazzard
Xurxo Méndez Pérez
Alan Palazzolo
Ian Turton
Couzic Mikael
Acquision Editor
Usha Iyer
Development Editor
Maitreya Bhakal
Technical Editors
Pallavi Kachare
Hemangini Bari
Rekha Nair
Editorial Team Leader
Aanchal Kumar
Project Team Leader
Priya Mukherji
Project Coordinator
Jovita Pinto
Steve Maguire
Nilesh Mohite
Producon Coordinator
Adline Swetha Jesuthas
Cover Work
Adline Swetha Jesuthas
About the Author
Erik Hazzard is a web developer—designer, Open Source advocate, and VI user. He
loves to learn, teach, and occasionally blogs on his website at
As a professional web developer of ve years, Erik specializes in Python and JavaScript,
using open source soware whenever possible. When he's not developing web applicaons,
he's oen developing or designing video games.
He works at FREAC (Florida Resources and Environmental Analysis Center), a great place
with great people that does all kinds of GIS and web development work.
I'd like to thank the developers of OpenLayers, who connually do a
fantasc job of developing the best web-mapping framework. I'd like to
also thank my friends and mentors Ian Johnson and David Arthur for giving
me the condence and support I needed to get into web development.
I'd like to thank Georgianna Strode and Stephen Hodge for their guidance,
advice, and providing me with the opportunity to become a beer web
developer. I could not have wrien this book without the help of the great
team at Packt; I hope every author can be as lucky as me to have such an
excellent group of people to work with. I'd like to thank my parents for
their never ending support. Lastly, I'd like to thank my love, Alisen, for her
understanding and taking the me to help me make sure that the book is
as easy to read as possible.
About the Reviewers
Xurxo Méndez Pérez was born in 1983 in Ourense, a lile town in the south of Galicia,
Spain. He lived there unl he started the study for a degree in IT in the University of A
Coruña, which nalized in 2008.
For the last two years he has been working, at the Computer Architecture Group of the
University of A Coruña developing GIS applicaons (making intensive use of many OGC
standards) like Sitegal and SIUXFor (web GIS based applicaons to manage land properes
and promote their good uses in the Galician region), MeteoSIX (a GIS system that provides
access to geolocated observed and forecasted meteorological data in Galicia) and others.
He also has large experience (3+ years) as a developer of mobile applicaons, having played
rst with JavaME, but nowadays he specializes in Google Android, with more than a dozen
developed applicaons, some of them combining concepts like GIS and geolocaon, real
me responsiveness, and muluser needs.
Alan Palazzolo has been building web applicaons big and small for over ve years,
most of which have been with the open source, content management system Drupal, and
along the way has picked up some experience in data visualizaon and mapping. He is a
strong believer and advocate for the open source methodology in soware and in life. He
was involved in starng a Free Geek chapter in the Twin Cies, and constantly tries to use
technology, and specically the Internet, to enhance the lives of those that are less fortunate
than most.
Ian Turton is a geography researcher at the Pennsylvania State University. He became a
geographer by accident nearly 20 years ago and hasn't managed to escape yet. During that
period he was a co-founder of the GeoTools open source Java toolkit that is now used as
the basis of many geographic open source projects. He connues to serve on the Project
Steering Commiee for the project as well as comming new code and patches. He has also
taught the very popular course "Open Web Mapping" using open standards and open source
programs at the Pennsylvania State University and the University of Leeds.
Support les, eBooks, discount offers, and more
You might want to visit for support les and downloads related to your
Did you know that Packt oers eBook versions of every book published, with PDF and ePub
les available? You can upgrade to the eBook version at and as a print
book customer, you are entled to a discount on the eBook copy. Get in touch with us at for more details.
At, you can also read a collecon of free technical arcles, sign up for a
range of free newsleers and receive exclusive discounts and oers on Packt books and eBooks.
Do you need instant soluons to your IT quesons? PacktLib is Packt's online digital book
library. Here, you can access, read and search across Packt's enre library of books.
Why Subscribe?
Fully searchable across every book published by Packt
Copy and paste, print and bookmark content
On demand and accessible via web browser
Free Access for Packt account holders
If you have an account with Packt at, you can use this to access
PacktLib today and view nine enrely free books. Simply use your login credenals for
immediate access.
Table of Contents
Preface 1
Chapter 1: Geng Started with OpenLayers 7
What is OpenLayers? 8
Why use OpenLayers? 8
What, technically, is OpenLayers? 8
Client side 8
Library 9
Anatomy of a web-mapping applicaon 9
Web map client 10
Web map server 10
Relaon to Google / Yahoo! / and other mapping APIs 11
Layers in OpenLayers 11
What is a Layer? 12
The OpenLayers website 12
Time for acon – downloading OpenLayers 13
Making our rst map 15
Time for acon – creang your rst map 15
How the code works 17
Understanding the code—Line by line 18
JavaScript object notaon 21
Behind the scenes—Object Oriented Programming (OOP) 24
Interacon happens with objects 25
MadLibs 25
Time for Acon – play MadLibs 25
Programming with OOP 26
Subclasses 26
Now what? 27
API docs 28
Table of Contents
[ ii ]
Where to go for help 28
This book's website 28
Mailing lists 28
IRC 29
OpenLayers source code repository 29
Summary 30
Chapter 2: Squashing Bugs With Firebug 31
What is Firebug? 32
Seng up Firebug 32
Time for Acon – downloading Firebug 32
Firebug controls 34
Panels 34
Console panel 35
HTML panel 35
CSS panel 37
Script panel 37
DOM panel 38
Net panel 38
Panel conclusion 41
Using the Console panel 42
Time for Acon – execung code in the Console 42
Time for Acon – creang object literals 43
Object literals 44
Time for Acon – interacng with a map 45
API documentaon 47
Summary 47
Chapter 3: The 'Layers' in OpenLayers 49
What's a layer? 50
Layers in OpenLayers 50
Base layer 51
Overlay layers 51
Time for Acon – creang a map with mulple layers 51
Creang layer objects 54
Layer.WMS class 55
WMS layer parameters: 55
Parameters versus arguments 57
Time for Acon – conguring the opons parameter 58
Conguring layer opons 61
wms_state_lines layer opons 61
Scale dependency 61
wms_layer_labels layer opons 62
The visibility property 62
Table of Contents
[ iii ]
The opacity property 62
Map les 62
Many images make up a map 63
Available layer properes 65
Data types 66
OpenLayers.Layer class properes 66
Modifying layer properes 71
The OpenLayers.Layer class 71
Subclasses 71
Layer Class—Sub and super classes 72
Other layer types 72
Layer.ArcGIS93Rest 72
Layer.ArcIMS 73
Layer.Google 73
Time for Acon – creang a Google Maps layer 73
Layer.Grid 75
Layer.Image 76
Time for Acon – using the image layer 76
Image layer parameters 77
Layer.MapGuide 78
Layer.TileCache 79
Layer.Vector 79
Layer.VirtualEarth 79
Layer.WFS 80
Layer.WMS 80
Layer.Yahoo 80
Accessing layer objects 80
Time for Acon – accessing map.layers 80
Time for Acon – accessing layer objects in Firebug 82
Accessing layer properes 82
map.layers 82
Storing references to layer objects 83
Layer class methods 85
Time for Acon – dening a global layer object variable 85
Layer class method denions 86
Summary 88
Chapter 4: Wrapping Our Heads Around Projecons 89
Map projecons 90
Why on earth are Projecons used? 90
Projecon characteriscs 90
Area 90
Table of Contents
[ iv ]
Scale 91
Shape 91
Other characteriscs 91
Types of projecons 92
EPSG codes 92
Time for Acon – using dierent projecon codes 93
Specifying a dierent projecon 94
Longitude/Latude 95
Latude 96
Longitude 96
Time for Acon – determining LonLat coordinates 96
OpenLayers projecon class 97
Creang a projecon object 97
Parameters 97
Funcons 98
Transforming projecons 99
Time for Acon – coordinate transforms 99
The Proj4js library 100
Time for Acon – seng up 101
Dening custom projecons 102
Summary 102
Chapter 5: Interacng with Third Party APIs 103
Third party mapping APIs 103
Map mashups 104
OpenLayers and third party APIs 104
Google Maps 104
Dierences between Google Maps version 2 and version 3 105
Time for Acon – using Goole Maps V3 (standard way) 105
Creang a Google Map layer object 108
Google layer properes 108
sphericalMercator {Boolean} 109
type {GmapType} 109
V2 GMapType values 110
Time for Acon – creang a Google Map layer with V2 (Deprecated) 111
Yahoo! Maps API 113
Time for Acon – using the Yahoo! Maps Layer 113
Yahoo! Maps Layer class properes 115
Yahoo! Maps Layer types 115
Microso's mapping API 115
Time for Acon – creang a Bing/Virtual Earth Layer 115
VirtualEarth layer class properes 117
Possible type values 118
OpenStreetMap 118
Table of Contents
[ v ]
Time for Acon – creang an OpenStreetMap Layer 118
Accessing your own OSM les 119
Spherical Mercator 120
Spherical Mercator—EPSG code 120
Time for Acon – using Spherical Mercator 121
Map properes with Spherical Mercator layers 122
maxExtent 122
maxResoluon 122
units 123
projecon 123
Using Google Maps and other layers 123
Time For Acon – creang your rst mashup 124
WMS with Spherical Mercator/third party map layers 127
Summary 127
Chapter 6: Taking Control of Controls 129
What are controls? 130
Using controls in OpenLayers 130
Adding controls to your map 130
Time for Acon – creang a map with no controls 131
Time for Acon—Adding controls to a map 132
Adding controls by passing in an array of controls 135
Adding controls to map with addControl() and addControls() 135
Removing controls 136
OpenLayers.Control class 136
OpenLayers.Control properes 137
OpenLayers.Control funcons 137
OpenLayers.Control subclasses 138
OpenLayers.Control.ArgParser 138
OpenLayers.Control.Permalink 139
OpenLayers.Control.Aribuon 139
Aribuon properes 139
Time for Acon – using aribuons 140
OpenLayers.Control.EdingToolbar 141
OpenLayers.Control.Gracule 141
Gracule properes 142
OpenLayers.Control.KeyboardDefaults 143
KeyboardDefaults properes 143
OpenLayers.Control.LayerSwitcher 143
LayerSwitcher properes 143
LayerSwitcher funcons 144
OpenLayers.Control.MousePosion 144
MousePosion properes 144
Table of Contents
[ vi ]
OpenLayers.Control.Navigaon 145
Navigaon properes 145
OpenLayers.Control.NavigaonHistory 146
NavigaonHistory properes 146
NavigaonHistory funcons 146
Time for Acon – using the NavigaonHistory control 146
OpenLayers.Control.NavToolbar 147
OpenLayers.Control.OverviewMap 147
OverviewMap properes 148
OverviewMap funcons 150
OpenLayers.Control.PanPanel 150
PanPanel properes 151
OpenLayers.Control.PanZoom 151
OpenLayers.Control.PanZoomBar 151
PanZoomBar properes 151
OpenLayers.Control.Scale 151
Scale properes 152
OpenLayers.Control.ScaleLine 152
ScaleLine properes 152
OpenLayers.Control.ZoomPanel 153
Panels 153
Control types 153
Time for Acon – using Panels 154
OpenLayers.Control.Panel 157
Panel properes 158
Panel funcons 159
Now what? 159
Creang our own controls 159
OpenLayers.Control.Buon 159
Buon properes 160
Buon funcons 161
Creang a custom buon 161
Time for Acon – creang a simple buon 161
Other control types 165
Process for creang other buon control types 165
Events 165
Event listeners and handlers 165
Custom events 166
Creang a TYPE_TOGGLE control 166
Time for Acon – creang a custom TYPE_TOGGLE control 166
Summary 170
Table of Contents
[ vii ]
Chapter 7: Styling Controls 171
What is CSS? 172
Ideas behind CSS and HTML 172
Eding CSS 172
HTML elements 173
HTML—IDs and classes 173
Styling HTML elements with CSS 174
Using CSS in your code 175
Time for Acon – using external CSS les 176
Cascading Style Sheets—Inheritance 178
Order of inheritance 178
Referencing elements 179
OpenLayers and CSS 180
Styling OpenLayers—using themes 180
Creang your own themes 181
OpenLayers—class names and IDs 181
Time for Acon – styling controls 182
Time for Acon – styling the LayerSwitcher control 186
Other resources 188
Summary 189
Chapter 8: Charng the Map Class 191
The Map class 192
Creang a map object 192
Map class properes 192
Map properes 193
allOverlayers 193
controls 193
displayProjecon 194
div 194
Time for Acon – using the allOverlays Map property 194
eventListeners 196
fallThrough 197
layers 197
maxExtent 198
minExtent 198
restrictedExtent 198
numZoomLevels 198
Time for Acon – seng zoom levels and maxExtent 199
Map properes—Connued 200
Resoluons 200
Time for Acon – using resoluons array 201
Map/Layer property inheritance 201
Table of Contents
[ viii ]
Map properes discussion—Connued 202
maxResoluon 202
minResoluon 202
Time for Acon – using Min and Max resoluon 202
scales 204
maxScale 204
minScale 204
Time for Acon – Using scales 205
panMethod 206
panDuraon 207
Time for Acon – working with Pan animaons 207
projecon 208
theme 208
leSize 208
unit 208
Map funcons 209
Control related 209
Time for Acon – using control methods 210
Extent/Coordinate/Bounds related 210
Methods 211
Time for Acon – using coordinate related funcons 213
Layer related funcons 214
Other funcons 214
Doing stu with events 215
Map event types 216
Using map events 216
Using the eventListeners property 217
Time for Acon – using eventListeners 217
Using 218
Event object 218
Time for Acon – working with Map events 219
Mulple maps 220
Using mulple map objects 220
Time for Acon – using mulple map objects 221
Mulple maps and custom events 223
Time for Acon – creang a mulple map and custom event applicaon 223
Summary 225
Chapter 9: Using Vector Layers 227
What is the Vector Layer? 228
What makes the Vector Layer special? 229
The Vector Layer is client side
Table of Contents
[ ix ]
Other uses 229
What is a 'Vector'? 230
Time for Acon – creang a Vector Layer 230
How the Vector Layer works 232
How the Vector Layer is rendered 233
SVG 233
Canvas 233
VML 233
'Renderers' array 233
Time for Acon – changing the Renderers array 234
Vector Layer class 235
OpenLayers.Layer.Vector properes 235
OpenLayers.Layer.Vector methods 237
Working with features 237
Time for Acon – adding features 237
Vector Layer methods (Connued) 239
Time for Acon – destroying features 239
Vector Layer methods (Connued) 241
Time For Acon – working with feature events 242
Vector Layer class events 243
Vector Layer event types 244
Time For Acon – using Vector Layer events 246
Time For Acons – working with more events 247
Geometry and Feature classes 248
Geometry class 249
Geometry subclasses—Theory 249
Geometry class methods 250
Time for Acon – using Geometry class methods 251
Geometry subclasses 253
Geometry subclass methods 255
Feature class 255
How the Feature class works 255
Feature subclasses 256
Feature funcons 256
Instanang a feature object 256
Interacng with Features using Control.SelectFeature 257
Time For Acon – using the SelectFeature control 257
Control.SelectFeature class 262
SelectFeature control properes 262
SelectFeature control methods 264
The Vector class, part two 264
Format, protocol, and strategy classes 265
Who invited these classes over? 265
Table of Contents
[ x ]
Brief overview of the three classes 266
How these three classes interact 267
Example instanaon 267
Time for Acon – creang a Vector Layer 268
Cross server requests 269
Using the Vector Layer without a Protocol class 270
Time for Acon – using the Format and Strategy classes alone 270
Format class 273
Format class properes 273
Format class methods 273
Format subclasses 274
Strategy class 274
Strategy.BBOX 274
Strategy.Cluster 274
Strategy.Filter 275
Strategy.Fixed 275
Strategy.Paging 275
Strategy.Refresh 275
Strategy.Save 276
Summary 276
Chapter 10: Vector Layer Style Guide 277
Styling the Vector Layer 277
Applying styles 278
What are symbolizers? 278
Time For Acon – applying some basic Styling 279
The StyleMap class 281
What is an 'intent'? 281
The Style class 281
Symbolizer properes 282
List of common symbolizer properes 282
Time for Acon – common style examples 284
Remaining symbolizer properes 286
Aribute replacement 287
Time For Acon – working with aribute replacement 287
Rules and lters 289
How do we follow rules? 289
Using addUniqueValueRules 290
Calling the addUniqueValueRules funcon 290
The intent parameter 290
The property parameter 290
The symbolizer_lookup parameter 291
The context parameter 291
Table of Contents
[ xi ]
Time For Acon – using addUniqueValueRules 291
Rules and lters 294
How do they work? 295
How do we use them? 295
Time for Acon – using rules and lters 295
OpenLayers.Rule class 298
OpenLayers.Filter class 299
Filter Subclasses 299
Filter.Comparison 299
Filter.FeatureId 303
Feature.Logical 303
Time For Acon – guring out logical lters 304
Feature.Spaal 308
Summary 309
Chapter 11: Making Web Map Apps 311
Development strategies 311
Creang a web map applicaon using Flickr 312
Note on APIs 312
Accessing the Flickr public data feeds 312
How we'll do it 313
Time For Acon – geng Flickr data 313
Why did we do this? 314
Reducing possible errors 314
Time for Acon – adding data to your map 315
Time for Acon – extract style 317
Turning our example into an applicaon 318
Adding interacvity 319
Selecng features 319
Time for Acon – adding some interacvity 319
Using real me data with a ProxyHost 325
Time for Acon – geng dynamic data 325
Wrapping up the applicaon 326
Recap 326
The plan 327
Changing the URL 327
Time For Acon – adding dynamic tags to your map 327
Deploying an applicaon 330
Building the OpenLayers Library le 330
Always try to serve small les 330
Using the OpenLayers build le 331
Conguring the build script 331
Time for Acon – building a Cong le 332
Table of Contents
[ xii ]
Running the build script 333
Time for Acon – running the Build script 333
Summary 334
Appendix: Pop Quiz Answers 335
Chapter 2: Squashing Bugs With Firebug 335
Chapter 3: The 'Layers' in OpenLayers 335
Chapter 4: Wrapping Our Heads Around Projecons 335
Chapter 6: Taking Control of Controls 335
Chapter 7: Styling Controls 336
Chapter 8: Charng the Map Class 336
Chapter 9: Using Vector Layers 336
Chapter 10: Vector Layer Style Guide 336
Chapter 11: Making Web Map Apps 336
Index 337
Web mapping is the process of designing, implemenng, generang, and delivering maps
on the World Wide Web and its products. OpenLayers is a powerful, community driven,
open source, pure JavaScript web-mapping library. With it, you can easily create your
own web map mashup using WMS, Google Maps, and a myriad of other map backends.
Interested in knowing more about OpenLayers? This book is going to help you learn
OpenLayers from scratch.
OpenLayers 2.10 Beginner's Guide will walk you through the OpenLayers library in the easiest
and most ecient way possible. The core components of OpenLayers are covered
in detail, with examples, structured so that you can easily refer back to them later.
The book starts o by introducing you to the OpenLayers library and ends with developing
and deploying a full-edged web map applicaon, guiding you through every step of the way.
Throughout the book, you'll learn about each component of the OpenLayers library. You'll
work with backend services like WMS, third-party APIs like Google Maps, and even create
maps from stac images. You'll load data from KML and GeoJSON les, create interacve
vector layers, and customize the behavior and appearance of your maps.
There is a growing trend in mixing locaon data with web applicaons. OpenLayers 2.10
Beginner's Guide will show you how to create powerful web maps using the best web
mapping library around.
This book will guide you to develop powerful web maps with ease using the open source
JavaScript library OpenLayers.
[ 2 ]
What you need for this book
The only thing you'll need for this book is a computer and text editor. Your operang system
will come with a text editor, and any will do, but if you are using Windows I recommend
using Notepad++ (, VI if you are using Linux, and
Textmate if on OSX. An Internet connecon will be required to view the maps, and you'll
also need a modern web browser such as Firefox, Google Chrome, Safari, or Opera. While a
modern browser is required to get the most of the library, OpenLayers even provides support
for non standards based browsers such as Internet Explorer (even IE6, to some extent).
No knowledge of Geographic Informaon Systems (GIS) is required, nor is extensive
JavaScript experience. A basic understanding of JavaScript syntax and HTML / CSS will greatly
aid in understanding the material, but is not required.
What this book covers
Chapter 1: Geng Started with OpenLayers. This chapter will introduce OpenLayers and
some programming concepts behind it. It covers how to create a map, walking through
how to set up the code and congure various sengs.
Chapter 2: Squashing Bugs with Firebug. This chapter will cover seng up the Firebug
plugin, which we'll use throughout the book, so that we can do simple debugging and
beer understand how OpenLayers works behind the scenes.
Chapter 3: The 'Layers' in OpenLayers. Here, we'll cover one of the core classes of
OpenLayers—the Layer class. We'll discuss what a 'Layer' is, how to work with layers
and the dierent layer classes.
Chapter 4: Wrapping our Heads Around Projecons. This chapter will cover a few basic
geography concepts and why understanding them will help us use OpenLayers. We'll also
cover projecons, why they are used, and how to use them.
Chapter 5: Interacng With Third Party APIs. This chapter will focus on creang an
OpenLayers map using dierent third party APIs, such as Google Maps and OpenStreetMaps.
Chapter 6: Taking Control of Controls. We'll cover another core class of OpenLayers, the
Control class. We'll cover what controls are and discuss the various types of controls, along
with how to work with the events.
Chapter 7: Giving Controls Some Style. This chapter will walk through how OpenLayers uses
CSS to style controls.
[ 3 ]
Chapter 8: Charng the Map Class. This chapter will discuss another core component of
OpenLayers—the Map class. We'll learn about how to map funcons and their properes,
along with how to set up mulple maps on the same page.
Chapter 9: Using Vector Layers. Here, we'll learn what a Vector layer is and how it works.
We'll also cover how to work with the data, such as KML les.
Chapter 10: Vector Layer Style Guide. In this chapter we'll cover how to style the vector
layer and how to use the Rule and Filter classes.
Chapter 11: Creang Web Map Applicaons. This nal chapter will go over how to build
a web-mapping applicaon from scratch, and how to use the OpenLayers build le.
Who this book is for
This book is for anyone who has any interest in using maps on their website, from hobbyists
to professional web developers. OpenLayers provides a powerful, but easy-to-use, pure
JavaScript and HTML (no third-party plug-ins involved) toolkit to quickly make cross-
browser web maps. A basic understanding of JavaScript will be helpful, but there is no prior
knowledge required to use this book. If you've never worked with maps before, this book
will introduce you to some common mapping topics and gently guide you through the
OpenLayers library. If you're an experienced applicaon developer, this book will also serve
as a reference to the core components of OpenLayers.
How to read this book
This book is primarily designed to be read from start to nish, with chapters building on each
other and increasing in complexity. At the same me, however, the chapters are modular
so that each can also serve as reference once you've learned the material. This book should
preferably be read straight through rst, of course, and then serve as a reference later.
In this book, you will nd several headings appearing frequently.
[ 4 ]
To give clear instrucons of how to complete a procedure or task, we use:
Time for action – heading
1. Acon 1
2. Acon 2
3. Acon 3
Instrucons oen need some extra explanaon so that they make sense, so they are
followed with:
What just happened?
This heading explains the working of tasks or instrucons that you have just completed.
You will also nd some other learning aids in the book, including:
Pop quiz – heading
These are short quesons intended to help you test your own understanding.
Have a go hero – heading
These set praccal challenges and give you ideas for experimenng with what you have
You will also nd a number of styles of text that disnguish between dierent kinds of
informaon. Here are some examples of these styles, and an explanaon of their meaning.
Code words in text are shown as follows: "You can download it as either a tar.gz or .zip."
A block of code is set as follows:
Lines [21] to [23]
When we wish to draw your aenon to a parcular part of a code block, the relevant lines
or items are set in bold:
var wms_layer = new OpenLayers.Layer.WMS(
'WMS Layer Title',
[ 5 ]
{layers: 'basic'},
New terms and important words are shown in bold. Words that you see on the screen, in
menus or dialog boxes for example, appear in the text like this: "By default, your map adds
an argParser control which will try to pull informaon from a permalink.".
Warnings or important notes appear in a box like this.
Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this
book—what you liked or may have disliked. Reader feedback is important for us to
develop tles that you really get the most out of.
To send us general feedback, simply send an e-mail to, and
menon the book tle via the subject of your message.
If there is a book that you need and would like to see us publish, please send us a note in
the SUGGEST A TITLE form on or e-mail
If there is a topic that you have experse in and you are interested in either wring or
contribung to a book, see our author guide on
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you
to get the most from your purchase.
Downloading the example code for this book
You can download the example code les for all Packt books you have purchased from your
account at If you purchased this book elsewhere, you can
visit and register to have the les e-mailed directly
to you.
[ 6 ]
Although we have taken every care to ensure the accuracy of our content, mistakes do
happen. If you nd a mistake in one of our books—maybe a mistake in the text or the code—
we would be grateful if you would report this to us. By doing so, you can save other readers
from frustraon and help us improve subsequent versions of this book. If you nd any
errata, please report them by vising, selecng
your book, clicking on the errata submission form link, and entering the details of your
errata. Once your errata are veried, your submission will be accepted and the errata will
be uploaded on our website, or added to any list of exisng errata, under the Errata secon
of that tle. Any exisng errata can be viewed by selecng your tle from http://www.
Piracy of copyright material on the Internet is an ongoing problem across all media.
At Packt, we take the protecon of our copyright and licenses very seriously. If you come
across any illegal copies of our works, in any form, on the Internet, please provide us with
the locaon address or website name immediately so that we can pursue a remedy.
Please contact us at with a link to the suspected
pirated material.
We appreciate your help in protecng our authors, and our ability to bring you
valuable content.
You can contact us at if you are having a problem with any
aspect of the book, and we will do our best to address it.
Getting Started with OpenLayers
Within the past few years, the popularity of interacve web maps has exploded.
In the past, creang interacve maps was reserved for large companies or
experts with lots of money. But now, with the advent of free services like Google
and Yahoo! Maps, online mapping is easily accessible to everyone. Today,
with the right tools, anyone can easily create a web map with lile or even no
knowledge of geography, cartography, or programming.
Web maps are expected to be fast, accurate, and easy to use. Since they
are online, they are expected to be accessible from anywhere on nearly any
plaorm. There are only a few tools that fulll all these expectaons.
OpenLayers is one such tool. It's free, open source, and very powerful. Providing
both novice developers and seasoned GIS professionals with a robust library,
OpenLayers makes it easy to create modern, fast, and interacve web-mapping
In this chapter we will
Learn what OpenLayers is
Discuss some web mapping applicaon concepts
Make our First Map
Cover concepts behind OpenLayers, such as Object Oriented Programming
Provide informaon on resources outside of this book
Geng Started with OpenLayers
[ 8 ]
What is OpenLayers?
OpenLayers is an open source, client side JavaScript library for making interacve web
maps, viewable in nearly any web browser. Since it is a client side library, it requires no
special server side soware or sengs—you can use it without even downloading
anything! Originally developed by Metacarta, as a response, in part, to Google Maps, it
has grown into a mature, popular framework with many passionate developers and a very
helpful community.
Why use OpenLayers?
OpenLayers makes creang powerful web-mapping applicaons easy and fun. It is very
powerful but also easy to use—you don't even need to be a programmer to make a great
map with it. It's open source, free, and has a strong community behind it. So if you want to
dig into the internal code, or even improve it, you're encouraged to do so. Cross browser
compability is handled for you—it even works in IE6.
OpenLayers is not ed to any proprietary technology or company, so you don't have to
worry so much about your applicaon breaking (unless you break it). At the me of wring,
support for modern mobile and touch devices is in the works (with many proof of concept
examples), and should be in the ocial library in the near future—if they aren't by the me
you're reading this.
OpenLayers allows you to build enre mapping applicaons from the ground up, with the
ability to customize every aspect of your map—layers, controls, events, etc. You can use a
multude of dierent map server backends together, including a powerful vector layer. It
makes creang map 'mashups' extremely easy.
What, technically, is OpenLayers?
We said OpenLayers is a client side JavaScript library, but what does this mean?
Client side
When we say client side we are referring to the user's computer, specically their web browser.
The only thing you need to have to make OpenLayers work is the OpenLayers code itself and
a web browser. You can either download it and use it on your computer locally, or download
nothing and simply link to the JavaScript le served on the site that hosts the OpenLayers
project ( OpenLayers works on nearly all browsers and can be
served by any web server or your own computer. Using a modern, standard-based browser
such as Firefox, Google Chrome, Safari, or Opera is recommended.
Chapter 1
[ 9 ]
When we say library we mean that OpenLayers is an API (Applicaon Programmer
Interface) that provides you with tools to develop your own web maps. Instead of building
a mapping applicaon from scratch, you can use OpenLayers for the mapping part, which is
maintained and developed by a bunch of brilliant people.
For example, if you wanted to write a blog you could either write your own blog engine,
or use an exisng one such as WordPress or Blogger and build on top of it. Similarly, if you
wanted to create a web map, you could write your own from scratch, or use soware that
has been developed and tested by a group of developers with a strong community behind it.
By choosing to use OpenLayers, you do have to learn how to use the library (or else you
wouldn't be reading this book), but the benets greatly outweigh the costs. You get to use
a rich, highly tested and maintained code base, and all you have to do is learn how to use it.
Hopefully, this book will help you with that.
OpenLayers is wrien in JavaScript, but don't fret if you don't know it very well. All you really
need is some knowledge of the basic syntax, and we'll try to keep things as clear as possible
in the code examples.
If you are unfamiliar with JavaScript, Mozilla provides phenomenal
JavaScript documentaon at https://developer.mozilla.
Anatomy of a web-mapping application
First o—what is a 'web-mapping applicaon'? To put it bluntly, it's some type of Internet
applicaon that makes use of a map. This could be a site that displays the latest geo-tagged
images from Flickr (we'll do this in Chapter 11), a map that shows markers of locaons
you've traveled to, or an applicaon that tracks invasive plant species and displays them. If it
contains a map and it does something, you could argue that it is a web map applicaon. The
term can be used in a prey broad sense.
Downloa d f r o m W o w ! e B o o k < w w w.woweb o o k . c o m >
Geng Started with OpenLayers
[ 10 ]
So where exactly does OpenLayers t in? We know OpenLayers is a client side mapping
library, but what does that mean? Let's take a look at the following screenshot:
This is called the Client / Server Model and it is, essenally, the core of how all web
applicaons operate. In the case of a web map applicaon, some sort of map client (e.g.,
OpenLayers) communicates with some sort of web map server (e.g., a WMS server or the
Google Maps backend).
Web map client
OpenLayers lives on the client side. One of the primary tasks the client performs is to get
map images from a map server. Essenally, the client has to ask a map server for what you
want to look at. Every me you navigate or zoom around on the map, the client has to make
new requests to the server—because you're asking to look at something dierent.
OpenLayers handles this all for you, and it is happening via asynchronous JavaScript (AJAX)
calls to a map server. To reiterate—the basic concept is that OpenLayers sends requests to a
map server for map images every me you interact with the map, then OpenLayers pieces
together all the returned map images so it looks like one big, seamless map. In Chapter 2,
we'll cover this concept in more depth.
Web map server
A map server (or map service) provides the map itself. There are a myriad of dierent map
server backends. A small sample includes WMS, Google Maps, Yahoo! Maps, ESRI ArcGIS,
WFS, and OpenStreet Maps. If you are unfamiliar with those terms, don't sweat it. The basic
principle behind all those services is that they allow you to specify the area of the map you
want to look at (by sending a request), and then the map servers send back a response
containing the map image. With OpenLayers, you can choose to use as many dierent
backends in any sort of combinaon as you'd like.
OpenLayers is not a web map server; it only consumes data from them. So, you will need to
be able to access some type of web map service. Don't worry though. Fortunately, there are
a myriad of free and/or open source web map servers available that are remotely hosted or
easy to set up yourself, such as MapServer.
Chapter 1
[ 11 ]
Throughout this book, we'll oen use a freely available web mapping service
from OSGeo, so don't worry about having to provide your own.
With many web map servers you do not have to do anything to use them—just supplying
a URL to them in OpenLayers is enough. OSGeo, OpenStreet Maps, Google, Yahoo!, and
Bing Maps, for instance, provide access to their map servers (although, some commercial
restricons may apply with various services in some situaons).
Relation to Google / Yahoo! / and other mapping APIs
The Google, Yahoo!, Bing, and ESRI Mappings API allow you to connect with their map
server backend. Their APIs also usually provide a client side interface (at least in the
case of Google Maps).
The Google Maps API, for instance, is fairly powerful. You have the ability to add markers,
plot routes, and use KML data (things you can also do in OpenLayers)—but the main
drawback is that your mapping applicaon relies totally on Google. The map client and map
server are provided by a third party. This is not inherently a bad thing, and for many projects,
Google Maps and the like are a good t.
However, there are quite a few drawbacks.
You're not in control of the backend
You can't really customize the map server backend, and it can change at any me
There may be some commercial restricons, or some costs involved
These other APIs also cannot provide you with anything near the amount
of exibility and customizaon that an open source mapping applicaon
framework (i.e., OpenLayers) oers
Layers in OpenLayers
So, what's with the Layer in OpenLayers? Well, OpenLayers allows you to have mulple
dierent 'backend' servers that your map can use. To access a web map server, you create
a layer object and add it to your map with OpenLayers.
For instance, if you wanted to have a Google Maps and a WMS service displayed on your
map, you would use OpenLayers to create a GoogleMaps layer object and a WMS layer
object, and then add them to your OpenLayers map. We'll soon see an example with a
WMS layer, so don't worry if you're a lile confused.
Geng Started with OpenLayers
[ 12 ]
What is a Layer?
Like layers of an onion, each layer is above and will cover up the previous one; the order
that you add in the layers is important. With OpenLayers, you can arbitrarily set the overall
transparency of any layer, so you are easily able to control how much layers cover each other
up, and dynamically change the layer order at any me.
For instance, you could have a Google map as your base layer, a layer with satellite imagery
that is semi-transparent, and a vector layer all acve on your map at once. A vector layer is
a powerful layer that lets us add markers and various geometric objects to our maps—we'll
cover it in Chapter 9. Thus, in this example, your map would have three separate layers. We'll
go into much more depth about layers and how to use and combine them in Chapter 3.
The OpenLayers website
The website for OpenLayers is located at To begin, we need to
download a copy of OpenLayers (or, we can directly link to the library—but we'll download a
local copy). You can download the compressed library as either a .tar.gz or .zip, but both
contain the same les.
Chapter 1
[ 13 ]
Let's go over the links:
Link to the hosted version: If you do not want to actually download OpenLayers,
you can instead link to the OpenLayers library by adding this script URL to your site
in a <script> tag.
2.10 (Stable) .tar.gz or .zip: This should show the latest stable release (2.10 at
the me of wring). You can download it as either a tar.gz or .zip; if you are
unsure of which to get, you should download the .zip version.
2.10 Release Notes: This highlights things that have changed, bugs that have been
xed, etc.
Class documentaon, more documentaon: These are links to the API
documentaon, which we will make heavy use of throughout the book. I
recommend opening it up and keeping it up while working through the examples.
See examples...: OpenLayers provides a rich array of examples demonstrang
features of the library; if you're ever stuck or looking for a good example—go here.
Time for action – downloading OpenLayers
Let's download the OpenLayers library. Aer you're done, you should have the OpenLayers
library les set up on your computer.
1. Go to the OpenLayers website ( and download the
.zip version (or if you prefer the .tar.gz version).
2. Extract the le you just downloaded. When you extract it, you'll end up with a folder
called OpenLayers-2.10 (or whatever your version is).
Geng Started with OpenLayers
[ 14 ]
3. Open up the OpenLayers folder. Once inside, you'll see a lot of folders and les, but
the ones we are concerned with right now is a le called OpenLayers.js and two
folders, /img and /theme. We'll be copying these to a new folder.
4. Create a new folder outside the OpenLayers directory; we'll use ~/code/ (if you are
on Windows, then c:/code). You can name the folder whatever you like, but we'll
refer to it as the code folder. Inside the code folder, copy over the OpenLayers.
js and two folders (/img and /theme) from the previous step. Your new folder
structure should look similar to this:
What just happened?
We just 'installed' OpenLayers by copying over a pre-built, compressed JavaScript le
containing the enre OpenLayers library code and two directories containing assets (images
and stylesheets). To use OpenLayers, you'll need at a minimum the OpenLayers.js le and
the img and theme folders.
Chapter 1
[ 15 ]
If you open the OpenLayers.js le, you'll noce it is nearly unreadable. This is because
this is a minied version, which basically means extra white space and unnecessary
characters have been stripped out to cut down on the le size. While it is no longer readable,
it is a bit smaller and thus requires less me to download. If you want to look at the
uncompressed source code, you can view it by looking in the OpenLayers source code folder
you extracted.
You can, as we'll see in the last chapter of this book, build your own custom conguraons
of the library, including only the things you need. But for now, we'll just use the enre library.
Now that we have our OpenLayers library les ready to use, let's make use of them!
Making our rst map
The process for creang a map with OpenLayers requires, at a minimum, the
following things:
Including the OpenLayers library les
Creang an HTML element that the map will appear in
Creang a map object from the Map class
Creang a layer object from a Layer class
Adding the layer to the map
Dening the map's extent (seng the area the map will inially be displaying)
Now we're nally ready to create our rst map!
Time for action – creating your rst map
Let's dive into OpenLayers and make a map! Aer you nish this secon, you should have a
working map, which uses a publicly available WMS server backend from OSGeo.
1. Navigate to the code directory that contains the OpenLayers.js le, /img and /
theme directories. Create a le here called index.html. This directory (/code) will
be referred to as our root directory, because it is the base (root) folder where all our
les reside.
2. Add in the following code to index.html and save the le as an .html le—if
you are using Windows, I suggest using Notepad++. Do not try to edit the le in a
program like Microso Word, as it will not save properly. The following code will also
be used as the base template code for many future examples in this book, so we'll
be coming back to it a lot.
Geng Started with OpenLayers
[ 16 ]
The lines numbers in the code are for demonstraon purposes; do not type
them in when you are wring your code.
1.<!DOCTYPE html>
2.<html lang='en'>
4. <meta charset='utf-8' />
5. <title>My OpenLayers Map</title>
6. <script type='text/javascript' src='OpenLayers.js'></script>
7. <script type='text/javascript'>
9. var map;
11. function init() {
12. map = new OpenLayers.Map('map_element', {});
13. var wms = new OpenLayers.Layer.WMS(
14. 'OpenLayers WMS',
15. '',
16. {layers: 'basic'},
17. {}
18. );
20. map.addLayer(wms);
21. if(!map.getCenter()){
22. map.zoomToMaxExtent();
23. }
24. }
26. </script>
29.<body onload='init();'>
30. <div id='map_element' style='width: 500px; height: 500px;'>
31. </div>
3. Open up index.html in your web browser. You should see something similar to:
Chapter 1
[ 17 ]
What just happened?
We just created our rst map using OpenLayers! If it did not work for you for some reason,
try double checking the code and making sure all the commas and parentheses are in place.
You can also refer to the Preface where a link to code samples used in the book is given. By
default, we're given a few controls if we don't specify any. We will use the le we created as
a template for many examples throughout the book, so save a copy of it so you can easily
reference it later.
The control on the le side (the navigaon buons) is called the PanZoom control. You can
click the buons to navigate around the map, drag the map with your mouse/use the scroll
wheel to zoom in, or use your keyboard's arrow keys. We'll cover controls in far greater detail
in Chapter 6.
How the code works
Now, let's take a look at the code—line by line. Before we do that, let's include a quick
reference to the line numbers at which the requirements from the previous secon occur at.
These are the core things that you need to do to have a funconing map.
Geng Started with OpenLayers
[ 18 ]
We'll denote line numbers with brackets—[x], where x is the line number.
1. Including the OpenLayers library les:
Line [6]
<script type='text/javascript' src='OpenLayers.js'></script>
2. Creang an HTML element for our map:
Lines [30] and [31]
<div id='map_element' style='width: 500px; height: 500px'>
3. Creang a map object from the Map class:
Line [12]
map = new OpenLayers.Map('map_element', { });
4. Creang a layer object from a Layer class:
Lines [13] to [18]
var wms_layer = new OpenLayers.Layer.WMS(
'WMS Layer Title',
{layers: 'basic'},
5. Adding the layer to the map:
Line [20]
6. Dening the map's extent:
Lines [21] to [23]
Understanding the code—Line by line
Lines [1] to [5]: Sets up the HTML page. Every HTML page needs an <html> and <head> tag,
and the extraneous code you see species various sengs that inform your browser that this
is an HTML5 compliant page. For example, we include the DOCTYPE declaraon in line [1] to
specify that the page conforms to standards set by the WC3. We also specify a <title> tag,
which contains the tle that will be displayed on the page.
Chapter 1
[ 19 ]
This is the structure that all our code examples will follow, so this basic
code template will be implicitly assumed in all examples that follow
throughout the book.
Line [6]: <script type='text/javascript' src='OpenLayers.js'></script>
This includes the OpenLayers library. The locaon of the le is specied by the
src='OpenLayers.js' aribute. Here, we're using a relave path. As the index.
html page is in the same folder as the OpenLayers.js le, we don't have to worry about
specifying the path to it. The le could be either on your computer or another computer—it
doesn't maer much, as long as the browser can load it.
We can also use an absolute path, which means we pass in a URL that the script is located at. hosts the script le as well; we could use the following line of code to link
to the library le directly:
<script type='text/javascirpt' src='
Noce how the src species an actual URL—this is how we use absolute paths. Either way
works, however, throughout the book we'll assume that you are using a relave path and
have the OpenLayers library on your own computer/server. If you use the hosted OpenLayers
library, you cannot be sure that it will always be available, and it may change overnight (and
changes when the library is updated)—so using a local copy is recommended.
Line [7]: Starts a <script> block. We'll set up all our code inside it to create our map. Since
the OpenLayers library has been included in line [5], we are able to use all the classes and
funcons the library contains.
Line [8]: var map;
Here we create a global variable called map. In JavaScript, anyme we create a variable we
need to place var in front of it to ensure that we don't run into scope issues (what funcons
can access which variables). When accessing a variable, you do not need to put var in front
of it.
Since we are dening map as a variable at the global level (outside of any funcons), we can
access it anywhere in our code. Soon we will make this map variable our map object, but
right now it is just an empty global variable.
Geng Started with OpenLayers
[ 20 ]
Line [11]: Creates a funcon called init. When the page loads (via body
onload='init();' on line [29]), this funcon will get called. This funcon contains all of
our code to set up our OpenLayers map. If you are familiar with JavaScript, you do not have
to put all the code in a funcon call—you could, for instance, just put the code at the boom
of the page and avoid a funcon call all together. Creang a funcon that gets called when
the page loads is a common pracce and so we will be doing it throughout the book.
Line [12]: map = new OpenLayers.Map('map_element', { });
Remember that global map variable? Well, now we're making it a map object, created from
the OpenLayers.Map class. It is also referred to as an instance of the Map class. We'll talk
about what this means later in this chapter in the Object Oriented Programming secon. The
map object is the crux of our OpenLayers applicaon— we call its funcons to tell the map to
zoom to areas, re o events, keep track of layers, etc.
Now, let's look at the right hand side of the equal sign (=): new means that we are creang a
new object from the class that follows it. OpenLayers.Map is the class name which we are
creang an object from. Noce that something is inside the parenthesis: ('map_element',
{}). This means we are passing two things into the class (called arguments, and you pass
them in separated by a comma). Every class in OpenLayers expects dierent arguments to be
passed into it, and some classes don't expect anything.
The Map class expects two parameters. The rst argument, map_element, is the ID of the
HTML element that the map will appear in. The second argument, { }, are the map opons,
consisng of key:value pairs (e.g., {key:value} ). This is also called JavaScript Object
Notaon, a way to create objects on the y. We'll cover this in more depth very shortly in the
next secon. Also, you are not required to include this argument if it is empty (even though
we just did it), but we are just doing it here for consistency.
Because we passed in map_element as the rst parameter, we will have an HTML element
(almost always a <div>) with the ID of map_element. The HTML element ID can be anything,
but for the sake of clarity and to avoid confusion, we call it map_element.
Line [13]: var wms = new OpenLayers.Layer.WMS(
Here, we create a layer object for the map to use from the WMS subclass of the Layer class.
In OpenLayers, every map needs to have at least one layer. The layer points to the 'back end',
or the server side map server, as we discussed earlier. The layer can be any of a multude of
dierent services, but we are using WMS here. WMS, which stands for Web Map Service, is
an internaonal standard dened by the Open Geospaal Consorum (OGC).
The arguments we can pass in for layers are dependent on the layer class—we cover layers
in detail in Chapter 3. If you don't want to wait, you can also check out the documentaon
at to see
what arguments dierent layers of classes expect.
Chapter 1
[ 21 ]
Noce we don't include everything on one line when creang our layer object—this
improves readability, making it easier to see what we pass in. The only dierence is that we
are also adding a new line aer the commas which separate arguments, which doesn't aect
the code (but does make it easier to read).
Line [14]: 'WMS Layer Title',
This is the rst parameter passed in; the layer's tle. Most layer classes expect the rst
parameter passed in to be the tle of the layer. This tle can be anything you would like, the
main purpose of it is for human readability—it is displayed in controls such as the layer list.
Line [15]: '',
The URL is the second parameter that the WMS layer class expects to receive. For now, we're
using a publicly available WMS service from OSGeo. We will cover in depth the WMS in
Chapter 3. For now, all you need to know is that this is the base URL, which the layer will be
Line [16]: {layers: 'basic'},
The third parameter is an anonymous object containing the layer properes (similar in
format to the previous opons object on line [12]), and is specic to the WMS layer class.
These are the things that are actually added (more or less) straight into the GET call to the
map server backend when OpenLayers makes requests for the map images.
JavaScript object notation
In OpenLayers, we pass in anonymous objects to classes a lot. In JavaScript, anonymous
objects are comma separated key:value pairs, and are set up in the format of
{key1:value1, key2:value2}. They are, basically, objects that are created without
deriving from a class. This format is also referred to as JavaScript Object Notaon.
When we say key1:value1, it's similar to saying "key1 = value1", but we use a colon
instead of an equals sign. We can also create an anonymous object and pass it in instead of
creang it on the line, for example:
var layer_parameters = {layers: 'basic'};
var wms = new OpenLayers.Layer.WMS('layer_title', 'url',
layer_parameters, …);
With a WMS layer, we need to pass in, at a minimum, a layers key. In this case it has the
value of 'basic'. This layer parameter species layers that exist on the map server. So,
when you ask the WMS server from a map image with the layer 'basic', it sends you back
an image that is composed of that layer. You can also ask for mulple layers from the map
server. In this case, we only want the WMS service to give us back an image that contains a
layer called 'basic'.
Geng Started with OpenLayers
[ 22 ]
Let's get back to the code.
Line [17]: { }
The fourth parameter is an oponal opons object, an anonymous object in the format we
just discussed. These properes are generally shared by every OpenLayers Layer class. For
instance, regardless of the Layer type (e.g., WMS or Google Layer), you can pass in an opacity
seng (e.g., {opacity: .8} for 80 percent opacity). So, regardless of whether you are
working with a WMS or a Vector layer, this opacity property can apply to either layer.
Since this is the last thing passed into the Layer object creaon call, make sure
there is not a leading trailing comma. Trailing commas are a common error and
are oen tedious to debug.
This opons object is oponal, but we will oen use it, so it's a good habit to keep our code
consistent and provide an empty object (by {}), even if we aren't passing anything into it yet.
Line [18]: );
This simply nalizes the object creaon call.
Line [20]: map.addLayer(wms);
Now that we have a wms_layer object created, we need to add it to the map object. Noce
we are calling a funcon of the map object. There are actually a few ways to go about adding
a layer to a map object. We can use the above code (by calling map.addLayer), where we
pass in an individual layer, or we could use map.addLayers:
map.addLayers( [layer1, layer2, ...] );
Here, we pass an array of layers. Both methods are equally valid, but it may be easier to pass
in an array when you have mulple layers.
You can also create the layer objects before you create the map object and pass the layer
objects into the map when you create it, for instance:
map = new OpenLayers.Map('map_element', {layers: [layer1, layer2,
All ways are valid, but we will usually use addLayer or addLayers throughout the book.
Line [21] - [23]:
Chapter 1
[ 23 ]
Finally, we must specify the map's viewable area. Here, the actual code that moves the map
is map.zoomToMaxExtent(), which zooms the map to the map's maximum extent. It is
inside an if statement. This if statement checks to see whether the map already has a
center point.
The reason why we add in this check is because, by default, your map can accept a specially
formaed URL that can contain an extent and layers to turn on/o. This is, in more common
terms, referred to as a permalink. If we did not check to see if a center has already been
set, permalinks would not work.
By default, your map adds an argParser control which will try to pull
informaon from a permalink. We cover this in Chapter 6, but to see it in acon
now you can simply add the following to your URL, which will zoom the map to
the same coordinate and zoom level: ?zoom=4&lat=56&lon=-116
So, your URL might look like c:/code/index.
There are a few ways to set the map's extent. If you know you want to show everything, the
map.zoomToMaxExtent() funcon is a quick and good way to do it. There are other ways
as well, such as
map.zoomToExtent(new OpenLayers.Bounds([minx,miny,maxx,maxy]);
There are even more ways though. If you know a specic locaon you want the map to start
at, this is another way to do it:
map.setCenter(new OpenLayers.LonLat(x,y));
Where x,y are the Lon/Lat values, and 5 is the zoom level you wish to zoom to. By default,
your map will have 16 zoom levels, which can be congured by seng the numZoomLevels
property when creang your map object.
More ways exist, but these are the most common strategies. The basic idea is that you need
to specify a center locaon and zoom level—seng the extent accomplishes this, as does
explicitly seng the center and zoom level.
Line [24]: }
This simply nishes the init() funcon.
Lines [26], [27]:
These lines close the script tag and head tag.
Line [29]: <body onload='init();'>
Geng Started with OpenLayers
[ 24 ]
This starts the body tag. When the page is nished loading, via the onload='init();'
aribute in the body tag, it will call the JavaScript init() funcon. We have to wait unl
the page loads to do this because we cannot use the map div (or any HTML element) unl
the page has been loaded. Another way to do this would be to put the init() call in a
JavaScript tag at the boom of the page (which would not be called unl the page loads), but
both methods accomplish the same thing.
When browsers load a page, they load it from top to boom. To use any DOM (Document
Object Model) elements (any HTML element on your page) in JavaScript, they rst have to
be loaded by the browser. So, you cannot reference HTML with JavaScript before the browser
sees the element. It'd be similar to trying to access a variable that hasn't yet been created.
Even though we have JavaScript code that references the map_element div at the top of
the page, it is not actually executed unl the page is loaded (hence the need for the onload
and init() funcon call).
Line [30] and [31]: <div id='map_element' style='width: 500px; height:
To make an OpenLayers map, we need an HTML element where the map will be displayed in.
Almost always this element will be a div. You can give it whatever ID you would like, and the
ID of this HTML element is passed into the call to create the map object. You can style the div
however you would like—seng the width and height to be 100 percent, for instance, if you
wanted a full page map. It would be best to style the elements using CSS, but styling the div
in line like this works as well.
Lines [32] and [33]: These lines nalize the page by closing the remaining tags.
Behind the scenes—Object Oriented Programming (OOP)
Now, let's talk about how this stu works from a more theorecal and technical level.
OpenLayers employs Object Oriented Programming (OOP) techniques, meaning that to use
with the library, we create objects from built in classes that OpenLayers provides.
What does this mean? You already are familiar with what classes and objects are, but you
just may not know it. Think of the concepts of a class and object in terms of the parts of
speech. For example, think of what the abstract idea of a noun means—a person, place,
thing, or idea. Noun itself (the abstract idea) is a class. But the actual, concrete words that
qualify as a noun are objects.
Chapter 1
[ 25 ]
Interaction happens with objects
Ironman and Batman are two separate words (or, in terms of OOP, two objects), but they
belong to the same noun class. A class is primarily used to generate objects; we interact with
objects. Consider these two sentences:
"Noun was in a ght with noun."
"Ironman was in a ght with Batman."
Now, the second sentence is more of an actual sentence. We use the words Ironman and
Batman in the sentence (which are objects; they are instances of the noun class). We don't
use noun (a class) in the sentence, because interacng with a class like this doesn't make
much sense. This is one of the important concepts of OOP—we interact with objects, and we
generate objects through classes.
Madlibs, for those unfamiliar with it, is a game where you are given text with some missing
words. The point is to come up with words to ll in the blanks, but each blank can only
contain a certain type of word (noun, adjecve, verb, and so on). The type of word is a class
and the actual word you insert is an object.
Time for Action – play MadLibs
Finish this sentence, by replacing verb and noun with verb and noun 'objects':
I verb up to the noun. It's about 7 or 8 o'clock. I looked at my noun. I was there, to verb on
my throne as prince of noun(place).
What Just Happened?
You just did a Madlibs, demonstrang some of the concepts of OOP. As you can see, it
doesn't make much sense to read the sentence as "I verb up to the noun". Since verb and
noun are classes, we don't use the actual term verb or noun in the sentence.
So, the idea would be to generate separate objects, one of the class noun and one of the
class verb. For example, the previous sentence could be completed like: "I pulled up to
the house". Pulled and house are objects that are instances of the verb and noun classes,
We use words that belong to those classes, which are objects. Another term used when
referring to objects is instance, which is used to designate the class the object is derived
from, for example, Frodo (a person / hobbit) is an instance of a noun.
Downloa d f r o m W o w ! e B o o k < w w w.woweb o o k . c o m >
Geng Started with OpenLayers
[ 26 ]
Programming with OOP
The same concept applies to programming. The only thing we can really do with a class is to
create an object from it. Objects are derived from classes—you can interact and do things
with objects, but not with classes. So, in OpenLayers, we need to create objects from the
built in classes to be able to really do anything. The main thing we need are map and layers
objects. If we want to create an OpenLayers map, we need a map object, and we create it in
the following manner:
var map = new OpenLayers.Map( … );
The new declaraon means that we want to create a new object from the OpenLayers.Map
class. The ellipsis (...) in the parenthesis presents things we pass into the class to create
our object, called arguments. Each class expects dierent arguments to be passed into it. It
is similar to the Madlibs example—the noun class accepts only certain words. If we were to
create a word object in JavaScript, the code may look something like this:
var my_word_object = new Noun('Ironman');
Here, we pass in 'Ironman' to the noun class, and now we have our word object. Because
the Noun class only accepts nouns, this would work ne. If we try to pass in a verb, for
instance, it would not work because the noun class cannot accept things that are verbs.
Similarly, the Map class expects dierent arguments to be passed into it than the Layer class
There are also subclasses, which are classes derived from another class and inherit all the
aributes from the 'base' class it inherits from. Subclasses can also override properes and
methods that they inherit.
For instance, let's say we have a Dog class that is a subclass of the Animal class. The Dog class
would inherit all the aributes of the base Animal class—such as, perhaps, a speak method.
Now, the Dog class would override the speak method and it would bark (or 'yap' annoyingly)
when called. The Dog class might also provide addional methods that weren't in the base
Animal class, such as, perhaps, a wag_tail method.
Chapter 1
[ 27 ]
'Base' class and 'Subclasses' are both classes; the terminology just helps to clear
up what class inherits from what other class.
There are many subclasses in OpenLayers, for example, the GoogleMap Layer class is a
subclass of the base Layer class, and the Navigaon control class is a subclass of the base
Control class. Subclasses are sll classes, and the exact same concept applies; we sll need
to generate objects from the class to use it.
The previous secon was just an introducon to OOP. While you don't necessarily need
to know a whole lot more about OOP concepts to use this book, a great resource to learn
more about the concepts can be found at
Classes are easy to spot in OpenLayers code. By convenon, in OpenLayers
(and many other places) class names are CamelCased, which means the
rst leer of each word is capitalized, while objects are not. For example,
MyClass would be an example of a class name, while my_object would be
an example of an object.
Now what?
Our coverage of the sample code was not meant to be extremely thorough; just enough to
give you an idea how it works. We'll be covering OOP concepts in more detail throughout the
chapters, so if anything is bit unclear, don't worry too much.
As OpenLayers is a library and provides funcons for you, it is important to know what those
funcons are and what they do. There are many places to do this, but the best source is the
API docs.
Geng Started with OpenLayers
[ 28 ]
API docs
The API documentaon is always up to date and contains an exhausve descripon of all
the classes in OpenLayers. It is usually the best rst place to go when you have a queson.
You can access the documentaon at
OpenLayers-js.html. It is connually updated and contains a wealth of informaon. We
will constantly refer to it throughout the book, so keep the link handy! Somemes, however,
the API docs may not seem clear enough, but there are plenty of other resources out there
to help you.
Where to go for help
Books are great, but they're basically just a one way form of communicaon. If you have any
quesons that the book does not answer, Google is the best rst place to go. Mailing lists
and IRC are other great resources. Somemes it's hard to formulate the right queson, but
there is help!
This book's website
The extension website for this book can be found at
book. Current, up to date correcons and code xes, along with more advanced tutorials
and explanaons, can be found there—and also on my blog at
You can also grab the code and more informaon about this book at Packt Publishing's
website for the book, located at
Mailing lists
The OpenLayers mailing list is an invaluable resource that lets you not only post quesons,
but also browse quesons others have asked (and answered). There are two main
OpenLayers news groups—Users and Dev. The Users list is where the majority of quesons
are asked. Dev is reserved for development of the OpenLayers library itself. If you have
quesons about how to use OpenLayers, they belong in the Users list, not the Dev list. You
can subscribe to the mailing list at
There are various ways to browse the content, and I prefer to use Nabble. You can view the
lists at
Chapter 1
[ 29 ]
Please do a thorough search before posng quesons, as it is likely that a
queson similar to yours has already been asked and solved. If you have a
queson about using OpenLayers, please use the User list. Please do not post
quesons to the Dev list, unless it has to do strictly with development of the
OpenLayers library itself.
When posng a queson, please be as thorough as possible, stang your problem, what you
have done, and the relevant source code (e.g. "I have a problem with using a WMS layer. I
have tried this and that, and here is what my source code looks like..."). A good guideline
for asking quesons in a way that will best elicit a response can be found at http://www.
Internet Relay Chat (IRC) is another great place to go if you have quesons about
OpenLayers. IRC is used for group communicaon; a big chat room, essenally. If you have
exhausted Google and the mailing list, IRC provides you with real me with other people
interested in OpenLayers.
Generally, the people who hang out in the OpenLayers chat room are very friendly, but
please try to nd an answer before asking in IRC. The server is and
the chat room is #openlayers. You can download an IRC client online; a good Windows
one is mIRC ( More informaon about how to use IRC can be found at
OpenLayers source code repository
Tradionally, OpenLayers has used SVN as its revision management system. At the me of
wring, however, the source code repository locaon is hosted at GitHub. You can access the
enre code repository at
Feel free to download a copy and play around with it yourself. There is a process to actually
get your code permanently added to the ocial source code base, but it cannot hurt to
download a copy of the code base and look around it yourself to gure out how it's really
Geng Started with OpenLayers
[ 30 ]
In this chapter we were introduced to OpenLayers and learned a bit about it.
We saw what Web Map Applicaons are and how they work. Aer that, we created our rst
map with OpenLayers, then analyzed how the code works. Then we covered a fundamental
concept, Object Oriented Programming, which we'll need to know about while really working
with OpenLayers. Lastly, resources for help and informaon outside this book were provided.
Now that we have a basic handle on OpenLayers, we'll jump straight into debugging
OpenLayers. By doing so, we'll cover more thoroughly many of the concepts that we've
discussed, such as how OpenLayers requests and receives map images, and how it puts
them together.
Squashing Bugs With Firebug
OpenLayers is, at a fundamental level, not doing anything that is conceptually
too hard to grasp. It gets map images from a server, and puts them together.
From a technical level, however, there is a lot of work going on, and it might
seem magical how it all works together so well.
Fortunately, there are many tools to dispel any potenal magical thinking
we might have and show us how OpenLayers is working behind the scenes.
Firebug, a free and open source plugin for Firefox, is one such great tool.
Speeding up development me, viewing network communicaon, and
squashing bugs are just a few things that Firebug, and other web development
tools, do that make them hard to live without.
To really use OpenLayers eecvely and to its full potenal, we need to
understand how it works. In this chapter, we'll try our best to do just that, by
using web development tools to examine OpenLayers' inner workings. By doing
so, we'll accomplish two things. First, we'll become familiar with these tools
which will signicantly help us when developing our maps. Secondly, and more
importantly for now, we'll gain a beer understanding of how OpenLayers
Throughout this chapter we'll cover:
What Firebug and other development tools are
Seng up Firebug
Each of the Firebug Panels
Using the JavaScript Command Line Console panel
Squashing Bugs With Firebug
[ 32 ]
What is Firebug?
Firebug is a free, open source addon for Firefox. If you do not have Firefox, I recommend
downloading it (it is also free and open source). However, other modern and standards
based browsers, such as Google's Chrome, Apple's Safari, and Opera, also work well and
have great built in developer tools.
Firebug, and other web development tools, makes the web development process much
easier and quicker. What do I mean by this? With these tools, we can change anything on
our site, on the y, without eding or saving any les. We can type in JavaScript code with
a command line interface and execute it immediately. We can view all the requests that our
web page sends to servers, along with the server's reply. For example, if our map isn't able to
get back map images from the server, we could examine the requests our page is making and
nd out if we have any typos or haven't set up our map layer properly.
Using these tools makes it a lot easier to develop not only an OpenLayers mapping
applicaon, but any web applicaon, and makes it easier to x any bugs we encounter in the
process. We'll focus on Firebug in this chapter and refer back to it throughout the book, but
other tools such as Google's Chrome and Apple's Safari's built in developer tools work just as
well (although some funconality may vary).
Setting up Firebug
Since Firebug is an extension of Firefox, you'll need to rst install Firefox. You can download
it for free at Aer that, Firebug can be freely downloaded at When you click on the link to download Firebug, Firefox will
prompt you with a message asking if you wish to install the plugin. Aer installing, all you
have to do is restart Firefox and you'll be good to go.
Time for Action – downloading Firebug
If you do not already have an up to date version of Firefox installed, please do so now. Aer
you have installed Firefox, set up Firebug by following these steps:
1. Go to
2. Click on the Install Firebug for Firefox buon. Once you click this, you should see a
message similar to this:
Chapter 2
[ 33 ]
3. Click Install, wait for it to nish installing, and then restart Firefox.
4. Now that Firebug is installed, you should see a Firebug icon on the boom
right side of your screen.
What Just Happened?
When Firebug is not enabled, the Firebug Icon is gray. When it is in enabled, it has an orange
color—this is just a quick way for you to tell if Firebug is enabled or not for the current page
you're on.
Squashing Bugs With Firebug
[ 34 ]
When you click on the Firebug icon (near the boom right of your browser's window),
Firebug will open and you can start using it. But before we start, let's take a look at what
Firebug looks like aer inially installing it and clicking on the Firebug icon:
The top row contains two icons (a Firebug icon and a Page Inspector icon), mulple panels
that provide specic funconality (they look and act similar to tabs, but the technical term is
"panels"), a search box, and nally minimize, maximize, and close the buons. Let's go over
the items, le to right, one at a me.
The posion of the icons may change over me as Firebug is updated; but the
general funconality should remain (more or less) the same.
Firebug controls
Firebug icon: The Firebug icon on the top le contains various commands and opons
related to Firebug when you click on it.
Page Inspector icon: This icon, a cursor inside a rectangle, is the HTML Inspector. When
you click on it, your mouse cursor will idenfy HTML elements on the web page. So, when
you mouse over anything on a website, the element will be outlined in blue and the HTML
panel will open up and show you the element your mouse is over.
The next set of controls is called panels; each panel provides a dierent type of funcon. The
panels act like tabs (the two terms can be used interchangeably), but Firebug refers to them
as 'panels' in the documentaon. Let's go over each panel, since they are, essenally, what
makes up Firebug.
Chapter 2
[ 35 ]
Console panel
Firebug's Console panel is where we'll spend most of our me. It acts as a powerful
JavaScript command line, or interpreter, which means we can type in JavaScript code
and execute it right away—no need to save or edit any les.
One thing that makes this so useful is that we can interact directly with the DOM (Document
Object Model—any HTML element on the webpage), including any exisng JavaScript code
the page contains. So, this means we're able to interact with our OpenLayers map on the y,
issuing command and tesng code to instantly see what works and what doesn't. As you can
imagine, this saves a ton of me!
By default, the Console panel is disabled. To enable it, click on the arrow near the Console
text and select Enabled.
HTML panel
The HTML panel provides not just a display of the HTML source code, but also the ability
to quickly edit any HTML element and its associated style. You can add and remove HTML
elements, edit HTML aributes, and change nearly anything about the page without having
to save any les. It's great for development.
Squashing Bugs With Firebug
[ 36 ]
How it works
Firebug automacally builds a tree structure from your HTML code, allowing you to expand
and hide each HTML tag. It is important to note that the code you see in the HTML panel
is generated HTML code—the code in the panel may not be exactly the same as the page's
source code.
HTML panel contents
Here is what the HTML tab looks like when Firebug is opened while viewing a webpage:
On the le side, Firebug shows us the HTML of the page. We can right click on any tag and do
various things—such as copying the HTML to the clipboard, deleng the element, changing
the tag aributes, and more.
On the right side, we see the associated style informaon for the element we have selected.
Here, we can modify or add properes and they will instantly appear on the page. In this
example we selected a div element with a class of 'left_sidebar_item'. Looking at the
CSS on the right side, there is no denion for the 'left_sidebar_item' class (if there
was, we would see something called .left_sidebar_item, with a period in front of it
to indicate that it is indeed a class). We do, however, see a denion for #left_sidebar,
which is a parent div of the currently selected div.
If you are unfamiliar with HTML or CSS, the w3schools site is a great resource.
For more informaon on HTML, visit
html/default.asp and for CSS visit
What does this mean? Well, Firebug lists all inherited style informaon, and parent element
styles propagate down to all their child elements (each child has all its parent's styles, unless
the child overrides a style, which doesn't happen in this example). That's why we also see
the body, html denion, and every div will display that, since every div sits inside the
<html> and <body> tags of the web page.
Chapter 2
[ 37 ]
By double clicking on prey much anything in the HTML or CSS list you can quickly change
values and names. Any change you make will immediately show up on the page, which
makes it very easy to change style in real me and see how the page is aected without
having to edit and save any les. Play around with it a bit—if you mess anything up, you can
just reload the page.
When eding pages with Firebug, any changes you make will disappear when
you refresh the page. You are not eding the actual web server's les with
Firebug—instead, you are eding a copy that is on your computer that only you
can see when you make changes to it. So, if you make any changes and want
them to be saved, you'll have to edit your actual source code.
CSS panel
This panel provides similar funconality as the CSS sidebar in the HTML panel we just talked
about. It also provides the opon to edit any CSS document associated with the page, not
just the style of a selected element. We need not talk much about this panel, and for the
purposes of this book we won't spend much me here. But if you are a web designer, this is
another powerful panel that can greatly speed up your development me.
Script panel
The Script panel is very powerful. Not only does it allow you to view all the JavaScript
code associated with the page, it is a great real-me code debugger. You can set watch
expressions, view the stack, set breakpoints, etc. If those terms are foreign, don't worry,
we won't be spending much me with this panel.
However, before we move on to the next panel I want to quickly talk about enabling
breaking on errors. With this opon enabled, Firebug will stop the web page whenever a
JavaScript error is encountered. This makes it very easy to quickly pinpoint where your page
is blowing up at. To enable it, simply click on the pause-buon icon.
Squashing Bugs With Firebug
[ 38 ]
Keep note of when you enable it—I've been frustrated more than once when developing
because I forgot that it had been enabled. When it is enabled, the Script text will glow
yellow, as demonstrated in the above screenshot. You can also enable/disable it through
the Console panel.
Unfortunately (depending on your viewpoint), we can't go much more in depth with these
tools, as it is outside the scope of this book. But please feel free to play around with them,
as Firebug's powerful debugger is a great resource. More informaon on it can be found at
DOM panel
The next panel is the Document Object Model panel, or DOM panel. The DOM is, basically,
a representaon of HTML elements as objects. The DOM panel automacally sets up a
tree structure to represent our HTML page, allowing us to view everything our HTML page
contains. We can also see JavaScript variables and their values, as well as funcons, objects,
and more. When using the DOM panel, aributes and properes are colored black, and
funcons and methods are colored green.
We won't go much more in depth here, but the DOM panel is a very valuable tool, especially
when you want to take a peek at JavaScript components. By using the DOM panel (and
assuming we are looking at a page that includes OpenLayers), we can quickly see all of
OpenLayer's classes, funcons, etc. It is not a replacement for the API docs, but serves as a
good, quick way to view such informaon.
Net panel
Firebug's Net panel is a tool we will oen use throughout this book. Basically, it provides a
way for us to monitor network acvity by viewing all the requests and responses the web
page is making. We can see any Asynchronous JavaScript (AJAX) request the page makes.
Without AJAX, we would have to refresh our enre page anyme we wanted to do anything
with our OpenLayers map. So, for example, every me you zoom in, OpenLayers makes a
series of requests to the map server to get new map images, and the map server's response
is a new map image that OpenLayers then displays. This request/response method is handled
via AJAX—without it, we would have to refresh the enre page aer every request.
AJAX is a method by which, through JavaScript, you can send a request
to a server and receive a response without actually refreshing the page.
Tradionally, if you want your web page to get an update from the server,
you would need to have the page itself send a request.
Chapter 2
[ 39 ]
The Net panel allows us to see the URL that is being requested, the GET or POST parameters,
the server's response, the size of the response in KB, and the me it took to complete the
request. You may also have to enable the Net panel—it can be enabled in a similar way we
enabled the Console panel, by clicking on the arrow next to the Net text on the top tab. Let's
take a look at what the Net panel looks like for the example from Chapter 1:
Before we talk about the requests being made, take a look at the toolbar above the lists of
requests—the one that contains the links Clear, Persist, All, HTML, etc. Clicking on Clear will
do what its name implies—clears out the list of requests. Clicking on Persist will cause the
list of requests to persist, or not get deleted, on page reloads.
The next grouping of links allows us to lter the requests by type. Because we are geng
back only images from the map server in this case, all the requests you see would belong to
the Images opon. If the CSS opon was clicked, we would not see those requests, as they
are not CSS les.
Now, let's break down the actual request list.
Request list
The request list shows us all the requests the page makes. Each URL in the previous
screenshot is a URL that OpenLayers is making a request to. By clicking on the + (plus) sign
next to each request, we can get more informaon about the request, including the full
request URL and the response. When we click on the plus sign, we get a box with Params,
Headers, Response, and Cache tabs. The Params tab lists all the parameters, or key/value
pairs the URL contains. The Response tab provides us with the server's response to our
request. For the purpose of this book, we do not need to worry about the other two tabs.
Squashing Bugs With Firebug
[ 40 ]
Take a look again at the list—before we mouse over the text in the screenshot, the tles
contain GET vmap0?LAYERS. The GET species that the request type is GET, which basically
means we are embedding variables inside the URL itself with key=value pairs, separated
by a & sign.
When we mouse over a URL, we can see more of it—as in the previous screenshot, we
see a bunch of variables in the format key=value&key=value& . . .. These values
correspond to the values listed in the Params tab when you expand the URL.
If you take a look at the link we have our mouse over, you'll noce that the URL is the same
as the URL from the example in Chapter 1,
However, there is an addional text aer vmap0; a queson mark followed by key=value
pairs. The queson mark signies the start of the key=value pairs in a GET request.
Let's take a look at some of the variables the URL contains.
?LAYERS=basic&SERVICE=wms . . .
The LAYERS key should look familiar, as we specied in Chapter 1. In that example,
we used the code:
{layers: 'basic'},
When we dened the key:value pair, we were essenally telling OpenLayers what to pass
into the actual URL it generates. From the generated URL, we can see that it did indeed pass
over the right layer name. Now, as we discussed earlier, this layer name, basic, is the layer
we want from the WMS service. The layer name we pass in here aects what image the WMS
server responds with. In this case, we'll get back an image with the layer named basic.
Noce that there are many more parameters (separated by & signs) than what we passed in.
OpenLayers automacally adds these parameters for you, so we get back the right image of a
map without us having to manually build each URL.
To see the enre key:value pairs, or parameters, expand the URL and look at the
Params tab.
Note that these GET variables, such as LAYERS and SERVICE are specic to WMS.
Other layer types will use dierent values.
Downloa d f r o m W o w ! e B o o k < w w w.woweb o o k . c o m >
Chapter 2
[ 41 ]
BBOX parameter
One of the important variables to take a look at in the URL is the BBOX, or Bounding Box,
parameter. Expand one of the URLs by clicking on the plus sign next to it and take a look in
the Params tab. This BBOX number is the extent of that individual map image piece. You'll
see a number in the following format:
minx, miny, maxx, maxy
These four numbers form a rectangle that contains the extent of the map image. A number
example might be something like -73.5, 39.3, -67.5, 45. These numbers will depend
on the projecon your map is in—but don't worry too much about that for now.
If you look at the BBOX parameter of other URLs, you'll noce that part (or all) of the
BBOX values change for each request. URLs that are grouped together in the request
list share some values for their BBOX parameter. It is analogous to a grid; each request
returns an individual cell of the grid. (This funconality is not the same for all Layer types in
OpenLayers, but this basic concept holds for the majority of Layer types, including the WMS
layer in this example.)
Pop Quiz– panel
1. What panel would you use if you wanted to execute JavaScript code?
a. The Net panel
b. The Console panel
c. The DOM panel
d. The HTML panel
Panel conclusion
Each panel serves a certain purpose and all of Firebug's panels are extremely useful, but
throughout the book we will be mainly focusing on the following panels:
Console panel (Command Line JavaScript)
HTML panel
Net panel
These three panels will be used the most throughout the book. We'll occasionally come back
to the other panels, but we won't spend a whole lot of me with them. However, before
we conclude this chapter, let's get a bit more familiar with the Console panel, since we'll be
making heavy use of it in the coming chapters.
Squashing Bugs With Firebug
[ 42 ]
Using the Console panel
We talked a bit about what the console panel is—essenally, a JavaScript command line. We
can execute any JavaScript code we want, and interact with any page element. There are two
primary components to the Console panel—the console log area and the input area.
The console log area will display informaon about any errors, along with displaying any
code that is entered. The input area allows us to either enter a single line of code or, by
clicking on the red arrow on the right side of the input box, mulple lines of code.
Before we start using the console with our maps, let's get familiar with the console by
execung some JavaScript code.
Time for Action – executing code in the Console
We're going to do some basic JavaScript coding via the Firebug console; specically, just
calling a built in alert() funcon to display an alert.
1. Open up Firefox. It doesn't maer at this point what website (if any) that you go to,
since we will be wring a stand alone code.
2. Open up Firebug by clicking on the Firebug icon. Go to the Console panel. If it is not
enabled, enable it.
3. Now, at the boom of your screen you'll see an area where you can enter code,
designated by >>>. Clicking anywhere aer that will allow you to enter the code.
4. Type in the following code, and then hit Enter.
alert('Narwhals like bacon');
5. You should see an alert box pop up with the text Narhwals like bacon (or
whatever string you passed into the alert funcon). Aer the code is executed,
it will appear in the log above the input line.
Chapter 2
[ 43 ]
What Just Happened?
We just executed some JavaScript code without having to edit and save any les. Although
we did a simple alert, we are really not limited by what we can do. Anything that we could
save in a JavaScript le, we could enter in the Console.
You'll also noce that the same code that we typed in appeared in the log area. We'll also get
an error message if any errors occur with the code—go ahead and try it! Instead of typing
alert('My alert'); type something like fakealert('Boom');. This will give you a
reference error, since nowhere is the funcon fakealert() dened—alert(), on the
other hand, is a built in funcon, so we can call it from any page.
That's prey much to it! The rest just builds on those principles. Let's go ahead and do just
one more thing, something only slightly more involved, before jumping into manipulang an
OpenLayers page.
Time for Action – creating object literals
We're going to introduce object literals and get acclimated with how to manipulate them
now, so we can beer work with OpenLayers code.
1. Open up Firefox and Firebug's Console panel (enabling it if it disabled)—again, it
doesn't maer right now what page you're on.
2. Click on the red arrow on the boom right, above the Firebug icon. This will open
up a side panel where we can type in mulple lines of code. The code will not be
executed when we press Enter, like in single line mode. Instead, we can execute the
code by either pressing Ctrl + Enter or clicking Run.
3. Type in the following code, and then execute it by pressing Ctrl+Enter or clicking
var my_parameters = {'answer': 42, 'question': null};
4. The above code should display, in the console log area, something similar to
Object { answer=42 }. Click on it, and the DOM panel will open, showing you
all the informaon about the object you just created.
5. Click on the Console panel to get back to it. In the input box, add the following code
to the exisng code and execute it:
Squashing Bugs With Firebug
[ 44 ]
6. You should see a line of output in the console area containing the number 42.
What Just Happened?
We just created what is called in JavaScript an anonymous object, or object literal. Now, we
have discussed how objects are created from classes, and in JavaScript we need to use the
new keyword to instanate an object from a class. But there is no new keyword here!
Object literals
The key concept here is that we are just creang a single object that does not derive from a
class. Since object literals (anonymous objects) do not derive from a class, it is, essenally, an
empty object. It contains only what we explicitly dene. The value associated with a key can
be almost anything—a string, integer, funcon, array, or even another object literal.
We encountered object literals in Chapter 1 when we discussed JavaScript Object
Notaon—they were the {key:value} pairs used to dene the parameters and opons
of our layer and objects. The only dierence is that we did not assign a variable to them;
we simply passed them in when we created our layer object.
Object literals are extremely useful for a variety of tasks, and it is a great way to package
informaon in an easy to use form. They are in the form of {key:value, key2:value2}.
We can access any property of an object literal by using dot notaon, in the form of my_
object_literal.key. The key, like before, is the key part of the key:value pair. In the
above code, we call console.log(my_parameters.answer); and the value of the key
answer is displayed in the console's log area.
Chapter 2
[ 45 ]
console.log(): The Firebug funcon console.log() is a funcon that will,
essenally, display what you pass into it in the console log. You can pass in
variables, strings, objects; anything, and it will display in the log. It comes in
handy oen, so geng familiar with it is a good idea.
We will use object literals frequently when making our maps—so if they don't make much
sense yet, don't worry. The basic idea to grasp, and the primary way we will use them, is
that they are essenally key:value pairs. Before we end this chapter, let's do one quicker
example where we interact with an OpenLayers map using the Console panel.
Time for Action – interacting with a map
We'll use the map we created in Chapter 1 to do this example, interacng with our
OpenLayers map by calling various funcons of the map.
1. Open up the map from Chapter 1 in Firefox. Enable Firebug and the Console panel. If
you would like, you can take a look at the Net panel and view the network acvity to
see the requests your page is making.
2. Go to the Console panel, input and then execute the following code:
3. You should see the map object informaon come up in the console log. Click on
it, and take a moment to look over the various aributes it has. Near the boom,
you can see a list of all the funcons that belong to it (which are also referred to as
Take note of the funcon names, as we'll be using them.
4. Go back to the Console panel, type in and execute the following code:
5. Take note of the extent. Clear out the code you typed in, then type in the following
and execute it:
Squashing Bugs With Firebug
[ 46 ]
6. Now, let's take a look at some properes of the map object. We can access the map
properes using the dot notation, which we discussed previously. Clear any code
you've typed so far, input and execute the following code:
7. Refer back to the funcons of the map object (by running console.log(map);
then clicking on the output in the log area). Try playing around with dierent
funcons and aributes the map object has. To access the funcons, you just need
to type in map.function();.
You can also access the properes of the map by typing map.key, where key would
be something like id (so the full code would be The aributes are black in
the DOM panel, and the funcons are colored green.
Chapter 2
[ 47 ]
What Just Happened?
We just executed some funcons of our map and accessed some properes of it. All we
have to do is call our object, map, followed by a period, then a funcon or property it owns.
Using this dot notaon (e.g., map.zoomIn();), we can access any property or funcon of
the map object.
We also saw how the DOM panel comes in handy, and took a look at funcons that we
can call, which the map object owns. Any funcon listed there can be called via map.
functionname();, but some funcons require parameters to be passed in or they will not
work. But where can we go to gure out more informaon about the funcons and what
they require?
Have a Go Hero – experiment with functions
Try to call dierent funcons that you see listed in the DOM tab. Many funcons will not
work unless you pass certain arguments into them, but don't be afraid of errors! Poke
around the various funcons and properes and try to interact with them using the Console
tab like in the example above.
API documentation
The API documentaon for the Map class, which our map object derives from (and thus,
inherits all the funcons and properes of the class) provides more detailed explanaons
of the properes, funcons, and what we can do with them. They can be found at http:// Even though Firebug is a great resource to quickly
interact with code and learn from it, the API docs present an extra level of informaon that
Firebug cannot necessarily provide.
In this chapter, we learned more about how OpenLayers works. We learned how to set up
and use Firebug and other Web Development tools.
We then took a look at the panels that Firebug provides and what they are used for. Finally,
we spent me with the Console panel—something you'll be making extensive use of
throughout this book (and when you're developing your own web maps).
This chapter aimed to provide some foundaonal knowledge of web development tools for
geng into both OpenLayers and general web development. Web development tools, like
Firebug, are one of the biggest assets in our toolkit. They speed up development me, help
us idenfy bugs, interact with our code beer, and much more.
Squashing Bugs With Firebug
[ 48 ]
Firebug and such tools can also degrade performance if you are just browsing
the web, so it is probably best to leave them disabled unless you're using them.
For the code exercises in the following chapters, it will be very benecial if you use Firebug to
rst test the code, to see what it's doing. That way, you immediately know, so to say, where
each piece of the puzzle ts in; you know what each line of code actually does, and how it
aects the enre project.
In the next chapter, we'll really dive into OpenLayers, covering perhaps the most
fundamental topic in OpenLayers: the Layer class.
The 'Layers' in OpenLayers
Maps can contain an overwhelming amount of informaon, but some maps
don't show enough. Figuring out just what informaon to display on a map is
certainly an art form, and creang printed maps with just the right balance of
informaon is quite dicult.
Fortunately, creang maps for the web is slightly easier in this respect, because
we can let the user determine what informaon they want to see. Imagine
two people looking at a city map—one person just cares about the bus routes,
while the other wants to only know about bicycle routes. Instead of creang
two maps, we could create a single map with two dierent layers, one for
each route. Then the user can decide if they want to see the bus routes, bicycle
routes, both, or none at all.
OpenLayers provides us with a variety of layer types to choose from and use.
We can do all sorts of things—such as changing layer opacity, turning the layers
on or o, changing the layer order, and much more.
In this chapter we'll go over what Layers are—both in the abstract and concrete sense
(via OpenLayer's Layer class). By the end, you will possess enough experse to use
dierent types of Layers on your map and interact with them. In this chapter, we will:
Learn what layers are
Show the dierence between base layers and overlay layers
Talk about the WMS layer class
Learn about the layer class properes
Cover other types of layers
Discuss layer class funcons
The 'Layers' in OpenLayers
[ 50 ]
What's a layer?
A layer is basically a way to show mulple levels of informaon independent of each other.
Layers are not just a mapping or cartography concept; graphic designers and digital arsts
make heavy use of layers.
Imagine a printed-out map of a city. Let's say you also have two sheets of transparent paper.
One sheet has blue lines that indicate bus routes, and the other sheet contains green lines
that indicate bicycle routes. Now, if you placed the transparent sheet of paper with bicycle
routes on top of the map, you would see a map of the city with the bicycle routes outlined.
Pung on or taking o these transparent pieces of paper would be equivalent to turning
a layer on or o. The order you place the sheets on top of each other also aects what the
map will look like—if two lines intersect, you would either see the green line on top or the
blue line on top. That's the basic concept of a layer.
Layers in OpenLayers
OpenLayers is a JavaScript framework, and as discussed earlier is built using Object Oriented
Programming. When we want to actually create a layer, we create (or instanate) an object
from an OpenLayers Layer class.
OpenLayers has many dierent Layer classes, each allowing you to connect to a dierent
type of map server 'back end.' For example, if you wanted to connect to a WMS map server,
you would use the Layer.WMS class, and if you wanted to use Google Maps you'd use the
Layer.Google class. Each layer object is independent of other layer objects, so doing
things to one layer won't necessarily aect the other.
How many layers can I have?
The safest maximum amount of layers you can have on a map at one me
depends largely on the user's machine (i.e., their processing power and
memory). Too many layers can also overwhelm users; many popular web
maps (e.g., Google and Yahoo!) contain just a few layers. If you need to
use tons of layers (say, more than y), it might be a beer idea to create/
destroy them as necessary, as having too many layers may slow down your
map on some machines.
Whatever the purpose of your web map applicaon is, you will need at least one layer to
have a usable map. An OpenLayers map without any layers would be sort of like an atlas
without any maps. You need at least one layer—at least one Base layer. All other layers
that 'sit above' the base layer are called Overlay layers. These are the two 'types' of layers
in OpenLayers.
Chapter 3
[ 51 ]
Base layer
A base layer is at the very boom of the layer list, and all other layers are on top of it. This
would be our printed out map from the earlier example. The order of the other layers can
change, but the base layer is always below the overlay layers. By default, the rst layer that
you add to your map acts as the base layer. You can, however, change the property of any
layer on your map to act as the base layer (by seng the isBaseLayer property to True).
You may also have mulple base layers. However, only one base layer can be acve at a me.
When one base layer is turned on, all the other base layers are turned o. Overlay layers (non
base layers), however, do not behave this way—turning on or o overlay layers will not aect
other overlay layers. Base layers are similar to radio buons—only one can be acve at a me.
Overlay layers are similar to check boxes—you can have as many on or o as you'd like.
At the me of wring, there was a discussion to remove the 'base layer'
terminology and replace it with 'mutually exclusive layers.' If this is the case
when you are reading this, the ideas and concepts work the same as the base
layer/overlay concept.
Overlay layers
Any layer that is not a base layer is called an overlay layer. Like we talked about, the order
that you add layers to your map is important. Every me you add a layer to the map, it is
placed above the previous one.
Throughout the rest of this book, we'll be using the map we created in Chapter
1's example as a sort of template. The only thing that will change is that you will
not be using the lines of code that create the WMS layer and add it to the map.
You will need to delete those lines of code yourself, or refer to the template from
the book's website at
Time for Action – creating a map with multiple layers
Let's create a map with two WMS layers. One layer will act as our base layer, and the other
will be an overlay layer containing labels for country, state, and city names.
1. Create a copy of the le you made for the last example of Chapter 1 and remove
the exisng WMS layer code (or, use the template from
openlayers_book/). You can name it whatever you'd like, but we'll refer to it as
chapter3_ex1_wms_layers.html. Make sure it is in the same directory as your
OpenLayers.js le.
The 'Layers' in OpenLayers
[ 52 ]
1. First we're going to remove everything that was in the init() funcon. Your
funcon should now look like this:
function init() {
2. Next, inside the init() funcon, we're going to setup our map object like before:
map = new OpenLayers.Map('map_element', {});
3. Now we're going to create our rst layer. We'll use a WMS layer and ask the WMS
server for the layer 'basic' (a layer on the WMS service). We'll also explicitly set it
to be a base layer.
var wms_layer_map = new OpenLayers.Layer.WMS(
'Base layer',
{layers: 'basic'},
{isBaseLayer: true}
4. Let's create a second layer object now. It will also be a WMS layer. This me, we're
going to ask for a few dierent layers from the WMS service—a bunch of labels.
We're also going to set the transparent property to true, so the map images
which the server sends back will be transparent. We'll also set the opacity to be 50
percent (by seng the opacity to .5). This layer will be an overlay layer.
var wms_layer_labels = new OpenLayers.Layer.WMS(
'Location Labels',
{layers: 'clabel,ctylabel,statelabel',
transparent: true},
{opacity: .5}
5. Time to add the layers to the map. We'll use the addLayers funcon and pass in an
array of layer objects.
map.addLayers([wms_layer_map, wms_layer_labels]);
6. Now, let's add a Layer Switcher control that will show us the layers on the map.
map.addControl(new OpenLayers.Control.LayerSwitcher({}));
Chapter 3
[ 53 ]
7. Finally, we need to set the map center informaon. This last step needs to be
repeated for all further examples throughout the book—you need to be sure to
include it even if it isn't explicitly asked for. All our maps will need to have their
extent set somehow, and this is one standard way to do so (refer to Chapter 1 for
more explanaon).
8. Save the le, and then open it up in your web browser (preferably Firefox, since we'll
be using Firebug). Because we're just working with HTML and JavaScript, you don't
need to place this on a server or anything. You can simply open the le with your
web browser directly from the folder. You should see something like this:
What Just Happened?
We just created a map with two WMS layers and a Layer Switcher Control that allows us
to turn on and o layers. Controls are what OpenLayers provides that allows us to actually
interact with the map and layers. To use controls, we create objects from dierent Control
classes. By default, all maps get a Navigaon control object which allows us to pan and zoom
the map. In Chapter 6, we'll cover controls in depth.
The 'Layers' in OpenLayers
[ 54 ]
In the previous example, our layer objects were called wms_base_layer
and wms_overlay_layer. Throughout this book, this will be the format I
will use to name objects—all lowercase with underscores (_), no spaces. You
can, of course, use whichever convenon you like, as long as your naming
scheme is consistent.
Creating layer objects
The process to work with layers consists of two steps:
1. Create the layer object.
2. Add the layer object to the map. You can use either map.addLayer(layer)
to add an individual layer, or map.addLayers([layer1, layer2, ...])
to add an array of layers, like in the previous example.
These two steps can actually be combined into one step (by instanang the layer object
when calling the addLayer funcon—this works, but I don't recommend it as it makes it a
lile harder to work with the layer object). By now, we have a bit of experience instanang
objects from the WMS Layer class. Let's take a look at the code that creates our wms_base
layer object.
var wms_layer_map = new OpenLayers.Layer.WMS(
'Base layer',
{layers: 'basic'},
{isBaseLayer: true}
Each item inside the parentheses, aer OpenLayers.Layer.WMS(, are called arguments
which we pass in while creang the object. But how did I know what arguments to pass in?
We didn't write the class, so we don't know what it expects to take in. So, as with nearly any
third party library, we have to refer to the documentaon to see what arguments the class
expects. OpenLayers has great documentaon, and we'll be using it throughout the book.
Since we're using a WMS Layer, let's take a look at the documentaon for the WMS class at
Chapter 3
[ 55 ]
Layer.WMS class
There's a lot of informaon in the API docs, but let's look specically at the secon
tled Constructor. This will tell us how to create a WMS layer object. The process varies
for dierent types of layer but let's focus on the WMS class for now. Take a look at the
Parameters sub secon—this species what arguments this specic class expects to take in:
Parameters Descripon
name {String} A name for the layer.
url {String} Base url for the WMS (e.g.
params {Object} An object with key/value pairs represenng the GetMap query string
parameters and parameter values.
opons {Object} Hashtable of extra opons to tag onto the layer.
The parameters tell us about the order of arguments to pass in, and what each argument
means. The word in between the curly brackets ({ }) refers to the data type of parameter.
So, {string} means the parameter should be a string.
Let's take a look at the wms_base_layer layer instanaon code and see how we use the
four parameters.
WMS layer parameters:
The four WMS layer parameters are as follows:
The rst parameter is the layer's name and it should be a string. We pass in 'Base Layer'.
Noce how we enclose Base Layer in quotes—this is how we signify that it is a string. The
tle can be anything that you like—if you have a layer switcher control, the tle will show
up in it. Keep in mind that there is a comma aer the closing quote, which means that we're
done with this rst argument and are ready to proceed to the next one.
This name parameter is present in nearly all Layer classes.
The URL is the second parameter, and it should also be a string. It species the URL of the
web map server. We pass in ''. This URL
parameter is present in most Layer classes.
The 'Layers' in OpenLayers
[ 56 ]
Params is the third parameter, and it is an anonymous objector consisng of key:value pairs.
This parameter species server side sengs that aect the map image, which the WMS
server returns. The key:value pairs you pass in here will be appended (more or less) to the
URL that OpenLayers generates when it makes requests to the map server.
For example, in the previous example when creang the wms_layer_labels we
passed in {layers: 'clabel,ctylabel,statelabel'}. In this case, we are
asking the WMS server to give us back a map image with the server side layers called
'clabel,ctylabel,statelabel' turned on. We specify mulple server side layers—it
doesn't maer what or how many server side layers we request though, because the WMS
Layer object on the client side is sll considered by OpenLayers to be a single layer object.
This params parameter is present in most Layer classes.
Possible params keys and values
The possible keys and values for this params object depend on the map server you are
working with. Unfortunately, covering them all for all layer types is outside the scope of this
book. We'll only be using a few WMS parameters throughout this book—layers (to specify
what layers the WMS service should give us), transparent (to ask for transparent images,
for things such as label layers), and srs (to specify the projecon).
For now, at least, our main concerns are just guring out what layer names are on the
WMS server. To gure this out, you can issue a GETCAPABILITIES request in the URL
(SERVICE=WMS must also be specied). For instance, to get the possible layers from the
WMS service we've been using so far go to the following URL:
If you are interested in more informaon about WMS, the specicaons can be found at
Opons is the last parameter and is an anonymous object that species the layer object's
sengs. You are not required to pass in this parameter.
The opons object contains properes for the client side OpenLayers Layer object. These
are the sengs for the layer object itself, so all Layer classes have this parameter. To
dene various properes of the OpenLayers Layer object, we use this options argument.
Properes include sengs such as isBaseLayer, opacity, and visibility. Since the
layer properes are client side sengs, the WMS server (or whichever map server the layer
uses) doesn't know about them.
Downloa d f r o m W o w ! e B o o k < w w w.woweb o o k . c o m >
Chapter 3
[ 57 ]
The possible values are, basically, anything that you nd in the API documentaon for either
the base Layer class (at
Layer-js.html), or the specic subclass you're working with, e.g., the WMS Layer Class,
You can use this opons parameter to inialize any of the layer parameters
described in the API—the best way to get more familiar with it is to just
play around with the dierent properes listed in the docs. The Layer class
docs can be found at
Parameters versus arguments
These two terms are oen confused and used interchangeably (but usually, that's ok).
Parameters are what the items are called during the class or funcon denion, but when
we call the funcon, the actual values of the parameters are referred to as arguments. For
example, this is how we create a funcon in JavaScript:
function add_numbers(a, b){
return a + b;
This is referred to as the add_numbers funcon denion. Here a and b are referred to as
parameters. Now, take a look at how we call it:
var the_sum = add_numbers(13, 37);
Here, 13 and 37 are referred to as the arguments. In the add_numbers funcon, 13 acts as
a and 37 acts as b.
Both terms are technically talking about the same thing. Parameter is the term to use when
talking about funcon denions, and argument is the term to use when talking about
funcon calls. The disncon is sort of like that of a meteoroid (when it's in space), a meteor
(when it's in the atmosphere), and a meteorite (when it hits the ground)—these three terms
refer to the same object.
Now, let's take a look at some of the dierent arguments we can pass in when creang our
layer objects.
The 'Layers' in OpenLayers
[ 58 ]
Time for Action – conguring the options parameter
The opons parameter is something that is present in all Layer classes, so let's get a bit more
familiar with it. I suggest opening up the Layer documentaon and following along, and even
trying to add in the opons yourself from the possible list of layer properes (at http://
1. Use the template (or code from Chapter 1 with the WMS layer code removed).
We'll be adding some WMS layers, and we'll refer to this le as chapter_3_ex2_
2. First we'll add in a layer that contains the 'basic' layer from the WMS server, like
in the previous example.
// Setup our two layer objects
var wms_layer_map = new OpenLayers.Layer.WMS(
'Base layer',
{layers: 'basic'},
{isBaseLayer: true}
3. Next we'll create another layer object. We'll create a layer using labels, like in
the previous example. This me though, let's set the layer's opons to include
visibility: false. This will cause the layer to be hidden by default. The layer
denion should now look like:
var wms_layer_labels = new OpenLayers.Layer.WMS(
'Location Labels',
{layers: 'clabel,ctylabel,statelabel',
transparent: true},
{visibility: false, opacity:0.5}
4. Time to create another layer. We'll set the layer params to ask the WMS service for
the stateboundary layer. Then, we'll specify the opons so that it won't display
in the layer switcher control (via displayInLayerSwitcher: false) and set a
minimum scale at which it will be visible (via minScale). That means this layer will
only show up once we've reached a certain scale. Add the following to your init()
var wms_state_lines = new OpenLayers.Layer.WMS(
'State Line Layer',
{layers: 'stateboundary',
Chapter 3
[ 59 ]
transparent: true},
{displayInLayerSwitcher: false,
minScale: 13841995.078125}
5. Now let's add a layer that will show a dierent layer from the WMS service and we'll
set the layer object's opacity to .8 (or 80 percent):
var wms_water_depth = new OpenLayers.Layer.WMS(
'Water Depth',
{layers: 'depthcontour',
transparent: true},
6. Finally, we'll create a layer object that shows some road layers from the WMS
service and has an opons object containing the transitionEffect: resize
property. This causes the layer to have a 'resize' animaon when zooming in or out.
var wms_roads = new OpenLayers.Layer.WMS(
{layers: 'priroad,secroad,rail',
transparent: true},
7. Now we just add the layers to the map (replace the previous addLayers funcon
call with this one):
8. Save the le and then open it in your web browser.
The 'Layers' in OpenLayers
[ 60 ]
9. Zoom in a few mes around the Gulf of Mexico. You'll start to noce black contour
lines in the ocean when you zoom in, and you should see a resize eect from the
base ground layer. Depending on where you zoom, you should see something
like this:
What Just Happened?
We just created another map with a few more layers and demonstrated some more layer
opons. The map looks slightly dierent than the rst example's map because we are using
dierent WMS server side layers (which are congured in each layer's params argument).
For now, let's focus on the fourth argument passed in—the opons argument. This argument
is used in all Layer classes, so when we move on to other types of Layers you'll be able to
use all the same properes we're talking about. The opons argument controls the layer's
object's properes.
Chapter 3
[ 61 ]
Conguring layer options
Let's take a look at a couple of the layer's options argument we passed in during the
previous example.
Pay close aenon to the commas. Both arguments and key:value pairs are
separated by a comma, but make sure you do not have a comma aer the
last pair. Trailing commas will usually break your map and are usually a pain
to debug—so if your map isn't working and you don't see any helpful error
messages in Firebug, check for trailing commas. A great site to help with your
code is
wms_state_lines layer options
This layer's opons are:
{ displayInLayerSwitcher: false, minScale: 13841995.078125}
The rst property, displayInLayerSwitcher, can be either true or false, and
determines if the layer will appear in the layer switcher control (if there is a layer switcher
control). In our example, we do have a layer switcher control and you'll noce that we
don't see it in the list of layers. The layer is sll there, and we can programmacally
turn it on or o through the setVisibility() funcon, e.g. wms_state_lines.
setVisibility(false);. In fact, when you turn on or o a layer through the layer
switcher control, this setVisibility funcon is what is being called. This property is
useful when you want to include layers in your map that you don't want to let the user
The second property is minScale: 13841995.078125. The value for this property is
oat, a number that can contain a decimal point. This minScale property determines the
minimum scale the map must be at before the layer is displayed, which basically means
how far we must be zoomed in before the layer will be turned on. There is also a maxScale
property which determines how far we can zoom in before the layer is turned o. The term
for this behavior is referred to as scale dependency.
Scale dependency
Scale dependency can be controlled either from the client or server side (or both). You'll
noce that the wms_water_depth layer (with black contour lines in the water to specify
depth) does not turn on unl we start to zoom in. We haven't set the minScale property for
the wms_water_depth layer, so why don't we see it at all zoom levels? The reason is WMS
server has its own scale dependencies on the server side, so even if we wanted to see this
layer when the map is zoomed out we can't because the server does not allow it.
The 'Layers' in OpenLayers
[ 62 ]
When we set the minScale or maxScale properes on a layer, we are specifying client side
scale dependency—so even if the server allows it, we're telling OpenLayers not to show it. To
determine the current scale of the map, you can call the map.getScale(); funcon which
will show you the current scale value.
wms_layer_labels layer options
This layer's opons property consists of:
{visibility: false, opacity:0.5}
The visibility property
We've already covered the rst property, so let's talk about the visibility property.
Its value can be either true (by default) or false. This visibility property controls if a
layer is visible or not. Seng it to false will make it hidden, but the user can turn it on
by enabling it in the layer switcher control. The map.getVisibility(); and map.
setVisibility({{Boolean}}); funcons refer to this property. {{Boolean}}
means we can pass in a Boolean, in other words, we can pass in either true or false.
The opacity property
The next property is opacity. It accepts a oat with values between 0 and 1. A value of
0 means the layer will be completely transparent, and a value of 1 means the layer will be
completely opaque. We set it to 0.5 here, so it will be 50 percent opaque. If you turn on the
layer in the map (you can click on the layer in the layer switcher to enable it), you'll noce
the labels are sort of see-through. This opacity seng helps you to create more visually
pleasing maps, as by enabling mulple layers and changing their opacies you can produce
some niy eects.
Map tiles
Let's take a short break now and talk about just a lile bit of theory. It has been menoned
that OpenLayers works by requesng 'map les' from a backend map server, but I haven't
really gone much into what that means. Nearly all layers work on this map ling principle
(except the Vector layer and the Image layer). So, what is it exactly and how does it work?
Think of how you might go about creang a web map from scratch—specically, how would
you handle the map image itself? You could go about it in two ways. First, you could just
send back one giant image of a map. If the user zooms in, the server sends back an even
bigger, more zoomed in image of a map. Using this strategy, you'd very quickly be sending
over exponenally large image les every me the user zooms. This is why this method is not
really praccal.
Chapter 3
[ 63 ]
Many images make up a map
The second way is that you break up the desired map image into a bunch of smaller images,
or map les. So, no maer how far the user zooms in, the server only has to send over a
relavely small amount of images. This sort of map ling strategy is what nearly every web
map does—Google Maps, Yahoo! Maps, most OpenLayers Layers, etc. When you request a
new extent, OpenLayers asks for a new set of map images. Each map image is the same size
(e.g., 256 x 256 pixels); this is referred to as the le size, and can be specied when creang
your map.
Let's take a look at an example of a basic OpenLayers map. In our example, when you're
completely zoomed out, the enre visible area will t in one map le image.
When the client asks for the map's max extent, only one map le needs to be returned.
OpenLayers will gure out what extents to ask the map server for. In this case, it only needs
to ask for one map le, because we're zoomed out so far that the enre world will t in one
map image.
The 'Layers' in OpenLayers
[ 64 ]
At this point, you might be wondering if there is any benet in breaking the images into les,
as we're only geng back one image. However, when we zoom-in, it becomes more clear.
Now we've zoomed in once. OpenLayers has to gure out what the extent of your map is,
and how many les it has to ask the map server for. OpenLayers calculates the extent for
each le, and then sends a request to the map server to get an image of the requested
extent. So, in this example, OpenLayers determines that it needs to send two requests to the
map server. Each request will result in a response of a map image, and then OpenLayers will
piece the les together.
Keep in mind that the le size is sll the same as it was in the previous request. Your map
only has one le size, and in this case (and by default) it is 256 x 256 pixels. You can change
the size of the les with the map's tileSize property, which we'll talk more about in
Chapter 8 on the Map class. So what happens when we zoom in and move the map around
a lile bit?
Chapter 3
[ 65 ]
In this case, OpenLayers requests more les because the total map area is outside what you
can see (called the Viewport). The les are all sll 256 x 256 pixels, but now les lie outside
of the map's visible range. Any me the user moves their map to a new area (by zooming or
panning), OpenLayers gures out how many les it needs to get, the extent for each le, and
where to place them.
Available layer properties
Let's go over the properes available for OpenLayers version 2.9, as we'll be using
them throughout the book. These properes can be used by any Layer class, as all Layer
subclasses (such as the WMS and Google Maps Layer) inherit from them.
The 'Layers' in OpenLayers
[ 66 ]
Data types
Before we talk about the layer properes, let's quickly go over the notaon for the data
types used. The curly brackets { } indicate the JavaScript data type the parameter expects.
The data types are as follows:
{Array}: An array of elements separated by commas and enclosed in brackets. For
e.g.: [1,2,3]
{Boolean}: Possible values are true or false.
{Float}: Possible values are numbers that can contain a decimal point. For e.g.:
{Integer}: Possible values are whole numbers (no decimals). For e.g.: 42
{Object}: An anonymous object, key:value pairs separated by commas, enclosed
in curly brackets. For e.g.: {'answer': 42, 'question': null}
{OpenLayers.______}: An object instanated from an OpenLayers class. The
blank could be any OpenLayers class. For e.g.: new OpenLayers.Control.
{String}: Possible value is any string, indicated by enclosed quotes (either single
quote, ', or double quote, "). For e.g.: 'This is a string'
Now that we're familiar with some of the data types, let's take a look at the Layer properes
available to us.
OpenLayers.Layer class properties
So far we've only been working with the WMS Layer class, but OpenLayers has many more
Layer classes. The following properes apply to all layer classes. We can set these properes
via the opons argument when we create the layer, and we can access them in Firebug by
simply calling
The following is a table of layer properes available as of OpenLayers version 2.10. We
will be using them throughout the book, and coming back to them oen, so don't feel as
if you need to memorize them right now. The latest properes can always be found in the
OpenLayers Layer docs at
Chapter 3
[ 67 ]
Property Property Data
Descripon Default Value
events {OpenLayers.
An OpenLayers event object. We
can pass in an event object here
that will call a funcon when an
event, such as zooming in, occurs.
We will talk more about events in
a later chapter.
map {OpenLayers.
The map object that this
layer belongs to. This is set
automacally when the layer
is added to the map via the
setMap() funcon.
isBaseLayer {Boolean} Determines if a layer is to act as a
base layer.
alpha {Boolean} Species if the layer's images
contain an alpha channel. This
was originally designed to x
transparency issues in IE, but
incurs a large performance hit. It
is recommended that you do not
use this.
{Boolean} Determines if the layer should be
displayed in the layer switcher.
visibility {Boolean} Determines if the layer is visible
on the map and enabled or
disabled in the Layer Switcher
attribution {String} Text that is displayed when the
Aribuon control has been
added to the map. By default,
the aribuon text appears in
the boom right and each layer's
aribuon is separated by a
inRange {Boolean} Is either True or False,
depending if the current map's
resoluon is within the layer's
minimum and maximum range.
This is set when the zoom level
imageOffset {OpenLayers.
The displacement of the image
les for layers with a guer.
The 'Layers' in OpenLayers
[ 68 ]
Property Property Data
Descripon Default Value
options {Object} Oponal object whose properes
will be set on the layer. Any of
these layer properes can be
dened in this opons object.
This is the same opons object
we've spent the past couple of
pages discussing.
eventListeners {Object} Event listeners will be registered if
this is set during the layer object's
creaon. We will discuss this in
detail in Chapter 6.
gutter {Integer} Somemes you may noce
arfacts around the edges of les
that the map requests. When you
set the guer value, OpenLayers
will request les that are bigger
than the normal le size by two
mes the guer value. So, if your
default le size was 256 x 256,
and if you had a guer value of 10
then OpenLayers would request
les with a size of 276 x 276.
Anything outside the normal le
though (256 x 256 in this case)
is not shown, and to OpenLayers
the le size is sll 256 x 256. This
really only needs to be used when
you encounter problems with
arfacts near the edge of your
les. Non-led layers always have
a guer value of zero.
Chapter 3
[ 69 ]
Property Property Data
Descripon Default Value
projection {OpenLayers.
or {String}
This will override the default
projecon of the map if
specied. You may also need
to set the maxExtent,
maxResolution, and units
properes. If you pass in a
string instead of a projecon
object, it will be converted to a
projecon object. Projecons
are used to display a three
dimensional object (the earth)
in two dimensions (on our map).
Dierent projecons use dierent
coordinates and measurement
units. We will cover projecons in
more detail in Chapter 4.
units {String} The units the map's layer is in.
Possible values are 'degrees'
(or 'dd'), 'm', 'ft', 'km',
'mi', or 'inches'.
scales {Array} Contains the map scales,
from highest to lowest values.
The units property must also
be set when using this. It is
recommended that you use the
resoluons property instead.
resolutions {Array} Contains an array of map
resoluons (map units per pixel)
from highest to lowest values. If
this is not set, it will be calculated
automacally based on other
properes, such as maxExtent,
maxResolution, etc.).
The 'Layers' in OpenLayers
[ 70 ]
Property Property Data
Descripon Default Value
maxExtent {OpenLayers.
An OpenLayers.Bounds
object consisng of min x, min
y, max x, and max y values
that specify the extent of
the layer. Any coordinates
outside this bounding box
will not be displayed. If the
property is set to false, les
that fall outside these coordinates
will simply not be requested.
maxResolution {Float} Sets the maximum resoluon (the
width or height, in map units,
per pixel). Default max is 360
degrees/256 pixels. If you are not
using a geographic projecon,
specify a dierent value.
numZoomLevels {Float} Species the number of zoom
levels a layer has. The layer will
not be displayed if the zoom level
of the map is greater than this
minScale {Float} Species the minimum scale at
which the layer will turn on.
MaxScale {Float} Species the maximum scale at
which the layer will be shown.
If the map scale is greater than
this value, the layer will not be
{Boolean} Species if the map should
request les that are completely
outside of the layer's
maxExtent property.
wrapDateLine {Boolean} This will cause the map to wrap
around the date line. This allows
you to connue dragging the map
le/right forever, as the map is
wrapped around onto itself.
Chapter 3
[ 71 ]
Property Property Data
Descripon Default Value
transitionEffect {String} Species the transion eect to
use when the map is panned or
zoomed. Possible values at the
me of wring are null (no
eect) and 'resize.'
{Array} This is a constant—it does not
change. It contains a list of
support transion eects to use
with the transitionEffect
metadata {Object} Allows you to store addional
informaon about the layer. This
does not have an eect on the
layer itself.
Modifying layer properties
Now that you're familiar with a few more layer properes, try to modify the second
example's code, passing in addional properes to the opons object. Open up the
previous example and use Firebug to access individual layer properes, for example, map.
layers[1].propertyName. Play around by passing in dierent properes to the opons
object when creang the layer objects, and don't be afraid to break your code!
The OpenLayers.Layer class
So far, we've only been using the OpenLayers.Layer.WMS class in the examples. This has
been the beginning of all our layer object instanaon code so far:
var wms = new OpenLayers.Layer.WMS(
Noce the period between Layer and WMS: Layer.WMS. This means that we're accessing
the WMS subclass of the Layer superclass. What do I mean when I say this? Well, the WMS
class is a subclass of the Layer class, so let's briey refresh our knowledge about subclasses.
In Chapter 1, we menoned Subclasses. Subclasses are, basically, classes that derive from
some base class. This base class is called a Superclass. The Layer class is thus the Superclass
of all Layer subclasses (Superclasses and Subclasses are sll classes). Subclasses inherit all
the properes of their superclass.
The 'Layers' in OpenLayers
[ 72 ]
Layer Class—Sub and super classes
The Layer class is therefore the superclass from which all other Layer classes derive. The
Layer.WMS layer class is dierent from the Layer.Image class, and each of those two
classes has their own unique properes and funcons. But both layers also share all the
properes of their Layer superclass—so all those properes we discussed earlier apply to
both classes.
Some Layer classes also inherit from mulple Layer class in a hierarchical way. For
example, the Layer.WMS class inherits from the Layer.Grid class, which inherits
from the Layer class.
Other layer types
OpenLayers supports a multude of dierent Layer classes. As you may recall from Chapter
1, each Layer class is associated with a dierent map server back end. The Layer.WMS class
is used to connect to a WMS map server, and the Layer.Google class is used to connect to
the Google Maps service.
Because OpenLayers is such an acvely developed framework, there are a few layer classes
that are deprecated (not recommended to use anymore). Later versions of OpenLayers will
deprecate more Layer classes, so we'll try to focus on the classes that should be around for
a while. We won't be able to cover every Layer class, but we will discuss the common ones.
The Layer classes which we don't menon below will not be covered in this book, either
because they are deprecated or outside the scope of this book. Let's take a look.
This is the class that allows us to interact with ArcGIS Server 9.3 via its REST interface.
Interacon with the REST interface is handled by construcng requests with URLs, and is
similar in concept to how GET requests work.
The structure to instanate objects from this class is similar to Layer.WMS, as both inherit
from the Layer.Grid class. ArcGIS Server is a third party, proprietary piece of soware
from ESRI, but OpenLayers provides excellent support for it. The OpenLayers documentaon
for the ArcGIS layer can be found at
The documentaon for ArcGIS Server's REST API can be found at http://
Downloa d f r o m W o w ! e B o o k < w w w.woweb o o k . c o m >
Chapter 3
[ 73 ]
This layer class is similar to the ArcGIS93Rest class, and allows us to display data from
ArcIMS Mapping Services. ArcIMS is another proprietary soware product from ESRI. The
documentaon for this Layer class is at
OpenLayers/Layer/ArcIMS-js.html. More informaon about ArcIMS can be found at
This layer allows us to interact with Google Maps via the Google Maps API. The
documentaon for this layer class is located at
Time for Action – creating a Google Maps layer
Let's take a look at how to create a Google Maps layer.
1. From this point onward, I'm going to assume that when I say "create a new map"
you will use the template from, or
create a copy of the example from Chapter 1 and remove the WMS layer calls (they
both result in the same code). So, create a new map.
2. The rst thing we'll need to do is add in a script tag to the <head> secon that
references the Google API library. This allows us to actually use the Google Maps
<script src=""></
3. Now, we'll need to create a Google Maps layer object. We won't pass in any
addional sengs, so the default sengs will be used. By default, we'll see the
Google 'Streets' Map (we could ask for the aerial imagery layer, the physical
topology layer, etc—we'll cover this soon). Add the following in your init funcon:
var google_map_layer = new OpenLayers.Layer.Google(
'Google Map Layer',
4. All we have to do now is add the layer to the map. Before you do this, make sure
you've removed the exisng line of code that adds the WMS layer to the map. We
only want to have our map contain the google_map_layer.
The 'Layers' in OpenLayers
[ 74 ]
You should see something like this:
What Just Happened?
We just created a map with a single Google Maps layer object using the Google Maps API
(version 3). The layer that Google is showing us is the default layer named ROADMAP (referred
to also as the 'streets' map). We can change the type of layer we see by changing the type
value in the layer's opons object. The possible values we can set for the type key are:
google.maps.MapTypeId.ROADMAP (the default)
Chapter 3
[ 75 ]
You'll noce that each type is preceded by google.maps.MapTypeID., which must be
present. For example, to specify that you wish to use the hybrid layer (satellite imagery
combined with the ROADMAP layer), you could use:
var google_hybrid_layer = new OpenLayers.Layer.Google(
"Google Hybrid",
{type: google.maps.MapTypeId.HYBRID}
Because of the projecons Google Maps and the other third party APIs use, it can be
lile tricky to get other layers to work with them—we'll talk about this more in Chapter 4
and Chapter 5. Briey though, it has to do with the fact that these third party APIs use a
projecon called EPSG:900913, which uses a dierent coordinate system than EPSG:4326
(the projecon our WMS layers have been in so far). Because of this, the coordinates don't
match up. So, we can't just place our WMS layer (which is in the EPSG:4326 projecon) on
top of the Google Layer (which is in the EPSG:900913 projecon), as the coordinates are
very dierent. In the next chapters, we'll address how to solve this issue.
The Google Maps Version 3 API can be found at
com/apis/maps/documentation/javascript/ and more
informaon on possible Google Maps Layer types can be found at http://
This is a base class that many other layers, such as WMS, inherit from. We won't be using it
explicitly, but it is important to know that it exists. It works, basically, by construcng a grid
and placing les (map images) inside the grid. It uses the HTTPRequest class to communicate
with a map server to get the les it needs to build the map.
Classes that inherit from it, such as WMS, work in a similar way. So, if you're familiar
with how to use the WMS layer, you'll be familiar with how to use nearly any class that
inherits from the Layer.Grid class. The documentaon for this class is at http://dev.
The 'Layers' in OpenLayers
[ 76 ]
This class allows us to use an image as a map layer. It's bit dierent than the other layer
classes OpenLayers oers, because it doesn't strictly follow a client/server model. Once the
inial request for the image is made, the client has the image and OpenLayers handles all
further map interacon—no further requests are made to the server aer the rst request
to get the image. There are no les, like with other raster (non vector, which is nearly every
other layer class) layers. Instead, just a single image is used.
The original purpose (and one of the best uses) of this class is to use an image for the
overview map control. But it can be used for many more things than just that—this class, a
great example of OpenLayers can be used for other purposes than just mapping.
Time for Action – using the image layer
Let's use the image layer to create a sort of image viewer.
1. First we'll need to add an image layer. The image layer expects the name as the rst
parameter (like other layers), the URL of the image next, then an {OpenLayers.
Bounds} object specifying bounds of the image, then an {OpenLayers.Size}
object which contains Width, Height pixel dimensions, and nally an oponal
opons object.
var image_layer = new OpenLayers.Layer.Image(
new OpenLayers.Bounds(-180,-112.5,180,112.5),
new OpenLayers.Size(1920,1200),
{numZoomLevels:7, maxResolution:.625}
2. Let's create another image layer now. We'll set the opacity to 20 percent and make
sure it's not a base layer by seng isBaseLayer: false in the opons object.
We'll also be using a dierent URL:
var image_layer_2 = new OpenLayers.Layer.Image(
'Wallpaper 2',
new OpenLayers.Bounds(-180,-112.5,180,112.5),
new OpenLayers.Size(1920,1200),
{numZoomLevels:7, maxResolution:.625, isBaseLayer:false,
Chapter 3
[ 77 ]
3. Finally, add the image layers to the map:
map.addLayers([image_layer, image_layer_2]);
You should see the following:
What Just Happened?
We just created an OpenLayers map that wasn't a map at all, but more of an image viewer.
There are plenty of other uses for this though—you could overlay an image on top of a WMS
layer, create a map from image layers consisng of high resoluon scans of older printed
maps, etc. The parameters required to create an image layer are:
Image layer parameters
name: {String} Name of the layer.
url: {String} URL of the image. Can be on your own computer/server, or
an external server.
The 'Layers' in OpenLayers
[ 78 ]
extent: {OpenLayers.Bounds} The extent of the image.
size: {OpenLayers.Size} The size of the image, in pixels.
options: {Object} An anonymous object containing the layer property sengs.
Let's take a look at our image_layer object's extent, size, and opons arguments:
new OpenLayers.Bounds(-180,-112.5,180,112.5),
new OpenLayers.Size(1920,1200),
{numZoomLevels:7, maxResolution:.625}
The extent argument is an {OpenLayers.Bounds} object, which is created via
OpenLayers.Bounds(-180,-112.5,180,112.5). We pass in the min x, min y, max x,
and max y values to create the bounding box. For images, you may have to play around with
the values depending on your image's dimensions. The rao of our image (1920/1200) is 1.6,
so I've set the bounds to have a similar rao (180 / 112.5 = 1.6).
The size argument, new OpenLayers.Size(1920,1200), is an {OpenLayers.Size}
object, and we pass in the width and height of the image.
For the next argument, the opons, we pass in {numZoomLevels:7,
maxResolution:.625}. The numZoomLevels property can be anything you'd like, but
higher values may allow you to zoom in too far to the image. The value of maxResolution
property is set to .625, which is a value I arrived at by dividing 1200/1920 (the width divided
by the height)—just a rough calculaon that, in case, makes the map look just about right.
Documentaon for this layer class is at
Have a Go Hero – make your own image based maps
Using the previous example's code, nd other high resoluon images and create a similar
'image viewer' with them. Add as many layers as you'd like, and play around with the opacity
seng to see how the image layers interact with each other.
This is the layer for the open source MapGuide plaorm. We won't be covering MapGuide
in this book, but it is a popular project and, since it is free and open source, you're welcome
to install it on your own computer. It behaves similar to the Layer.WMS class and has the
same parameters. It also inherits from Layer.Grid. The documentaon for this layer class
can be found at
MapGuide-js.html. More informaon on MapGuide can be found at http://mapguide.
Chapter 3
[ 79 ]
The TileCache layer allows you to interact with MetaCarta's TileCache, which is free open
source soware that caches WMS requests. TileCache provides enormous performance
boosts because it caches requests to a WMS server. This means that once a request has been
made, the response (the map image) is stored either on the server's hard drive or in memory
and is immediately returned to the client.
The normal process of requesng a map image from a WMS server goes like this:
1. Client sends request to WMS server, asking for a specic part of the map.
2. WMS Server receives the request and generates an image based on the
requested map extent.
3. WMS Server returns the rendered map image to the client.
The boleneck is Step 2, the WMS server rendering the image based on the request. With
caching (either through TileCache or by other means), the second step becomes a lot easier.
With caching, the server only has to generate an image once, and then it saves it (in the hard
drive or memory). So, instead of having to generate an image for every request, it simply grabs
an image which it has already generated. This makes the request seem almost instantaneous,
and most popular web maps use some form of caching—including Google Maps.
We will be discussing TileCache a lile more in the last chapter, where we talk about deploying
and using OpenLayers in a producon environment. The documentaon for this layer class is
html. For more informaon on TileCache, head to
The vector layer is one of the more powerful features of OpenLayers. It allows us to draw
points and polygons on the map, style them however we want, retrieve and use KML and
other geo data formats, etc. The vector layer makes uses of Protocols (such as HTTP),
Formats (such as KML), and Strategies (such as Clustering) to display and provide an
interacve layer. The vector layer also allows us to create and edit vector features.
In Chapter 9, our chapter on the Vector Layer class, we'll go into far more detail.
This layer allows us to interact with Microso's VirtualEarth API. It works in a similar way to
the Google Layer, so we won't spend more me discussing it here. Chapter 6 will fully cover
this layer class.
The 'Layers' in OpenLayers
[ 80 ]
This is a class that is deprecated, so try to avoid using it, as it will soon no longer be
supported. I wanted to explicitly menon it because it is on its way out, but I sll see lots of
code that uses it. WFS (Web Feature Service), allow us to interact with data that is stored on
the server. If you would like to use WFS, the general procedure is to use the Layer.Vector
class and use WFS as the format. We'll be covering this in detail in Chapter 9, our chapter on
the Vector Layer class.
This is the Layer class we've been using throughout the book so far. It inherits from Layer.
Grid, and is similar to other classes we've menoned. WMS is a popular standard and
the way we interact with it is similar to how we interact with other Layer classes. We
will be using this class throughout the book, so you haven't seen the last of it. Layer
class documentaon can be found at
OpenLayers/Layer/WMS-js.html. More informaon and specicaons of the WMS
protocol can be found at
This Layer class allows us to interact with the Yahoo! API. It works in a similar way to
Layer.Google and Layer.VirtualEarth, and we'll be covering it in more detail in Chapter 6.
Documentaon for this layer class is at
OpenLayers/Layer/Yahoo-js.html. The Yahoo! Maps API can be found at http://
Accessing layer objects
The last topic to cover concerns the funcons of the base Layer class. Before we do that
though, let's go over how to access layer objects in Firebug. We'll be doing this oen
throughout the book, so it is quite important.
Time for Action – accessing map.layers
Let's jump in to using some of the Layer class funcons.
1. Open up the second WMS example, chapter3_ex2_opons_cong.html in Firefox.
We won't be eding the code yet.
2. Enable Firebug and go to the Console panel.
Chapter 3
[ 81 ]
3. In the console, input and run this line of code:
4. You should then see a list of layers.
What Just Happened?
You just accessed the layers property of the global map object. This is a property of the
map object that contains an array of all the layers in the map. The list is ordered by the way
you add layers to the map, so the rst item in the list corresponds to the rst layer we added
to the map, the wms_layer_map layer. Not only will Firebug list the layer objects, you can
also access any one of them by clicking on them.
The 'Layers' in OpenLayers
[ 82 ]
Time for Action – accessing layer objects in Firebug
Let's take a look at how to access an object in Firebug now.
Click on one of the items in the array of objects that was outpued from the previous
Time for Acon secon. You should see something like this:
What Just Happened?
We just accessed our map's wms_layer_map layer object. What you see in the DOM panel is
a lisng of all the properes and funcons that layer object contains. The DOM panel is one
way we can access a layer object's properes. The DOM panel is a great way to get a quick
look at all the properes and values of any object we wish to know more about. You'll noce
some of the properes have not yet been menoned; this is because some properes are
specic to the Layer.WMS class, and is not included in the base Layer class.
Accessing layer properties
There are two common ways to access a layer object's properes.
The rst way is by accessing the layer object through the map.layers array, which we did
in the previous example. Here, we are accessing the global map object, which was dened
outside the init() funcon with var map;.
Chapter 3
[ 83 ]
If we know the index of a layer object we wish to view, we can use map.layers[n] to
access the layer object (where n is the index). For example, if we wanted to access the
wms_layer_map layer object, we know it is the rst layer added to the map so its index
is 0 (because array start its index at 0), so we would type map.layers[0]. The next layer,
wms_layer_labels, has an index of 1, and so on.
Accessing layers this way, however, is not advised. Adding a layer will change the array, as
will deleng a layer. The best way to access layer objects is to store a reference to them,
like we've been doing in all the examples (e.g., var my_layer = new OpenLayers.
Layer()), as we'll go over now.
Storing references to layer objects
The second way is to dene our layer objects as global variables, like how we did with our
map object. So far, all our layer objects are dened inside the init() funcon, which means
we can't access them or refer to them outside of the init() funcon. If we try to access the
wms_base_ground layer object in Firebug, we will get an error because the wms_layer_
map layer object is not a global variable as we are not 'inside' of the init() funcon in
Firebug. This concept is referred to as scope.
Let's look at our code to see how the map object is dened as a global variable.
var map;
function init() {
//Setup our map object
map = new OpenLayers.Map('map_element', {});
// Setup our two layer objects
var wms_layer_map = new OpenLayers.Layer.WMS( ...
When you specify var, you are basically saying 'create a new variable here'. Noce how
we dene var map; outside the init() funcon. Inside the init() funcon, we do not
use var when we set map equal to the map object, because the map variable has already
been created.
The 'Layers' in OpenLayers
[ 84 ]
So, the process for making an object global is to:
1. Dene the object/variable outside of the init() (or any funcon) with var
2. When you create the object inside the init() funcon, do not specify var when
referring to variable_name.
Noce our code to create the wms_layer_map layer object: var wms_layer_map = new
OpenLayers.Layer.WMS(.…) Since we are using var inside the init funcon, the object
is only now being created, and can only be referenced inside the init funcon. The wms_
layer_map object will only be accessible inside the same scope that it was dened. In this
case, since it was dened inside init(), we can only refer to it with the code that is inside
the init() funcon. To dene it globally to access it outside the funcon, we could do:
var map;
var wms_layer_map
function init(){
map = new OpenLayers.Map ...
wms_layer_map = new OpenLayers.Layer.WMS( ...
Using global variables can make things easier, but try to avoid using them
if possible. If you do use them, keep track of them and take care when
naming them.
Pop Quiz – working with Variable Scope
Take a look at the following code. What will be the value of the variable final?
var a = 3;
//Create a function that will set a variable called 'b' equal to 5
function set_variable(){
var b = 5;
//Call the function
final = a + b;
1. 8
2. 3
3. 5
Chapter 3
[ 85 ]
4. There will be an error because the variable b cannot be accessed outside the
test funcon.
Layer class methods
We've covered the properes of the base layer class and discussed most of the layer
subclasses so far. The remaining topic to cover is the funcons or methods of the base layer
class. Since we'll be talking about the funcons of the layer class, all layer subclasses inherit
and use these funcons. Before we get to the funcons though, let's cover how to access
layer objects in Firebug.
What's the dierence between a funcon and a method? A method is just a
term for a funcon that is owned by an object or a class.
Time for Action – dening a global layer object variable
Let's make the layer objects global variables access some properes of a layer, and call one
of the layer's methods.
1. Make a copy of chapter3_ex2_options_config.html. Add the following lines
right above the init() funcon:
var wms_layer_map, wms_state_lines, wms_labels, wms_water_depth,
2. Inside your init() funcon, remove the var declaraon before each of the layer
object names. For example, the rst line of your wms_layer_map denion should
now look like this:
wms_layer_map = new OpenLayers.Layer.WMS(
3. Save the le (we'll refer to it as chapter3_ex5_global_variables.html).
4. Open it up in Firefox and enable the Firebug console.
5. In the console panel, input and run: wms_layer_map;. You should see some output
like this:
Object { options=Object, more... }
6. Input and run the following command in Firebug:
The 'Layers' in OpenLayers
[ 86 ]
7. Here we are directly accessing a property of the layer. You should see the layer's
name property output:
Base layer
8. Input and run the following command in Firebug:
9. Assuming you are at the full extent, you should no longer see the layer now, as
you've just turned o the base layer's visibility.
What Just Happened?
We just made wms_base_ground a global variable, accessed a property of it, and called one
of its methods. Any of the Layer class properes we talked about before can be accessed via;.
So, now that we're a bit more familiar with how to access layer properes and funcons
on the y, let's go over the methods of the base layer class. Now, just like properes, most
layer subclasses (e.g., Layer.WMS) have their own set of funcons, but also inherit all the
funcons from the base layer class.
Layer class method denitions
All of the following funcons can be called the same way we called the setVisibility()
funcon; by calling layer_object.function_name();. Some methods require that you
pass arguments into them. We won't cover all the funcons of the base layer class, as some
are either deprecated, found in the Map class funcon list, or outside the scope of this book.
The required arguments (if any) are listed under the parameters column.
Funcon Descripon/Acon Parameters Return Value
setName( newName ) Set a new name for
the layer based on the
passed in string. This will
also update the display
name for the layer in the
layer switcher control,
and may trigger a
changelayer event.
{String} The new
name of the layer.
Chapter 3
[ 87 ]
Funcon Descripon/Acon Parameters Return Value
options )
Add addional opons to
the layer. The parameter
behaves like the opons
parameter, and allows
you to set properes on
the layer.
{Object} An
anonymous object
containing key:value
pairs of layer
properes and
redraw() Redraws the layer.
Returns true if the layer
was successfully redrawn
or false if the layer
could not be redrawn.
You will need to call this
while adding features to
a vector layer, as we'll
cover in Chapter 9.
getVisibility() Checks if the layer is
visible or not. Returns
true if the layer is
visible, false if not.
visibility )
Sets the visibility to
true or false, hide/
show the layer, and
redraw it. The visibility
determines if a layer
should be shown or not.
{Boolean} true
to show the layer,
false to hide the
calculateInRange() Returns true or false
if the layer can be
displayed at the map's
current resoluon. If
the alwaysInRange
property is true, this
will always return true.
is_base )
Will turn the layer into
a base layer if true is
passed in and if false
is passed in it will no
longer make it a base
{Boolean} Set to
true to make layer
a base layer, false
to make it an overlay
The 'Layers' in OpenLayers
[ 88 ]
Funcon Descripon/Acon Parameters Return Value
opacity )
Sets the opacity of a
layer based on the value
passed in. The passed
in opacity value is a
oat with valid values
from 0 to 1, with 0 being
completely transparent
and 1 being fully
opaque. 0.5 would be
50 percent transparent.
{Float} Value of
desired opacity.
Have a Go Hero – call some functions
Now that we've gone over some of the Layer class funcons that we'll be making use of
throughout this book, try calling them yourself. Open up Firefox, enable Firebug, and try
calling some of the above funcons on the layer objects (accessing the layer objects through
either the map.layers array or the global layer objects themselves). Again, don't be afraid
to experiment or break things!
In this chapter we talked about the Layer class. We covered the concept of layers and the
dierences between base layers and overlay layers. We went in depth with the WMS Layer
class. We discussed the Layer class properes and methods and were introduced to various
layer subclasses.
Whew! This was all likely a lot to take in. We covered a lot of Layer classes individually,
but we have not yet made a map with dierent types of Layer classes. This is one of the
things that OpenLayers excels at, and is what drives map 'mash ups.' To understand how
to go about pung dierent layer classes together though, we'll need to have a basic
understanding of projecons—the topic of our next chapter.
Wrapping Our Heads Around
When you look at a map, you are looking at a two dimensional representaon
of a three dimensional object (the earth). Because we are, essenally, 'losing'
a dimension when we create a map, no map is a perfect representaon of the
earth. All maps have some distoron.
The distoron depends on what projecon (a method of represenng the
earth's surface on a two dimensional plane) you use. In this chapter, we'll talk
more about what projecons are, why they're important, and how we use them
in OpenLayers. We'll also cover some other fundamental geographic principles
that will help make it easier to beer understand OpenLayers.
In this chapter, we will cover:
Concept of map projecons
Types of projecons
Longitude, latude, and other geographic concepts
OpenLayers projecon class
Transforming coordinates
Let's get started!
Wrapping Our Heads Around Projecons
[ 90 ]
Map projections
No maps of the earth are truly perfect representaons; all maps have some distoron. The
reason for this is because they are aempng to represent a three dimensional object (an
ellipsoid: the earth) in two dimensions (a plane: the map itself).
A projecon is a representaon of the enre, or parts of a, surface of a three dimensional
sphere on a two dimensional plane (or other type of geometry).
Why on earth are Projections used?
Every map has some sort of projecon—it is an inherent aribute of maps. Imagine
unpeeling an orange and then aening the peel out. Some kind of distoron will occur, and
if you try to fully t the peel into a square or rectangle (like a at, two dimensional map),
you'd have a very hard me.
To get the peel to t perfectly onto a at square or rectangle, you could try to stretch out
certain parts of the peel or cut some pieces of the peel o and rearrange them. The same
sort of idea applies while trying to create a map.
There are literately an innite amount of possible map projecons; an unlimited number
of ways to represent a three dimensional surface in two dimensions, but none of them are
totally distoron free.
So, if there are so many dierent map projecons, how do we decide on what one to use?
Is there a best one? The answer is no. The 'best' projecon to use depends on the context in
which you use your map, what you're looking at, and what characteriscs you wish to preserve.
Projection characteristics
As a two dimensional representaon is not without distoron, each projecon makes a
tradeo between some characteriscs. And as we lose a dimension when projecng the
earth onto a map, we must make some sort of tradeo between the characteriscs we want
to preserve. There are numerous characteriscs, but for now let's focus on three of them.
Area refers to the size of features on the map. Projecons that preserve area are known as
equal area projecons (also known as equiareal, equivalent, or homolographic). A projecon
preserves area if, for example, an inch measured at dierent places on the map covers the
same area. Because area remains the same, angles, scales, and shapes are distorted. This is
what an equal area projected map may look like:
Chapter 4
[ 91 ]
Scale is the rao of the map's distance to the actual distance (e.g., one cenmeter on the
map may be equal to one hundred actual meters). All map projecons show scale incorrectly
at some areas throughout the map; no map can show the same scale throughout the map.
There are parts of the map, however, where scale remains correct—the placement of these
locaons migates scale errors elsewhere. The deformaon of scale also depends on the
area being mapped. Projecons are referred to as equidistant if they contain true scale
between a point and every other point on the map.
Maps that preserve shape are known as conformal or orthomorphic. Shape means that
relave angles to all points on a map are correct. Most maps that show the enre earth
are conformal, such as the Mercator projecon (used by Google Earth and other common
web maps). Depending on the specic projecon, areas throughout the map are generally
distorted but may be correct in certain places. A map that is conformal cannot also be
equal-area. The maps we've been using so far have been conformal.
Other characteristics
Projecons have numerous other characteriscs, such as bearing, distance, and direcon.
The key concept to take away here is that all projecons preserve some characteriscs
at the expense of others. For instance, a map that preserves shape cannot completely
preserve area.
There is no 'perfect' map projecon. The usefulness of a projecon depends on the context
the map is being used in. A parcular projecon may excel for a certain task, e.g. navigaon,
but can be a poor choice for other purposes.
Wrapping Our Heads Around Projecons
[ 92 ]
Types of projections
Projecons are a way to represent three dimensions with two dimension surface. Projecons
are projected onto some geometric surface, three of the most common ones being a plane,
cone, or cylinder.
Imagine a cylinder being wrapped around the earth, with the center of the cylinder's
circumference touching the equator. Now, the earth is projected onto the surface of this
cylinder, and if you cut the cylinder from top to boom vercally and unwrap it, and lay it
at, you'd have a regular cylindrical projecon:
The Mercator projecon is one type of projecon. If you've never worked with projecons
before, there is a good chance that most of the maps you've seen were in this projecon.
Because of its nature, there is heavy distoron near the ends of the poles. Looking at the
previous screenshot, you can see that the cells get progressively larger, the closer you get to
the North and South Poles. For example, Greenland looks larger than South America, but in
reality it is about the size of Mexico. If area distoron is important in your map, you might
consider using an equal area projecon as we previously menoned.
More informaon about projecons can be found at the USGS (US
Geological Survey) website at
EPSG codes
As we menoned, there are literally an innite number of possible projecons. So, it
makes sense that there should be some universally agreed upon classicaon system that
keeps track of projecon informaon. There are many dierent classicaon systems, but
OpenLayers uses EPSG codes. EPSG refers to the European Petroleum Survey Group, a
scienc organizaon involved in oil exploraon, which in 2005 was taken over by the OGP
(Internaonal Associaon of Oil and Gas Producers).
Chapter 4
[ 93 ]
For the purpose of OpenLayers, EPSG codes are referred to as:
The numbers (4326 in this case) aer EPSG: refer to the projecon idencaon number.
This projecon, EPSG:4326, is the default projecon which OpenLayers uses. It has been
the projecon used in all our examples so far, and uses the familiar Longitude/Latude
coordinate system, with coordinates that range from -180° to 180° (longitude) and -90° to
90° (latude).
Time for Action – using different projection codes
Let's create a basic map using a dierent projecon.
1. Using the template code, recreate your map object the following way. We'll be
specifying the projection property, along with the maxExtent, maxResolution,
and units properes. If we use a projecon other than the default projecon, we
need to tell OpenLayers the type of coordinates to use, and seng the maxExtent
is one way to do this. The projecon we're going to use is EPSG:900913, a
projecon used by Google Maps and other third party APIs.
map = new OpenLayers.Map('map_element', {
projection: 'EPSG:900913',
maxExtent: new OpenLayers.Bounds(-20037508, -20037508,
20037508, 20037508.34),
maxResolution: 156543.0339,
units: 'm'
2. Save the le, we'll refer to it as chapter4_ex1.html.
Downloa d f r o m W o w ! e B o o k < w w w.woweb o o k . c o m >
Wrapping Our Heads Around Projecons
[ 94 ]
3. You should see something like the following:
What Just Happened?
We just created a map with the projecon EPSG:900913. You'll noce that it looks quite a
bit dierent than the maps we've made so far. This is because it is in a dierent projecon.
Specifying a different projection
OpenLayers supports any projecon, but if you want to use a projecon other than
EPSG:4326, you must specify the following three opons:
maxExtent: Default value is -180,-90,180,90
maxResoluon: Default value is 1.40625
projecon: Default value is EPSG:4326
Chapter 4
[ 95 ]
If you do not specify those opons, the default values are used (all the other maps so far
have been using the default values). You should also specify the units property, as we did
with units: 'm', depending on the units your projecon uses.
The reason you must specify these properes is because dierent projecons use dierent
coordinates. In the above example, we set the maxExtent to:
maxExtent: new OpenLayers.Bounds(-20037508, -20037508,
20037508, 20037508.34)
These values are much dierent than the default values—they are not longitude and latude
values. Instead, they use an x/y coordinate system, and to OpenLayers the longitude is the x
value and latude is the y value.
Pop Quiz – projections
Give some reasons why you might want to use a projecon other than EPSG:4326. What
areas would not be best suited for displaying the EPSG:4326 projecon?
Longitude and latude are two terms most people are familiar with, even if they have
limited geographic knowledge or get confused by the two. Let's take a look at the following
screenshot and then go over these two terms.
Wrapping Our Heads Around Projecons
[ 96 ]
Latude lines are imaginary lines parallel to the equator, aptly known also as 'Parallels of
Latude'. Latude is divided into 90 'degrees', or 90 spaces (or cells), above and below the
equator. -90° is the South Pole, 0° would be the Equator, and 90° is the North Pole.
Each space, or cell, (from 42° to 43°, for example) is further divided into 60 minutes and each
minute is divided into 60 seconds. The minutes and seconds terminology has lile to do with
me. In the context of mapping, they are just terms used for precision. The size of a degree
of latude is constant. Because they measure 'north to south', OpenLayers considers the y
coordinate to be the latude.
Longitude lines are perpendicular to the lines of latude. All lines of longitude, also known
as meridians of longitude, intersect at the North Pole and South Pole, and unlike latude, the
length of each longitude line is the same. Longitude is divided into 360 'degrees', or spaces.
Similar to latude, each space is also divided into 60 minutes, and each minute is divided
into 60 seconds.
As the space between longitude lines gets smaller, the closer you get to the poles the size of
a degree of longitude changes. The closer you are to the poles, the shorter amount of me it
would take you to walk around the earth.
With latude, it makes sense to use the equator as 0°, but with longitude there is no
spot beer than another to start the 0° mark at. So, while this spot is really arbitrary, the
Observatory of Greenwich, England is today universally considered to be 0° longitude. Because
longitude measures east and west, OpenLayers considers the x coordinate to be longitude.
Time for Action – determining LonLat coordinates
Let's take a look at a couple of examples on coordinates from our previous maps.
1. Open up the nal example from Chapter 1.
2. Pan around the map in any direcon. Then, in Firebug, type:
3. Depending on where you have panned, your output should read something like this:
lon=-72.8125, lat=19.6875
4. Now, open up the example from the beginning of this chapter.
5. Pan around, and then in Firebug type:
Chapter 4
[ 97 ]
6. You should see something like:
What Just Happened?
We just took a look at the longitude and latude values for the center of the map in two
dierent maps with dierent projecons. When we call map.getCenter(), we get back an
OpenLayers LonLat object.
In the rst map, the max extent of the map was between -180° and 180° for longitude, and
between -90° and 90° for latude. These are the values used by the EPSG: 4326, and it is a
longitude/latude type of coordinate system. The values for longitude and latude change in
the second map because they are not in the same projecon (they are in EPSG:900913).
OpenLayers projection class
So far, we've been talking about the abstract idea of a projecon. Let's dive into OpenLayer's
Projecon class, OpenLayers.Projection, which is what we use to actually handle
projecons. The Projecon class relies on an external library called Proj4js, which can be
found at First, we'll talk about what we can do without the proj4js
library, and then talk about what we can do with it.
Creating a projection object
To instanate an object from the Projecon class, the code would look like the following:
my_proj = new OpenLayers.Projection('EPSG:4326', {});
Let's take a look at the parameters for the Projecon class.
projectionCode: {String}: A string of idenfying the Well Known Idener
(WKID) for the projecon, such as an EPSG code in the form of EPSG:4326.
options:{Object}: An oponal object. For instanang projecon objects, it is
very common to leave this out.
When creang a map and specifying the projecon property, you can either pass in a
projecon object (like the one created above), or pass a string containing the projecon
code. This string, such as EPSG:4326, is also known as an SRS code. When passing in a
code, like we've done with all our examples so far, OpenLayers automacally turns it into a
projecon object for you.
Wrapping Our Heads Around Projecons
[ 98 ]
The Projecon class has a number of methods, including:
Funcon Descripon Parameters
getCode() Returns a {String}
containing the projecon
code, e.g., 'EPSG:4326'
getUnits() Returns a {String}
the units string for
the projecon, e.g.,
'degrees'. If the Proj4js
library is not included on
your page, this will return
to, method)
Dene a custom
transformaon funcon
between two projecons.
This usually will not be
necessary, especially if you
are using Proj4js, unless you
need to dene a custom
projecon transformaon.
from: {String} Source
projecon code
to: {String} Desnaon
projecon code
method:{Function} A funcon
that transforms the source point to
the desnaon point, leaving the
original point unmodied.
Calling this funcon will
transform the passed in
point from the passed in
source projecon to the
passed in destination
projecon. You can also
pass in an {Object} as
long as it contains x and y
properes. This funcon
will transform the point in
place, meaning that the
point you passed in will be
transformed. If you need
a copy of the point,
you should rst make a
clone of it before calling
transform() by calling
the point's clone()
point: {Geometry.Point}
An object from the OpenLayers.
Geometry.Point class,
containing an x and y coordinate
Projection} Projecon object of
the source projecon
Projection} Projecon object of
the desnaon map projecon.
Chapter 4
[ 99 ]
Transforming projections
Transforming a point means you take a coordinate in one projecon and turn it into a
coordinate of another projecon. Apart from transforming EPSG:4326 to EPSG:900913
and vice-versa, OpenLayers does not provide support for transforming other projecons out
of the box—to do transforms of other projecons, you'll need to include Proj4js (which can
be found at
In most scenarios, it is the job of the backend map server to handle projecon
transformaons, but oen it's useful or faster to do it on the client side (such as in the
case of vector layer coordinate transformaons). Let's take a look at how to transform
EPSG:4326 to EPSG:900913 with OpenLayers.
Time for Action – coordinate transforms
Proj4js is not necessary for this example, as transforming between these two projecons is
possible without Proj4js.
1. Open up the previous example in Firefox. We won't be modifying any code, so any
page which includes the OpenLayers library will be ne.
2. Open Firebug. In the console, create two projecon objects:
var proj_4326 = new OpenLayers.Projection('EPSG:4326');
var proj_900913 = new OpenLayers.Projection('EPSG:900913');
3. Now let's create a LonLat object which will contain a point in EPSG:4326
var point_to_transform = new OpenLayers.LonLat(-79, 42);
4. And now let's transform it. We'll take it from EPSG:4326 (our source proj_4326
projecon object) to EPSG:900913 (our desnaon proj_900913 projecon
point_to_transform.transform(proj_4326, proj_900913);
5. Finally, we'll print the new value:
6. Your output should read something like:
lon=-8794239.7714444,lat=5160979.4433314 { lon=-8794239.7714444,
-8794239.7714444 5160979.4433314
Wrapping Our Heads Around Projecons
[ 100 ]
What Just Happened?
We just transformed a point in the EPSG:4326 projecon to a point in the EPSG:900913
projecon. Let's take a closer look at the transform method we called on the point_to_
transform object.
point_to_transform.transform(proj_4326, proj_900913);
This will transform the original point from the proj_4326 projecon to the proj_900913
projecon. Noce, we aren't calling the transform() funcon of a projecon object, but
of a LonLat object. The transform() funcon's denion for an OpenLayers.LonLat object
is as follows:
Funcon Descripon Parameters
This funcon transforms a point in
place, meaning that the original point
will be transformed; hence the original
value will be lost. If you need a copy of
it, use the .clone() method rst. It
returns itself.
source: Source projecon
dest: Desnaon
In this case, our source projecon is in EPSG:4326, and our desnaon projecon is in
EPSG:900913. Keep in mind however, that EPSG:4326 and EPSG:900913 are the only
two projecons you can do transforms on with OpenLayers if you do not include the
Proj4js library.
When creang your map, all your raster layers (image-based layers;
nearly every layer except the vector and image layer) must be in the
same projecon as your map. You can do projecon transformaons
with coordinates and the vector layer, but once OpenLayers gets back
an image from a map server it cannot reproject the image itself (that's
something the map server has to do).
The Proj4js library
The Proj4js library allows you to transform the coordinates from one coordinate system into
another coordinate system. The Proj4js website is located at By just
including the Proj4js library on your page (like you do with OpenLayers), you can do more
transforms within OpenLayers. Not all EPSG codes are supported, but there are many and if
your desired code is not supported you can add a projecon denion for it.
Chapter 4
[ 101 ]
The site contains Proj4js denions for
most of the EPSG codes.
Ideally, you should be using the same projecon throughout your map, but there are mes
when you may want to display the coordinates in a dierent projecon—such as with a
vector layer. Let's take a look at how to setup the Proj4js library.
Time for Action – setting up
This step is similar to the way we set up OpenLayers.
1. Download Proj4js from
At the me of wring, the latest version was, so go ahead and
download it (or whichever the latest version is).
2. Extract it and copy the proj4js folder to your root code directory (the folder where
your OpenLayers.js le is located).
3. Add the following line in the <head> secon of your code aer the OpenLayers
library inclusion code.
<script type='text/javascript' src="proj4js/lib/
4. Now, open up the page and start Firebug. Type and run the following:
var test_proj = new Proj4js.Proj('EPSG:4325');
5. You should see output that looks like the following:
Object { srsCodeInput="EPSG:4325", more...}
What Just Happened?
We just included the Proj4js library and tested to see if it worked. If you received an
error when you aempted to call new Proj4js.Proj() it means that the locaon
of the proj4js-combined.js le was wrong. Ensure that the directories are set up properly
(your example le should be in the same directory as the proj4js folder, and inside the
proj4js folder should be a bunch of les and folders, including a lib folder that contains
the proj4js-combined.js le).
Wrapping Our Heads Around Projecons
[ 102 ]
Dening custom projections
Now that the Proj4js library is included, you can do transforms with more projecons the
same way we did in the previous example. Not all projecons are dened; however, you are
able to dene them yourself, for example:
Proj4js.defs["EPSG:27563"] = "+title=LAMB sud france +proj=lcc
+lat_1=44.1 +lat_0=44.1 +lon_0=0 +k_0=0.999877499 +x_0=600000
+y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0
+pm=paris +units=m";
Aer that, you'd be able to use EPSG:27563 for projecon transformaons just like you
were able to use EPSG:4326 and EPSG:900913 from the earlier examples.
There are a number of already dened projecons, and you can view them more extensively
at A more complete list (containing Proj4js denions for nearly
any EPSG code) can be found at
In this chapter, we talked about projecons. We covered what they are and the various
dierent types of projecons. Longitude, latude, and other geographic concepts were also
discussed. While we just scratched the surface of these prey complex topics, you should
have enough fundamental informaon to understand how to use projecons.
We also talked about the Projecon class, along with how to transform coordinates and use
the Proj4js library. You'll oen work with data in coordinate systems other than EPSG:4326,
and knowing how to work with and transform data in other projecons is important.
In the next chapter, we'll take a look at Google Maps and other third party APIs, and put
some of our recently gained knowledge of projecons to use.
Interacting with Third Party APIs
Web maps are very popular today, and are growing in popularity. Aer Google
Maps was introduced, there was an explosion of interacve web maps. Google
provides an API to interface with its mapping service, as do others now, and
OpenLayers work well with most of them. Not only can we use these third party
APIs with OpenLayers, we can also 'mashup' other layers on top of them.
In this chapter, we're going to learn:
Concept of third party mapping APIs
Using the layer classes for third party APIs: Google, Microso, and Yahoo!
How to use OpenStreetMap
Working with Spherical Mercator
Combining dierent layer classes
Third party mapping APIs
Web based maps are commonplace today. The catalyst for the explosive growth of web maps
was the introducon of Google Maps. Web maps existed before, but they were not quick or
developer friendly. In June 2005, Google released an API for Google Maps which provided a
front end client (the role OpenLayers plays) along with an access to the backend map server.
This allowed anyone to insert not just a Google Map on their site, but also allowed them to
add in their own point data and manipulate the map in other ways. Google Maps grew in
popularity, and other companies, such as Microso and Yahoo!, followed in their footsteps,
creang their own web-mapping APIs.
Interacng with Third Party APIs
[ 104 ]
Map mashups
The term mashup refers to an applicaon that combines various dierent data sources and
funconality together. A map mashup is a map that combines dierent layers and data. Third
party mapping APIs, like Google and Yahoo! Maps, allow people to more easily create these
'map mashups'. For example, a map with a Google Maps base layer overlaid with markers
that track places you've traveled to could be considered a map mashup.
OpenLayers did not introduce map mashups, but it allows us to create very powerful ones
with ease. Combining a Google's Map layer, a WMS layer, and a Vector layer is prey simple
with OpenLayers.
OpenLayers and third party APIs
OpenLayers allows you to use third party mapping APIs inside your map applicaon, leng
you use their maps inside of yours. The main caveat is that, at the me of wring, the third
party API map must be a base layer (but, as we discussed before, you can use as many base
layers as you wish).
The three large commercial mapping APIs that OpenLayers can communicate with are
Google Maps, Yahoo! Maps, and Bing (Microso) Maps. There is another free and open
source API that OpenLayers works well with (and works in a similar manner to the previous
three) called OpenStreetMap.
We'll rst take a look at each of these four Layer classes, and then we'll go over how to
combine them with other Layer classes.
Google Maps
The soware behind Google Maps consists of a client and server. The client is what you use
when you visit, and it communicates with the Google Maps
backend servers. Google provides an API that lets you use their own client and backend
server, but since OpenLayers is used as our client, we're only interested in interacng with
Google's backend map server.
There may be legal restricons depending on how you plan to use the Google
Maps. Full restricons can be found at
maps/terms.html and
Chapter 5
[ 105 ]
In the previous chapters, we've set up the Google Layer using Version 3 (V3) of the Google
Map API. Because Google Maps updates their API, OpenLayers must also update to
accommodate any changes that are made. OpenLayers versions prior to 2.10 (the one this
book is based on) use Version 2 (V2) of the Google Maps API. Google Maps V2 usage is
deprecated however, so we will focus on using V3. From our perspecve, our code doesn't
change much—OpenLayers handles all the version specic funconality behind the scenes
for us.
However, you are likely to encounter older OpenLayers maps made using Google Maps
Version 2, so we will cover how to use both V2 and V3. Again, please use only V3 when
making new maps, as V2 will eventually no longer be supported.
Differences between Google Maps version 2 and version 3
There are really only three things that you must do dierently when going from Google
Maps V3 to V2 (or vice versa):
1. The script tag you add in to reference the Google Maps library is dierent. You do
not need to provide an API key with V3 of the Google Maps API.
2. The layer names used in the type property are dierent. For example, the 'terrain'
layer in V3 is dened as type: google.maps.MapTypeId.TERRAIN, but in V2 it
is type: G_PHYSICAL_MAP.
3. The layer is congured with spherical Mercator (we'll cover what this means
It is recommended you use V3 of the Google Maps API. The ocial Google Maps
V3 documentaon can be found at
Ocial Google Maps API docs for V2 can be found at http://code.
Time for Action – using Goole Maps V3 (standard way)
Let's create a map using V3 of the Google Maps API. We've already done this in Chapter 3,
so you should be somewhat familiar with it. This is the standard way to use the Google Maps
Layer, and you should use this method unless you specically need a layer type in V2 that V3
does not yet support.
Interacng with Third Party APIs
[ 106 ]
With versions of OpenLayers prior to 2.10, accessing Google Maps V3 may
not work.
1. Version 3 of the Google Maps API does not require an API key. However, you sll
must include the following in your <head> secon, so OpenLayers knows where
to look for the Google Maps API library. We'll be asking the map's API and specify
that we want v3.2 of the Google Maps API (you can leave the &v=3.2 parameter if
you'd like to let Google Maps provide the latest version for you automacally). Add
this before your OpenLayers inclusion script:
2. Let's start by adding a hybrid layer to our map. The type property is in the form
of google.maps.MapTypeId.TYPE, where TYPE in this case is HYBRID:
var google_hybrid = new OpenLayers.Layer.Google(
"Google Hybrid",
{type: google.maps.MapTypeId.HYBRID}
3. Now we'll add a physical (topographic type) layer:
var google_physical = new OpenLayers.Layer.Google(
"Google Physical",
{type: google.maps.MapTypeId.TERRAIN}
4. To add a satellite layer type:
var google_satellite = new OpenLayers.Layer.Google(
"Google Satellite",
{type: google.maps.MapTypeId.SATELLITE}
5. Now, we'll create a streets layer. If we do not pass in a layer type, the streets layer
is used by default. If you wish to manually specify the type, the streets map type is
var google_streets = new OpenLayers.Layer.Google(
"Google Streets",
Chapter 5
[ 107 ]
6. We'll add the layers to the map:
7. Finally, add a layer switcher control. You'll also noce that all the layers on the map
that we've added are all base layers. By default, third party map API layers act as
base layers.
map.addControl(new OpenLayers.Control.LayerSwitcher());
8. Open up the page. You should see something similar to this:
Interacng with Third Party APIs
[ 108 ]
What Just Happened?
We just created a map using Google Maps API V3. We only needed to do two things:
1. Include the Google Maps V3 API with <script src="
com/maps/api/js?sensor=false&v=3.2"></script>. This lets OpenLayers
access the Google Maps API.
2. Set the type property, such as type: google.maps.MapTypeId.HYBRID.
Including the Google Maps API enables OpenLayers to communicate with the Google Maps
backend. Because we included the Google Maps API, we can use variables that are part of
it. Specically, the possible values for the type property come directly from the Google
Maps API—for example, if we didn't include the API, we could not use google.maps.
Noce that if you run map.getCenter(); in Firebug, the center point we get back has very
dierent coordinates than what we're used to—they aren't longitude/latude values. This is
because sphericalMercator is set for us automacally, so we can easily lay other layers,
such as vector layers, on top of the third party map layer. Before we cover the reason for this
(which is related to the other third party mapping APIs) let's go over the Google Map Layer
class in more detail.
Creating a Google Map layer object
The format to create a Google Map layer object is the same for both V2 and V3 of the
Google Maps API. The basic format for instanang a Google Maps layer is:
var google_layer_object = new OpenLayers.Layer.Google(
'Layer Name',
The rst argument, as with most Layer classes, is the layer's name. The second argument
is a properes object. There are just a few Google Layer specic properes, so let's go
over them.
Google layer properties
Because the Google Layer inherits from the base Layer class, you can use nearly any property
that the Layer class provides—such as numZoomLevels or maxExtent. We'll cover just the
properes that are specic to the Google Maps layer class. The possible values for the type
aribute depend on the version of the Google Maps API used.
Chapter 5
[ 109 ]
sphericalMercator {Boolean}
This property determines if the map should behave as a Mercator-projected map. Seng
to true will allow us to use other layers, such as the Vector layer, with the actual map
projecon. Spherical Mercator is covered in more depth later in this chapter. When using
V3 of the Google Map API, this property is automacally set to true. With V2, you will have
manually set it to true. Example: sphericalMercator: true.
type {GmapType}
The type property species the Google Map layer type—what layer Google should give us.
V2 and V3 of the Google Maps API have dierent possible values. Let's go over Version 3's
values, and then take a look at Version 2's values.
V3 GMapType values
The standard, V3 way to refer to layer types is in the form of:
var google_layer_V3 = new OpenLayers.Layer.Google(
'Google Maps V3 Layer',
{type: google.maps.MapTypeId.TYPE}
To specify the layer type, we can simply change the TYPE property. The possible TYPE values
can be one of the following:
Type Descripon
google.maps.MapTypeId.ROADMAP The default value, used if nothing is passed
in. Shows the default street map (same as G_
google.maps.MapTypeId.HYBRID Displays a map with a semi-transparent street layer
overlaid on satellite imagery (same as G_HYBRID_
Displays satellite imagery (same as G_
google.maps.MapTypeId.TERRAIN Displays a map with features such as terrain (same
An up-to-date list of possible layer types can be found in the Google Maps
API documentaon at
documentation/javascript/maptypes. html#MapTypes.
At the me of wring, the non-earth (moon, Mars, and sky) layers were not yet available
from Google Maps.
Interacng with Third Party APIs
[ 110 ]
V2 GMapType values
Version 2 of the Google Maps API provides various layers as well. Some of the layer types
are even maps of other planets, but no extra work is required to view them inside the
OpenLayers. To specify the map type for V2, use the following:
var google_layer_V2 = new OpenLayers.Layer.Google(
'Google Maps V2 Layer',
{type: TYPE}
The possible TYPE values are the following:
Type Descripon
G_NORMAL_MAP The default value. This is used if no GMapType is specied. This
map type will display the normal street map.
G_SATTELITE_MAP Displays satellite imagery.
G_AERIAL_MAP Displays aerial photography.
G_HYBRID_MAP Displays a map with a semi-transparent street layer overlaid on
satellite imagery.
Displays a map with a semi-transparent street layer overlaid on
aerial imagery.
G_PHYSICAL_MAP Displays a map with features such as terrain.
Displays a terrain map of the moon with altude color coded.
G_MOON_VISIBLE_MAP Displays photography taken from orbit around the moon.
Displays a terrain map of Mars with altude color coded.
G_MARS_VISIBLE_MAP Displays photography taken from orbit around Mars.
Displays infrared imagery of Mars. Warm areas are bright and
cooler areas are dark.
G_SKY_VISIBLE Displays a map of the full celesal sphere.
To use any of these layer types, simply pass in the type name when creang the layer.
Example: type: G_NORMAL_MAP.
The previous list was the supported layer types at me of wring, but current
and up-to-date layer values can be found on the Google Maps V2 API docs
Chapter 5
[ 111 ]
Time for Action – creating a Google Map layer with V2
Let's create a map with V2 of the Google Maps API. This is not the proper way to use the
Google Maps layer, but I am including it because you are likely to come across a code that
uses V2 of the API. Google Maps V2 also provides a few dierent layer types (like a moon
layer) that V3 does not provide at the me of wring.
1. V2 of the Google Maps API requires you to register an API key, so grab one (for free)
at If you don't have a
domain name, use http://localhost.
2. In the <head> secon, before the OpenLayers script tag, include the following.
Replace YOUR_KEY with the key generated from Step 1:
3. Let's create some layers now. The format of the type aribute is slightly dierent
with V2. We'll go over the possible layer type values right aer this example. First,
let's create some layers, starng with a 'hybrid' layer. The type value for the hybrid
layer is G_HYBRID_MAP. We'll also specify 20 zoom levels with the numZoomLevels
property. Dierent base layers can support dierent numbers of zoom levels:
//Create Google Map Layer objects
var google_hybrid = new OpenLayers.Layer.Google(
"Google Hybrid",
{type: G_HYBRID_MAP, numZoomLevels: 20}
4. Now let's create a 'physical' layer, which is a terrain/topology type of layer. The
type is G_PHYSICAL_MAP, and we'll specify a dierent numZoomLevels property:
var google_physical = new OpenLayers.Layer.Google(
"Google Physical",
{type: G_PHYSICAL_MAP, numZoomLevels: 22}
5. We'll use the G_SATELLITE_MAP to create a satellite layer:
var google_satellite = new OpenLayers.Layer.Google(
"Google Satellite",
Interacng with Third Party APIs
[ 112 ]
6. If we don't pass in a type, the default 'streets map' layer will be used. This is the
layer you'll see by default in Google Maps. If you wish to manually specify this layer
type, it is called G_NORMAL_MAP.
var google_streets = new OpenLayers.Layer.Google(
"Google Streets",
7. Now let's add a layer type that is not (at the me of wring) supported by V3
of the Google Maps API—a layer of Mars:
var google_mars = new OpenLayers.Layer.Google(
"Google Mars",
8. Finally we just add the layers to the map:
9. Take a look at your map. You should see something like this:
Chapter 5
[ 113 ]
What Just Happened?
We just created a map using Google Maps V2 with a few of the possible Google Maps
layer types. Because we're using a dierent version of the API here, you'll noce that our
code is slightly dierent than it was when using the standard (V3) of the Google Maps API.
Specically, the type property is dierent because V2 of the API supports dierent layer
types than Version 3 does.
Yahoo! Maps API
OpenLayers provides us with an easy way to interface with the Yahoo! mapping API as well.
We work with it similar to how we work with the Google Maps Layer class. The ocial
Yahoo! Maps API documentaon can be found at
Let's take a look!
Time for Action – using the Yahoo! Maps Layer
Let's create a map with the Yahoo! Maps Layer class.
1. In the <head> secon, we need to reference the locaon of the Yahoo! Maps API.
Add the following before the OpenLayers inclusion script tag:
2. Let's set up some Yahoo! layer objects now. Like the Google Maps Layer, we specify
the type of the layer we want by seng the type property. Let's create a hybrid
layer. The type property for Yahoo! layers start with YAHOO_MAP_, followed by a
three character code:
var yahoo_hybrid = new OpenLayers.Layer.Yahoo(
{type: YAHOO_MAP_HYB, numZoomLevels: 24}
3. Now let's create a satellite layer type. The three character code for satellite is SAT.
We'll also set a dierent amount of zoom levels to further illustrate how each base
layer can have its own amount of zoom levels:
var yahoo_satellite = new OpenLayers.Layer.Yahoo(
{type: YAHOO_MAP_SAT, numZoomLevels: 20}