summaryrefslogtreecommitdiff
path: root/protected/extensions/egmap/assets/geoxml3.js
diff options
context:
space:
mode:
Diffstat (limited to 'protected/extensions/egmap/assets/geoxml3.js')
-rw-r--r--protected/extensions/egmap/assets/geoxml3.js1018
1 files changed, 1018 insertions, 0 deletions
diff --git a/protected/extensions/egmap/assets/geoxml3.js b/protected/extensions/egmap/assets/geoxml3.js
new file mode 100644
index 0000000..58b4cd1
--- /dev/null
+++ b/protected/extensions/egmap/assets/geoxml3.js
@@ -0,0 +1,1018 @@
+/*
+ geoxml3.js
+
+ Renders KML on the Google Maps JavaScript API Version 3
+ http://code.google.com/p/geoxml3/
+
+ Copyright 2010 Sterling Udell, Larry Ross
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+// Extend the global String object with a method to remove leading and trailing whitespace
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return this.replace(/^\s+|\s+$/g, '');
+ };
+}
+
+// Declare namespace
+geoXML3 = window.geoXML3 || {instances: []};
+
+// Constructor for the root KML parser object
+geoXML3.parser = function (options) {
+ // Private variables
+ var parserOptions = geoXML3.combineOptions(options, {
+ singleInfoWindow: false,
+ processStyles: true,
+ zoom: true
+ });
+ var docs = []; // Individual KML documents
+ var lastPlacemark;
+ var parserName;
+ if (!parserOptions.infoWindow && parserOptions.singleInfoWindow)
+ parserOptions.infoWindow = new google.maps.InfoWindow();
+ // Private methods
+
+ var parse = function (urls, docSet) {
+ // Process one or more KML documents
+ if (!parserName) {
+ parserName = 'geoXML3.instances[' + (geoXML3.instances.push(this) - 1) + ']';
+ }
+
+ if (typeof urls === 'string') {
+ // Single KML document
+ urls = [urls];
+ }
+
+ // Internal values for the set of documents as a whole
+ var internals = {
+ parser: this,
+ docSet: docSet || [],
+ remaining: urls.length,
+ parseOnly: !(parserOptions.afterParse || parserOptions.processStyles)
+ };
+ var thisDoc, j;
+ for (var i = 0; i < urls.length; i++) {
+ var baseUrl = urls[i].split('?')[0];
+ for (j = 0; j < docs.length; j++) {
+ if (baseUrl === docs[j].baseUrl) {
+ // Reloading an existing document
+ thisDoc = docs[j];
+ thisDoc.url = urls[i];
+ thisDoc.internals = internals;
+ thisDoc.reload = true;
+ docs.splice(j, 1);
+ break;
+ }
+ }
+ thisDoc = thisDoc || {
+ url: urls[i],
+ baseUrl: baseUrl,
+ internals: internals
+ };
+ internals.docSet.push(thisDoc);
+ geoXML3.fetchXML(thisDoc.url, function (responseXML) {render(responseXML, thisDoc);});
+ }
+ };
+
+ var hideDocument = function (doc) {
+ if (!doc) doc = docs[0];
+ // Hide the map objects associated with a document
+ var i;
+ if (!!doc.markers) {
+ for (i = 0; i < doc.markers.length; i++) {
+ if(!!doc.markers[i].infoWindow) doc.markers[i].infoWindow.close();
+ doc.markers[i].setVisible(false);
+ }
+ }
+ if (!!doc.ggroundoverlays) {
+ for (i = 0; i < doc.ggroundoverlays.length; i++) {
+ doc.ggroundoverlays[i].setOpacity(0);
+ }
+ }
+ if (!!doc.gpolylines) {
+ for (i=0;i<doc.gpolylines.length;i++) {
+ doc.gpolylines[i].setMap(null);
+ }
+ }
+ if (!!doc.gpolygons) {
+ for (i=0;i<doc.gpolygons.length;i++) {
+ doc.gpolygons[i].setMap(null);
+ }
+ }
+ };
+
+ var showDocument = function (doc) {
+ if (!doc) doc = docs[0];
+ // Show the map objects associated with a document
+ var i;
+ if (!!doc.markers) {
+ for (i = 0; i < doc.markers.length; i++) {
+ doc.markers[i].setVisible(true);
+ }
+ }
+ if (!!doc.ggroundoverlays) {
+ for (i = 0; i < doc.ggroundoverlays.length; i++) {
+ doc.ggroundoverlays[i].setOpacity(doc.ggroundoverlays[i].percentOpacity_);
+ }
+ }
+ if (!!doc.gpolylines) {
+ for (i=0;i<doc.gpolylines.length;i++) {
+ doc.gpolylines[i].setMap(parserOptions.map);
+ }
+ }
+ if (!!doc.gpolygons) {
+ for (i=0;i<doc.gpolygons.length;i++) {
+ doc.gpolygons[i].setMap(parserOptions.map);
+ }
+ }
+ };
+
+function processStyle(thisNode, styles, styleID) {
+ var nodeValue = geoXML3.nodeValue;
+ var defaultStyle = {
+ color: "ff000000", // black
+ width: 1,
+ fill: true,
+ outline: true,
+ fillcolor: "3fff0000" // blue
+ };
+ styles[styleID] = styles[styleID] || defaultStyle;
+ var styleNodes = thisNode.getElementsByTagName('Icon');
+ if (!!styleNodes && !!styleNodes.length && (styleNodes.length > 0)) {
+ styles[styleID] = {
+ href: nodeValue(styleNodes[0].getElementsByTagName('href')[0]),
+ scale: nodeValue(styleNodes[0].getElementsByTagName('scale')[0])
+ };
+ if (!isNaN(styles[styleID].scale)) styles[styleID].scale = 1.0;
+ }
+ styleNodes = thisNode.getElementsByTagName('LineStyle');
+ if (!!styleNodes && !!styleNodes.length && (styleNodes.length > 0)) {
+ styles[styleID].color = nodeValue(styleNodes[0].getElementsByTagName('color')[0]),
+ styles[styleID].width = nodeValue(styleNodes[0].getElementsByTagName('width')[0])
+ }
+ styleNodes = thisNode.getElementsByTagName('PolyStyle');
+ if (!!styleNodes && !!styleNodes.length && (styleNodes.length > 0)) {
+ styles[styleID].outline = getBooleanValue(styleNodes[0].getElementsByTagName('outline')[0]);
+ styles[styleID].fill = getBooleanValue(styleNodes[0].getElementsByTagName('fill')[0]);
+ styles[styleID].fillcolor = nodeValue(styleNodes[0].getElementsByTagName('color')[0]);
+ }
+ return styles[styleID];
+}
+
+function getBooleanValue(node) {
+ var nodeContents = geoXML3.nodeValue(node);
+ if (!nodeContents) return true;
+ if (nodeContents) nodeContents = parseInt(nodeContents);
+ if (isNaN(nodeContents)) return true;
+ if (nodeContents == 0) return false;
+ else return true;
+}
+
+function processPlacemarkCoords(node, tag) {
+ var parent = node.getElementsByTagName(tag);
+var coordListA = [];
+ for (var i=0; i<parent.length; i++) {
+ var coordNodes = parent[i].getElementsByTagName('coordinates')
+ if (!coordNodes) {
+ if (coordListA.length > 0) {
+ break;
+ } else {
+ return [{coordinates: []}];
+ }
+ }
+
+ for (var j=0; j<coordNodes.length;j++) {
+ var coords = geoXML3.nodeValue(coordNodes[j]).trim();
+ coords = coords.replace(/,\s+/g, ',');
+ var path = coords.split(/\s+/g);
+ var pathLength = path.length;
+ var coordList = [];
+ for (var k = 0; k < pathLength; k++) {
+ coords = path[k].split(',');
+ coordList.push({
+ lat: parseFloat(coords[1]),
+ lng: parseFloat(coords[0]),
+ alt: parseFloat(coords[2])
+ });
+ }
+ coordListA.push({coordinates: coordList});
+ }
+}
+ return coordListA;
+}
+
+ var render = function (responseXML, doc) {
+ // Callback for retrieving a KML document: parse the KML and display it on the map
+ if (!responseXML) {
+ // Error retrieving the data
+ geoXML3.log('Unable to retrieve ' + doc.url);
+ if (parserOptions.failedParse) {
+ parserOptions.failedParse(doc);
+ }
+ } else if (!doc) {
+ throw 'geoXML3 internal error: render called with null document';
+ } else { //no errors
+ var i;
+ var styles = {};
+ doc.placemarks = [];
+ doc.groundoverlays = [];
+ doc.ggroundoverlays = [];
+ doc.networkLinks = [];
+ doc.gpolygons = [];
+ doc.gpolylines = [];
+
+ // Declare some helper functions in local scope for better performance
+ var nodeValue = geoXML3.nodeValue;
+
+ // Parse styles
+ var styleID, styleNodes;
+ nodes = responseXML.getElementsByTagName('Style');
+ nodeCount = nodes.length;
+ for (i = 0; i < nodeCount; i++) {
+ thisNode = nodes[i];
+ var thisNodeId = thisNode.getAttribute('id');
+ if (!!thisNodeId) {
+ styleID = '#' + thisNodeId;
+ processStyle(thisNode, styles, styleID);
+ }
+ }
+ doc.styles = styles;
+ if (!!parserOptions.processStyles || !parserOptions.createMarker) {
+ // Convert parsed styles into GMaps equivalents
+ processStyles(doc);
+ }
+
+ // Parse placemarks
+ if (!!doc.reload && !!doc.markers) {
+ for (i = 0; i < doc.markers.length; i++) {
+ doc.markers[i].active = false;
+ }
+ }
+ var placemark, node, coords, path, marker, poly;
+ var placemark, coords, path, pathLength, marker, polygonNodes, coordList;
+ var placemarkNodes = responseXML.getElementsByTagName('Placemark');
+ for (pm = 0; pm < placemarkNodes.length; pm++) {
+ // Init the placemark object
+ node = placemarkNodes[pm];
+ placemark = {
+ name: geoXML3.nodeValue(node.getElementsByTagName('name')[0]),
+ description: geoXML3.nodeValue(node.getElementsByTagName('description')[0]),
+ styleUrl: geoXML3.nodeValue(node.getElementsByTagName('styleUrl')[0])
+ };
+ var defaultStyle = {
+ color: "ff000000", // black
+ width: 1,
+ fill: true,
+ outline: true,
+ fillcolor: "3fff0000" // blue
+ };
+ placemark.style = doc.styles[placemark.styleUrl] || defaultStyle;
+ // inline style overrides shared style
+ var inlineStyles = node.getElementsByTagName('Style');
+ if (inlineStyles && (inlineStyles.length > 0)) {
+ var style = processStyle(node,doc.styles,"inline");
+ processStyleID(style);
+ if (style) placemark.style = style;
+ }
+ if (/^https?:\/\//.test(placemark.description)) {
+ placemark.description = ['<a href="', placemark.description, '">', placemark.description, '</a>'].join('');
+ }
+
+ // process MultiGeometry
+ var GeometryNodes = node.getElementsByTagName('coordinates');
+ var Geometry = null;
+ if (!!GeometryNodes && (GeometryNodes.length > 0)) {
+ for (var gn=0;gn<GeometryNodes.length;gn++) {
+ if (!GeometryNodes[gn].parentNode ||
+ !GeometryNodes[gn].parentNode.nodeName) {
+
+ } else { // parentNode.nodeName exists
+ var GeometryPN = GeometryNodes[gn].parentNode;
+ Geometry = GeometryPN.nodeName;
+
+ // Extract the coordinates
+ // What sort of placemark?
+ switch(Geometry) {
+ case "Point":
+ placemark.Point = processPlacemarkCoords(node, "Point")[0];
+ placemark.latlng = new google.maps.LatLng(placemark.Point.coordinates[0].lat, placemark.Point.coordinates[0].lng);
+ pathLength = 1;
+ break;
+ case "LinearRing":
+ // Polygon/line
+ polygonNodes = node.getElementsByTagName('Polygon');
+ // Polygon
+ if (!placemark.Polygon)
+ placemark.Polygon = [{
+ outerBoundaryIs: {coordinates: []},
+ innerBoundaryIs: [{coordinates: []}]
+ }];
+ for (var pg=0;pg<polygonNodes.length;pg++) {
+ placemark.Polygon[pg] = {
+ outerBoundaryIs: {coordinates: []},
+ innerBoundaryIs: [{coordinates: []}]
+ }
+ placemark.Polygon[pg].outerBoundaryIs = processPlacemarkCoords(polygonNodes[pg], "outerBoundaryIs");
+ placemark.Polygon[pg].innerBoundaryIs = processPlacemarkCoords(polygonNodes[pg], "innerBoundaryIs");
+ }
+ coordList = placemark.Polygon[0].outerBoundaryIs;
+ break;
+
+ case "LineString":
+ pathLength = 0;
+ placemark.LineString = processPlacemarkCoords(node,"LineString");
+ break;
+
+ default:
+ break;
+ }
+ } // parentNode.nodeName exists
+ } // GeometryNodes loop
+ } // if GeometryNodes
+ // call the custom placemark parse function if it is defined
+ if (!!parserOptions.pmParseFn) parserOptions.pmParseFn(node, placemark);
+ doc.placemarks.push(placemark);
+
+ if (placemark.Point) {
+ if (parserOptions.zoom && !!google.maps) {
+ doc.bounds = doc.bounds || new google.maps.LatLngBounds();
+ doc.bounds.extend(placemark.latlng);
+ }
+
+ if (!!parserOptions.createMarker) {
+ // User-defined marker handler
+ parserOptions.createMarker(placemark, doc);
+ } else { // !user defined createMarker
+ // Check to see if this marker was created on a previous load of this document
+ var found = false;
+ if (!!doc) {
+ doc.markers = doc.markers || [];
+ if (doc.reload) {
+ for (var j = 0; j < doc.markers.length; j++) {
+ if (doc.markers[j].getPosition().equals(placemark.latlng)) {
+ found = doc.markers[j].active = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found) {
+ // Call the built-in marker creator
+ marker = createMarker(placemark, doc);
+ marker.active = true;
+ }
+ }
+ }
+ if (placemark.Polygon) { // poly test 2
+ if (!!doc) {
+ doc.gpolygons = doc.gpolygons || [];
+ }
+
+ if (!!parserOptions.createPolygon) {
+ // User-defined polygon handler
+ poly = parserOptions.createPolygon(placemark, doc);
+ } else { // ! user defined createPolygon
+ // Check to see if this marker was created on a previous load of this document
+ poly = createPolygon(placemark,doc);
+ poly.active = true;
+ }
+ if (parserOptions.zoom && !!google.maps) {
+ doc.bounds = doc.bounds || new google.maps.LatLngBounds();
+ doc.bounds.union(poly.bounds);
+ }
+ }
+ if (placemark.LineString) { // polyline
+ if (!!doc) {
+ doc.gpolylines = doc.gpolylines || [];
+ }
+ if (!!parserOptions.createPolyline) {
+ // User-defined polyline handler
+ poly = parserOptions.createPolyline(placemark, doc);
+ } else { // ! user defined createPolyline
+ // Check to see if this marker was created on a previous load of this document
+ poly = createPolyline(placemark,doc);
+ poly.active = true;
+ }
+ if (parserOptions.zoom && !!google.maps) {
+ doc.bounds = doc.bounds || new google.maps.LatLngBounds();
+ doc.bounds.union(poly.bounds);
+ }
+ }
+
+ } // placemark loop
+
+ if (!!doc.reload && !!doc.markers) {
+ for (i = doc.markers.length - 1; i >= 0 ; i--) {
+ if (!doc.markers[i].active) {
+ if (!!doc.markers[i].infoWindow) {
+ doc.markers[i].infoWindow.close();
+ }
+ doc.markers[i].setMap(null);
+ doc.markers.splice(i, 1);
+ }
+ }
+ }
+
+ // Parse ground overlays
+ if (!!doc.reload && !!doc.groundoverlays) {
+ for (i = 0; i < doc.groundoverlays.length; i++) {
+ doc.groundoverlays[i].active = false;
+ }
+ }
+
+ if (!!doc) {
+ doc.groundoverlays = doc.groundoverlays || [];
+ }
+ // doc.groundoverlays =[];
+ var groundOverlay, color, transparency, overlay;
+ var groundNodes = responseXML.getElementsByTagName('GroundOverlay');
+ for (i = 0; i < groundNodes.length; i++) {
+ node = groundNodes[i];
+
+ // Init the ground overlay object
+ groundOverlay = {
+ name: geoXML3.nodeValue(node.getElementsByTagName('name')[0]),
+ description: geoXML3.nodeValue(node.getElementsByTagName('description')[0]),
+ icon: {href: geoXML3.nodeValue(node.getElementsByTagName('href')[0])},
+ latLonBox: {
+ north: parseFloat(geoXML3.nodeValue(node.getElementsByTagName('north')[0])),
+ east: parseFloat(geoXML3.nodeValue(node.getElementsByTagName('east')[0])),
+ south: parseFloat(geoXML3.nodeValue(node.getElementsByTagName('south')[0])),
+ west: parseFloat(geoXML3.nodeValue(node.getElementsByTagName('west')[0]))
+ }
+ };
+ if (parserOptions.zoom && !!google.maps) {
+ doc.bounds = doc.bounds || new google.maps.LatLngBounds();
+ doc.bounds.union(new google.maps.LatLngBounds(
+ new google.maps.LatLng(groundOverlay.latLonBox.south, groundOverlay.latLonBox.west),
+ new google.maps.LatLng(groundOverlay.latLonBox.north, groundOverlay.latLonBox.east)
+ ));
+ }
+
+ // Opacity is encoded in the color node
+ var colorNode = node.getElementsByTagName('color');
+ if ( colorNode && colorNode.length && (colorNode.length > 0)) {
+ groundOverlay.opacity = geoXML3.getOpacity(nodeValue(colorNode[0]));
+ } else {
+ groundOverlay.opacity = 0.45;
+ }
+
+ doc.groundoverlays.push(groundOverlay);
+
+ if (!!parserOptions.createOverlay) {
+ // User-defined overlay handler
+ parserOptions.createOverlay(groundOverlay, doc);
+ } else { // ! user defined createOverlay
+ // Check to see if this overlay was created on a previous load of this document
+ var found = false;
+ if (!!doc) {
+ doc.groundoverlays = doc.groundoverlays || [];
+ if (doc.reload) {
+ overlayBounds = new google.maps.LatLngBounds(
+ new google.maps.LatLng(groundOverlay.latLonBox.south, groundOverlay.latLonBox.west),
+ new google.maps.LatLng(groundOverlay.latLonBox.north, groundOverlay.latLonBox.east));
+ var overlays = doc.groundoverlays;
+ for (i = overlays.length; i--;) {
+ if ((overlays[i].bounds().equals(overlayBounds)) &&
+ (overlays.url_ === groundOverlay.icon.href)) {
+ found = overlays[i].active = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found) {
+ // Call the built-in overlay creator
+ overlay = createOverlay(groundOverlay, doc);
+ overlay.active = true;
+ }
+ }
+ if (!!doc.reload && !!doc.groundoverlays && !!doc.groundoverlays.length) {
+ var overlays = doc.groundoverlays;
+ for (i = overlays.length; i--;) {
+ if (!overlays[i].active) {
+ overlays[i].remove();
+ overlays.splice(i, 1);
+ }
+ }
+ doc.groundoverlays = overlays;
+ }
+ }
+ // Parse network links
+ var networkLink;
+ var docPath = document.location.pathname.split('/');
+ docPath = docPath.splice(0, docPath.length - 1).join('/');
+ var linkNodes = responseXML.getElementsByTagName('NetworkLink');
+ for (i = 0; i < linkNodes.length; i++) {
+ node = linkNodes[i];
+
+ // Init the network link object
+ networkLink = {
+ name: geoXML3.nodeValue(node.getElementsByTagName('name')[0]),
+ link: {
+ href: geoXML3.nodeValue(node.getElementsByTagName('href')[0]),
+ refreshMode: geoXML3.nodeValue(node.getElementsByTagName('refreshMode')[0])
+ }
+ };
+
+ // Establish the specific refresh mode
+ if (networkLink.link.refreshMode === '') {
+ networkLink.link.refreshMode = 'onChange';
+ }
+ if (networkLink.link.refreshMode === 'onInterval') {
+ networkLink.link.refreshInterval = parseFloat(geoXML3.nodeValue(node.getElementsByTagName('refreshInterval')[0]));
+ if (isNaN(networkLink.link.refreshInterval)) {
+ networkLink.link.refreshInterval = 0;
+ }
+ } else if (networkLink.link.refreshMode === 'onChange') {
+ networkLink.link.viewRefreshMode = geoXML3.nodeValue(node.getElementsByTagName('viewRefreshMode')[0]);
+ if (networkLink.link.viewRefreshMode === '') {
+ networkLink.link.viewRefreshMode = 'never';
+ }
+ if (networkLink.link.viewRefreshMode === 'onStop') {
+ networkLink.link.viewRefreshTime = geoXML3.nodeValue(node.getElementsByTagName('refreshMode')[0]);
+ networkLink.link.viewFormat = geoXML3.nodeValue(node.getElementsByTagName('refreshMode')[0]);
+ if (networkLink.link.viewFormat === '') {
+ networkLink.link.viewFormat = 'BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]';
+ }
+ }
+ }
+
+ if (!/^[\/|http]/.test(networkLink.link.href)) {
+ // Fully-qualify the HREF
+ networkLink.link.href = docPath + '/' + networkLink.link.href;
+ }
+
+ // Apply the link
+ if ((networkLink.link.refreshMode === 'onInterval') &&
+ (networkLink.link.refreshInterval > 0)) {
+ // Reload at regular intervals
+ setInterval(parserName + '.parse("' + networkLink.link.href + '")',
+ 1000 * networkLink.link.refreshInterval);
+ } else if (networkLink.link.refreshMode === 'onChange') {
+ if (networkLink.link.viewRefreshMode === 'never') {
+ // Load the link just once
+ doc.internals.parser.parse(networkLink.link.href, doc.internals.docSet);
+ } else if (networkLink.link.viewRefreshMode === 'onStop') {
+ // Reload when the map view changes
+
+ }
+ }
+ }
+}
+
+ if (!!doc.bounds) {
+ doc.internals.bounds = doc.internals.bounds || new google.maps.LatLngBounds();
+ doc.internals.bounds.union(doc.bounds);
+ }
+ if (!!doc.markers || !!doc.groundoverlays || !!doc.gpolylines || !!doc.gpolygons) {
+ doc.internals.parseOnly = false;
+ }
+
+ doc.internals.remaining -= 1;
+ if (doc.internals.remaining === 0) {
+ // We're done processing this set of KML documents
+ // Options that get invoked after parsing completes
+ if (!!doc.internals.bounds) {
+ parserOptions.map.fitBounds(doc.internals.bounds);
+ }
+ if (parserOptions.afterParse) {
+ parserOptions.afterParse(doc.internals.docSet);
+ }
+
+ if (!doc.internals.parseOnly) {
+ // geoXML3 is not being used only as a real-time parser, so keep the processed documents around
+ for (var i=(doc.internals.docSet.length-1);i>=0;i--) {
+ docs.push(doc.internals.docSet[i]);
+ }
+ }
+ }
+ };
+
+var kmlColor = function (kmlIn) {
+ var kmlColor = {};
+ if (kmlIn) {
+ aa = kmlIn.substr(0,2);
+ bb = kmlIn.substr(2,2);
+ gg = kmlIn.substr(4,2);
+ rr = kmlIn.substr(6,2);
+ kmlColor.color = "#" + rr + gg + bb;
+ kmlColor.opacity = parseInt(aa,16)/256;
+ } else {
+ // defaults
+ kmlColor.color = randomColor();
+ kmlColor.opacity = 0.45;
+ }
+ return kmlColor;
+}
+
+var randomColor = function(){
+ var color="#";
+ var colorNum = Math.random()*8388607.0; // 8388607 = Math.pow(2,23)-1
+ var colorStr = colorNum.toString(16);
+ color += colorStr.substring(0,colorStr.indexOf('.'));
+ return color;
+};
+
+ var processStyleID = function (style) {
+ var zeroPoint = new google.maps.Point(0,0);
+ if (!!style.href) {
+ var markerRegEx = /\/(red|blue|green|yellow|lightblue|purple|pink|orange|pause|go|stop)(-dot)?\.png/;
+ if (markerRegEx.test(style.href)) {
+ //bottom middle
+ var anchorPoint = new google.maps.Point(16*style.scale, 32*style.scale);
+ } else {
+ var anchorPoint = new google.maps.Point(16*style.scale, 12*style.scale);
+ }
+ // Init the style object with a standard KML icon
+ style.icon = new google.maps.MarkerImage(
+ style.href,
+ new google.maps.Size(32*style.scale, 32*style.scale),
+ zeroPoint,
+ // bottom middle
+ anchorPoint,
+ new google.maps.Size(32,32)
+
+ );
+
+ // Look for a predictable shadow
+ var stdRegEx = /\/(red|blue|green|yellow|lightblue|purple|pink|orange)(-dot)?\.png/;
+ var shadowSize = new google.maps.Size(59, 32);
+ var shadowPoint = new google.maps.Point(16,32);
+ if (stdRegEx.test(style.href)) {
+ // A standard GMap-style marker icon
+ style.shadow = new google.maps.MarkerImage(
+ 'http://maps.google.com/mapfiles/ms/micons/msmarker.shadow.png',
+ shadowSize,
+ zeroPoint,
+ shadowPoint);
+ } else if (style.href.indexOf('-pushpin.png') > -1) {
+ // Pushpin marker icon
+ style.shadow = new google.maps.MarkerImage(
+ 'http://maps.google.com/mapfiles/ms/micons/pushpin_shadow.png',
+ shadowSize,
+ zeroPoint,
+ shadowPoint);
+ } else {
+ // Other MyMaps KML standard icon
+ style.shadow = new google.maps.MarkerImage(
+ style.href.replace('.png', '.shadow.png'),
+ shadowSize,
+ zeroPoint,
+ shadowPoint);
+ }
+ }
+ }
+
+ var processStyles = function (doc) {
+ for (var styleID in doc.styles) {
+ processStyleID(doc.styles[styleID]);
+ }
+ };
+
+ var createMarker = function (placemark, doc) {
+ // create a Marker to the map from a placemark KML object
+
+ // Load basic marker properties
+ var markerOptions = geoXML3.combineOptions(parserOptions.markerOptions, {
+ map: parserOptions.map,
+ position: new google.maps.LatLng(placemark.Point.coordinates[0].lat, placemark.Point.coordinates[0].lng),
+ title: placemark.name,
+ zIndex: Math.round(placemark.Point.coordinates[0].lat * -100000)<<5,
+ icon: placemark.style.icon,
+ shadow: placemark.style.shadow
+ });
+
+ // Create the marker on the map
+ var marker = new google.maps.Marker(markerOptions);
+ if (!!doc) {
+ doc.markers.push(marker);
+ }
+
+ // Set up and create the infowindow
+ var infoWindowOptions = geoXML3.combineOptions(parserOptions.infoWindowOptions, {
+ content: '<div class="geoxml3_infowindow"><h3>' + placemark.name +
+ '</h3><div>' + placemark.description + '</div></div>',
+ pixelOffset: new google.maps.Size(0, 2)
+ });
+ if (parserOptions.infoWindow) {
+ marker.infoWindow = parserOptions.infoWindow;
+ } else {
+ marker.infoWindow = new google.maps.InfoWindow(infoWindowOptions);
+ }
+ // Infowindow-opening event handler
+ google.maps.event.addListener(marker, 'click', function() {
+ marker.infoWindow.setOptions(infoWindowOptions);
+ this.infoWindow.open(this.map, this);
+ });
+ placemark.marker = marker;
+ return marker;
+ };
+
+ var createOverlay = function (groundOverlay, doc) {
+ // Add a ProjectedOverlay to the map from a groundOverlay KML object
+
+ if (!window.ProjectedOverlay) {
+ throw 'geoXML3 error: ProjectedOverlay not found while rendering GroundOverlay from KML';
+ }
+
+ var bounds = new google.maps.LatLngBounds(
+ new google.maps.LatLng(groundOverlay.latLonBox.south, groundOverlay.latLonBox.west),
+ new google.maps.LatLng(groundOverlay.latLonBox.north, groundOverlay.latLonBox.east)
+ );
+ var overlayOptions = geoXML3.combineOptions(parserOptions.overlayOptions, {percentOpacity: groundOverlay.opacity*100});
+ var overlay = new ProjectedOverlay(parserOptions.map, groundOverlay.icon.href, bounds, overlayOptions);
+
+ if (!!doc) {
+ doc.ggroundoverlays = doc.ggroundoverlays || [];
+ doc.ggroundoverlays.push(overlay);
+ }
+
+ return overlay;
+ };
+
+// Create Polyline
+
+ var createPolyline = function(placemark, doc) {
+ var path = [];
+ for (var j=0; j<placemark.LineString.length; j++) {
+ var coords = placemark.LineString[j].coordinates;
+ var bounds = new google.maps.LatLngBounds();
+ for (var i=0;i<coords.length;i++) {
+ var pt = new google.maps.LatLng(coords[i].lat, coords[i].lng);
+ path.push(pt);
+ bounds.extend(pt);
+ }
+ }
+ // point to open the infowindow if triggered
+ var point = path[Math.floor(path.length/2)];
+ // Load basic polyline properties
+ var kmlStrokeColor = kmlColor(placemark.style.color);
+ var polyOptions = geoXML3.combineOptions(parserOptions.polylineOptions, {
+ map: parserOptions.map,
+ path: path,
+ strokeColor: kmlStrokeColor.color,
+ strokeWeight: placemark.style.width,
+ strokeOpacity: kmlStrokeColor.opacity,
+ title: placemark.name
+ });
+ var infoWindowOptions = geoXML3.combineOptions(parserOptions.infoWindowOptions, {
+ content: '<div class="geoxml3_infowindow"><h3>' + placemark.name +
+ '</h3><div>' + placemark.description + '</div></div>',
+ pixelOffset: new google.maps.Size(0, 2)
+ });
+ var p = new google.maps.Polyline(polyOptions);
+ p.bounds = bounds;
+ if (parserOptions.infoWindow) {
+ p.infoWindow = parserOptions.infoWindow;
+ } else {
+ p.infoWindow = new google.maps.InfoWindow(infoWindowOptions);
+ }
+ // Infowindow-opening event handler
+ google.maps.event.addListener(p, 'click', function(e) {
+ p.infoWindow.setOptions(infoWindowOptions);
+ if (e && e.latLng) {
+ p.infoWindow.setPosition(e.latLng);
+ } else {
+ p.infoWindow.setPosition(point);
+ }
+ p.infoWindow.open(this.map);
+ });
+ if (!!doc) doc.gpolylines.push(p);
+ placemark.polyline = p;
+ return p;
+}
+
+// Create Polygon
+
+var createPolygon = function(placemark, doc) {
+ var bounds = new google.maps.LatLngBounds();
+ var pathsLength = 0;
+ var paths = [];
+ for (var polygonPart=0;polygonPart<placemark.Polygon.length;polygonPart++) {
+ for (var j=0; j<placemark.Polygon[polygonPart].outerBoundaryIs.length; j++) {
+ var coords = placemark.Polygon[polygonPart].outerBoundaryIs[j].coordinates;
+ var path = [];
+ for (var i=0;i<coords.length;i++) {
+ var pt = new google.maps.LatLng(coords[i].lat, coords[i].lng);
+ path.push(pt);
+ bounds.extend(pt);
+ }
+ paths.push(path);
+ pathsLength += path.length;
+ }
+ for (var j=0; j<placemark.Polygon[polygonPart].innerBoundaryIs.length; j++) {
+ var coords = placemark.Polygon[polygonPart].innerBoundaryIs[j].coordinates;
+ var path = [];
+ for (var i=0;i<coords.length;i++) {
+ var pt = new google.maps.LatLng(coords[i].lat, coords[i].lng);
+ path.push(pt);
+ bounds.extend(pt);
+ }
+ paths.push(path);
+ pathsLength += path.length;
+ }
+ }
+
+ // Load basic polygon properties
+ var kmlStrokeColor = kmlColor(placemark.style.color);
+ var kmlFillColor = kmlColor(placemark.style.fillcolor);
+ if (!placemark.style.fill) kmlFillColor.opacity = 0.0;
+ var strokeWeight = placemark.style.width;
+ if (!placemark.style.outline) {
+ strokeWeight = 0;
+ kmlStrokeColor.opacity = 0.0;
+ }
+ var polyOptions = geoXML3.combineOptions(parserOptions.polygonOptions, {
+ map: parserOptions.map,
+ paths: paths,
+ title: placemark.name,
+ strokeColor: kmlStrokeColor.color,
+ strokeWeight: strokeWeight,
+ strokeOpacity: kmlStrokeColor.opacity,
+ fillColor: kmlFillColor.color,
+ fillOpacity: kmlFillColor.opacity
+ });
+
+ var infoWindowOptions = geoXML3.combineOptions(parserOptions.infoWindowOptions, {
+ content: '<div class="geoxml3_infowindow"><h3>' + placemark.name +
+ '</h3><div>' + placemark.description + '</div></div>',
+ pixelOffset: new google.maps.Size(0, 2)
+ });
+ var p = new google.maps.Polygon(polyOptions);
+ p.bounds = bounds;
+ if (parserOptions.infoWindow) {
+ p.infoWindow = parserOptions.infoWindow;
+ } else {
+ p.infoWindow = new google.maps.InfoWindow(infoWindowOptions);
+ }
+ // Infowindow-opening event handler
+ google.maps.event.addListener(p, 'click', function(e) {
+ p.infoWindow.setOptions(infoWindowOptions);
+ if (e && e.latLng) {
+ p.infoWindow.setPosition(e.latLng);
+ } else {
+ p.infoWindow.setPosition(p.bounds.getCenter());
+ }
+ p.infoWindow.open(this.map);
+ });
+ if (!!doc) doc.gpolygons.push(p);
+ placemark.polygon = p;
+ return p;
+}
+
+ return {
+ // Expose some properties and methods
+
+ options: parserOptions,
+ docs: docs,
+
+ parse: parse,
+ hideDocument: hideDocument,
+ showDocument: showDocument,
+ processStyles: processStyles,
+ createMarker: createMarker,
+ createOverlay: createOverlay,
+ createPolyline: createPolyline,
+ createPolygon: createPolygon
+ };
+};
+// End of KML Parser
+
+// Helper objects and functions
+geoXML3.getOpacity = function (kmlColor) {
+ // Extract opacity encoded in a KML color value. Returns a number between 0 and 1.
+ if (!!kmlColor &&
+ (kmlColor !== '') &&
+ (kmlColor.length == 8)) {
+ var transparency = parseInt(kmlColor.substr(0, 2), 16);
+ return transparency / 255;
+ } else {
+ return 1;
+ }
+};
+
+// Log a message to the debugging console, if one exists
+geoXML3.log = function(msg) {
+ if (!!window.console) {
+ console.log(msg);
+ } else { alert("log:"+msg); }
+};
+
+// Combine two options objects: a set of default values and a set of override values
+geoXML3.combineOptions = function (overrides, defaults) {
+ var result = {};
+ if (!!overrides) {
+ for (var prop in overrides) {
+ if (overrides.hasOwnProperty(prop)) {
+ result[prop] = overrides[prop];
+ }
+ }
+ }
+ if (!!defaults) {
+ for (prop in defaults) {
+ if (defaults.hasOwnProperty(prop) && (result[prop] === undefined)) {
+ result[prop] = defaults[prop];
+ }
+ }
+ }
+ return result;
+};
+
+// Retrieve an XML document from url and pass it to callback as a DOM document
+geoXML3.fetchers = [];
+
+// parse text to XML doc
+/**
+ * Parses the given XML string and returns the parsed document in a
+ * DOM data structure. This function will return an empty DOM node if
+ * XML parsing is not supported in this browser.
+ * @param {string} str XML string.
+ * @return {Element|Document} DOM.
+ */
+geoXML3.xmlParse = function (str) {
+ if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
+ var doc = new ActiveXObject('Microsoft.XMLDOM');
+ doc.loadXML(str);
+ return doc;
+ }
+
+ if (typeof DOMParser != 'undefined') {
+ return (new DOMParser()).parseFromString(str, 'text/xml');
+ }
+
+ return createElement('div', null);
+}
+
+geoXML3.fetchXML = function (url, callback) {
+ function timeoutHandler() {
+ callback();
+ };
+
+ var xhrFetcher;
+ if (!!geoXML3.fetchers.length) {
+ xhrFetcher = geoXML3.fetchers.pop();
+ } else {
+ if (!!window.XMLHttpRequest) {
+ xhrFetcher = new window.XMLHttpRequest(); // Most browsers
+ } else if (!!window.ActiveXObject) {
+ xhrFetcher = new window.ActiveXObject('Microsoft.XMLHTTP'); // Some IE
+ }
+ }
+
+ if (!xhrFetcher) {
+ geoXML3.log('Unable to create XHR object');
+ callback(null);
+ } else {
+ xhrFetcher.open('GET', url, true);
+ xhrFetcher.onreadystatechange = function () {
+ if (xhrFetcher.readyState === 4) {
+ // Retrieval complete
+ if (!!geoXML3.xhrtimeout)
+ clearTimeout(geoXML3.xhrtimeout);
+ if (xhrFetcher.status >= 400) {
+ geoXML3.log('HTTP error ' + xhrFetcher.status + ' retrieving ' + url);
+ callback();
+ } else {
+ // Returned successfully
+ callback(geoXML3.xmlParse(xhrFetcher.responseText));
+ }
+ // We're done with this fetcher object
+ geoXML3.fetchers.push(xhrFetcher);
+ }
+ };
+ geoXML3.xhrtimeout = setTimeout(timeoutHandler, 60000);
+ xhrFetcher.send(null);
+ }
+};
+
+//nodeValue: Extract the text value of a DOM node, with leading and trailing whitespace trimmed
+geoXML3.nodeValue = function(node) {
+ var retStr="";
+ if (!node) {
+ return '';
+ }
+ if(node.nodeType==3||node.nodeType==4||node.nodeType==2){
+ retStr+=node.nodeValue;
+ }else if(node.nodeType==1||node.nodeType==9||node.nodeType==11){
+ for(var i=0;i<node.childNodes.length;++i){
+ retStr+=arguments.callee(node.childNodes[i]);
+ }
+ }
+ return retStr;
+}; \ No newline at end of file