Reputation: 8471
I'm writing an application to render trails on a map. I would like to dynamically modify the color of these trails depending on eg. how muddy they are.
I'm using the Google Maps v3 API.
I would like to do everything in Javascript, if possible. The KML may not be served on the same domain as the page containing the Javascript so I might not be able to XmlHttpRequest it.
It looks like the color is specified in the KML file itself, so I could write server-side code to fetch the original KML and re-serve a modified version of it.
My question is: can I do this without server-side processing and just set a property on the KmlLayer to set the color?
Upvotes: 1
Views: 8286
Reputation:
For changing the polygon color, you need to use 3rd party kml parsers like geoxml3. see this, changing the color of Polygons from KML rendered using geoxml3 on mouseover
Upvotes: 1
Reputation: 2108
Refer : highlight a polygon while on click using kml
Please try this.
<style type="text/css">
html, body, #map_canvas {
width: 750px;
height: 600px;
margin: 0;
padding: 0;
}
.infowindow * {font-size: 90%; margin: 0}
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://geoxml3.googlecode.com/svn/branches/kmz/ZipFile.complete.js"></script>
<script type="text/javascript" src="http://geoxml3.googlecode.com/svn/branches/kmz/geoxml3.js"></script>
<script type="text/javascript" src="http://geoxml3.googlecode.com/svn/trunk/ProjectedOverlay.js"></script>
<script type="text/javascript">
var geoXml = null;
var geoXmlDoc = null;
var map = null;
var myLatLng = null;
var myGeoXml3Zoom = true;
var sidebarHtml = "";
var infowindow = null;
var kmlLayer = null;
var filename = "test.kmz"; //kml or kmz file
function MapTypeId2UrlValue(maptype) {
var urlValue = 'm';
switch (maptype) {
case google.maps.MapTypeId.HYBRID: urlValue = 'h';
break;
case google.maps.MapTypeId.SATELLITE: urlValue = 'k';
break;
case google.maps.MapTypeId.TERRAIN: urlValue = 't';
break;
default:
case google.maps.MapTypeId.ROADMAP: urlValue = 'm';
break;
}
return urlValue;
}
function initialize() {
myLatLng = new google.maps.LatLng(39.8000959563484, -89.549560546875);
// these set the initial center, zoom and maptype for the map
// if it is not specified in the query string
var lat = 37.422104808;
var lng = -122.0838851;
var zoom = 18;
var maptype = google.maps.MapTypeId.ROADMAP;
// If there are any parameters at eh end of the URL, they will be in location.search
// looking something like "?marker=3"
// skip the first character, we are not interested in the "?"
var query = location.search.substring(1);
// split the rest at each "&" character to give a list of "argname=value" pairs
var pairs = query.split("&");
for (var i = 0; i < pairs.length; i++) {
// break each pair at the first "=" to obtain the argname and value
var pos = pairs[i].indexOf("=");
var argname = pairs[i].substring(0, pos).toLowerCase();
var value = pairs[i].substring(pos + 1).toLowerCase();
// process each possible argname - use unescape() if theres any chance of spaces
if (argname == "id") { id = unescape(value); }
if (argname == "filename") { filename = unescape(value); }
if (argname == "marker") { index = parseFloat(value); }
if (argname == "lat") { lat = parseFloat(value); }
if (argname == "lng") { lng = parseFloat(value); }
if (argname == "zoom") {
zoom = parseInt(value);
myGeoXml3Zoom = false;
}
if (argname == "type") {
// from the v3 documentation 8/24/2010
// HYBRID This map type displays a transparent layer of major streets on satellite images.
// ROADMAP This map type displays a normal street map.
// SATELLITE This map type displays satellite images.
// TERRAIN This map type displays maps with physical features such as terrain and vegetation.
if (value == "m") { maptype = google.maps.MapTypeId.ROADMAP; }
if (value == "k") { maptype = google.maps.MapTypeId.SATELLITE; }
if (value == "h") { maptype = google.maps.MapTypeId.HYBRID; }
if (value == "t") { maptype = google.maps.MapTypeId.TERRAIN; }
}
}
if (!isNaN(lat) && !isNaN(lng)) {
myLatLng = new google.maps.LatLng(lat, lng);
}
var myOptions = {
zoom: zoom,
center: myLatLng,
// zoom: 5,
// center: myLatlng,
mapTypeId: maptype
};
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
infowindow = new google.maps.InfoWindow({});
geoXml = new geoXML3.parser({
map: map,
infoWindow: infowindow,
singleInfoWindow: true,
zoom: myGeoXml3Zoom,
markerOptions: { optimized: false },
afterParse: useTheData
});
geoXml.parse(filename);
};
// function kmlPgClick(pm) {
// if (geoXml.docs[0].placemarks[pm].polygon.getMap()) {
// google.maps.event.trigger(geoXmlDoc.placemarks[pm].polygon, "click");
// } else {
// geoXmlDoc.placemarks[pm].polygon.setMap(map);
// google.maps.event.trigger(geoXmlDoc.placemarks[pm].polygon, "click");
// }
// }
// function kmlPlClick(pm) {
// if (geoXml.docs[0].placemarks[pm].polyline.getMap()) {
// google.maps.event.trigger(geoXmlDoc.placemarks[pm].polyline, "click");
// } else {
// geoXmlDoc.placemarks[pm].polyline.setMap(map);
// google.maps.event.trigger(geoXmlDoc.placemarks[pm].polyline, "click");
// }
// }
// function kmlClick(pm) {
// if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
// google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker, "click");
// } else {
// geoXmlDoc.placemarks[pm].marker.setMap(map);
// google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker, "click");
// }
// }
function kmlColor(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 = "red";
kmlColor.opacity = 0.45;
}
return kmlColor;
}
var highlightOptions = { fillColor: "red", strokeColor: "#000000", fillOpacity: 0.9, strokeWidth: 10 };
var highlightLineOptions = { strokeColor: "red", strokeWidth: 10 };
function kmlHighlightPoly(pm) {
for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
var placemark = geoXmlDoc.placemarks[i];
if (i == pm) {
if (placemark.polygon) placemark.polygon.setOptions(highlightOptions);
if (placemark.polyline) placemark.polyline.setOptions(highlightLineOptions);
} else {
if (placemark.polygon) placemark.polygon.setOptions(placemark.polygon.normalStyle);
if (placemark.polyline) placemark.polyline.setOptions(placemark.polyline.normalStyle);
}
}
}
function kmlUnHighlightPoly(pm) {
for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
if (i == pm) {
var placemark = geoXmlDoc.placemarks[i];
if (placemark.polygon) placemark.polygon.setOptions(placemark.polygon.normalStyle);
if (placemark.polyline) placemark.polyline.setOptions(placemark.polyline.normalStyle);
}
}
}
function showAll() {
map.fitBounds(geoXmlDoc.bounds);
for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
var placemark = geoXmlDoc.placemarks[i];
if (placemark.polygon) placemark.polygon.setMap(map);
if (placemark.polyline) placemark.polyline.setMap(map);
if (placemark.marker) placemark.marker.setMap(map);
}
}
function highlightPoly(poly, polynum) {
// poly.setOptions({fillColor: "#0000FF", strokeColor: "#0000FF", fillOpacity: 0.3}) ;
google.maps.event.addListener(poly, "mouseover", function () {
var rowElem = document.getElementById('row' + polynum);
if (rowElem) rowElem.style.backgroundColor = "red";
if (poly instanceof google.maps.Polygon) {
poly.setOptions(highlightOptions);
} else if (poly instanceof google.maps.Polyline) {
poly.setOptions(highlightLineOptions);
}
});
google.maps.event.addListener(poly, "mouseout", function () {
var rowElem = document.getElementById('row' + polynum);
if (rowElem) rowElem.style.backgroundColor = "red";
poly.setOptions(poly.normalStyle);
});
}
function makeSidebarPolylineEntry(i) {
var name = geoXmlDoc.placemarks[i].name;
if (!name || (name.length == 0)) name = "polyline #" + i;
// alert(name);
sidebarHtml += '<tr id="row' + i + '"><td onmouseover="kmlHighlightPoly(' + i + ');" onmouseout="kmlUnHighlightPoly(' + i + ');"><a href="javascript:kmlPlClick(' + i + ');">' + name + '</a> - <a href="javascript:kmlShowPlacemark(' + i + ');">show</a></td></tr>';
}
function makeSidebarEntry(i) {
var name = geoXmlDoc.placemarks[i].name;
if (!name || (name.length == 0)) name = "marker #" + i;
// alert(name);
sidebarHtml += '<tr id="row' + i + '"><td><a href="javascript:kmlClick(' + i + ');">' + name + '</a></td></tr>';
}
function useTheData(doc) {
var currentBounds = map.getBounds();
if (!currentBounds) currentBounds = new google.maps.LatLngBounds();
// Geodata handling goes here, using JSON properties of the doc object
sidebarHtml = '<table><tr><td><a href="javascript:showAll();">Show All</a></td></tr>';
// var sidebarHtml = '<table>';
geoXmlDoc = doc[0];
for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
// console.log(doc[0].markers[i].title);
var placemark = geoXmlDoc.placemarks[i];
if (placemark.polygon) {
if (currentBounds.intersects(placemark.polygon.bounds)) {
//makeSidebarPolygonEntry(i);
}
var kmlStrokeColor = kmlColor(placemark.style.color);
var kmlFillColor = kmlColor(placemark.style.fillcolor);
var normalStyle = {
strokeColor: kmlStrokeColor.color,
strokeWeight: placemark.style.width,
strokeOpacity: kmlStrokeColor.opacity,
fillColor: kmlFillColor.color,
fillOpacity: kmlFillColor.opacity
};
placemark.polygon.normalStyle = normalStyle;
highlightPoly(placemark.polygon, i);
}
if (placemark.polyline) {
if (currentBounds.intersects(placemark.polyline.bounds)) {
makeSidebarPolylineEntry(i);
}
var kmlStrokeColor = kmlColor(placemark.style.color);
var normalStyle = {
strokeColor: kmlStrokeColor.color,
strokeWeight: placemark.style.width,
strokeOpacity: kmlStrokeColor.opacity
};
placemark.polyline.normalStyle = normalStyle;
highlightPoly(placemark.polyline, i);
}
if (placemark.marker) {
if (currentBounds.contains(placemark.marker.getPosition())) {
makeSidebarEntry(i);
}
}
/* doc[0].markers[i].setVisible(false); */
}
sidebarHtml += "</table>";
document.getElementById("sidebar").innerHTML = sidebarHtml; //show to all link
};
</script>
Upvotes: 2
Reputation: 8471
For what it's worth, I wrote an App Engine app that takes a url pointing to a KML or GPX file and converts it to a JSON array containing the lat/lng coordinates in the given file.
Source code is here: https://github.com/Moishe/XmlToPoints
Demo page is here: http://xmltopoints.appspot.com/map?uris=http://bouldermountainbike.org/sites/default/files/Sourdough%20Trail%20(South).gpx
Example URL of getting points is: http://xmltopoints.appspot.com/getpoints?uri=http://bouldermountainbike.org/sites/default/files/Sourdough%20Trail%20(South).gpx&cache=y&jsonp=callback
Upvotes: 0
Reputation: 10619
I don't think there is any property on KmlLayer object to change the color as of now. It is possible to dynamically change the polygon fillColor using for example
new google.maps.Polygon({
paths: triangleCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
But fillColor
is not an option in KmlLayer constructor.
Upvotes: 3