Ricardo Mehr
Ricardo Mehr

Reputation: 310

Google maps change marker color based on xml value

Based on this tutorial https://developers.google.com/maps/documentation/javascript/mysql-to-maps about markers using a mysql database.

I have the following response:

<?xml version="1.0" encoding="ISO-8859-1"?>
<markers>
<marker id="1" lng="151.171936" lat="-33.861034" address="580 Darling Street, Rozelle, NSW" name="Love.Fish" color="green"/>
<marker id="2" lng="151.174469" lat="-33.898113" address="76 Wilford Street, Newtown, NSW" name="Young Henrys" color="green"/>
<marker id="3" lng="151.207474" lat="-33.840282" address="Greenwood Plaza, 36 Blue St, North Sydney NSW" name="Hunter Gatherer" color="yellow"/>
<marker id="4" lng="151.194168" lat="-33.910751" address="7A, 2 Huntley Street, Alexandria, NSW" name="The Potting Shed" color="yellow"/>
<marker id="5" lng="151.210449" lat="-33.879917" address="16 Foster Street, Surry Hills, NSW" name="Nomad" color="orange"/>
<marker id="6" lng="151.263763" lat="-33.906357" address="43 Macpherson Street, Bronte, NSW" name="Three Blue Ducks" color="orange"/>
<marker id="7" lng="151.209656" lat="-33.881123" address="60-64 Reservoir Street, Surry Hills, NSW" name="Single Origin Roasters" color="orange"/>
<marker id="8" lng="151.215530" lat="-33.874737" address="60 Riley Street, Darlinghurst, NSW" name="Red Lantern" color="orange"/>
</markers>

As you can see, I added the color value.

I want the markers on the map to have the color from the response file. How can it be done using the tutorial example?

function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
          center: new google.maps.LatLng(-33.863276, 151.207977),
          zoom: 12
        });
        var infoWindow = new google.maps.InfoWindow;

          // Change this depending on the name of your PHP or XML file
          downloadUrl('https://storage.googleapis.com/mapsdevsite/json/mapmarkers2.xml', function(data) {
            var xml = data.responseXML;
            var markers = xml.documentElement.getElementsByTagName('marker');
            Array.prototype.forEach.call(markers, function(markerElem) {
              var id = markerElem.getAttribute('id');
              var name = markerElem.getAttribute('name');
              var address = markerElem.getAttribute('address');
              var type = markerElem.getAttribute('type');
              var point = new google.maps.LatLng(
                  parseFloat(markerElem.getAttribute('lat')),
                  parseFloat(markerElem.getAttribute('lng')));

              var infowincontent = document.createElement('div');
              var strong = document.createElement('strong');
              strong.textContent = name
              infowincontent.appendChild(strong);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = address
              infowincontent.appendChild(text);
              var icon = customLabel[type] || {};
              var marker = new google.maps.Marker({
                map: map,
                position: point,
                label: icon.label,
              });
              marker.addListener('click', function() {
                infoWindow.setContent(infowincontent);
                infoWindow.open(map, marker);
              });
            });
          });
        }



      function downloadUrl(url, callback) {
        var request = window.ActiveXObject ?
            new ActiveXObject('Microsoft.XMLHTTP') :
            new XMLHttpRequest;

        request.onreadystatechange = function() {
          if (request.readyState == 4) {
            request.onreadystatechange = doNothing;
            callback(request, request.status);
          }
        };

        request.open('GET', url, true);
        request.send(null);
      }

      function doNothing() {}

Upvotes: 1

Views: 1115

Answers (1)

geocodezip
geocodezip

Reputation: 161404

To use the "color" attribute in your XML, you need to parse it out and use it in the definition of the marker icons.

  1. Parse the "color" attribute out of the XML:
var color = markerElem.getAttribute('color');

2a. (png icons) Use that value to define the icons for the markers (requires access to different colored icons, Google has some at "http://maps.google.com/mapfiles/ms/micons/"+color+".png", for a limited set of colors.

 var marker = new google.maps.Marker({
    map: map,
    position: point,
    icon: "http://maps.google.com/mapfiles/ms/micons/"+color+".png",
  });

proof of concept fiddle

screenshot of resulting map (PNG) code snippet (with PNG icons):

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(-33.863276, 151.207977),
    zoom: 12
  });
  var infoWindow = new google.maps.InfoWindow;

  // parse local XML string, rather than using XmlHttpRequest
  var xml = parseXml(xmlStr);
  var markers = xml.documentElement.getElementsByTagName('marker');
  console.log("markers.length=" + markers.length);
  var bounds = new google.maps.LatLngBounds();
  Array.prototype.forEach.call(markers, function(markerElem) {
    var id = markerElem.getAttribute('id');
    var name = markerElem.getAttribute('name');
    var address = markerElem.getAttribute('address');
    var type = markerElem.getAttribute('type');
    var color = markerElem.getAttribute('color');
    var point = new google.maps.LatLng(
      parseFloat(markerElem.getAttribute('lat')),
      parseFloat(markerElem.getAttribute('lng')));
    bounds.extend(point);
    map.fitBounds(bounds);

    var infowincontent = document.createElement('div');
    var strong = document.createElement('strong');
    strong.textContent = name
    infowincontent.appendChild(strong);
    infowincontent.appendChild(document.createElement('br'));

    var text = document.createElement('text');
    text.textContent = address
    infowincontent.appendChild(text);
    var marker = new google.maps.Marker({
      map: map,
      position: point,
      icon: "http://maps.google.com/mapfiles/ms/micons/" + color + ".png",
    });
    marker.addListener('click', function() {
      infoWindow.setContent(infowincontent);
      infoWindow.open(map, marker);
    });
  });
}
// function to parse XML string to XML DOM
function parseXml(str) {
  if (window.ActiveXObject) {
    var doc = new ActiveXObject('MicrosoftXMLDOM');
    doc.loadXML(str);
    return doc;
  } else if (window.DOMParser) {
    return (new DOMParser).parseFromString(str, 'text/xml');
  }
};

// XML data as string
var xmlStr = '<?xml version="1.0" encoding="ISO-8859-1"?><markers><marker id="1" lng="151.171936" lat="-33.861034" address="580 Darling Street, Rozelle, NSW" name="Love.Fish" color="green"/><marker id="2" lng="151.174469" lat="-33.898113" address="76 Wilford Street, Newtown, NSW" name="Young Henrys" color="green"/><marker id="3" lng="151.207474" lat="-33.840282" address="Greenwood Plaza, 36 Blue St, North Sydney NSW" name="Hunter Gatherer" color="yellow"/><marker id="4" lng="151.194168" lat="-33.910751" address="7A, 2 Huntley Street, Alexandria, NSW" name="The Potting Shed" color="yellow"/><marker id="5" lng="151.210449" lat="-33.879917" address="16 Foster Street, Surry Hills, NSW" name="Nomad" color="orange"/><marker id="6" lng="151.263763" lat="-33.906357" address="43 Macpherson Street, Bronte, NSW" name="Three Blue Ducks" color="orange"/><marker id="7" lng="151.209656" lat="-33.881123" address="60-64 Reservoir Street, Surry Hills, NSW" name="Single Origin Roasters" color="orange"/><marker id="8" lng="151.215530" lat="-33.874737" address="60 Riley Street, Darlinghurst, NSW" name="Red Lantern" color="orange"/></markers>';
html,
body,
#map {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"></script>

2b. (SVG icons) Per MrUpsidown's suggestion, you can use SVG icons. One option is the path used in my answer to this question: change google map marker color to a color of my choice:

  var marker = new google.maps.Marker({
    map: map,
    position: point,
    icon: pinSymbol(color),
  });

where pinSymbol is (from the above referenced answer):

function pinSymbol(color) {
    return {
        path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
        fillColor: color,
        fillOpacity: 1,
        strokeColor: '#000',
        strokeWeight: 2,
        scale: 1
    };
}

proof of concept fiddle

screenshot of resulting map (SVG)

**code snippet (with SVG icons):

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(-33.863276, 151.207977),
    zoom: 12
  });
  var infoWindow = new google.maps.InfoWindow;

  // parse local XML string, rather than using XmlHttpRequest
  var xml = parseXml(xmlStr);
  var markers = xml.documentElement.getElementsByTagName('marker');
  console.log("markers.length=" + markers.length);
  var bounds = new google.maps.LatLngBounds();
  Array.prototype.forEach.call(markers, function(markerElem) {
    var id = markerElem.getAttribute('id');
    var name = markerElem.getAttribute('name');
    var address = markerElem.getAttribute('address');
    var type = markerElem.getAttribute('type');
    var color = markerElem.getAttribute('color');
    var point = new google.maps.LatLng(
      parseFloat(markerElem.getAttribute('lat')),
      parseFloat(markerElem.getAttribute('lng')));
    bounds.extend(point);
    map.fitBounds(bounds);

    var infowincontent = document.createElement('div');
    var strong = document.createElement('strong');
    strong.textContent = name
    infowincontent.appendChild(strong);
    infowincontent.appendChild(document.createElement('br'));

    var text = document.createElement('text');
    text.textContent = address
    infowincontent.appendChild(text);
    var marker = new google.maps.Marker({
      map: map,
      position: point,
      icon: pinSymbol(color),
    });
    marker.addListener('click', function() {
      infoWindow.setContent(infowincontent);
      infoWindow.open(map, marker);
    });
  });
}
// function to parse XML string to XML DOM
function parseXml(str) {
  if (window.ActiveXObject) {
    var doc = new ActiveXObject('MicrosoftXMLDOM');
    doc.loadXML(str);
    return doc;
  } else if (window.DOMParser) {
    return (new DOMParser).parseFromString(str, 'text/xml');
  }
};

function pinSymbol(color) {
  return {
    path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
    fillColor: color,
    fillOpacity: 1,
    strokeColor: '#000',
    strokeWeight: 2,
    scale: 1
  };
}
// XML data as string
var xmlStr = '<?xml version="1.0" encoding="ISO-8859-1"?><markers><marker id="1" lng="151.171936" lat="-33.861034" address="580 Darling Street, Rozelle, NSW" name="Love.Fish" color="green"/><marker id="2" lng="151.174469" lat="-33.898113" address="76 Wilford Street, Newtown, NSW" name="Young Henrys" color="green"/><marker id="3" lng="151.207474" lat="-33.840282" address="Greenwood Plaza, 36 Blue St, North Sydney NSW" name="Hunter Gatherer" color="yellow"/><marker id="4" lng="151.194168" lat="-33.910751" address="7A, 2 Huntley Street, Alexandria, NSW" name="The Potting Shed" color="yellow"/><marker id="5" lng="151.210449" lat="-33.879917" address="16 Foster Street, Surry Hills, NSW" name="Nomad" color="orange"/><marker id="6" lng="151.263763" lat="-33.906357" address="43 Macpherson Street, Bronte, NSW" name="Three Blue Ducks" color="orange"/><marker id="7" lng="151.209656" lat="-33.881123" address="60-64 Reservoir Street, Surry Hills, NSW" name="Single Origin Roasters" color="orange"/><marker id="8" lng="151.215530" lat="-33.874737" address="60 Riley Street, Darlinghurst, NSW" name="Red Lantern" color="orange"/></markers>';
html,
body,
#map {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"></script>

Upvotes: 2

Related Questions