
/*********************************************************************\
*                                                                     *
* egeoxml.js                                         by Mike Williams *
*                                                                     *
* A Google Maps API Extension                                         *
*                                                                     *
* Renders the contents of a My Maps (or similar) KML file             *
*                                                                     *
* Documentation: http://econym.org.uk/gmap/egeoxml.htm                * 
*                                                                     *
***********************************************************************
*                                                                     *
*   This Javascript is provided by Mike Williams                      *
*   Community Church Javascript Team                                  *
*   http://www.bisphamchurch.org.uk/                                  *
*   http://econym.org.uk/gmap/                                        *
*                                                                     *
*   This work is licenced under a Creative Commons Licence            *
*   http://creativecommons.org/licenses/by/2.0/uk/                    *
*                                                                     *
\*********************************************************************/


// Version 0.0   17 Apr 2007 - Initial testing, just markers
// Version 0.1   17 Apr 2007 - Sensible shadows, and a few general improvements
// Version 0.2   18 Apr 2007 - Polylines (non-clickable, no sidebar)
// Version 0.3   18 Apr 2007 - Polygons (non-clickable, no sidebar)
// Version 0.4   18 Apr 2007 - Sidebar entries for polygons
// Version 0.5   19 Apr 2007 - Accept an array of XML filenames, and add the {sortbyname} option
// Version 0.6   19 Apr 2007 - Sidebar entries for polylines, get directions and search nearby
// Version 0.7   20 Apr 2007 - Info Window Styles
// Version 0.8   21 Apr 2007 - baseicon
// Version 0.9   21 Apr 2007 - iwoptions and markeroptions
// Version 1.0   21 Apr 2007 - Launched
// Version 1.1   25 Apr 2007 - Bugfix - would crash if no options were specified
// Version 1.2   25 Apr 2007 - If the description begins with "http://" make it into a link.
// Version 1.3   30 Apr 2007 - printgif, dropbox
// Version 1.4   14 May 2007 - Elabels
// Version 1.5   17 May 2007 - Default values for width, fill and outline
// Version 1.6   21 May 2007 - GGroundOverlay (needs API V2.79+)
// Version 1.7   22 May 2007 - Better icon positioning for MyMaps icons
// Version 1.8   31 May 2007 - polyline bugfix
// Version 1.9   23 Jun 2007 - add .parseString() method
// Version 2.0   23 Jun 2007 - .parseString() handles an array of strings
// Version 2.1   25 Jul 2007 - imagescan
// Version 2.2   10 Aug 2007 - Support new My Maps icons
// Version 2.3   25 Nov 2007 - Clear variables used by .parse() so that it can be rerun
// Version 2.4   08 Dec 2007 - polylineoptions and polygonoptions
// Version 2.5   11 Dec 2007 - EGeoXml.value() trims leading and trailing whitespace 
// Version 2.6   08 Feb 2008 - Trailing whitespace wasn't removed in the previous change
// Version 2.7   14 Oct 2008 - If there's no <description> try looking for <text> instead
// Version 2.8   12 Jan 2009 - Bugfix - last point of poly was omitted
// Version 2.9   05 Feb 2009 - add .hide() .show()

// Constructor

function EGeoXml(e,d,b,c){this.myvar=e;this.map=d;this.url=b;if(typeof b=="string"){this.urls=[b]}else{this.urls=b}this.opts=c||{};this.titlestyle=this.opts.titlestyle||'style = "font-family: arial, sans-serif;font-size: medium;font-weight:bold;font-size: 100%;"';this.descstyle=this.opts.descstyle||'style = "font-family: arial, sans-serif;font-size: small;padding-bottom:.7em;"';this.directionstyle=this.opts.directionstyle||'style="font-family: arial, sans-serif;font-size: small;padding-left: 1px;padding-top: 1px;padding-right: 4px;"';this.sidebarfn=this.opts.sidebarfn||EGeoXml.addSidebar;this.dropboxfn=this.opts.dropboxfn||EGeoXml.addDropdown;this.elabelopacity=this.opts.elabelopacity||100;this.bounds=new GLatLngBounds();this.gmarkers=[];this.gpolylines=[];this.gpolygons=[];this.groundoverlays=[];this.side_bar_html="";this.side_bar_list=[];this.styles=[];this.iwwidth=this.opts.iwwidth||250;this.progress=0;this.lastmarker={};this.myimages=[];this.imageNum=0}EGeoXml.value=function(b){a=GXml.value(b);a=a.replace(/^\s*/,"");a=a.replace(/\s*$/,"");return a};EGeoXml.prototype.createMarker=function(point,name,desc,style){var icon=G_DEFAULT_ICON;var myvar=this.myvar;var iwoptions=this.opts.iwoptions||{};var markeroptions=this.opts.markeroptions||{};var icontype=this.opts.icontype||"style";if(icontype=="style"){if(!!this.styles[style]){icon=this.styles[style]}}if(!markeroptions.icon){markeroptions.icon=icon}var m=new GMarker(point,markeroptions);if(this.opts.preloadimages){var text=desc;var pattern=/<\s*img/ig;var result;var pattern2=/src\s*=\s*[\'\"]/;var pattern3=/[\'\"]/;while((result=pattern.exec(text))!=null){var stuff=text.substr(result.index);var result2=pattern2.exec(stuff);if(result2!=null){stuff=stuff.substr(result2.index+result2[0].length);var result3=pattern3.exec(stuff);if(result3!=null){var imageUrl=stuff.substr(0,result3.index);this.myimages[this.imageNum]=new Image();this.myimages[this.imageNum].src=imageUrl;this.imageNum++}}}}if(this.opts.elabelclass){var l=new ELabel(point,name,this.opts.elabelclass,this.opts.elabeloffset,this.elabelopacity,true);this.map.addOverlay(l)}var html="<div style = 'width:"+this.iwwidth+"px'><h1 "+this.titlestyle+">"+name+"</h1><div "+this.descstyle+">"+desc+"</div>";if(this.opts.directions){var html1=html+"<div "+this.directionstyle+'>Get Directions: <a href="javascript:GEvent.trigger('+this.myvar+".lastmarker,'click2')\">To Here</a> - <a href=\"javascript:GEvent.trigger("+this.myvar+".lastmarker,'click3')\">From Here</a><br><a href=\"javascript:GEvent.trigger("+this.myvar+".lastmarker,'click4')\">Search nearby</a></div>";var html2=html+"<div "+this.directionstyle+'>Get Directions: To here - <a href="javascript:GEvent.trigger('+this.myvar+'.lastmarker,\'click3\')">From Here</a><br>Start address:<form action="http://maps.google.com/maps" method="get" target="_blank"><input type="text" SIZE=35 MAXLENGTH=80 name="saddr" id="saddr" value="" /><INPUT value="Go" TYPE="SUBMIT"><input type="hidden" name="daddr" value="'+point.lat()+","+point.lng()+"("+name+')"/><br><a href="javascript:GEvent.trigger('+this.myvar+".lastmarker,'click')\">&#171; Back</a></div>";var html3=html+"<div "+this.directionstyle+'>Get Directions: <a href="javascript:GEvent.trigger('+this.myvar+'.lastmarker,\'click2\')">To Here</a> - From Here<br>End address:<form action="http://maps.google.com/maps" method="get"" target="_blank"><input type="text" SIZE=35 MAXLENGTH=80 name="daddr" id="daddr" value="" /><INPUT value="Go" TYPE="SUBMIT"><input type="hidden" name="saddr" value="'+point.lat()+","+point.lng()+"("+name+')"/><br><a href="javascript:GEvent.trigger('+this.myvar+".lastmarker,'click')\">&#171; Back</a></div>";var html4=html+"<div "+this.directionstyle+'>Search nearby: e.g. "pizza"<br><form action="http://maps.google.com/maps" method="get"" target="_blank"><input type="text" SIZE=35 MAXLENGTH=80 name="q" id="q" value="" /><INPUT value="Go" TYPE="SUBMIT"><input type="hidden" name="near" value="'+name+" @"+point.lat()+","+point.lng()+'"/><br><a href="javascript:GEvent.trigger('+this.myvar+".lastmarker,'click')\">&#171; Back</a></div>";GEvent.addListener(m,"click2",function(){m.openInfoWindowHtml(html2+"</div>",iwoptions)});GEvent.addListener(m,"click3",function(){m.openInfoWindowHtml(html3+"</div>",iwoptions)});GEvent.addListener(m,"click4",function(){m.openInfoWindowHtml(html4+"</div>",iwoptions)})}else{var html1=html}GEvent.addListener(m,"click",function(){eval(myvar+".lastmarker = m");m.openInfoWindowHtml(html1+"</div>",iwoptions)});if(!!this.opts.addmarker){this.opts.addmarker(m,name,desc,icon.image,this.gmarkers.length)}else{this.map.addOverlay(m)}this.gmarkers.push(m);if(this.opts.sidebarid||this.opts.dropboxid){var n=this.gmarkers.length-1;this.side_bar_list.push(name+"$$$marker$$$"+n+"$$$")}};EGeoXml.prototype.createPolyline=function(o,h,e,k,l,c,j){var m=this.map;var q=this.opts.iwoptions||{};var f=this.opts.polylineoptions||{};var d=new GPolyline(o,h,e,k,f);this.map.addOverlay(d);this.gpolylines.push(d);var i="<div style='font-weight: bold; font-size: medium; margin-bottom: 0em;'>"+c+"</div><div style='font-family: Arial, sans-serif;font-size: small;width:"+this.iwwidth+"px'>"+j+"</div>";GEvent.addListener(d,"click",function(){m.openInfoWindowHtml(d.getVertex(Math.floor(d.getVertexCount()/2)),i,q)});if(this.opts.sidebarid){var g=this.gpolylines.length-1;var b='&nbsp;&nbsp;<span style=";border-left:'+e+"px solid "+h+';">&nbsp;</span> ';this.side_bar_list.push(c+"$$$polyline$$$"+g+"$$$"+b)}};EGeoXml.prototype.createPolygon=function(r,h,e,m,g,j,o,c,l){var q=this.map;var s=this.opts.iwoptions||{};var i=this.opts.polygonoptions||{};var d=new GPolygon(r,h,e,m,g,j,i);this.map.addOverlay(d);this.gpolygons.push(d);var k="<div style='font-weight: bold; font-size: medium; margin-bottom: 0em;'>"+c+"</div><div style='font-family: Arial, sans-serif;font-size: small;width:"+this.iwwidth+"px'>"+l+"</div>";GEvent.addListener(d,"click",function(){q.openInfoWindowHtml(o.getCenter(),k,s)});if(this.opts.sidebarid){var f=this.gpolygons.length-1;var b='<span style="background-color:'+g+";border:2px solid "+h+';">&nbsp;&nbsp;&nbsp;&nbsp;</span> ';this.side_bar_list.push(c+"$$$polygon$$$"+f+"$$$"+b)}};EGeoXml.addSidebar=function(e,b,d,c,f){if(d=="marker"){return'<a href="javascript:GEvent.trigger('+e+".gmarkers["+c+"],'click')\">"+b+"</a><br>"}if(d=="polyline"){return'<div style="margin-top:6px;"><a href="javascript:GEvent.trigger('+e+".gpolylines["+c+"],'click')\">"+f+b+"</a></div>"}if(d=="polygon"){return'<div style="margin-top:6px;"><a href="javascript:GEvent.trigger('+e+".gpolygons["+c+"],'click')\">"+f+b+"</a></div>"}};EGeoXml.addDropdown=function(e,b,d,c,f){return'<option value="'+c+'">'+b+"</option>"};EGeoXml.prototype.parse=function(){this.gmarkers=[];this.gpolylines=[];this.gpolygons=[];this.groundoverlays=[];this.side_bar_html="";this.side_bar_list=[];this.styles=[];this.lastmarker={};this.myimages=[];this.imageNum=0;var b=this;this.progress=this.urls.length;for(u=0;u<this.urls.length;u++){GDownloadUrl(this.urls[u],function(c){b.processing(c)})}};EGeoXml.prototype.parseString=function(b){this.gmarkers=[];this.gpolylines=[];this.gpolygons=[];this.groundoverlays=[];this.side_bar_html="";this.side_bar_list=[];this.styles=[];this.lastmarker={};this.myimages=[];this.imageNum=0;if(typeof b=="string"){this.docs=[b]}else{this.docs=b}this.progress=this.docs.length;for(u=0;u<this.docs.length;u++){this.processing(this.docs[u])}};EGeoXml.prototype.processing=function(h){var H=this;var q=GXml.parse(trim(h));var C=q.documentElement.getElementsByTagName("Style");for(var Q=0;Q<C.length;Q++){var j=C[Q].getAttribute("id");var U=C[Q].getElementsByTagName("Icon");if(U.length>0){var y=EGeoXml.value(U[0].getElementsByTagName("href")[0]);if(!!y){if(!!H.opts.baseicon){H.styles["#"+j]=new GIcon(H.opts.baseicon,y)}else{H.styles["#"+j]=new GIcon(G_DEFAULT_ICON,y);H.styles["#"+j].iconSize=new GSize(32,32);H.styles["#"+j].shadowSize=new GSize(59,32);H.styles["#"+j].dragCrossAnchor=new GPoint(2,8);H.styles["#"+j].iconAnchor=new GPoint(16,32);if(H.opts.printgif){var b=y.split("/");var K=b[b.length-1];K=H.opts.printgifpath+K.replace(/.png/i,".gif");H.styles["#"+j].printImage=K;H.styles["#"+j].mozPrintImage=K}if(!!H.opts.noshadow){H.styles["#"+j].shadow="";H.styles["#"+j].transparent=""}else{if(y.indexOf("/red.png")>-1||y.indexOf("/blue.png")>-1||y.indexOf("/green.png")>-1||y.indexOf("/yellow.png")>-1||y.indexOf("/lightblue.png")>-1||y.indexOf("/purple.png")>-1||y.indexOf("/pink.png")>-1||y.indexOf("/orange.png")>-1||y.indexOf("-dot.png")>-1){H.styles["#"+j].shadow="http://maps.google.com/mapfiles/ms/micons/msmarker.shadow.png"}else{if(y.indexOf("-pushpin.png")>-1){H.styles["#"+j].shadow="http://maps.google.com/mapfiles/ms/micons/pushpin_shadow.png"}else{var G=y.replace(".png",".shadow.png");H.styles["#"+j].shadow=G}}}}}}var E=C[Q].getElementsByTagName("LineStyle");if(E.length>0){var c=parseInt(GXml.value(E[0].getElementsByTagName("width")[0]));if(c<1){c=5}var A=EGeoXml.value(E[0].getElementsByTagName("color")[0]);var v=A.substr(0,2);var V=A.substr(2,2);var s=A.substr(4,2);var D=A.substr(6,2);A="#"+D+s+V;var R=parseInt(v,16)/256;if(!H.styles["#"+j]){H.styles["#"+j]={}}H.styles["#"+j].color=A;H.styles["#"+j].width=c;H.styles["#"+j].opacity=R}var S=C[Q].getElementsByTagName("PolyStyle");if(S.length>0){var w=parseInt(GXml.value(S[0].getElementsByTagName("fill")[0]));var g=parseInt(GXml.value(S[0].getElementsByTagName("outline")[0]));var A=EGeoXml.value(S[0].getElementsByTagName("color")[0]);if(S[0].getElementsByTagName("fill").length==0){w=1}if(S[0].getElementsByTagName("outline").length==0){g=1}var v=A.substr(0,2);var V=A.substr(2,2);var s=A.substr(4,2);var D=A.substr(6,2);A="#"+D+s+V;var R=parseInt(v,16)/256;if(!H.styles["#"+j]){H.styles["#"+j]={}}H.styles["#"+j].fillcolor=A;H.styles["#"+j].fillopacity=R;if(!w){H.styles["#"+j].fillopacity=0}if(!g){H.styles["#"+j].opacity=0}}}var P=q.documentElement.getElementsByTagName("Placemark");for(var Q=0;Q<P.length;Q++){var o=EGeoXml.value(P[Q].getElementsByTagName("name")[0]);var L=EGeoXml.value(P[Q].getElementsByTagName("description")[0]);if(L==""){var L=EGeoXml.value(P[Q].getElementsByTagName("text")[0]);L=L.replace(/\$\[name\]/,o);L=L.replace(/\$\[geDirections\]/,"")}if(L.match(/^http:\/\//i)){L='<a href="'+L+'">'+L+"</a>"}if(L.match(/^https:\/\//i)){L='<a href="'+L+'">'+L+"</a>"}var O=EGeoXml.value(P[Q].getElementsByTagName("styleUrl")[0]);var n=GXml.value(P[Q].getElementsByTagName("coordinates")[0]);n=n.replace(/\s+/g," ");n=n.replace(/^ /,"");n=n.replace(/ $/,"");n=n.replace(/, /,",");var M=n.split(" ");if(M.length>1){var J=[];var T=new GLatLngBounds();for(var N=0;N<M.length;N++){var b=M[N].split(",");var F=new GLatLng(parseFloat(b[1]),parseFloat(b[0]));J.push(F);H.bounds.extend(F);T.extend(F)}var r=P[Q].getElementsByTagName("LineString");if(r.length){if(!!H.styles[O]){var c=H.styles[O].width;var A=H.styles[O].color;var R=H.styles[O].opacity}else{var c=5;var A="#0000ff";var R=0.45}if(!!H.opts.createpolyline){H.opts.createpolyline(J,A,c,R,T,o,L)}else{H.createPolyline(J,A,c,R,T,o,L)}}var W=P[Q].getElementsByTagName("Polygon");if(W.length){if(!!H.styles[O]){var c=H.styles[O].width;var A=H.styles[O].color;var R=H.styles[O].opacity;var I=H.styles[O].fillopacity;var m=H.styles[O].fillcolor}else{var c=5;var A="#0000ff";var R=0.45;var I=0.25;var m="#0055ff"}if(!!H.opts.createpolygon){H.opts.createpolygon(J,A,c,R,m,I,T,o,L)}else{H.createPolygon(J,A,c,R,m,I,T,o,L)}}}else{var b=M[0].split(",");var F=new GLatLng(parseFloat(b[1]),parseFloat(b[0]));H.bounds.extend(F);if(!!H.opts.createmarker){H.opts.createmarker(F,o,L,O)}else{H.createMarker(F,o,L,O)}}}var k=q.documentElement.getElementsByTagName("GroundOverlay");for(var Q=0;Q<k.length;Q++){var f=EGeoXml.value(k[Q].getElementsByTagName("href")[0]);var t=parseFloat(GXml.value(k[Q].getElementsByTagName("north")[0]));var B=parseFloat(GXml.value(k[Q].getElementsByTagName("south")[0]));var z=parseFloat(GXml.value(k[Q].getElementsByTagName("east")[0]));var x=parseFloat(GXml.value(k[Q].getElementsByTagName("west")[0]));var l=new GLatLng(B,x);var e=new GLatLng(t,z);var d=new GGroundOverlay(f,new GLatLngBounds(l,e));H.bounds.extend(l);H.bounds.extend(e);H.groundoverlays.push(d);H.map.addOverlay(d)}H.progress--;if(H.progress==0){if(!H.opts.nozoom){H.map.setZoom(H.map.getBoundsZoomLevel(H.bounds));H.map.setCenter(H.bounds.getCenter())}if(H.opts.sortbyname){H.side_bar_list.sort()}if(H.opts.sidebarid){for(var Q=0;Q<H.side_bar_list.length;Q++){var b=H.side_bar_list[Q].split("$$$",4);H.side_bar_html+=H.sidebarfn(H.myvar,b[0],b[1],b[2],b[3])}document.getElementById(H.opts.sidebarid).innerHTML+=H.side_bar_html}if(H.opts.dropboxid){for(var Q=0;Q<H.side_bar_list.length;Q++){var b=H.side_bar_list[Q].split("$$$",4);if(b[1]=="marker"){H.side_bar_html+=H.dropboxfn(H.myvar,b[0],b[1],b[2],b[3])}}document.getElementById(H.opts.dropboxid).innerHTML='<select onChange="var I=this.value;if(I>-1){GEvent.trigger('+H.myvar+".gmarkers[I],'click'); }\"><option selected> - Select a location - </option>"+H.side_bar_html+"</select>"}GEvent.trigger(H,"parsed")}};EGeoXml.prototype.hide=function(){for(var b=0;b<this.gmarkers.length;b++){this.gmarkers[b].hide()}for(var b=0;b<this.gpolylines.length;b++){this.gpolylines[b].hide()}for(var b=0;b<this.gpolygons.length;b++){this.gpolygons[b].hide()}for(var b=0;b<this.groundoverlays.length;b++){this.groundoverlays[b].hide()}if(this.opts.sidebarid){document.getElementById(this.opts.sidebarid).style.display="none"}if(this.opts.dropboxid){document.getElementById(this.opts.dropboxid).style.display="none"}};EGeoXml.prototype.show=function(){for(var b=0;b<this.gmarkers.length;b++){this.gmarkers[b].show()}for(var b=0;b<this.gpolylines.length;b++){this.gpolylines[b].show()}for(var b=0;b<this.gpolygons.length;b++){this.gpolygons[b].show()}for(var b=0;b<this.groundoverlays.length;b++){this.groundoverlays[b].show()}if(this.opts.sidebarid){document.getElementById(this.opts.sidebarid).style.display=""}if(this.opts.dropboxid){document.getElementById(this.opts.dropboxid).style.display=""}};


