[OpenLayers-Users] Unable to use both OpenLayers.Layer.Google and OpenLayers.Layer.TMS

Nick Burch nick at torchbox.com
Tue Jul 17 12:26:34 EDT 2007


On Tue, 5 Jun 2007, Nick Burch wrote:
> Attached is a patch for GoogleMercator which sorts this. It checks to 
> see if the overall maps projection is set to EPSG:41001 or not. If it's 
> not, the current behaviour applies. If it is, then it uses slightly 
> different conversion routines, which allow it to be compatible.

I've just noticed I got the logic in the forwardMercator41001 function 
slightly off, and I had the x and y variables the wrong way around

The attached patch gets them right, and also allows you to specify a 
projection property to the constructor, so it can get the max resolution 
correct (41001 and 54004 have a very slightly different one). It's against 
the latest tschaub sandbox checkout.

Nick
-------------- next part --------------
--- GoogleMercator.js.sav	2007-06-05 15:28:53.000000000 +0100
+++ GoogleMercator.js	2007-07-17 17:19:49.000000000 +0100
@@ -19,6 +19,7 @@
     rMajor: 6378137.0,
     rMinor: 6356752.31424518,
     eccent: Math.sqrt(1.0 - Math.pow(6356752.31424518 / 6378137.0, 2)),
+    halfExt41001: 20037508.34,
 
     /** 
      * @constructor
@@ -26,13 +27,19 @@
      * @param {String} name
      */
     initialize: function(name, options) {
-        // set up properties for Mercator - assume EPSG:54004
+        // set up properties for Mercator - assume EPSG:54004, unless
+        //  EPSG:41001 is specified
         this.RESOLUTIONS = new Array();
         var maxResolution = 156543.0339;
+        this.projection = "EPSG:54004";
+        if(options['projection'] == 'EPSG:41001') {
+           maxResolution = 156543;
+           this.projection = options['projection'];
+        }
+
         for(var zoom=this.MIN_ZOOM_LEVEL; zoom<=this.MAX_ZOOM_LEVEL; ++zoom) {
             this.RESOLUTIONS[zoom] = maxResolution / Math.pow(2, zoom);
         }
-        this.projection = "EPSG:54004";
         this.units = "m";
         OpenLayers.Layer.Google.prototype.initialize.apply(this, arguments);
     },
@@ -159,7 +166,8 @@
     },
     
     /**
-     * Given a point in EPSG:4326, return a point in EPSG:54005 (Mercator)
+     * Given a point in EPSG:4326, return a point in EPSG:54005 (Mercator),
+     *  or EPSG:41001 if that's set for the map.
      *
      * @param {OpenLayers.LonLat|GLatLng} lonlat
      * @type OpenLayers.LonLat
@@ -174,7 +182,37 @@
             lon = lonlat.lon;
             lat = lonlat.lat;
         }
-        
+
+		if(this.map.projection == "EPSG:41001") {
+			return this.forwardMercator41001(lon,lat);
+		}
+		return this.forwardMercator54005(lon,lat);
+	},
+
+    /**
+     * Given a point in EPSG:4326, return a point in EPSG:41001 (Google Modified Mercator)
+     *
+     * @param {OpenLayers.LonLat|GLatLng} lonlat
+     * @type OpenLayers.LonLat
+     * @returns The coordinates transformed to Mercator
+     */
+	forwardMercator41001: function(lon,lat) {    
+		var y = Math.log( Math.tan( (90+lat) * Math.PI / 360 ) ) / (Math.PI/180);	
+		y = y * this.halfExt41001 / 180;
+
+		var x = lon * this.halfExt41001 / 180;
+		
+        return new OpenLayers.LonLat(x, y);
+	},
+    
+    /**
+     * Given a point in EPSG:4326, return a point in EPSG:54005 (Mercator)
+     *
+     * @param {OpenLayers.LonLat|GLatLng} lonlat
+     * @type OpenLayers.LonLat
+     * @returns The coordinates transformed to Mercator
+     */
+	forwardMercator54005: function(lon,lat) {    
         // convert to radians
         if(lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) {
             lat *= this.deg2rad;
@@ -202,7 +240,8 @@
     },
 
     /**
-     * Given a point in EPSG:54005 (Mercator), return a point in EPSG:4326.
+     * Given a point in EPSG:54005 (Mercator) or EPSG:41001 (if set for the
+     *  overall Map), return a point in EPSG:4326.
      * Ignore that the argument type is named LonLat - these are coordinates in
      * a Mercator projection, with units of meters.
      *
@@ -211,7 +250,42 @@
      * @returns The coordinates transformed to EPSG:4326
      */
     inverseMercator: function(merc) {
+		if(this.map.projection == "EPSG:41001") {
+			return this.inverseMercator41001(merc);
+		}
+		return this.inverseMercator54005(merc);
+	},
+
+    /**
+     * Given a point in EPSG:41001 (Google Modified Mercator), return a point in EPSG:4326.
+     * Ignore that the argument type is named LonLat - these are coordinates in
+     * a Mercator projection, with units of meters.
+     *
+     * @param {OpenLayers.LonLat} merc
+     * @type OpenLayers.LonLat
+     * @returns The coordinates transformed to EPSG:4326
+     */
+    inverseMercator41001: function(merc) {
+		var lon = merc.lon * 180 / this.halfExt41001;
+		var lat = merc.lat * 180 / this.halfExt41001;
+
+		lat = lat * Math.PI / 180;
+		lat = Math.atan( Math.pow(Math.E,lat) ) / PI * 360
+		lat = lat - 90
 
+        return new OpenLayers.LonLat(lon, lat);
+	},
+
+    /**
+     * Given a point in EPSG:54005 (Mercator), return a point in EPSG:4326.
+     * Ignore that the argument type is named LonLat - these are coordinates in
+     * a Mercator projection, with units of meters.
+     *
+     * @param {OpenLayers.LonLat} merc
+     * @type OpenLayers.LonLat
+     * @returns The coordinates transformed to EPSG:4326
+     */
+    inverseMercator54005: function(merc) {
         // calculate latitude
         var temp = this.rMinor / this.rMajor;
         var ts = Math.exp(-merc.lat / this.rMajor);


More information about the Users mailing list