How to create an online map with a non-Mercator Projection: Part 2

In the first part of this article we created a WMS server of basemaps using an unconventional map projection (the Mollweide projection). In this second part, we shall implement the client side of the project, creating a working application that will plot user data on the basemaps.

The end result can be seen on the website. Note: this website also offers the ability to plot external data files – something we shall not be covering in this article.

In common with many MapServer applications, we shall be using the OpenLayers toolkit to create the web map. This can be easily configured to view WMS tiles. Additional layers can be added to plot other data (eg. GeoRSS or KML). The latest version of OpenLayers can be downloaded from the main OpenLayers website. In order to implement a scalebar, you will need the OpenLayers ScaleBar add-in. This may be automatically included in your OpenLayers package. If it is not, it can be downloaded from the OpenLayers website, here.

Finally, we will be using the Proj4JS library to transform coordinates from the geographic WGS84 coordinates (eg. as used by KML files) to our chosen projection (Mollweide WGS84 in our case). OpenLayers uses Proj4JS to perform the transformations, but the standard OpenLayers package does not include it. Proj4JS can be downloaded from the Proj4JS website.

After everything has been downloaded and installed, we can create the actual client webpage. This is a simple application with one HTML webpage. The website implements a number of different projections on different pages, and uses PHP for various reasons. Here, I shall simply present HTML fragments.

First we need to define the required styles, and to include the various JavaScript libraries. The following code, located in the header, performs this:

{include_code_listing /usr/www/users/winwaed/geowebguru/img/2009/proj_html_styledefs.html }


Note that you may need to modify the paths, depending on where you installed the code. The styles include special styles for popup windows, the scale bar, and the map object.

Next we come to the functionality. This is implemented as JavaScript, and should also be included in the page’s header:

{include_code_listing /usr/www/users/winwaed/geowebguru/img/2009/proj_html_js.js }


The first section of this code, defines the parameters for the different map projections in Proj4JS. These are standard Proj.4 definitions. We only actually need the EPSG:54009 definition in this example, but the others are included for reference. EPSG:102012 is our own invention, required due to the lack of a an EPSG code for the Craster Parabolic projection that uses WGS84. Inventing codes like this was mentioned in Part 1.

Note also that Proj4JS does not ship with all of these projection types. “moll” (Mollweide) is implemented as standard, but most of the others are not. This does not matter if you are only plotting WMS data using the missing projection type, but it must be implemented if you are to use OpenLayers to transform between coordinate systems (eg. to plot KML data). side-stepped the issue by only implementing the overlay maps for three of these projections. Type “cea” (Cylindrical Equal Area – used by the Behrmann projection) was considered too important, so I had to write my own projection transformation code. This is an excellent example of the value of open source: It is possible to implement your own missing features! I have submitted the “cea” code to the Proj4JS source tree, and it should be included in the next distribution.

The init() function creates the map and the WMS base map. This is a standard OpenLayers initialization routine, except the bounds are defined in metres for the EPSG:54009 coordinate system (Mollweide, WGS84).

addGeoRSS() and addKML() are button callback functions. These add data layers using data feeds (GeoRSS or KML, respectively) entered by the user into an edit box. Again, these are fairly standard “add layer” OpenLayer implementations. Note that they explicitly state the coordinate system used by the input data (EPSG: 4326 – geographic WGS84). This ensures OpenLayers knows the coordinates need to be transformed to the map’s coordinate system (EPSG:54009 Mollweide). The GeoRSS callback also has some code which uses different colored marker icons for each successive layer – cycling through four different icons. KML usually has styling information and does not need this marker system.

Note that both the GeoRSS and KML data feeds must be on the same domain as your client webpage. This is due to a security feature in JavaScript that prohibits a JavaScript program from loading an XML file from a different domain. There are ways around this, but they are beyond the scope of this article.

The remaining callbacks are standard OpenLayers callbacks for icon popup balloon handling.

For completeness, here are the essential parts of the HTML:

{include_code_listing /usr/www/users/winwaed/geowebguru/img/2009/proj_html.html }

This defines the body onInit callback to init(), the map div object, and the form that allows a user to enter the GeoRSS and KML data feed URLs.

And that is it! You have the core of a working map application that uses an equal area projection that is not provided by any of the main map providers. The basemap uses the equal area projection, and the OpenLayers client re-projects input data to a matching coordinate system.

A complete example can be seen at implements a number of different equal area projections, and allows overlays to be added to three of them. Unlike the above example, it can read data feeds from other sites.

Leave a Reply