Merge pull request #484 from ahocevar/484
Rework Google layer. r=@bartvde
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers All Overlays with Google and OSM</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers Google (v3) Layer Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers Google (v3) Layer Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
@@ -30,21 +29,6 @@
|
||||
spherical mercator projection. See the
|
||||
<a href="google-v3.js" target="_blank">google-v3.js source</a>
|
||||
to see how this is done.
|
||||
<p>
|
||||
In order to position the Google attribution div in the default
|
||||
location, you must include the extra theme/default/google.css
|
||||
stylesheet.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Note on Google Maps API versioning:</strong>
|
||||
This example uses the "nightly" version of Google Maps
|
||||
API. This is specified by using <code>v=3</code> in the
|
||||
the Google Maps API URL. Production applications should use the
|
||||
"release" or "frozen" versions of Google Maps
|
||||
API. See the <code>OpenLayers.Layer.Google.v3</code> API
|
||||
docs, and the
|
||||
<a href="https://developers.google.com/maps/documentation/javascript/basics#Versioning">Versioning Section</a>
|
||||
of the Google Maps API docs, for more details.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
map = new OpenLayers.Map('map');
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
var gphy = new OpenLayers.Layer.Google(
|
||||
map = new OpenLayers.Map('map', {
|
||||
projection: 'EPSG:3857',
|
||||
layers: [
|
||||
new OpenLayers.Layer.Google(
|
||||
"Google Physical",
|
||||
{type: google.maps.MapTypeId.TERRAIN}
|
||||
);
|
||||
var gmap = new OpenLayers.Layer.Google(
|
||||
),
|
||||
new OpenLayers.Layer.Google(
|
||||
"Google Streets", // the default
|
||||
{numZoomLevels: 20}
|
||||
);
|
||||
var ghyb = new OpenLayers.Layer.Google(
|
||||
),
|
||||
new OpenLayers.Layer.Google(
|
||||
"Google Hybrid",
|
||||
{type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20}
|
||||
);
|
||||
var gsat = new OpenLayers.Layer.Google(
|
||||
),
|
||||
new OpenLayers.Layer.Google(
|
||||
"Google Satellite",
|
||||
{type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}
|
||||
);
|
||||
|
||||
map.addLayers([gphy, gmap, ghyb, gsat]);
|
||||
|
||||
// Google.v3 uses EPSG:900913 as projection, so we have to
|
||||
)
|
||||
],
|
||||
center: new OpenLayers.LonLat(10.2, 48.9)
|
||||
// Google.v3 uses web mercator as projection, so we have to
|
||||
// transform our coordinates
|
||||
map.setCenter(new OpenLayers.LonLat(10.2, 48.9).transform(
|
||||
new OpenLayers.Projection("EPSG:4326"),
|
||||
map.getProjectionObject()
|
||||
), 5);
|
||||
.transform('EPSG:4326', 'EPSG:3857'),
|
||||
zoom: 5
|
||||
});
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
// add behavior to html
|
||||
var animate = document.getElementById("animate");
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers OSM and Google Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
right: inherit;
|
||||
width: 400px;
|
||||
}
|
||||
/* conditionally position control differently for Google Maps */
|
||||
.olForeignContainer div.olControlMousePosition {
|
||||
bottom: 28px;
|
||||
}
|
||||
#map {
|
||||
height: 512px;
|
||||
}
|
||||
@@ -38,7 +42,12 @@
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
|
||||
<div id="docs"></div>
|
||||
<div id="docs">
|
||||
<p>Note that maps with Google layers are a special case, because we
|
||||
cannot control the position of the attribution. To conditionally
|
||||
position controls differently for Google layers, prepend the
|
||||
css selector with <code>.olForeignContainer</code>.</p>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new OpenLayers.Map({
|
||||
|
||||
@@ -15,35 +15,6 @@
|
||||
*
|
||||
* To use this layer, you must include the GMaps v3 API in your html.
|
||||
*
|
||||
* Because OpenLayers needs to control mouse events, it isolates the GMaps mapObject
|
||||
* (the DOM elements provided by Google) using the EventPane.
|
||||
* However, because the Terms of Use require some of those elements,
|
||||
* such as the links to Google's terms, to be clickable, these elements have
|
||||
* to be moved up to OpenLayers' container div. There is however no easy way
|
||||
* to identify these, and the logic (see the repositionMapElements function
|
||||
* in the source) may need to be changed if Google changes them.
|
||||
* These elements are not part of the published API and can be changed at any time,
|
||||
* so a given OpenLayers release can only guarantee support for the 'frozen'
|
||||
* Google release at the time of the OpenLayers release. See
|
||||
* https://developers.google.com/maps/documentation/javascript/basics#Versioning
|
||||
* for Google's current release cycle.
|
||||
*
|
||||
* For this reason, it's recommended that production code specifically loads
|
||||
* the current frozen version, for example:
|
||||
*
|
||||
* (code)
|
||||
* <script src="http://maps.google.com/maps/api/js?v=3.7&sensor=false"></script>
|
||||
* (end)
|
||||
*
|
||||
* but that development code should use the latest 'nightly' version, so that any
|
||||
* problems can be dealt with as soon as they arise, and before they affect the production, 'frozen', code.
|
||||
*
|
||||
* Note, however, that frozen versions are retired as part of Google's release
|
||||
* cycle, and once this happens, you will get the next version, in the example above, 3.8 once 3.7 is retired.
|
||||
*
|
||||
* This version supports 3.7.
|
||||
*
|
||||
*
|
||||
* Note that this layer configures the google.maps.map object with the
|
||||
* "disableDefaultUI" option set to true. Using UI controls that the Google
|
||||
* Maps API provides is not supported by the OpenLayers API.
|
||||
@@ -98,18 +69,13 @@ OpenLayers.Layer.Google.v3 = {
|
||||
++cache.count;
|
||||
} else {
|
||||
// this is the first Google layer for this map
|
||||
|
||||
var container = this.map.viewPortDiv;
|
||||
var div = document.createElement("div");
|
||||
div.id = this.map.id + "_GMapContainer";
|
||||
div.style.position = "absolute";
|
||||
div.style.width = "100%";
|
||||
div.style.height = "100%";
|
||||
container.appendChild(div);
|
||||
|
||||
// create GMap and shuffle elements
|
||||
// create GMap
|
||||
var center = this.map.getCenter();
|
||||
mapObject = new google.maps.Map(div, {
|
||||
var container = document.createElement('div');
|
||||
container.className = "olForeignContainer";
|
||||
container.style.width = '100%';
|
||||
container.style.height = '100%';
|
||||
mapObject = new google.maps.Map(container, {
|
||||
center: center ?
|
||||
new google.maps.LatLng(center.lat, center.lon) :
|
||||
new google.maps.LatLng(0, 0),
|
||||
@@ -122,95 +88,30 @@ OpenLayers.Layer.Google.v3 = {
|
||||
scrollwheel: false,
|
||||
streetViewControl: false
|
||||
});
|
||||
var googleControl = document.createElement('div');
|
||||
googleControl.style.width = '100%';
|
||||
googleControl.style.height = '100%';
|
||||
mapObject.controls[google.maps.ControlPosition.TOP_LEFT].push(googleControl);
|
||||
|
||||
// cache elements for use by any other google layers added to
|
||||
// this same map
|
||||
cache = {
|
||||
googleControl: googleControl,
|
||||
mapObject: mapObject,
|
||||
count: 1
|
||||
};
|
||||
OpenLayers.Layer.Google.cache[this.map.id] = cache;
|
||||
this.repositionListener = google.maps.event.addListenerOnce(
|
||||
mapObject,
|
||||
"center_changed",
|
||||
OpenLayers.Function.bind(this.repositionMapElements, this)
|
||||
);
|
||||
}
|
||||
this.mapObject = mapObject;
|
||||
this.setGMapVisibility(this.visibility);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: repositionMapElements
|
||||
*
|
||||
* Waits until powered by and terms of use elements are available and then
|
||||
* moves them so they are clickable.
|
||||
*/
|
||||
repositionMapElements: function() {
|
||||
|
||||
// This is the first time any Google layer in this mapObject has been
|
||||
// made visible. The mapObject needs to know the container size.
|
||||
google.maps.event.trigger(this.mapObject, "resize");
|
||||
|
||||
var div = this.mapObject.getDiv().firstChild;
|
||||
if (!div || div.childNodes.length < 3) {
|
||||
this.repositionTimer = window.setTimeout(
|
||||
OpenLayers.Function.bind(this.repositionMapElements, this),
|
||||
250
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
var cache = OpenLayers.Layer.Google.cache[this.map.id];
|
||||
var container = this.map.viewPortDiv;
|
||||
|
||||
// move the ToS and branding stuff up to the container div
|
||||
// depends on value of zIndex, which is not robust
|
||||
for (var i=div.children.length-1; i>=0; --i) {
|
||||
if (div.children[i].style.zIndex == 1000001) {
|
||||
var termsOfUse = div.children[i];
|
||||
container.appendChild(termsOfUse);
|
||||
termsOfUse.style.zIndex = "1100";
|
||||
termsOfUse.style.bottom = "";
|
||||
termsOfUse.className = "olLayerGoogleCopyright olLayerGoogleV3";
|
||||
termsOfUse.style.display = "";
|
||||
cache.termsOfUse = termsOfUse;
|
||||
}
|
||||
if (div.children[i].style.zIndex == 1000000) {
|
||||
var poweredBy = div.children[i];
|
||||
container.appendChild(poweredBy);
|
||||
poweredBy.style.zIndex = "1100";
|
||||
poweredBy.style.bottom = "";
|
||||
poweredBy.className = "olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint";
|
||||
poweredBy.style.display = "";
|
||||
cache.poweredBy = poweredBy;
|
||||
}
|
||||
if (div.children[i].style.zIndex == 10000002) {
|
||||
container.appendChild(div.children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.setGMapVisibility(this.visibility);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: onMapResize
|
||||
*/
|
||||
onMapResize: function() {
|
||||
if (this.visibility) {
|
||||
google.maps.event.trigger(this.mapObject, "resize");
|
||||
} else {
|
||||
var cache = OpenLayers.Layer.Google.cache[this.map.id];
|
||||
if (!cache.resized) {
|
||||
var layer = this;
|
||||
google.maps.event.addListenerOnce(this.mapObject, "tilesloaded", function() {
|
||||
google.maps.event.trigger(layer.mapObject, "resize");
|
||||
layer.moveTo(layer.map.getCenter(), layer.map.getZoom());
|
||||
delete cache.resized;
|
||||
});
|
||||
}
|
||||
cache.resized = true;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -238,27 +139,19 @@ OpenLayers.Layer.Google.v3 = {
|
||||
}
|
||||
var container = this.mapObject.getDiv();
|
||||
if (visible === true) {
|
||||
this.mapObject.setMapTypeId(type);
|
||||
container.style.left = "";
|
||||
if (cache.termsOfUse && cache.termsOfUse.style) {
|
||||
cache.termsOfUse.style.left = "";
|
||||
cache.termsOfUse.style.display = "";
|
||||
cache.poweredBy.style.display = "";
|
||||
if (!cache.googleControl.hasChildNodes()) {
|
||||
cache.googleControl.appendChild(this.map.viewPortDiv);
|
||||
this.map.div.appendChild(container);
|
||||
google.maps.event.trigger(this.mapObject, 'resize');
|
||||
}
|
||||
this.mapObject.setMapTypeId(type);
|
||||
cache.displayed = this.id;
|
||||
} else {
|
||||
delete cache.displayed;
|
||||
container.style.left = "-9999px";
|
||||
if (cache.termsOfUse && cache.termsOfUse.style) {
|
||||
cache.termsOfUse.style.display = "none";
|
||||
// move ToU far to the left in addition to setting
|
||||
// display to "none", because at the end of the GMap
|
||||
// load sequence, display: none will be unset and ToU
|
||||
// would be visible after loading a map with a google
|
||||
// layer that is initially hidden.
|
||||
cache.termsOfUse.style.left = "-9999px";
|
||||
cache.poweredBy.style.display = "none";
|
||||
if (cache.googleControl.hasChildNodes()) {
|
||||
this.map.div.removeChild(container);
|
||||
this.map.div.appendChild(this.map.viewPortDiv);
|
||||
}
|
||||
delete cache.displayed;
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -448,20 +341,6 @@ OpenLayers.Layer.Google.v3 = {
|
||||
*/
|
||||
getMapObjectPixelFromXY: function(x, y) {
|
||||
return new google.maps.Point(x, y);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: destroy
|
||||
* Clean up this layer.
|
||||
*/
|
||||
destroy: function() {
|
||||
if (this.repositionListener) {
|
||||
google.maps.event.removeListener(this.repositionListener);
|
||||
}
|
||||
if (this.repositionTimer) {
|
||||
window.clearTimeout(this.repositionTimer);
|
||||
}
|
||||
OpenLayers.Layer.Google.prototype.destroy.apply(this, arguments);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -772,8 +772,8 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
}
|
||||
this.layers = null;
|
||||
}
|
||||
if (this.viewPortDiv) {
|
||||
this.div.removeChild(this.viewPortDiv);
|
||||
if (this.viewPortDiv && this.viewPortDiv.parentNode) {
|
||||
this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);
|
||||
}
|
||||
this.viewPortDiv = null;
|
||||
|
||||
|
||||
@@ -170,68 +170,6 @@
|
||||
t.eq(satellite.div.style.display, "block", "Satellite layer is visible.");
|
||||
}
|
||||
|
||||
function test_Layer_Google_setGMapVisibility(t) {
|
||||
t.plan(3);
|
||||
|
||||
var map = new OpenLayers.Map('map');
|
||||
var gmap = new OpenLayers.Layer.Google("Google Streets");
|
||||
var dummy = new OpenLayers.Layer("Dummy", {isBaseLayer: true});
|
||||
map.addLayers([dummy, gmap]);
|
||||
map.zoomToMaxExtent();
|
||||
|
||||
// In v3, the terms of use and powered by elements are not available
|
||||
// until the layer loads. This can occur before the layer is visible,
|
||||
// but we don't try to access these elements until after the layer is
|
||||
// made visible for the first time.
|
||||
var cache = OpenLayers.Layer.Google.cache[map.id];
|
||||
t.ok(!cache.termsOfUse, "termsOfUse is not yet cached");
|
||||
t.ok(!cache.poweredBy, "poweredBy is not yet cached");
|
||||
|
||||
var called = 0;
|
||||
var original = gmap.repositionMapElements;
|
||||
gmap.repositionMapElements = function() {
|
||||
++called;
|
||||
original.apply(gmap, arguments);
|
||||
}
|
||||
|
||||
map.setBaseLayer(gmap);
|
||||
t.delay_call(4, function() {
|
||||
t.ok(called > 0, "repositionMapElements called");
|
||||
map.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
function test_Layer_Google_setGMapVisibility_allOverlays(t) {
|
||||
t.plan(3);
|
||||
|
||||
var map = new OpenLayers.Map('map', {allOverlays: true});
|
||||
var gmap = new OpenLayers.Layer.Google("Google Streets", {visibility: false});
|
||||
var dummy = new OpenLayers.Layer("Dummy");
|
||||
map.addLayers([gmap, dummy]);
|
||||
map.zoomToMaxExtent();
|
||||
|
||||
// In v3, the terms of use and powered by elements are not available
|
||||
// until the layer loads. This can occur before the layer is visible,
|
||||
// but we don't try to access these elements until after the layer is
|
||||
// made visible for the first time.
|
||||
var cache = OpenLayers.Layer.Google.cache[map.id];
|
||||
t.ok(!cache.termsOfUse, "termsOfUse is not yet cached");
|
||||
t.ok(!cache.poweredBy, "poweredBy is not yet cached");
|
||||
|
||||
var called = 0;
|
||||
var original = gmap.repositionMapElements;
|
||||
gmap.repositionMapElements = function() {
|
||||
++called;
|
||||
original.apply(gmap, arguments);
|
||||
}
|
||||
|
||||
gmap.setVisibility(true);
|
||||
t.delay_call(2, function() {
|
||||
t.ok(called > 0, "repositionMapElements called");
|
||||
map.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
function test_allOverlays_invisible(t) {
|
||||
|
||||
t.plan(1);
|
||||
@@ -319,10 +257,9 @@
|
||||
t.plan(2);
|
||||
|
||||
var origPrecision = OpenLayers.Util.DEFAULT_PRECISION;
|
||||
// GMaps v3 seems to use a default precision of 13, which is lower
|
||||
// than what we use in OpenLayers.
|
||||
// Our default precision is very high - millimeters should be enough.
|
||||
// See http://trac.osgeo.org/openlayers/ticket/3059
|
||||
OpenLayers.Util.DEFAULT_PRECISION = 13;
|
||||
OpenLayers.Util.DEFAULT_PRECISION = 12;
|
||||
|
||||
var map = new OpenLayers.Map("map");
|
||||
|
||||
@@ -370,6 +307,28 @@
|
||||
|
||||
}
|
||||
|
||||
function test_moveViewportDiv(t) {
|
||||
t.plan(2);
|
||||
|
||||
var map = new OpenLayers.Map('map', {
|
||||
projection: 'EPSG:3857',
|
||||
center: [0, 0],
|
||||
zoom: 1
|
||||
});
|
||||
var gmap = new OpenLayers.Layer.Google();
|
||||
map.addLayer(gmap);
|
||||
|
||||
t.delay_call(1, function() {
|
||||
t.ok(map.viewPortDiv.parentNode !== map.div, 'viewport moved inside GMaps');
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
map.addLayer(osm);
|
||||
map.setBaseLayer(osm);
|
||||
|
||||
t.ok(map.viewPortDiv.parentNode === map.div, 'viewport moved back');
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers Google (v3) Layer Example</title>
|
||||
<link rel="stylesheet" href="../../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="../../examples/style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?v=3.6&sensor=false"></script>
|
||||
<script src="../../lib/OpenLayers.js"></script>
|
||||
|
||||
@@ -3,15 +3,7 @@
|
||||
bottom: 2px;
|
||||
left: auto;
|
||||
}
|
||||
.olLayerGoogleV3.olLayerGoogleCopyright {
|
||||
bottom: 0px;
|
||||
right: 0px !important;
|
||||
}
|
||||
.olLayerGooglePoweredBy {
|
||||
left: 2px;
|
||||
bottom: 2px;
|
||||
}
|
||||
.olLayerGoogleV3.olLayerGooglePoweredBy {
|
||||
bottom: 0px !important;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user