User:Gregory.Szorc/case.js

Note: After saving, you may have to bypass your browser's cache to see the changes. Mozilla / Firefox / Safari: hold down Shift while clicking Reload, or press Ctrl-Shift-R (Cmd-Shift-R on Apple Mac); IE: hold Ctrl while clicking Refresh, or press Ctrl-F5; Konqueror:: simply click the Reload button, or press F5; Opera users may need to completely clear their cache in Tools→Preferences.

//registers the Gmap_onload function as a window.onload event
hookEvent('load', Gmap_onload);

//searches for all maps on the current page and calls their render function
function Gmap_onload() {
	var maps = getElementsByClass('div', 'googleMap');
 	for (i = 1; i <= maps.length; i++) {
		var gmap_id = 'gmap_'+i;
		var form_id = 'mapform_'+i;

		var renderer = document.getElementById(form_id).renderer;
		
		if (!renderer) {
			alert('The Google Maps extensions is broken.  Could not find renderer.');
		} else {
			if (!window[renderer.value]) {
				alert('The map renderer ' + renderer.value + ' is not a valid function');
			} else {
				window[renderer.value](i);
			}
		}
	}
	
}

//renders map n on a page
//data is read from a form with name and id "mapform_n" where n is an integer starting at 1 and incrementing by 1
//the creation of this form is handled by the gmap extension
function Gmap_renderMapOld(n) {
  gmap_id = 'gmap_'+n;
  form_id = 'mapform_'+n;
  message_id = 'gmapmessage_'+n;

  document.getElementById(gmap_id).style.width = document.getElementById(form_id).width.value;
  document.getElementById(gmap_id).style.height = document.getElementById(form_id).height.value;

  var map = new GMap2(document.getElementById(gmap_id));
  map.addControl(new GSmallMapControl());
  map.setCenter(new GLatLng(document.getElementById(form_id).lat.value, document.getElementById(form_id).lon.value, true), parseInt(document.getElementById(form_id).zoom.value), G_NORMAL_MAP);

  if (document.getElementById(form_id).controls.value == 'yes') {
    map.addControl(new GMapTypeControl());
  }

  if (document.getElementById(form_id).type.value == 'G_SATELLITE_MAP') {
    map.setMapType(G_SATELLITE_MAP);
  }
  else if (document.getElementById(form_id).type.value == 'G_NORMAP_MAP') {
    map.setMapType(G_NORMAL_MAP);
  }
  else if (document.getElementById(form_id).type.value == 'G_HYBRID_MAP') {
    map.setMapType(G_HYBRID_MAP);
  }

  GEvent.addListener(map, "moveend", function() {
    var center = map.getCenter();
    var latLngStr = '(' + center.y + ', ' + center.x + ')';
    document.getElementById(message_id).innerHTML = latLngStr;
  });


  if (document.getElementById(form_id).rss){
    //if the rss form element is defined, plot datapoints from an rss feed
    feedarray = document.getElementById(form_id).rss.value.split('|');

    for (var i = 0; i < feedarray.length; i++) {
      renderRSSFeed(map, feedarray[i]);
    }

  }
  else {
    var request = GXmlHttp.create();
    //the php script returns a very simple XML document
    request.open("GET", "/Special:GraphStructure/xml/locations", true);
    request.onreadystatechange = function() {

    	if (request.readyState == 4) {
        	var doc = request.responseXML;
        	var nodes = doc.documentElement.getElementsByTagName('node');
        	
        	for (var i = 0; i < nodes.length; i++) {
         		var node = nodes[i];
         		if (node.hasAttribute('smw:Coordinates')) {
         	    	var nodeType = node.getAttribute('type');
           	  	    var nodeTitle = node.getAttribute('title');
          	        var nodePoint = node.getAttribute('smw:Coordinates');
           	        var nodeURI = nodeTitle.replace(/ /g, '_');
                	if (nodeType == 'category') {
                    	nodeURI = "Category:" + nodeURI;
	                }
    	            var html = "<div id=\"gmapInfoWindow\"><a href=\"/" + nodeURI + "\">" + nodeTitle + "</a>";
        	        html += "<br/><strong>Location: </strong>" + nodePoint + "</div>";
            	    
					//we find entities "located in" this node by using xpath
					foundNodes = findNodesWithRelationTo(doc, node.getAttribute("id"), "Located in");

					if (foundNodes.length > 0) {
						html += "<br />Located Here:</strong><br /><ul>";
						for (var j = 0; j < foundNodes.length; j++) {
							var insertLink = foundNodes[j].getAttribute("title");
							
							if (foundNodes[j].getAttribute("namespace") == 0) {
								insertLink = "<a href=\"/" + foundNodes[j].getAttribute("title").replace(/ /g, '_') + "\">" + insertLink + "</a>";
							}
							
							html += "<li>" + insertLink + "</li>";
						}
						
						html += "</ul>";
					}

            	    var point = parsePoint(nodePoint);
                	var marker = createMarker(point, html);
                	map.addOverlay(marker);
            	}
        	}
        }
    }

    request.send(null);
  }

}

//finds all nodes having relation to a destination node
//for example, dstNode=6 relation="Located In"
function findNodesWithRelationTo(doc, dstNode, relation) {
	var nodes = doc.documentElement.getElementsByTagName("node");
	var foundNodes = new Array();

	var foundEdgesPattern = "/MediaWikiGraph/edge[@relation='"+relation+"'][@to='"+dstNode+"']";
	
	var resultEdges = doc.evaluate(foundEdgesPattern, doc.documentElement, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
	
	var thisEdge = resultEdges.iterateNext();

	while (thisEdge) {
		//find the node in the document
		for (var i = 0; i < nodes.length; i++) {
			var node = nodes[i];
			if (node.getAttribute("id") == thisEdge.getAttribute("from")) {
				foundNodes.push(node);
			}
		}

		thisEdge = resultEdges.iterateNext();
	}
	
	return foundNodes;
	
}

function arcDegrees(arcminutes, arcseconds) {
    arcminutes = parseFloat(arcminutes);
    arcseconds = parseFloat(arcseconds);
    return (arcminutes / 60.0 + arcseconds / 3600.0);
}
 
function parsePoint(str) {
    var values = str.split(/\s*,\s*/);
    //            1         2           3               4
    var expr = /(\d+)&.*?;(\d+)&.*?;(\d+.?\d*)&.*?;\s*(\w)/;
    var lat = expr.exec(values[0]);
    var lng = expr.exec(values[1]);
    var latitude = parseFloat(lat[1]) + arcDegrees(lat[2], lat[3]);
    var longitude = parseFloat(lng[1]) + arcDegrees(lng[2], lng[3]);
    if (lat[4] == 'S') {
        latitude *= -1;
    }
    if (lng[4] == 'W') {
        longitude *= -1;
    }
    return new GLatLng(latitude, longitude, true);

}
 
function renderRSSFeed(map, rssurl) {
  var request = GXmlHttp.create();
  //the request.open method doesn't like URL's not on our server
  //the proxy.php script is a very simplistic proxy with some security features
  rssurl = "/misc/proxy.php?" + rssurl;
  request.open("GET", rssurl, true);
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
       var xmlDoc = request.responseXML;
       var items = xmlDoc.documentElement.getElementsByTagName("item");
       for (var i = 0; i < items.length; i++) {
          var marker = createMarkerFromRSSItem(items[i]);
          map.addOverlay(marker);
       }
    }
  }
  request.send(null);
}

function createMarkerFromRSSItem(item) {
  var title = item.getElementsByTagName("title")[0].childNodes[0].nodeValue;
  var description = item.getElementsByTagName("description")[0].childNodes[0].nodeValue;
  var link = item.getElementsByTagName("link")[0].childNodes[0].nodeValue;

  var lat = item.getElementsByTagNameNS("http://www.w3.org/2003/01/geo/wgs84_pos#", "lat")[0].childNodes[0].nodeValue;
  var lon = item.getElementsByTagNameNS("http://www.w3.org/2003/01/geo/wgs84_pos#", "long")[0].childNodes[0].nodeValue;

  var point = new GPoint(parseFloat(lon), parseFloat(lat));
  var marker = new GMarker(point);
  var html = '<a href="' + link + '">' + title + '</a><p />' + description;

  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml(html);
  });

  return marker;
}


function createMarker(point, html) {
  var marker = new GMarker(point);

  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml(html);
  });

  return marker;
}

//a helper function that returns an array of element ids of a given type and class
function getElementsByClass(elem, classname) {
  classes = new Array();
  alltags = document.getElementsByTagName(elem);
  for (i=0; i<alltags.length; i++) {
    if (alltags[i].className == classname) {
      classes.push(alltags[i].id);
    }
  }
  return classes;
}





var brianScript = {

'arcDegrees': function(arcminutes, arcseconds) {
    arcminutes = parseFloat(arcminutes);
    arcseconds = parseFloat(arcseconds);
    return (arcminutes / 60.0 + arcseconds / 3600.0);
},
 
'parsePoint': function(str) {
    var values = str.split(/, /);
    var expr = /(\d+)(?:\D|(?:&#176;))(\d+)(?:\D|(?:&#8242;))(\d+\.?\d*)(?:\D|(?:&#8243;)) ([NSEW])/;
    var lat = values[0].match(expr);
    var lng = values[1].match(expr);
    var latitude = parseFloat(lat[1]) + brianScript.arcDegrees(lat[2], lat[3]);
    var longitude = parseFloat(lng[1]) + brianScript.arcDegrees(lng[2], lng[3]);
    if (lat[4] == 'S') {
        latitude *= -1;
    }
    if (lng[4] == 'W') {
        longitude *= -1;
    }
    return new GLatLng(latitude, longitude, true);
},

'handleHttpResponse': function() {
    var request = brianScript._request;
    var map = brianScript._map;
    if (request.readyState == 4) {
        var doc = request.responseXML;
        var smwNS = "http://opensource.case.edu/projects/MediaWikiHacks/"
        var nodes = doc.documentElement.getElementsByTagName('node');
        var nodeMap = {};
        // Build a node map once so we don't have to iterate
        // it scanning for node IDs every time.
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            nodeMap[node.getAttribute('id')] = node;
        }
        // Build a relation map for every node.
        var relationMap = brianScript.buildRelationMap(doc, nodeMap, 'Located in');
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            if (node.hasAttributeNS(smwNS, 'Coordinates')) {
                var nodeID = node.getAttribute('id');
                var nodeType = node.getAttribute('type');
                var nodeTitle = node.getAttribute('title');
                var nodePoint = node.getAttributeNS(smwNS, 'Coordinates');
                var nodeURI = brianScript.makeNodeURI(node);
                var html = '<div id="gmapInfoWindow">'
                html += '<a href="' + nodeURI + '">' + nodeTitle + '</a><br/>';
                html += '<strong>Location: </strong>' + nodePoint + '<br/>';
 
                var related = relationMap[nodeID];
                related = related ? related : new Array();
                if (related.length) {
                    html += '<strong>Located here:</strong><br/>';
                    html += '<ul>';
                    for (var j = 0; j < related.length; j++) {
                        var relNode = related[j];
                        var relTitle = relNode.getAttribute('title');
                        var relURI = brianScript.makeNodeURI(relNode);
                        html += '<li><a href="' + relURI + '">' + relTitle + '</a></li>';
                    }
                    html += '</ul>';
                }
 
                html += '</div>';
                var point = brianScript.parsePoint(nodePoint);
                var marker = createMarker(point, html);
                map.addOverlay(marker); 
            }
        }
    }
},
 
'makeNodeURI': function(node) {
    var uri = node.getAttribute('title').replace(/ /g, '_');
    if (node.getAttribute('type') == "category") {
        uri = "Category:" + uri;
    }
    return '/' + uri;
},
 
 
'buildRelationMap': function(doc, nodeMap, relation) {
    var relations = {};
    if (doc.evaluate) {
        var foundEdgesPattern = "/MediaWikiGraph/edge[@relation='" + relation + "']";
        var resultEdges = doc.evaluate(foundEdgesPattern, doc.documentElement, null,
                                       XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
        var thisEdge = resultEdges.iterateNext();
        while (thisEdge) {
            var fromID = thisEdge.getAttribute('from');
            var toID = thisEdge.getAttribute('to');
            var node = nodeMap[fromID];
            if (relations[toID]) {
                relations[toID].push(node);
            }
            else {
                relations[toID] = [node];
            }
            thisEdge = resultEdges.iterateNext();
        }
    }
    else {
        var edges = doc.documentElement.getElementsByTagName('edge');
        for (var i = 0; i < edges.length; i++) {
            var edge = edges[i];
            var edgeRel = edge.getAttribute('relation');
            if (edgeRel == relation) {
                var fromID = edge.getAttribute('from');
                var toID = edge.getAttribute('to');
                var node = nodeMap[fromID];
                if (relations[toID]) {
                    relations[toID].push(node);
                }
                else {
                    relations[toID] = [node];
                }
            }
        }
    }
    return relations;
},

'renderMap': function(n) {
    gmap_id = 'gmap_'+n;
    form_id = 'mapform_'+n;
    message_id = 'gmapmessage_'+n;

    document.getElementById(gmap_id).style.width = document.getElementById(form_id).width.value;
    document.getElementById(gmap_id).style.height = document.getElementById(form_id).height.value;

    var map = new GMap2(document.getElementById(gmap_id));
    map.addControl(new GSmallMapControl());
    map.setCenter(new GLatLng(document.getElementById(form_id).lat.value, document.getElementById(form_id).lon.value, true), parseInt(document.getElementById(form_id).zoom.value), G_NORMAL_MAP);

    if (document.getElementById(form_id).controls.value == 'yes') {
        map.addControl(new GMapTypeControl());
    }

    if (document.getElementById(form_id).type.value == 'G_SATELLITE_MAP') {
        map.setMapType(G_SATELLITE_MAP);
    }
    else if (document.getElementById(form_id).type.value == 'G_NORMAP_MAP') {
        map.setMapType(G_NORMAL_MAP);
    }
    else if (document.getElementById(form_id).type.value == 'G_HYBRID_MAP') {
        map.setMapType(G_HYBRID_MAP);
    }

    GEvent.addListener(map, "moveend", function() {
        var center = map.getCenter();
        var latLngStr = '(' + center.y + ', ' + center.x + ')';
        document.getElementById(message_id).innerHTML = latLngStr;
    });


    if (document.getElementById(form_id).rss) {
        //if the rss form element is defined, plot datapoints from an rss feed
        feedarray = document.getElementById(form_id).rss.value.split('|');

        for (var i = 0; i < feedarray.length; i++) {
            renderRSSFeed(map, feedarray[i]);
        }
    }
    else {
        var request = GXmlHttp.create();
        //the php script returns a very simple XML document
        request.open("GET", "/Special:GraphStructure/xml/locations", true);
        brianScript._map = map;
        brianScript._request = request;
        request.onreadystatechange = brianScript.handleHttpResponse;
        request.send(null);
    }
}

}

var Gmap_renderMap = brianScript.renderMap;
This page has been accessed 717 times.
This page was last modified 16:26, October 26, 2006 by Gregory Szorc.
About | Disclaimers