From 9fd7463680cbd529d50e12a520f0fdc7080118ad Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 29 Jul 2010 17:23:10 +0000 Subject: [PATCH] Making it so layers that use the SphericalMercator mixin call getLonLatFromViewPortPx and getViewPortPxFromLonLat on the Layer prototype instead of relying on the underlying map object for pixel to map location translations. This allows the Google (and other SM) layers to be used as a base layer but not be visible (with allOverlays set true on the map). r=ahocevar (closes #2759) git-svn-id: http://svn.openlayers.org/trunk/openlayers@10554 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Layer/Google.js | 8 ++ lib/OpenLayers/Layer/SphericalMercator.js | 32 ++++++++ lib/OpenLayers/Layer/VirtualEarth.js | 8 ++ lib/OpenLayers/Layer/Yahoo.js | 8 ++ tests/Layer/Google/v3.html | 95 +++++++++++++++++++++++ 5 files changed, 151 insertions(+) diff --git a/lib/OpenLayers/Layer/Google.js b/lib/OpenLayers/Layer/Google.js index 1759391100..1d84ceff82 100644 --- a/lib/OpenLayers/Layer/Google.js +++ b/lib/OpenLayers/Layer/Google.js @@ -69,6 +69,14 @@ OpenLayers.Layer.Google = OpenLayers.Class( */ type: null, + /** + * APIProperty: wrapDateLine + * {Boolean} Allow user to pan forever east/west. Default is true. + * Setting this to false only restricts panning if + * is true. + */ + wrapDateLine: true, + /** * APIProperty: sphericalMercator * {Boolean} Should the map act as a mercator-projected map? This will diff --git a/lib/OpenLayers/Layer/SphericalMercator.js b/lib/OpenLayers/Layer/SphericalMercator.js index 730d8305b1..fddf11d327 100644 --- a/lib/OpenLayers/Layer/SphericalMercator.js +++ b/lib/OpenLayers/Layer/SphericalMercator.js @@ -50,6 +50,38 @@ OpenLayers.Layer.SphericalMercator = { return extent; }, + /** + * Method: getLonLatFromViewPortPx + * Get a map location from a pixel location + * + * Parameters: + * viewPortPx - {} + * + * Returns: + * {} An OpenLayers.LonLat which is the passed-in view + * port OpenLayers.Pixel, translated into lon/lat by map lib + * If the map lib is not loaded or not centered, returns null + */ + getLonLatFromViewPortPx: function (viewPortPx) { + return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this, arguments); + }, + + /** + * Method: getViewPortPxFromLonLat + * Get a pixel location from a map location + * + * Parameters: + * lonlat - {} + * + * Returns: + * {} An OpenLayers.Pixel which is the passed-in + * OpenLayers.LonLat, translated into view port pixels by map lib + * If map lib is not loaded or not centered, returns null + */ + getViewPortPxFromLonLat: function (lonlat) { + return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this, arguments); + }, + /** * Method: initMercatorParameters * Set up the mercator parameters on the layer: resolutions, diff --git a/lib/OpenLayers/Layer/VirtualEarth.js b/lib/OpenLayers/Layer/VirtualEarth.js index ebccc68afe..c4a63e0fbe 100644 --- a/lib/OpenLayers/Layer/VirtualEarth.js +++ b/lib/OpenLayers/Layer/VirtualEarth.js @@ -65,6 +65,14 @@ OpenLayers.Layer.VirtualEarth = OpenLayers.Class( */ type: null, + /** + * APIProperty: wrapDateLine + * {Boolean} Allow user to pan forever east/west. Default is true. + * Setting this to false only restricts panning if + * is true. + */ + wrapDateLine: true, + /** * APIProperty: sphericalMercator * {Boolean} Should the map act as a mercator-projected map? This will diff --git a/lib/OpenLayers/Layer/Yahoo.js b/lib/OpenLayers/Layer/Yahoo.js index 4bbcef67ea..bde68903ca 100644 --- a/lib/OpenLayers/Layer/Yahoo.js +++ b/lib/OpenLayers/Layer/Yahoo.js @@ -63,6 +63,14 @@ OpenLayers.Layer.Yahoo = OpenLayers.Class( */ type: null, + /** + * APIProperty: wrapDateLine + * {Boolean} Allow user to pan forever east/west. Default is true. + * Setting this to false only restricts panning if + * is true. + */ + wrapDateLine: true, + /** * APIProperty: sphericalMercator * {Boolean} Should the map act as a mercator-projected map? This will diff --git a/tests/Layer/Google/v3.html b/tests/Layer/Google/v3.html index 30a2c7a429..6d5df4ed9e 100644 --- a/tests/Layer/Google/v3.html +++ b/tests/Layer/Google/v3.html @@ -260,6 +260,101 @@ map.destroy(); } + + function test_allOverlays_pan(t) { + + t.plan(8); + + var map = new OpenLayers.Map('map', {allOverlays: true}); + + var gmap = new OpenLayers.Layer.Google("Google Streets"); + var osm = new OpenLayers.Layer.OSM(); + map.addLayers([gmap, osm]); + + var origin = new OpenLayers.LonLat(1000000, 6000000); + map.setCenter(origin, 4); + var resolution = map.getResolution(); + + var dx, dy, center, expectedX, expectedY; + + // confirm that panning works with Google visible + dx = 100, dy = -100; + map.pan(dx, dy, {animate: false}); + center = map.getCenter(); + expectedX = origin.lon + (resolution * dx); + expectedY = origin.lat - (resolution * dy); + t.eq(center.lon, expectedX, "x panning with Google visible " + dx + ", " + dy); + t.eq(center.lat, expectedY, "y panning with Google visible " + dx + ", " + dy); + map.pan(-dx, -dy, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, origin.lon, "x panning with Google visible " + (-dx) + ", " + (-dy)); + t.eq(center.lat, origin.lat, "y panning with Google visible " + (-dx) + ", " + (-dy)); + + // confirm that panning works with Google invisible + gmap.setVisibility(false); + dx = 100, dy = -100; + map.pan(dx, dy, {animate: false}); + center = map.getCenter(); + expectedX = origin.lon + (resolution * dx); + expectedY = origin.lat - (resolution * dy); + t.eq(center.lon, expectedX, "x panning with Google invisible " + dx + ", " + dy); + t.eq(center.lat, expectedY, "y panning with Google invisible " + dx + ", " + dy); + map.pan(-dx, -dy, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, origin.lon, "x panning with Google invisible " + (-dx) + ", " + (-dy)); + t.eq(center.lat, origin.lat, "y panning with Google invisible " + (-dx) + ", " + (-dy)); + + map.destroy(); + + } + + function test_wrapDateLine(t) { + t.plan(2); + + var map = new OpenLayers.Map("map"); + + var gmap = new OpenLayers.Layer.Google("Google Streets"); + map.addLayer(gmap); + map.setCenter(new OpenLayers.LonLat(0, 0), 1); + + var center; + + // pan to the edge of the world + map.pan(256, 0, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, 20037508.3392, "edge of the world"); + // pan off the edge of the world + map.pan(100, 0, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, -12210356.6442, "magically back in the western hemisphere"); + + map.destroy(); + + } + + function test_respectDateLine(t) { + t.plan(2); + + var map = new OpenLayers.Map("map"); + + var gmap = new OpenLayers.Layer.Google("Google Streets", {wrapDateLine: false}); + map.addLayer(gmap); + map.setCenter(new OpenLayers.LonLat(0, 0), 1); + + var center; + + // pan to the edge of the world + map.pan(256, 0, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, 20037508.3392, "edge of the world"); + // pan off the edge of the world + map.pan(100, 0, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, 20037508.3392, "whew, still on the edge"); + + map.destroy(); + + }