<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Switch Projection</title>
    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
    <link rel="stylesheet" href="style.css" type="text/css" />
    <style type="text/css">
        #map {
            height: 512px;
        }
        #switchProjection {
            list-style: none;
        }
        /* avoid pink tiles */
        .olImageLoadError {
            background-color: transparent !important;
        }
    </style>

    <script src="../lib/OpenLayers.js"></script>
    <script type="text/javascript">

        // make map available for easy debugging
        var map;

        var switchProjection;

        OpenLayers.Control.SwitchProjection = OpenLayers.Class(OpenLayers.Control, {
            config: null,

            initialize: function(options) {
                OpenLayers.Control.prototype.initialize.apply(this, arguments);
            },

            switchTo: function(dstProjCode) {
                var cfg = this.config[dstProjCode];
                var srcProjCode = this.map.getProjection();
                if(!cfg ||
                   dstProjCode == srcProjCode) {
                    return;
                }

                var oldExtent = this.map.getExtent();

                this.resetMap(dstProjCode, cfg);
                this.resetLayers(dstProjCode, cfg);

                var tmp = this.reproject(srcProjCode, dstProjCode, oldExtent);
                var newCenter = tmp[0], newExtent = tmp[1];

                var newZoom = this.map.getZoomForExtent(newExtent, true);
                this.map.setCenter(newCenter, newZoom, false, true);
            },

            resetMap: function(projCode) {
                var cfg = this.config[projCode];
                this.map.projection = projCode;
                this.map.units = cfg.units;
                this.map.maxExtent = cfg.maxExtent;
                this.map.maxResolution = cfg.maxResolution;
                this.map.numZoomLevels = cfg.numZoomLevels;
            },

            resetLayers: function(projCode) {
                var i, len, layer;
                for(i=0,len=this.map.layers.length; i<len; i++) {
                    layer = map.layers[i];
                    layer.projection = new OpenLayers.Projection(projCode);
                    layer.maxExtent = this.config[projCode].maxExtent;
                    layer.initResolutions();
                }
            },

            reproject: function(srcProjCode, dstProjCode, oldExtent) {
                var srcProj = new OpenLayers.Projection(srcProjCode);
                var dstProj = new OpenLayers.Projection(dstProjCode);
                var center = this.map.getCenter().transform(srcProj, dstProj);
                var extent = oldExtent.transform(srcProj, dstProj);
                var maxExtent = this.config[dstProjCode].maxExtent;
                if(!maxExtent.containsLonLat(center) ||
                   !maxExtent.containsBounds(extent)) {
                    extent = maxExtent;
                    center = extent.getCenterLonLat();
                }
                return [center, extent];
            },

            CLASS_NAME: "OpenLayers.Control.SwitchProjection"
        });

        function init(){
            map = new OpenLayers.Map('map', {
                displayProjection: new OpenLayers.Projection("EPSG:4326")
            });

            var wms = new OpenLayers.Layer.WMS(
                "OpenLayers WMS",
                "http://labs.metacarta.com/wms/vmap0",
                {layers: 'basic'},
                {wrapDateLine: false}
            );

            map.addLayers([wms]);
            map.addControl(new OpenLayers.Control.LayerSwitcher());
            map.addControl(new OpenLayers.Control.MousePosition());

            switchProjection = new OpenLayers.Control.SwitchProjection({
                config: {
                    "EPSG:900913": {
                        units: "m",
                        maxExtent: new OpenLayers.Bounds(
                            -20037508.34, -20037508.34,
                             20037508.34, 20037508.34
                        ),
                        maxResolution: 156543.0339,
                        numZoomLevels: 18
                    },
                    "EPSG:4326": {
                        units: "degrees",
                        maxExtent: new OpenLayers.Bounds(
                            -180, -90, 180, 90
                        ),
                        maxResolution: 1.40625,
                        numZoomLevels: 16
                    }
                }
            });
            map.addControl(switchProjection);

            map.zoomToMaxExtent();
        }

        function switchProj(element) {
            if(element.value == "900913") {
                switchProjection.switchTo("EPSG:900913");
            } else {
                switchProjection.switchTo("EPSG:4326");
            }
        }


    </script>
  </head>
  <body onload="init()">
    <h1 id="title">Switch Projection Example</h1>

    <div id="tags">
    </div>
    <p id="shortdesc">
        This example shows how to switch from one projection to another.
        OpenLayers hasn't been designed for this, so this example includes
        hackish code that may break in further OpenLayers releases.
    </p>
    <div id="map" class="smallmap"></div>
    <ul id="switchProjection">
        <li>
            <input type="radio" name="proj" value="4326" id="4326"
                   checked="checked" onclick="switchProj(this);" />
            <label for="4326">EPSG:4326</label>
        </li>
        <li>
            <input type="radio" name="proj" value="900913" id="900913"
                   onclick="switchProj(this);" />
            <label for="900913">EPSG:900913</label>
        </li>
    </ul>
    <div id="docs">
    </div>
  </body>
</html>