Dashed polylines on Google Maps
This is rewritten Bill Chadwick's BDCCPolyline.js script. I rewrote it because its not working correctly. In the redraw function he is expecting that Google will always draw all polylines but that's not true. Google will draw only visible polylines. I need to come with a solution how to uniquely identify a polyline. Then I found a solution using the opacity attribute.
Example:
- You create a polyline with opacity = 1.
- This is you first polyline so the KMPolylineCounter = 1.
- The constructor change the opacity using this formula: opacity - (KMPolylineCounter + 1) / 10000
- Opacity for our first polyline is now 0.9998. The change is so small that you wont see the difference.
With this solution you can identify your polyline using the opacity attribute even when all polylines are not drawn.
Note: Non-solid polylines only if drawing is performed using VML or SVG.
/*!
* KMPolyline - Draw solid or dashed polylines.
*
* Extended Google's GPolyline class.
*
* Rewritten Bill Chadwick's BDCCPolyline.js script.
* http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm
*
* Non-solid polylines only if drawing is performed using VML or SVG.
*
* Prototype.js v1.6+ required - http://prototypejs.org/
*
* Downloaded from: Martin Milesich - http://milesich.com/
*
* Free for any use.
*/
var KMPolylineCounter = 0;
// Constructor
function KMPolyline(points, color, weight, opacity, tooltip, dash)
{
++KMPolylineCounter;
this.points = points || [];
this.color = color || "#000000";
this.weight = weight || 1;
this.tooltip = tooltip || "";
this.dash = dash || "solid";
this.elemId = "KMPolylineId" + KMPolylineCounter.toString();
this.opacity = Math.abs(opacity - (KMPolylineCounter + 1) / 10000);
this.usesVml = Prototype.Browser.IE;
GPolyline.call(this, this.points, this.color, this.weight, this.opacity, {"clickable": false}); //call parent constructor
}
KMPolyline.prototype = new GPolyline([new GLatLng(0,0)]);
KMPolyline.prototype.copy = function()
{
return new KMPolyline(this.points, this.color, this.weight, this.opacity, this.tooltip, this.dash);
}
KMPolyline.prototype.redraw = function(force)
{
GPolyline.prototype.redraw.call(this, force); //call parent
var elem = null;
if (this.usesVml) {
// VML
var shps = $$('shape');
for (i = 0; i < shps.length; i++) {
if (shps[i].stroke.opacity.toFixed(4) == this.opacity) {
elem = shps[i];
break;
}
}
} else {
// SVG
elem = $$('path[stroke-opacity="'+this.opacity+'"]').first();
if (elem != null) {
Element.writeAttribute(elem, "pointer-events", "stroke");
}
}
if (elem != null) {
if (this.tooltip != "") {
elem.style.cursor = "help";
Element.writeAttribute(elem, 'title', this.tooltip);
}
Element.writeAttribute(elem, 'id', this.elemId);
this.setDash(this.dash);
var eClick = GEvent.callback(this, this.onClick);
var eOver = GEvent.callback(this, this.onOver);
var eOut = GEvent.callback(this, this.onOut);
GEvent.clearInstanceListeners(elem);
GEvent.addDomListener(elem, "click", function() {eClick()});
GEvent.addDomListener(elem, "mouseover", function() {eOver()});
GEvent.addDomListener(elem, "mouseout", function() {eOut()});
}
}
// event handlers
KMPolyline.prototype.onClick = function() {GEvent.trigger(this, "click")}
KMPolyline.prototype.onOver = function() {GEvent.trigger(this, "mouseover")}
KMPolyline.prototype.onOut = function() {GEvent.trigger(this, "mouseout")}
// getX functions
KMPolyline.prototype.getDash = function() {return this.dash}
KMPolyline.prototype.getWeight = function() {return this.weight}
KMPolyline.prototype.getColor = function() {return this.color}
// setX functions
KMPolyline.prototype.setDash = function(dash)
{
this.dash = dash;
var elem = $(this.elemId);
if (!elem) return;
if (this.usesVml) {
switch (this.dash) {
case "dash" : elem.stroke.dashstyle = "dash";
break;
case "dot" : elem.stroke.dashstyle = "dot";
break;
default : elem.stroke.dashstyle = "";
}
} else {
switch (this.dash) {
case "dash" : Element.writeAttribute(elem, "stroke-dasharray", "10,10");
break;
case "dot" : Element.writeAttribute(elem, "stroke-dasharray", "3,17");
break;
default : Element.writeAttribute(elem, "stroke-dasharray", null); // remove attribute
}
}
}
KMPolyline.prototype.setWeight = function(weight)
{
this.weight = weight;
var elem = $(this.elemId);
if (!elem) return;
if (this.usesVml) {
elem.stroke.weight = this.weight.toString() + "px";
} else {
Element.writeAttribute(elem, "stroke-width", this.weight.toString() + "px");
}
}
KMPolyline.prototype.setColor = function(color)
{
this.color = color;
var elem = $(this.elemId);
if (!elem) return;
if (this.usesVml) {
elem.stroke.color = this.color;
} else {
Element.writeAttribute(elem, "stroke", this.color);
}
}


But don't forget this code:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<STYLE>
v\:* { behavior: url(#default#VML); display:inline-block}
</STYLE>
and do NOT include doctype declaration:
<!DOCTYPE html PUBLIC ...
(??)
if you want to see dotted and dashed polylines in the Internet Explorer.
It can draw no more than 2 dashed or dotted polylines in the Internet Explorer:
http://darekk.com/mapy/index_zoom_11_2.html ...
And the prototype.js file inhibits somehow displaying of markers and generates an error ('posn' is null or not an object - IE; place.posn undefined - Firefox) in my script based on the "Google Offices" example of the marker manager. However this can be worked around easily by replacing lines
for (var i in officeLayer) {
and
for (var j in layer["places"]) {
by
for (var i = 0; i < officeLayer.length; i++) {
and
for (var i = 0; i < layer["places"]; i++) {
respectively.
But the doctype declaration does not affect appearance of lines.
> It can draw no more than 2 dashed or dotted polylines in the Internet Explorer:
Even if they are fully visible on a map:
http://darekk.com/mapy/index_zoom_11_3.html
But the original Chadwick's BDCCPolyline moves styles from invisible polylines to visible ones:
http://darekk.com/mapy/index_zoom_16.html
The green dotted polyline changes to a red solid one when the map is zoomed out. First style belongs to another, invisible polyline.
Sometimes it is possible to convert solid polylines to dashed and dotted ones by moving a map, but not in this case.
I've got to tell you, this worked beautifully.
Thanks for putting this together!