GxMagnifier is a
free add-in control for Google Maps that creates a moveable,
magnified window on top of your map. It was developed by Richard
Kagerer, and is not supported by Google or part of their official
API. Please note that GxMagnifier is beta
software, so there may be some bugs. If you run into anything,
report it in the
In case you're curious, I got the idea of trying to make a magnifier control for Google Maps after watching a concept video that shows a similar feature in mapping technology demonstrated under Windows Longhorn (a.k.a. Vista).
Update: GxMagnifier has not yet been upgraded to version 2 of the Maps API, and unfortunately Google has dropped support for version 1. You may also want to take a look at http://boxme.net/wdch/test.php, where two other members of the Google Maps community have happily startled me by independantly adopting the original codebase and worked toward upgrading it. The performance is slow but much of the basics are functional.
Download
Introduction
The "Hello World"
of GxMagnifier
Google Maps API
Compatibility
Browser Compatibility
Legal
10 Second Peek Behind the
Scenes
Updates
Known Bugs
Framework for Examples
Examples
Zooming
Resizing
Capturing the Click
Moving the Button
Automatically Panning
Docking
Consolidating Waypoints
Skinning
Starting with a Blank
Map
Multiple
Magnifiers and Negative Zoom
API Overview
Class Reference
GxMagnifier
GxMagnifierControl
GxControlPositionHack
DownloadBefore you get started you'll need to download these files and place them in the same directory as your web page. GxMagnifier.1.js (09-Oct-2005, tested on maps.23.js) magnify.png, spacer.png and optionally magnify2.png If you want to poke around in the source code, you'll need
GxMagnifier.1.source.js as well, and may find this Note: The obfuscated GxMagnifier.1.js was compiled using a very basic find-replace program that I wrote. The output appears correct and works with the examples, but if you run into troubles try using GxMagnifier.1.source.js instead, and let me know. IntroductionThe "Hello World" of GxMagnifierThe simplest implementation of GxMagnifier requires only two lines of code. Here's an example based on the "Hello World" page of the Google Maps API documentation. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>GxMagnifier Example - simple</title> <script src="http://maps.google.com/maps?file=api&v=1&key=abcdefg" type="text/javascript"></script> <script src="GxMagnifier.1.js" type="text/javascript"></script> </head> <body> <div id="map" style="width: 300px; height: 300px"></div> <script type="text/javascript"> //<![CDATA[ if (GBrowserIsCompatible()) { var map = new GMap(document.getElementById("map")); map.centerAndZoom(new GPoint(-122.4618, 37.7902), 9); map.addControl(new GxMagnifierControl()); } //]]> </script> </body> </html> View Example (simple.htm) If you download the example, don't forget to grab the files listed above and to substitute your key for abcdefg. Google Maps API CompatibilityGxMagnifier was developed under version 1 of the API, specifically under maps.12.js up to maps.14.js, and was originally released July 26, 2005. It uses a handful of undocumented functions in the API, which means it could break with future map updates (even if the API version number doesn't change). I've tried to stick to functions that seem like they're here to stay (e.g. I definitely don't call ones that have been obfuscated down to jumbled letters). Updates are briefly tested using the latest version of the API, and the example pages herein always use the latest version. I'm hoping that the hoards of great people in the
Google Maps programming community will help keep these classes
working when the maps.x.js source files get updated. So if things
break, you might want hop over to
Browser CompatibilityThe control has been loosely tested in Microsoft Internet Explorer 6.0 and Mozilla Firefox 1.0.4. Since this was done entirely in my free time, and I don't have any free time, I anticipate issues will be raised (and hopefully addressed) in the forum. LegalUse of this software is entirely at your own risk. There are no warrantees of any kind implied, and the author shall not be held liable for any damages whatsoever resulting from its use. 10 Second Peek Behind the ScenesWhen you add a UpdatesIf you want to make modifications, go ahead. But if you want them integrated into the source code listed here, I have just one completely archaic request to make. In your code editor please set your tab size to two spaces, and make sure the code still looks right. I don't want to have to spend a lot of time scrolling the screen left and right just to get around whitespace, or deleting spaces to make things line up. The source code has some more tips on coding conventions. Thanks, and sorry for the hassle. Known BugsThere's only one significant one I know of so far (as of July 26, 2005):
Framework for ExamplesThe surrounding HTML and code for initializing the main
map has been omitted below to to make the examples easier to read.
As well, I use a special script called Finally, since the In a nutshell, all the examples are encapsulated in a framework that looks like this (except for a few noted exceptions): if (GBrowserIsCompatible()) { var map = new GMap(document.getElementById("map")); map.centerAndZoom(new GPoint(-122.4618, 37.7902), 4); // Create the magnifier var magControl = new GxMagnifierControl(); map.addControl(magControl); // Get reference to the associated GxMagnifier for use in the examples var mag = magControl.GxMagnifier; // ...rest of the example goes here... } View Example (almost_as_simple.htm) This is the one you want to download to start you off on customizing the GxMagnifier.
ExamplesZoomingGxMagnifier automatically adjusts its zoom level as your main map is zoomed. Here we make it magnify by 3 zoom levels, instead of the default 2. mag.setMagnification(3);View example (zoom.htm) ResizingBy default, the magnified viewport is one third the size of your main map. You can change its dimensions.
mag.setSize(new GSize(150, 80));View example (resize.htm) Capturing the ClickYou may not want your magnifier to zoom in on the map when the
user clicks it. Here we override the click event to tell us
where we clicked and then close the magnifier window. You can of
course use
mag.disableDefaultClickHandler(); GEvent.addListener(mag, "click", function(point){ alert("You clicked " + point.toString()); this.hide(); // note, "this" is the GxMagnifier instance });View example (click.htm) Moving the ButtonHere we place the "magnifying glass" button 10
pixels away from the top right corner. Note that var magControl = new GxMagnifierControl(); magControl.setDefaultPosition(new GxControlPositionHack(1, 10, 10)); map.addControl(magControl); View example (reposition.htm)
Automatically PanningThe magnifier can scroll the map when it gets moved near to an edge. Note the panning region extends inward from the edges of the main map by half the size of the magnifier window. mag.enableAutoPan(); View example (autopan.htm) DockingYou can free the magnifier from the map's container, and put
it anywhere on the page. We do this by creating a In the head section: <!-- Set up the containers, and make a "fullscreen" window --> <style type="text/css"> html, body {width: 100%; height: 100%} body {margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 0px} #map {position:absolute; width:100%; height:100%} #magnifier {position:absolute; right:0px; bottom:0px; width:200px; height:200px; border:2px solid; border-bottom-style:outset} </style> In the body: <div id="map"></div> <div id="magnifier"></div> And here's the Javascript: // Create the magnifier var div = document.getElementById("magnifier"); div.style.zIndex = 10; // make it stay on top var mag = new GxMagnifier(map, null, div); mag.map.setMapType(G_SATELLITE_TYPE) // Monitor the window resize event and let the map know when it occurs // This isn't required for GxMagnifier, but it is required to accomplish // a correct full-screen Google Map. if (window.attachEvent) { window.attachEvent("onresize", function() {this.map.onResize()} ); } else { window.addEventListener("resize", function() {this.map.onResize()} , false); } View example (docking.htm) Consolidating WaypointsYou can take advantage of having two separate maps to come up
with some novel approaches to waypoint consolidation. The
magnified map is accessed through the
Show Code View example (consolidate.htm) SkinningYou can change the border and other style properties of the magnifier's container, and even put your own images inside of it.
// Turn off the normal GxMagnifier "loading" message, and the crosshair mag.hideLoadingMessage(); // Display a smaller border, and none on the top (since the image // already has a black line across the top) mag.container.style.border = "1px solid black" mag.container.style.borderTop = "none" // Add an image inside the magnified map container var img = mag.createImage("skin.png"); with (img.style) { position = "absolute"; // you need this for it to stay on top left = "0px"; top = "0px"; }View example (skinning.html) Starting with a Blank MapInstead of making a copy of your main map, you can start the
GxMagnifier with a blank map by specifying
// Add 10 random markers View example (blank.htm)
Multiple Magnifiers and Negative ZoomYou can include multiple GxMagnifiers on your map. In addition to the normal magnifier, this example expands on the Docking one and uses a negative magnification factor to create a "birds eye view" of where you are on the map. Scroll around to see it in action. (The code below shows the complete page) Show Code View example (multiple.htm)
API OverviewMost of the functionality is in theGxMagnifier
class, which is responsible for managing the overlayed (magnified)
map and its container. You can get at the magnified map (for adding
markers, etc.) by accessing the GxMagnifier.map
property.
The There are a couple of other helper classes which I won't delve into.
The
|
Constructor | Description |
---|---|
GxMagnifier(map,
useBlank?, container?) |
Creates a new magnifier on the page, by copying
map . If
useBlank is true , a blank new map is
created instead. You can specify a custom div
to use in container , which also puts
the GxMagnifier into parked mode. |
Method | Description |
---|---|
setMagnification(levels) |
Changes the
magnification factor. levels determines
how many levels to subtract from the zoom level of
your main map. (default is 2) |
setSize(size) |
Sets the size of the magnifier window to the given
GSize . (default is
is a third the size of your main map) |
setBorderWidth(pixels) |
Sets the border width, in pixels, for the magnified
map. Use this instead of trying to modify
GxMagnifier.container.style . (default is 2) |
setCursor(name) |
Sets cursor
for the magnifier container. (default is
"crosshair" ) |
enableMapSync() |
Update the magnified map as required when the main one's center/zoom/type is changed (enabled by default) |
disableMapSync() |
Lets you take over managing the magnified map's zoom/position/type. |
enableOverlaySync() |
Keeps the overlays on the magnified map in sync with
your main map. (enabled by default, unless
useBlank was
true in the
constructor) |
disableOverlaySync() |
Stops synchronizing overlays, allowing you to manage overlays on the magnified map yourself. |
enableAutoPan() |
Pans the main map when the magnifier is brought to an edge. (disabled by default, ignored in park mode) |
disableAutoPan() |
Turns off the autopan feature. |
enableMouseTracking() |
Normal mode: The magnified map
window follows the mouse around above the main map. Parked mode: The magnified map recenters to the cursor location on the main map. (enabled by default) |
disableMouseTracking() |
Turns off all mouse tracking
features (and disables
mouseover
and
mouseout
events from firing) |
enablePrefetch() |
Recenters the magnified map, even when it's hidden. This causes the map to download tiles, theoretically making them appear faster when you turn on the magnifier. (enabled by default) |
disablePrefetch() |
Doesn't update the magnified map if its not visible. Use to save bandwidth. (Note: If the user is constantly moving the mouse around over the main map, prefetching causes the magnified one to constantly recenter - which in fact never gives ANY of the tiles a chance to download. I'm curious to hear feedback on if the feature speeds things up, or slows things down, in practice) |
enableAutoMagnify() |
Like enableMapSync() ,
but only applies to the zoom feature. (enabled
by default, ignored if you called
disableMapSync ). |
disableAutoMagnify() |
Uncouples the
zoom level of the magnified map, allowing you to set
a specific one with GxMagnifier.map.zoomTo() .
This is more convenient than using
disableMapSync() if you simply want to
have a perma-zoomed, parked map. |
enableDefaultClickHandler() |
Zooms your main map when the magnifier is clicked on it. (enabled by default) |
disableDefaultClickHandler() |
Disables all GxMagnifier click
handling and lets you implement your own click
handler. (note
that click
events are still fired) |
enablePanBeforeAutoZoom() |
Pans the main map before zooming in after a click. (disabled by default) |
disablePanBeforeAutoZoom() |
Disables the pan-before-auto-zoom feature. |
enableAutoHide() |
Hide the magnified map window when the user clicks. (enabled by default, ignored in parked mode) |
disableAutoHide() |
Keeps the magnified map open until the user closes it by pressing the magnifier icon again. |
showLoadingMessage(msg?) |
Causes the "Loading Tiles" message
to be displayed behind map tiles before they are
loaded. The optional
msg
parameter can be set to your own HTML string (see
note below). |
hideLoadingMessage() |
Hides the "Loading Tiles" message. Note: I'd appreciate it if you leave the unobtrusive reference to GoogleMappers.com behind your magnifier. I put a lot of work into the component, and its the least you can do. |
Method | Description |
---|---|
show() |
Shows the magnified map. |
hide() |
Hides the magnified map |
park(point?) |
Causes the
magnifier to enter parked mode, centered on the
given GPoint (or wherever it happens to
be). It will stay where it is, no longer following
the mouse around the page, until you call
unpark() . |
parkAtMarker(marker, offsetX?, offsetY?) |
Centers the
magnifier on the given GMarker and
enters parked mode. Note that it is not
explicitly attached to the marker, and will not move
around with it as the map scrolls. OffsetX
and OffsetY can be used to fine tune
the magnifier's distance from the marker's anchor
point. |
unpark(marker) |
Allows the
magnifier to follow the mouse (ignored if custom
container was specified in the constructor). |
syncOverlays() |
Clears all overlays on the magnified map and recopies them from the main map. |
isVisible() |
Returns
true when the magnifier window is visible. |
Method | Description |
---|---|
createImage(imageSrc) |
Appends a new <img> element to the document, in the magnified map's container, and adds alpha filtering for transparent images if running under Internet Explorer (although it sometimes doesn't seem to work - maybe someone could improve upon my implementation here). |
Event | Arguments | Description |
---|---|---|
click |
point |
Triggered
when the user clicks anywhere in the magnified map.
As of GxMagnifier.1.js, point is always
the Lng/Lat center of the magnified map. This
is probably only useful if not in parked mode, and
the behavior of the argument may be changed in the
future. |
mouseover |
none | Triggered when the mouse enters the magnified window (only use this in parked mode). |
mouseout |
none | Triggered
when the mouse exits the magnified window (only use
this in parked mode). Note that both this and
the above event behave differently from normal
mouseover and mouseout events,
in that they occur only when the mouse is truly
leaving the element bounds, and not if the mouse is
simple rolling over another element contained within
the window. |
GxMagnifierControl
Provides a wrapper for a
GxMagnifier
, allowing it to be added to a
GMap
using
GMap.addControl()
.
Constructor | Description |
---|---|
GxMagnifierControl(useBlank?) |
Creates the
control, passing the
useBlank argument to the
GxMagnifier constructor if supplied.
By default, the control is
positioned in
the top-left corner at an offset that makes it fit nicely between
the north and west panning
controls of a default
GLargeMapControl
or
GSmallMapControl . |
Method | Description |
---|---|
GxMagnifier |
A reference to the
GxMagnifier
associated with this control. |
Method | Description |
---|---|
map() |
Returns a
reference to the magnified map. (Identical to
using GxMagnifier.map ). |
show() |
Displays the magnifying glass icon if its been hidden. |
hide() |
Hides the magnifying glass icon. |
setMagnifyImage(src) |
Sets the image file to use for the magnifying glass icon. If none is provided, "magnify.png" is used. Note: There is also some code to create a simple text "z" button but its been depricated. |
setDefaultPosition(position) |
Sets where to
display the control. position must be a
GxControlPositionHack object, or an
instance of whatever equivalent class Google
releases once an official API for map add-in
controls is published. Must be called before you add
the control to the map. |
GxControlPositionHack
This is class is meant to temporarily tide things over until Google comes out with an official spec on add-in controls, or until someone points out a definition for them that I've missed.
Constructor | Description |
---|---|
GxControlPositionHack(anchor,
offsetX?, offsetY?) |
Creates an
object containing positioning information for a
GxMagnifierControl . anchor
is 0 ,
1 ,
2 ,
or
3
to indicate top-left, top-right, bottom-left and bottom-right,
respectively. The next two arguments are a horizontal and
vertical offset
indicating how far from the corner the control should be positioned. |
One last quick note. The stylesheet for this
documentation was ruthlessly borrowed from the
Google Maps API
documentation, and even further ruthlessly edited in a really dumb
HTML editor. If
anyone wants to clean up this page for me, please get in touch!
You can reach me in the