Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is the code to create a 'tracker' marker. The logic resides completely in the <code>Pointer</code> object.</p> <p>You simple instantiate a new <code>Pointer</code> and pass the marker and map. The <code>Pointer</code> automatically shows and hides, no work necessary on your part.</p> <p>I see no licensing info but if I am not mistaken, this is based on a gmap sample I have seen in the past. What you do with it is up to you.</p> <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;title&gt;Marker Tracker Code&lt;/title&gt; &lt;script src="http://maps.google.com/maps?file=api&amp;amp;v=3" type="text/javascript"&gt;&lt;/script&gt; &lt;style type="text/css"&gt; .map { height: 450px; width: 500px; } &lt;/style&gt; &lt;script type="text/javascript"&gt; var map; function load() { if (GBrowserIsCompatible()) { var latlng = new GLatLng(37.4419, -122.1419); map = new GMap2(document.getElementById("map")); map.setCenter(latlng, 13); // create a marker var marker = new GMarker(latlng); map.addOverlay(marker); // create a tracker for marker var tracker = new Pointer(marker, map); } } /* Pointer creates an intelligent 'minimarker' that shows with a compass arrow pointing to the marker passed in to the constructor when the parent marker is off screen */ // Creates a Pointer for the given marker and displays it on the map as needed. function Pointer(marker, map) { this.map_ = map; this.marker_ = marker; this.enabled_ = true; this.arrowDisplayed_ = false; this.arrow_ = null; this.oldArrow_ = null; this.control_ = null; this.iconScale_ = 0.6; this.padding_ = 65; this.color_ = '#0000ff'; this.weight_ = 10; this.length_ = 10 this.opacity_ = 0.6 this.updateEvent_ = 'move'; this.panEvent_ = 'click'; this.quickPanEnabled_ = true; //replicate a different sized icon var babyIcon = new GIcon(marker.getIcon()); babyIcon.iconSize = new GSize( marker.getIcon().iconSize.width * this.iconScale_, marker.getIcon().iconSize.height * this.iconScale_); babyIcon.iconAnchor = new GPoint( marker.getIcon().iconAnchor.x * this.iconScale_, marker.getIcon().iconAnchor.y * this.iconScale_ / 2); // kill the shadow babyIcon.shadow = null; this.babyMarker_ = new GMarker(new GPoint(0, 0), babyIcon); //bind the update task to the event trigger GEvent.bind(this.map_, this.updateEvent_, this, this.updateArrow_); //update the arrow if the marker moves GEvent.bind(this.marker_, 'changed', this, this.updateArrow_); if (this.quickPanEnabled_) { GEvent.bind(this.babyMarker_, this.panEvent_, this, this.panToMarker_); } //do an inital check this.updateArrow_(); }; // Disables the pointer. Pointer.prototype.disable = function() { this.enabled_ = false; this.updateArrow_(); }; //Enables the pointer. Pointer.prototype.enable = function() { this.enabled_ = true; this.updateArrow_(); }; // Called on on the trigger event to update the arrow. Primary function is to // check if the parent marker is in view, if not draw the tracking arrow. Pointer.prototype.updateArrow_ = function() { if (!this.map_.getBounds().containsLatLng(this.marker_.getLatLng()) &amp;&amp; this.enabled_) { this.drawArrow_(); } else if (this.arrowDisplayed_) { this.hideArrow_(); } }; //Draws or redraws the arrow as needed, called when the parent marker is //not with in the map view. Pointer.prototype.drawArrow_ = function() { //convert to pixels var bounds = this.map_.getBounds(); var SE = this.map_.fromLatLngToDivPixel(bounds.getSouthWest()); var NE = this.map_.fromLatLngToDivPixel(bounds.getNorthEast()); //include the padding while deciding on the arrow location var minX = SE.x + this.padding_; var minY = NE.y + this.padding_; var maxX = NE.x - this.padding_; var maxY = SE.y - this.padding_; // find the geometric info for the marker realative to the center of the map var center = this.map_.fromLatLngToDivPixel(this.map_.getCenter()); var loc = this.map_.fromLatLngToDivPixel(this.marker_.getLatLng()); //get the slope of the line var m = (center.y - loc.y) / (center.x - loc.x); var b = (center.y - m * center.x); // end the line within the bounds if (loc.x &lt; maxX &amp;&amp; loc.x &gt; minX) { var x = loc.x; } else if (center.x &gt; loc.x) { var x = minX; } else { var x = maxX; } //calculate y and check boundaries again var y = m * x + b; if (y &gt; maxY) { y = maxY; x = (y - b) / m; } else if (y &lt; minY) { y = minY; x = (y - b) / m; } // get the proper angle of the arrow var ang = Math.atan(-m); if (x &gt; center.x) { ang = ang + Math.PI; } // define the point of the arrow var arrowLoc = this.map_.fromDivPixelToLatLng(new GPoint(x, y)); // left side of marker is at -1,1 var arrowLeft = this.map_.fromDivPixelToLatLng( this.getRotatedPoint_(((-1) * this.length_), this.length_, ang, x, y)); // right side of marker is at -1,-1 var arrowRight = this.map_.fromDivPixelToLatLng( this.getRotatedPoint_(((-1) * this.length_), ((-1) * this.length_), ang, x, y)); var center = this.map_.getCenter(); var loc = this.marker_.getLatLng(); this.oldArrow_ = this.arrow_; this.arrow_ = new GPolyline([arrowLeft, arrowLoc, arrowRight], this.color_, this.weight_, this.opacity_); this.map_.addOverlay(this.arrow_); // move the babyMarker to -1,0 this.babyMarker_.setLatLng(this.map_.fromDivPixelToLatLng( this.getRotatedPoint_(((-2) * this.length_), 0, ang, x, y))); if (!this.arrowDisplayed_) { this.map_.addOverlay(this.babyMarker_); this.arrowDisplayed_ = true; } if (this.oldArrow_) { this.map_.removeOverlay(this.oldArrow_); } }; //Hides the arrows. Pointer.prototype.hideArrow_ = function() { this.map_.removeOverlay(this.babyMarker_); if (this.arrow_) { this.map_.removeOverlay(this.arrow_); } if (this.oldArrow_) { this.map_.removeOverlay(this.oldArrow_); } this.arrowDisplayed_ = false; }; //Pans the map to the parent marker. Pointer.prototype.panToMarker_ = function() { this.map_.panTo(this.marker_.getLatLng()); }; //This applies a counter-clockwise rotation to any point. Pointer.prototype.getRotatedPoint_ = function(x, y, ang, xoffset, yoffset) { var newx = y * Math.sin(ang) - x * Math.cos(ang) + xoffset; var newy = x * Math.sin(ang) + y * Math.cos(ang) + yoffset; var rotatedPoint = new GPoint(newx, newy); return (rotatedPoint); }; &lt;/script&gt; &lt;/head&gt; &lt;body onload="load()" onunload="GUnload()"&gt; &lt;div&gt; &lt;div id="map" class="map"&gt; &lt;/div&gt; &lt;/div&gt; &lt;/body&gt; &lt;/html&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload