OpenLayers – An Alternative to Google Maps

Arno Slatius

Most of you have probably at some point used or looked at the Google Maps API or Bing Maps API because you wanted a fancy map on a contact page with a pointer on it. Let’s be honest; it adds an interactive element to the page which might give it a little more wow effect. Unfortunately, Google for one doesn’t allow you to use their maps in an area of your site that requires authentication.

OpenLayers gives you a way to visualize your data the way you want it in any environment. You are not bound by provided map material and can choose from a wide variety of map backgrounds. The OpenStreetMap is one of the best examples, maintained by volunteers like you and me. You’re allowed to update the map itself if you come across any flaws. The interface for this is easy and they’ll implement your change immediately.

Getting Started

The OpenLayers basics are simple – include the JavaScript in your page, place a div with an id and pass that to OpenLayers. The following example uses jQuery to load OpenLayers, but jQuery is not required.

jQuery(window).on('load', function() {
  var map = new OpenLayers.Map('map', {
    projection: new OpenLayers.Projection('EPSG:900913')
  });
  var osm = new OpenLayers.Layer.OSM();            
  var gmap = new OpenLayers.Layer.Google('Google street maps');
  var bing = new OpenLayers.Layer.Bing({
    key: 'register your api key at bingmapsportal.com',
    type: 'Road',
    metadataParams: { mapVersion: 'v1' }
  });

  map.addLayers([osm, gmap, bing]);
  map.setCenter(new OpenLayers.LonLat(2.2, 54.0)
    .transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject()), 5);
  map.addControl(new OpenLayers.Control.LayerSwitcher());
});

OpenLayers combine OSM, Bing and Google map layers

And now we have one map which holds the OpenStreet map, Google Street map, and Bing Street map.

There is one thing that I feel needs explanation. On the first line, you’ll see something about projections. What’s that you might ask? A projection is a way to see the world. For some time in the past the earth was believed to be flat and projections are a way to make the earth flat again. We all know the WGS84 coordinate system from our GPS (aka. EPSG:4326), but most countries have one or more projections which they use for their geographical data.

Quite popular in these applications is the Spherical Mercator projection (EPSG:900913), which is also used by Google and Bing. So that is why we tell OpenLayers to use that one. This is where OpenLayers excels. You can set different projections on each layer or data, and OpenLayers will handle the transformation between them.

The rest of the example speaks for itself – create all the map layers, add them to the view, center on some place (note the transformation again), and show a layer switcher.

Let’s Place Something on the Map

Now, let’s add our own thing to the map. For OpenLayers this means adding a vector layer. A vector layer will contain features which are made up of geometries. Let’s start with a simple one and add your location to the map. Here’s how it’s done.

var overlay = new OpenLayers.Layer.Vector('Your location');
var map = new OpenLayers.Map('map');

map.addLayers([new OpenLayers.Layer.OSM('OSM'), overlay]);
map.setCenter(
  new OpenLayers.LonLat(2.2, 54.0).transform(
    new OpenLayers.Projection('EPSG:4326'),
    map.getProjectionObject()
  ), 11);

navigator.geolocation.getCurrentPosition(function(position) {
  var yourLocation = new OpenLayers.Geometry.Point(position.coords.longitude, position.coords.latitude)
        .transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());

  map.getLayersByName('Your location')[0].addFeatures([new OpenLayers.Feature.Vector(yourLocation)]);
  map.setCenter(new OpenLayers.LonLat(yourLocation.getCentroid().x, yourLocation.getCentroid().y)); 
});

Openlayers put yourself on the map

The first line adds the vector layer. A point is created, based on your location, which is added as a feature to the vector layer. The map is then centered on you.

Adding Your Own Style

Would you be satisfied with orange dots on the map? Probably not. Luckily, it’s quite simple to customize your map with your own style map. Each layer can have a different style. On a layer there can be different styles for normal features (‘default’) or ‘selected’ features. Here’s an example of a simple style map with only a ‘default’ style.

var styleMap = new OpenLayers.StyleMap({
  pointRadius: 20,
  strokeColor: '#ff0000',
  fillColor: '#ff0000',
  fillOpacity: 0.6
});
var overlay = new OpenLayers.Layer.Vector('Your position', {styleMap: styleMap});

This causes our location to be displayed as a somewhat transparent red dot. But, we can go even further with this. If your features have attributes, you can tell the style to use those named attributes like this.

var styleMap = new OpenLayers.StyleMap({
  pointRadius: '$(pointRadius)',
  strokeColor: '#ff0000',
  fillColor: '$(pointColor)',
  fillOpacity: 0.6
});

If you have other requirements you can go even further. Define a context with references to functions which will be passed the current feature being rendered. From there control the rendering. An example of this is shown below.

var context = {
  getColor: function(feature) {
    return '#00ff00';
  },
  getPointRadius: function(feature) {
    return 15;
  }
}
var template = {
  strokeColor: '${getColor}',
  pointRadius: '${getPointRadius}',
}
var styleMap = new OpenLayers.StyleMap(new OpenLayers.Style(template, {context: context}));

Dynamic Map Data

Now, if you’re following along then you have something to show, right? Let’s talk about how you query your own back end for data to display. Below you see an example of a dynamic vector layer.

var myLayer = new OpenLayers.Layer.Vector('My vector data', {
  strategies: [new OpenLayers.Strategy.BBOX()],
  protocol: new OpenLayers.Protocol.HTTP({
    url: 'http://my.server.net/geoData',
    params: {
        src: map.projection,
        maxfeatures: 1500,
    },
    format: new OpenLayers.Format.GeoJSON(),
  }),
  styleMap: new OpenLayers.StyleMap(style),
});

The Bounding Box (BBOX) strategy will read new features when the views bounding box changes. I’ve chosen to use GeoJSON as the return format from my URL. OpenLayer supports many formats – KML, XML, GPX, XLS, CSV, JSON, GeoJSON, GeoRSS, and many more.

You’ll get a request there with a bounding parameter bbox=left,bottom,right,top. Those are the outer bounds of the current viewport. It is wise to pass yourself the projection of the layer for verification. I’ve also added maxFeatures to tell my back end how much to return. Here it’s set at 1500, which is quite a lot. Current web browsers might start to show problems depending on the performance of you users’ computers/devices. Moving around >500 elements in the DOM and rendering them might be a lot to ask. OpenLayers has a solution for that called Clustering.

var myLayer = new OpenLayers.Layer.Vector("My vector data", {
  strategies: [new OpenLayers.Strategy.BBOX(),
               new OpenLayers.Strategy.AnimatedCluster({
                  distance: 10,
                  animationMethod: OpenLayers.Easing.Expo.easeInOut,
                  animationDuration: 10
              })],
  protocol: new OpenLayers.Protocol.HTTP({
      ...
});

You can add that as a strategy to your layer so that it’ll start clustering your points if they are within a certain radius. In my example here I use the Animated Cluster strategy which you can download. It does the same with a fancy animation.

Now you have a solution that’ll ask you what you want to show within the users area. If features come too close it’ll nicely cluster them. You could add a different style to a cluster to show just that. It’s really up to you to decide!

Conclusion

With OpenLayers you get a lot of freedom in the way you supply and visualize your data. Take a look at the examples and API description at the OpenLayers website, and see how you can also draw on your vector layer. Don’t forget to check and update your neighborhood in the OpenStreetMap if you do use it.

We’re interested to hear if you see possibilities to use OpenLayers. Or perhaps you’ve already implemented it somewhere. Please let us know in the comments.

You can see the code from this article in action on the demo page.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • M S

    I really hate the washed out low-contrast look that’s so very trendy right now.
    It looks awful, and it harder to use.

    Is there any way to fix that so it looks more like the other maps?

    • http://www.abdmaster.com/ Ahmedul Haque Abid

      I feel the same… looks bad. Would be good if possible to change interface color.

  • amit d

    I had worked on Bing Maps API in 2012 while developing a GIS Desktop Application in Silverlight and Telerik Controls. Now, really want to implement this.

  • amit d

    OK, thanks for the update

  • http://www.ericlin.me Eric Lin

    Same here, looks a bit odd, maybe we are just used to Google Maps.

  • Adam Thede

    Honestly, this seems like a solution in search of a problem. Google Maps is light years ahead of every other mapping platform in accuracy, features, and design. A community supported option seems unnecessary and problematic, IMHO.

    • http://www.slatius.nl Arno Slatius

      I think I understand your point about the maps.
      Have you ever seriously tried to make a contribution to Google’s map? I find it highly frustrating. You cannot edit all the flaws you see and everything has to be validated which frustrates the process even further. OSM allows you to edit everything and commits it immediately. I don’t know so sure about accuracy by the way, I see loads of errors in the maps that I can’t fix with the editor.
      An other argument is that Google’s usage policy forbids the use of their map in a restricted area. You’ll have to buy a business licence then.