/*********************************************************************\ * * * egeoxml.js by Mike Williams * * * * A Google Maps API Extension * * * * Renders the contents of a My Maps (or similar) KML file * * * * Documentation: http://econym.googlepages.com/egeoxml.htm * * * \*********************************************************************/ // 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 // Constructor function EGeoXml(myvar, map, url, opts) { // store the parameters this.myvar = myvar; this.map = map; this.url = url; if (typeof url == "string") { this.urls = [url]; } else { this.urls = url; } this.opts = opts || {}; // infowindow styles 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;"'; // sidebar/dropbox functions this.sidebarfn = this.opts.sidebarfn || EGeoXml.addSidebar; this.dropboxfn = this.opts.dropboxfn || EGeoXml.addDropdown; // elabel options this.elabelopacity = this.opts.elabelopacity || 100; // other useful "global" stuff this.bounds = new GLatLngBounds(); this.gmarkers = []; this.gpolylines = []; this.gpolygons = []; this.groundoverlays = []; this.side_bar_html = ""; this.side_bar_list = []; this.styles = []; // associative array this.iwwidth = this.opts.iwwidth || 250; this.progress = 0; this.lastmarker = {}; this.myimages = []; this.imageNum =0; } // uses GXml.value, then removes leading and trailing whitespace EGeoXml.value = function(e) { a = GXml.value(e); a = a.replace(/^\s*/,""); a = a.replace(/\s*$/,""); return a; } // Create Marker 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); // Attempt to preload images 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 = "
" + "

"+name+"

" +"
"+desc+"
"; if (this.opts.directions) { var html1 = html + '
' + 'Get Directions: To Here - ' + 'From Here
' + 'Search nearby
'; var html2 = html + '
' + 'Get Directions: To here - ' + 'From Here
' + 'Start address:
' + '' + '' + '' + '
« Back
'; var html3 = html + '
' + 'Get Directions: To Here - ' + 'From Here
' + 'End address:' + '' + '' + '' + '
« Back
'; var html4 = html + '
' + 'Search nearby: e.g. "pizza"
' + '' + '' + '' + '' // + ''; + '
« Back
'; GEvent.addListener(m, "click2", function() { m.openInfoWindowHtml(html2 + "
",iwoptions); }); GEvent.addListener(m, "click3", function() { m.openInfoWindowHtml(html3 + "",iwoptions); }); GEvent.addListener(m, "click4", function() { m.openInfoWindowHtml(html4 + "",iwoptions); }); } else { var html1 = html; } GEvent.addListener(m, "click", function() { eval(myvar+".lastmarker = m"); m.openInfoWindowHtml(html1 + "",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 +"$$$" ); } } // Create Polyline EGeoXml.prototype.createPolyline = function(points,color,width,opacity,pbounds,name,desc) { var thismap = this.map; var iwoptions = this.opts.iwoptions || {}; var polylineoptions = this.opts.polylineoptions || {}; var p = new GPolyline(points,color,width,opacity,polylineoptions); this.map.addOverlay(p); this.gpolylines.push(p); var html = "
"+name+"
" +"
"+desc+"
"; GEvent.addListener(p,"click", function() { thismap.openInfoWindowHtml(p.getVertex(Math.floor(p.getVertexCount()/2)),html,iwoptions); } ); if (this.opts.sidebarid) { var n = this.gpolylines.length-1; var blob = '    '; this.side_bar_list.push (name + "$$$polyline$$$" + n +"$$$" + blob ); } } // Create Polygon EGeoXml.prototype.createPolygon = function(points,color,width,opacity,fillcolor,fillopacity,pbounds, name, desc) { var thismap = this.map; var iwoptions = this.opts.iwoptions || {}; var polygonoptions = this.opts.polygonoptions || {}; var p = new GPolygon(points,color,width,opacity,fillcolor,fillopacity,polygonoptions) this.map.addOverlay(p); this.gpolygons.push(p); var html = "
"+name+"
" +"
"+desc+"
"; GEvent.addListener(p,"click", function() { thismap.openInfoWindowHtml(pbounds.getCenter(),html,iwoptions); } ); if (this.opts.sidebarid) { var n = this.gpolygons.length-1; var blob = '     '; this.side_bar_list.push (name + "$$$polygon$$$" + n +"$$$" + blob ); } } // Sidebar factory method One - adds an entry to the sidebar EGeoXml.addSidebar = function(myvar,name,type,i,graphic) { if (type == "marker") { return '' + name + '
'; } if (type == "polyline") { return '
' + graphic + name + '
'; } if (type == "polygon") { return '
' + graphic + name + '
'; } } // Dropdown factory method EGeoXml.addDropdown = function(myvar,name,type,i,graphic) { return ''; } // Request to Parse an XML file EGeoXml.prototype.parse = function() { // clear some variables this.gmarkers = []; this.gpolylines = []; this.gpolygons = []; this.groundoverlays = []; this.side_bar_html = ""; this.side_bar_list = []; this.styles = []; // associative array this.lastmarker = {}; this.myimages = []; this.imageNum =0; var that = this; this.progress = this.urls.length; for (u=0; u 0) { var href=EGeoXml.value(icons[0].getElementsByTagName("href")[0]); if (!!href) { if (!!that.opts.baseicon) { that.styles["#"+styleID] = new GIcon(that.opts.baseicon,href); } else { that.styles["#"+styleID] = new GIcon(G_DEFAULT_ICON,href); that.styles["#"+styleID].iconSize = new GSize(32,32); that.styles["#"+styleID].shadowSize = new GSize(59,32); that.styles["#"+styleID].dragCrossAnchor = new GPoint(2,8); that.styles["#"+styleID].iconAnchor = new GPoint(16,32); if (that.opts.printgif) { var bits = href.split("/"); var gif = bits[bits.length-1]; gif = that.opts.printgifpath + gif.replace(/.png/i,".gif"); that.styles["#"+styleID].printImage = gif; that.styles["#"+styleID].mozPrintImage = gif; } if (!!that.opts.noshadow) { that.styles["#"+styleID].shadow=""; } else { // Try to guess the shadow image if (href.indexOf("/red.png")>-1 || href.indexOf("/blue.png")>-1 || href.indexOf("/green.png")>-1 || href.indexOf("/yellow.png")>-1 || href.indexOf("/lightblue.png")>-1 || href.indexOf("/purple.png")>-1 || href.indexOf("/pink.png")>-1 || href.indexOf("/orange.png")>-1 || href.indexOf("-dot.png")>-1 ) { that.styles["#"+styleID].shadow="http://maps.google.es/mapfiles/ms/micons/msmarker.shadow.png"; } else if (href.indexOf("-pushpin.png")>-1) { that.styles["#"+styleID].shadow="http://maps.google.es/mapfiles/ms/micons/pushpin_shadow.png"; } else { var shadow = href.replace(".png",".shadow.png"); that.styles["#"+styleID].shadow=shadow; } } } } } // is it a LineStyle ? var linestyles=styles[i].getElementsByTagName("LineStyle"); if (linestyles.length > 0) { var width = parseInt(GXml.value(linestyles[0].getElementsByTagName("width")[0])); if (width < 1) {width = 5;} var color = EGeoXml.value(linestyles[0].getElementsByTagName("color")[0]); var aa = color.substr(0,2); var bb = color.substr(2,2); var gg = color.substr(4,2); var rr = color.substr(6,2); color = "#" + rr + gg + bb; var opacity = parseInt(aa,16)/256; if (!that.styles["#"+styleID]) { that.styles["#"+styleID] = {}; } that.styles["#"+styleID].color=color; that.styles["#"+styleID].width=width; that.styles["#"+styleID].opacity=opacity; } // is it a PolyStyle ? var polystyles=styles[i].getElementsByTagName("PolyStyle"); if (polystyles.length > 0) { var fill = parseInt(GXml.value(polystyles[0].getElementsByTagName("fill")[0])); var outline = parseInt(GXml.value(polystyles[0].getElementsByTagName("outline")[0])); var color = EGeoXml.value(polystyles[0].getElementsByTagName("color")[0]); if (polystyles[0].getElementsByTagName("fill").length == 0) {fill = 1;} if (polystyles[0].getElementsByTagName("outline").length == 0) {outline = 1;} var aa = color.substr(0,2); var bb = color.substr(2,2); var gg = color.substr(4,2); var rr = color.substr(6,2); color = "#" + rr + gg + bb; var opacity = parseInt(aa,16)/256; if (!that.styles["#"+styleID]) { that.styles["#"+styleID] = {}; } that.styles["#"+styleID].fillcolor=color; that.styles["#"+styleID].fillopacity=opacity; if (!fill) that.styles["#"+styleID].fillopacity = 0; if (!outline) that.styles["#"+styleID].opacity = 0; } } // Read through the Placemarks var placemarks = xmlDoc.documentElement.getElementsByTagName("Placemark"); for (var i = 0; i < placemarks.length; i++) { var name=EGeoXml.value(placemarks[i].getElementsByTagName("name")[0]); var desc=EGeoXml.value(placemarks[i].getElementsByTagName("description")[0]); if (desc.match(/^http:\/\//i)) { desc = '' + desc + ''; } if (desc.match(/^https:\/\//i)) { desc = '' + desc + ''; } var style=EGeoXml.value(placemarks[i].getElementsByTagName("styleUrl")[0]); var coords=GXml.value(placemarks[i].getElementsByTagName("coordinates")[0]); coords=coords.replace(/\s+/g," "); // tidy the whitespace coords=coords.replace(/^ /,""); // remove possible leading whitespace coords=coords.replace(/, /,","); // tidy the commas var path = coords.split(" "); // Is this a polyline/polygon? if (path.length > 1) { // Build the list of points var points = []; var pbounds = new GLatLngBounds(); for (var p=0; p' + '' + that.side_bar_html + ''; } GEvent.trigger(that,"parsed"); } }