| 138 | | |
| 139 | | /** |
| 140 | | * Method: loadMapObject |
| 141 | | * Load the GMap and register appropriate event listeners. If we can't |
| 142 | | * load GMap2, then display a warning message. |
| 143 | | */ |
| 144 | | loadMapObject:function() { |
| 145 | | if (!this.type) { |
| 146 | | this.type = G_NORMAL_MAP; |
| 147 | | } |
| 148 | | var mapObject, termsOfUse, poweredBy; |
| 149 | | var cache = OpenLayers.Layer.Google.cache[this.map.id]; |
| 150 | | if (cache) { |
| 151 | | // there are already Google layers added to this map |
| 152 | | mapObject = cache.mapObject; |
| 153 | | termsOfUse = cache.termsOfUse; |
| 154 | | poweredBy = cache.poweredBy; |
| 155 | | // increment the layer count |
| 156 | | ++cache.count; |
| 157 | | } else { |
| 158 | | // this is the first Google layer for this map |
| 159 | | |
| 160 | | var container = this.map.viewPortDiv; |
| 161 | | var div = document.createElement("div"); |
| 162 | | div.id = this.map.id + "_GMap2Container"; |
| 163 | | div.style.position = "absolute"; |
| 164 | | div.style.width = "100%"; |
| 165 | | div.style.height = "100%"; |
| 166 | | container.appendChild(div); |
| 167 | | |
| 168 | | // create GMap and shuffle elements |
| 169 | | try { |
| 170 | | mapObject = new GMap2(div); |
| 171 | | |
| 172 | | // move the ToS and branding stuff up to the container div |
| 173 | | termsOfUse = div.lastChild; |
| 174 | | container.appendChild(termsOfUse); |
| 175 | | termsOfUse.style.zIndex = "1100"; |
| 176 | | termsOfUse.style.right = ""; |
| 177 | | termsOfUse.style.bottom = ""; |
| 178 | | termsOfUse.className = "olLayerGoogleCopyright"; |
| 179 | | |
| 180 | | poweredBy = div.lastChild; |
| 181 | | container.appendChild(poweredBy); |
| 182 | | poweredBy.style.zIndex = "1100"; |
| 183 | | poweredBy.style.right = ""; |
| 184 | | poweredBy.style.bottom = ""; |
| 185 | | poweredBy.className = "olLayerGooglePoweredBy gmnoprint"; |
| 186 | | |
| 187 | | } catch (e) { |
| 188 | | OpenLayers.Console.error(e); |
| 189 | | return; |
| 190 | | } |
| 191 | | // cache elements for use by any other google layers added to |
| 192 | | // this same map |
| 193 | | OpenLayers.Layer.Google.cache[this.map.id] = { |
| 194 | | mapObject: mapObject, |
| 195 | | termsOfUse: termsOfUse, |
| 196 | | poweredBy: poweredBy, |
| 197 | | count: 1 |
| 198 | | }; |
| 199 | | } |
| 200 | | |
| 201 | | this.mapObject = mapObject; |
| 202 | | this.termsOfUse = termsOfUse; |
| 203 | | this.poweredBy = poweredBy; |
| 204 | | |
| 205 | | // ensure this layer type is one of the mapObject types |
| 206 | | if (OpenLayers.Util.indexOf(this.mapObject.getMapTypes(), |
| 207 | | this.type) === -1) { |
| 208 | | this.mapObject.addMapType(this.type); |
| 209 | | } |
| 210 | | |
| 211 | | //since v 2.93 getDragObject is now available. |
| 212 | | if(typeof mapObject.getDragObject == "function") { |
| 213 | | this.dragObject = mapObject.getDragObject(); |
| 214 | | } else { |
| 215 | | this.dragPanMapObject = null; |
| 216 | | } |
| 217 | | |
| 218 | | if(this.isBaseLayer === false) { |
| 219 | | this.setGMapVisibility(this.div.style.display !== "none"); |
| 220 | | } |
| 221 | | |
| 222 | | }, |
| 223 | | |
| 224 | | /** |
| 225 | | * APIMethod: onMapResize |
| 226 | | */ |
| 227 | | onMapResize: function() { |
| 228 | | // workaround for resizing of invisible or not yet fully loaded layers |
| 229 | | // where GMap2.checkResize() does not work. We need to load the GMap |
| 230 | | // for the old div size, then checkResize(), and then call |
| 231 | | // layer.moveTo() to trigger GMap.setCenter() (which will finish |
| 232 | | // the GMap initialization). |
| 233 | | if(this.visibility && this.mapObject.isLoaded()) { |
| 234 | | this.mapObject.checkResize(); |
| 235 | | } else { |
| 236 | | if(!this._resized) { |
| 237 | | var layer = this; |
| 238 | | var handle = GEvent.addListener(this.mapObject, "load", function() { |
| 239 | | GEvent.removeListener(handle); |
| 240 | | delete layer._resized; |
| 241 | | layer.mapObject.checkResize(); |
| 242 | | layer.moveTo(layer.map.getCenter(), layer.map.getZoom()); |
| 243 | | }); |
| 244 | | } |
| 245 | | this._resized = true; |
| 246 | | } |
| 247 | | }, |
| 267 | | }, |
| 268 | | |
| 269 | | /** |
| 270 | | * Method: setGMapVisibility |
| 271 | | * Display the GMap container and associated elements. |
| 272 | | * |
| 273 | | * Parameters: |
| 274 | | * visible - {Boolean} Display the GMap elements. |
| 275 | | */ |
| 276 | | setGMapVisibility: function(visible) { |
| 277 | | var cache = OpenLayers.Layer.Google.cache[this.map.id]; |
| 278 | | if (cache) { |
| 279 | | var container = this.mapObject.getContainer(); |
| 280 | | if (visible === true) { |
| 281 | | this.mapObject.setMapType(this.type); |
| 282 | | container.style.display = ""; |
| 283 | | this.termsOfUse.style.left = ""; |
| 284 | | this.termsOfUse.style.display = ""; |
| 285 | | this.poweredBy.style.display = ""; |
| 286 | | cache.displayed = this.id; |
| 287 | | } else { |
| 288 | | if (cache.displayed === this.id) { |
| 289 | | delete cache.displayed; |
| 290 | | } |
| 291 | | if (!cache.displayed) { |
| 292 | | container.style.display = "none"; |
| 293 | | this.termsOfUse.style.display = "none"; |
| 294 | | // move ToU far to the left in addition to setting display |
| 295 | | // to "none", because at the end of the GMap2 load |
| 296 | | // sequence, display: none will be unset and ToU would be |
| 297 | | // visible after loading a map with a google layer that is |
| 298 | | // initially hidden. |
| 299 | | this.termsOfUse.style.left = "-9999px"; |
| 300 | | this.poweredBy.style.display = "none"; |
| 301 | | } |
| 302 | | } |
| 303 | | } |
| 327 | | * Method: removeGMapElements |
| 328 | | * Remove all elements added to the dom. This should only be called if |
| 329 | | * this is the last of the Google layers for the given map. |
| 330 | | */ |
| 331 | | removeGMapElements: function() { |
| 332 | | var cache = OpenLayers.Layer.Google.cache[this.map.id]; |
| 333 | | if (cache) { |
| 334 | | // remove shared elements from dom |
| 335 | | var container = this.mapObject && this.mapObject.getContainer(); |
| 336 | | if (container && container.parentNode) { |
| 337 | | container.parentNode.removeChild(container); |
| 338 | | } |
| 339 | | var termsOfUse = cache.termsOfUse; |
| 340 | | if (termsOfUse && termsOfUse.parentNode) { |
| 341 | | termsOfUse.parentNode.removeChild(termsOfUse); |
| 342 | | } |
| 343 | | var poweredBy = cache.poweredBy; |
| 344 | | if (poweredBy && poweredBy.parentNode) { |
| 345 | | poweredBy.parentNode.removeChild(poweredBy); |
| 346 | | } |
| 347 | | } |
| 348 | | }, |
| 349 | | |
| 350 | | /** |
| 443 | | /** |
| 444 | | * APIMethod: getMapObjectBoundsFromOLBounds |
| 445 | | * |
| 446 | | * Parameters: |
| 447 | | * olBounds - {<OpenLayers.Bounds>} |
| 448 | | * |
| 449 | | * Returns: |
| 450 | | * {Object} A MapObject Bounds, translated from olBounds |
| 451 | | * Returns null if null value is passed in |
| 452 | | */ |
| 453 | | getMapObjectBoundsFromOLBounds: function(olBounds) { |
| 454 | | var moBounds = null; |
| 455 | | if (olBounds != null) { |
| 456 | | var sw = this.sphericalMercator ? |
| 457 | | this.inverseMercator(olBounds.bottom, olBounds.left) : |
| 458 | | new OpenLayers.LonLat(olBounds.bottom, olBounds.left); |
| 459 | | var ne = this.sphericalMercator ? |
| 460 | | this.inverseMercator(olBounds.top, olBounds.right) : |
| 461 | | new OpenLayers.LonLat(olBounds.top, olBounds.right); |
| 462 | | moBounds = new GLatLngBounds(new GLatLng(sw.lat, sw.lon), |
| 463 | | new GLatLng(ne.lat, ne.lon)); |
| 464 | | } |
| 465 | | return moBounds; |
| 466 | | }, |
| 467 | | |
| 468 | | /** |
| 469 | | * Method: addContainerPxFunction |
| 470 | | * Hack-on function because GMAPS does not give it to us |
| 471 | | * |
| 472 | | * Parameters: |
| 473 | | * gLatLng - {GLatLng} |
| 474 | | * |
| 475 | | * Returns: |
| 476 | | * {GPoint} A GPoint specifying gLatLng translated into "Container" coords |
| 477 | | */ |
| 478 | | addContainerPxFunction: function() { |
| 479 | | if ( (typeof GMap2 != "undefined") && |
| 480 | | !GMap2.prototype.fromLatLngToContainerPixel) { |
| 481 | | |
| 482 | | GMap2.prototype.fromLatLngToContainerPixel = function(gLatLng) { |
| 483 | | |
| 484 | | // first we translate into "DivPixel" |
| 485 | | var gPoint = this.fromLatLngToDivPixel(gLatLng); |
| 486 | | |
| 487 | | // locate the sliding "Div" div |
| 488 | | var div = this.getContainer().firstChild.firstChild; |
| 489 | | |
| 490 | | // adjust by the offset of "Div" and voila! |
| 491 | | gPoint.x += div.offsetLeft; |
| 492 | | gPoint.y += div.offsetTop; |
| 493 | | |
| 494 | | return gPoint; |
| 495 | | }; |
| 496 | | } |
| 497 | | }, |
| 498 | | |
| 566 | | /** |
| 567 | | * APIMethod: getMapObjectLonLatFromMapObjectPixel |
| 568 | | * |
| 569 | | * Parameters: |
| 570 | | * moPixel - {Object} MapObject Pixel format |
| 571 | | * |
| 572 | | * Returns: |
| 573 | | * {Object} MapObject LonLat translated from MapObject Pixel |
| 574 | | */ |
| 575 | | getMapObjectLonLatFromMapObjectPixel: function(moPixel) { |
| 576 | | return this.mapObject.fromContainerPixelToLatLng(moPixel); |
| 577 | | }, |
| 578 | | |
| 579 | | /** |
| 580 | | * APIMethod: getMapObjectPixelFromMapObjectLonLat |
| 581 | | * |
| 582 | | * Parameters: |
| 583 | | * moLonLat - {Object} MapObject LonLat format |
| 584 | | * |
| 585 | | * Returns: |
| 586 | | * {Object} MapObject Pixel transtlated from MapObject LonLat |
| 587 | | */ |
| 588 | | getMapObjectPixelFromMapObjectLonLat: function(moLonLat) { |
| 589 | | return this.mapObject.fromLatLngToContainerPixel(moLonLat); |
| 590 | | }, |
| 591 | | |
| 592 | | |
| 593 | | // Bounds |
| 594 | | |
| 595 | | /** |
| 596 | | * APIMethod: getMapObjectZoomFromMapObjectBounds |
| 597 | | * |
| 598 | | * Parameters: |
| 599 | | * moBounds - {Object} MapObject Bounds format |
| 600 | | * |
| 601 | | * Returns: |
| 602 | | * {Object} MapObject Zoom for specified MapObject Bounds |
| 603 | | */ |
| 604 | | getMapObjectZoomFromMapObjectBounds: function(moBounds) { |
| 605 | | return this.mapObject.getBoundsZoomLevel(moBounds); |
| 606 | | }, |
| 607 | | |