0
votes

I have a wiki website that contains only the name and address in each wiki page and I need to map this in google maps. I've settled on Google's example of how to implement this, at https://developers.google.com/maps/articles/phpsqlsearch_v3 and it uses Google Maps' API version 3.

I've gotten to the point where I'm able to extract the name and address info from each wiki page and pass it to the file phpsqlsearch_genxml.php file, which generates xml text for the javascript code (see below) to parse into a google maps.

Currently, the javascript code (see below) works only if I include a generic distance, latitude, and longitude in the xml file like this:

<markers>
<marker name="Radio City Music Hall" address="1260 Avenue of the Americas, New York, NY"      
distance="50.0000" lat="40.7142" lng="-74.0000"/> 
<marker name="W Hotel, Times Square" address="1567 Broadway at 47th St, New York City, NY"  
distance="50.0000" lat="40.7142" lng="-74.0000"/>      
<marker name="Columbia University Student Service Centre" address="1140 Amsterdam Ave., New York, 
distance="50.0000" lat="40.7142" lng="-74.0000"/>  
</markers

(P.S. I'm just providing a few locations in the xml, just as an example here).

The distance of 50.0000 and lat of 40.7142, and lng of -74.0000 are just generic numbers that I entered to get the javascript below. And Yes, I realize that these numbers are not actually correct for the above locations but it does work in generating a location pin.

I want to make the Javascript below work with the limited unique XML info (name and address) that my wiki site actually provides, which is:

<markers>
<marker name="Radio City Music Hall" address="1260 Avenue of the Americas, New York, NY"/>
<marker name="W Hotel, Times Square" address="1567 Broadway at 47th St, New York City, NY"/>
<marker name="Columbia University Student Service Centre" address="1140 Amsterdam Ave., New York,  
NY"/>      
</markers>

I've read the documentation on the google site above and I've tried refactoring but I just can't get the limited xml with name and address only to work .

Does anyone know how I can refactor the code below so that only Google maps' geocoder will look up the XML's address and provide the necessary lat and long to put a location pin on the map? I know that Google places limits on the number of geocoding requests but I can worry about map caching and creating my own lat and long. coordinates later. In the code below, I also don't need distance calculation, so I think I can delete the methods searchLocations() and searchLocationsNear(center).

Also, how would I get rid of the user input? Right now, the javascript bode generates a user search box where the user clicks a "Search" button and then it provides the info. But for my map, I just want to generate a map that shows multiple location pins in New York City, with a tool to

I'm fairly new to Google maps so thanks in advance for all your help!

Javascript code from https://developers.google.com/maps/articles/phpsqlsearch_v3:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Google Maps AJAX + mySQL/PHP Example</title>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false"
        type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var map;
var markers = [];
var infoWindow;
var locationSelect;

function load() {
  map = new google.maps.Map(document.getElementById("map"), {
    center: new google.maps.LatLng(40.7142, -74.0000),
    zoom: 4,
    mapTypeId: 'roadmap',
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
  });
  infoWindow = new google.maps.InfoWindow();

  locationSelect = document.getElementById("locationSelect");
  locationSelect.onchange = function() {
    var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
    if (markerNum != "none"){
      google.maps.event.trigger(markers[markerNum], 'click');
    }
  };
}
function searchLocations() {
 var address = document.getElementById("addressInput").value;
 var geocoder = new google.maps.Geocoder();
 geocoder.geocode({address: address}, function(results, status) {
     if (status == google.maps.GeocoderStatus.OK) {
     searchLocationsNear(results[0].geometry.location);
     } else {
     alert(address + ' not found');
     }
 });
}

function clearLocations() {
   infoWindow.close();
       for (var i = 0; i < markers.length; i++) {
           markers[i].setMap(null);
   }
   markers.length = 0;

   locationSelect.innerHTML = "";
   var option = document.createElement("option");
   option.value = "none";
   option.innerHTML = "See all results:";
   locationSelect.appendChild(option);
}

function searchLocationsNear(center) {
   clearLocations();

   var radius = document.getElementById('radiusSelect').value;
   var searchUrl = 'phpsqlsearch_genxml.php?lat=' + center.lat() + '&lng=' + center.lng() +    
   '&radius=' + radius;           
 downloadUrl(searchUrl, function(data) {
   var xml = parseXml(data);
   var markerNodes = xml.documentElement.getElementsByTagName("marker");
   var bounds = new google.maps.LatLngBounds();
   for (var i = 0; i < markerNodes.length; i++) {
     var name = markerNodes[i].getAttribute("name");
     var address = markerNodes[i].getAttribute("address");
     var distance = parseFloat(markerNodes[i].getAttribute("distance"));
     var latlng = new google.maps.LatLng(
          parseFloat(markerNodes[i].getAttribute("lat")),
          parseFloat(markerNodes[i].getAttribute("lng")));

     createOption(name, distance, i);
     createMarker(latlng, name, address);
     bounds.extend(latlng);
   }
   map.fitBounds(bounds);
   locationSelect.style.visibility = "visible";
   locationSelect.onchange = function() {
     var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
     google.maps.event.trigger(markers[markerNum], 'click');
   };
  });
}
function createMarker(latlng, name, address) {
  var html = "<b>" + name + "</b> <br/>" + address;
  var marker = new google.maps.Marker({
    map: map,
    position: latlng
  });
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
  markers.push(marker);
}
function createOption(name, distance, num) {
  var option = document.createElement("option");
  option.value = num;
  option.innerHTML = name + "(" + distance.toFixed(1) + ")";
  locationSelect.appendChild(option);
}

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.responseText, request.status);
    }
  };

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

function parseXml(str) {
  if (window.ActiveXObject) {
    var doc = new ActiveXObject('Microsoft.XMLDOM');
    doc.loadXML(str);
    return doc;
  } else if (window.DOMParser) {
    return (new DOMParser).parseFromString(str, 'text/xml');
  }
}

function doNothing() {}

//]]>
</script>
</head>

<body style="margin:0px; padding:0px;" onload="load()">
<div>
 <input type="text" id="addressInput" size="10"/>
<select id="radiusSelect">
  <option value="25" selected>25mi</option>
  <option value="100">100mi</option>
  <option value="200">200mi</option>
</select>

<input type="button" onclick="searchLocations()" value="Search"/>
</div>
<div><select id="locationSelect" style="width:100%;visibility:hidden"></select></div>
<div id="map" style="width: 100%; height: 80%"></div>
</body>
</html>
1

1 Answers

0
votes

Your problem is that the XML that you return to your searchLocationsNear function doesn't contain any lat and lng data, so wont populate a map. Specifically that means that

 var latlng = new google.maps.LatLng(
      parseFloat(markerNodes[i].getAttribute("lat")),
      parseFloat(markerNodes[i].getAttribute("lng")));

will return NULL. To get around this you might try adding a new google geocode object into the searchLocationsNear function, passing it in turn all of the address variables. I'm also new but would imagine something like this might get you started:

 var xml = parseXml(data);
var markerNodes = xml.documentElement.getElementsByTagName("marker");
   var bounds = new google.maps.LatLngBounds();
   for (var i = 0; i < markerNodes.length; i++) {
     var name = markerNodes[i].getAttribute("name");
     var address = markerNodes[i].getAttribute("address");
    geocoder.geocode({address: address}, function(results, status) {
     if (status == google.maps.GeocoderStatus.OK) {
     var latlng = new google.maps.LatLng(
          parseFloat(results.lat),
          parseFloat(results.lng));
}}

I'm not sure how the results object contains the lat and lng data so you may have to tweak this - i'm also new but hoping to help.

Good luck!