Google
 

Sunday, September 11, 2011

Reprojection to EPSG:900913 using MapServer

If you are embedding a map on some web page (read: OpenLayers) and need to add layers from some third party GIS server, you're most likely to come across the word "Mercator" and its myriads of standards. Web based mapping services use Spherical Mercator, however commercial GIS services (like, Esri) might use some other standards like EPSG:4326. This incompatibility leads to a lot of trouble as OpenLayers only accepts Spherical Mercator.

From OpenLayers Docs:
Spherical Mercator is a de facto term used inside the OpenLayers community – and also the other existing Open Source GIS community – to describe the projection used by Google Maps, Microsoft Virtual Earth, Yahoo Maps, and other commercial API providers.

This term is used to refer to the fact that these providers use a Mercator projection which treats the earth as a sphere, rather than a projection which treats the earth as an ellipsoid. This affects calculations done based on treating the map as a flat plane, and is therefore important to be aware of when working with these map providers.

In order to properly overlay data on top of the maps provided by the commerical API providers, it is neccesary to use this projection. This applies primarily to displaying raster tiles over the commercial API layers – such as TMS, WMS, or other similar tiles.

In order to work well with the existing commercial APIs, many users who create data designed for use within Google Maps will also use this projection. One prime example is OpenStreetMap, whose raster map tiles are all projected into the ‘spherical mercator’ projection.

Projections in GIS are commonly referred to by their “EPSG” codes, identifiers managed by the European Petroleum Survey Group. One common identifier is “EPSG:4326”, which describes maps where latitude and longitude are treated as X/Y values. Spherical Mercator has an official designation of EPSG:3857. However, before this was established, a large amount of software used the identifier EPSG:900913. This is an unofficial code, but is still the commonly used code in OpenLayers. Any time you see the string “EPSG:4326”, you can assume it describes latitude/longitude coordinates. Any time you see the string “EPSG:900913”, it will be describing coordinates in meters in x/y.

If you are to overlay third party GIS layer, which is not in spherical mercator, you'll have to reproject the layer.
One of the reasons that the Spherical Mercator projection is so important is that it is the only projection which will allow for overlaying image data on top of commercial layers like Google Maps correctly. When using raster images, in the browser, it is not possible to reproject the images in the same way it might be in a ‘thick’ GIS client. Instead, all images must be in the same projection.

There are several tools for reprojection, but the popular (and free) one is MapServer. The process is explained here. The process works like this:

However this doesn't work. It turned out, MapServer doesn't reproject to 900913 properly (even after adding the 900913 reprojection line to /usr/share/proj/epsg). Maybe a bug.

So here's the hack: MapServer does reproject to EPSG:3857. But EPSG:3857 and EPSG:900913 are same thing. So we need to write an intermediate proxy which takes WMS request for 900913, replaces the 900913 to 3857 in the WMS request URL and redirects the request to MapServer.

Here's the PHP script (reproject.php) to act as proxy:

<?php
header("Location: http://{mapserver_address}/cgi-bin/mapserv?" . str_ireplace("epsg%3A900913","epsg%3A3857",$_SERVER['QUERY_STRING']));


1. Install MapServer. In Ubuntu,

sudo apt-get install apache2 php5 cgi-mapserver mapserver-bin


for verification, check http://localhost/cgi-bin/mapserv

2. Put the reproject.php file to web root (/var/www)

3. Write a configuration file (say, wms.map) and place it in the same folder as mapserv (usually at /usr/lib/cgi-bin/)

MAP

NAME "reprojected_wms"
PROJECTION
"init=epsg:3857"
END

WEB
IMAGEPATH "/var/www/docs_maps/"
IMAGEURL "http://{mapserver_address}/docs_maps/"

METADATA
"wms_title" "Reprojected WMS
"wms_onlineresource" "http://{mapserver_address}/reproject.php?map=wms.map&"
"wms_srs" "EPSG:3857"
"wms_server_version" "1.1.1"
END
END

EXTENT 8865484.246776307 3016430.900654626 9864020.0791919 3587377.91450212

LAYER
NAME "My Layer
TYPE RASTER
STATUS OFF
CONNECTION "http://{GIS_Server}/WMSServer?"
CONNECTIONTYPE WMS
PROJECTION
"init=epsg:3857"
END
METADATA
"wms_title" "GIS Layer"
"wms_srs" "EPSG:3857"
"wms_name" "1"
"wms_server_version" "1.1.1"
"wms_format" "image/png"
"wms_cache_to_disk" "1"
END

END
CONFIG "PROJ_LIB" "/usr/share/proj"

END


Now use the WMS URL http://{mapserver_address}/reproject.php?map=wms.map& wherever needed.

Many thanks to Prabhas for devising the steps and helping me with this blog.

2 comments:

  1. Nice practice of micro-mini-engineering for me.. :) :) :) Reading Reading and getting nothing..

    ReplyDelete
  2. Enormous piece of writing! Great information for Reprojection to EPSG:900913 using MapServer! Keyword research is important work in seo! I am pleased about it. I utterly agree with you! Great work!

    ReplyDelete