var _docList = new Array();
_docList.ids = new Array();
_docList.getDocByIndex = function(index)
{
return _docList[_docList.ids[index]];
};
var _map;
var _intervalHandle;
var _baseURL = document.URL.substring(0, document.URL.indexOf("?") + 1);
var _retrievedClassifiers = new Array();
var _preventLoopingSingleMarker = false;
var _searchRunning = false;
var _nearbyDocs = new Array();
var _scrollThroughDefault = true;
function initializeMapScripts()
{
modifyFunctions();
setUpMap();
var jsonNodeDiv = $("#jsonNodes");
if(jsonNodeDiv.length)
{
var jsonNodes = eval(jsonNodeDiv.html());
if(jsonNodes && jsonNodes.length > 0)
{
for(var i = 0; i < jsonNodes.length; i++)
{
_docList[jsonNodes[i].nodeID] = jsonNodes[i];
_docList.ids.push(jsonNodes[i].nodeID);
createMarker(jsonNodes[i], true);
}
updateMap();
}
else
{
//$("#map_canvas").css({visibility:"hidden", height:"0px"});
$("#map_canvas").css({visibility:"hidden"});
}
}
_docList.loopIndex = 0;
if(_docList.ids.length > 1)
{
var startStopCheckbox = $("", {"type": "checkbox", "checked": _scrollThroughDefault, "id": "scrollCheckbox"});
startStopCheckbox.click(function()
{
// http://stackoverflow.com/questions/901712/how-to-check-if-a-checkbox-is-checked-in-jquery
// http://stackoverflow.com/questions/5270689/attrchecked-checked-does-not-work
if($('#scrollCheckbox').is(':checked')) // OR: if(document.getElementById('scrollCheckbox').checked)
{
if(_intervalHandle == null)
{
_intervalHandle = setInterval(loopThroughMarkers, 2000);
}
}
else
{
clearInterval(_intervalHandle);
_intervalHandle = null;
}
});
var label = $("Scroll through places");
var container = $("
", {"class": "ui-widget-header ui-corner-all", "style": "clear:right; float:right; padding:0px 5px 3px 0px;"});
container.append(startStopCheckbox);
container.append(label);
$(container).insertAfter("#map_canvas");
if (_scrollThroughDefault) {
_intervalHandle = setInterval(loopThroughMarkers, 2000);
}
}
}
function setUpMap()
{
var myOptions =
{
zoom: 2,
center: new google.maps.LatLng(0, 0),
mapTypeId: google.maps.MapTypeId.HYBRID
};
_map = new google.maps.Map($("#map_canvas")[0], myOptions);
google.maps.event.addListener(_map, 'bounds_changed', performSearchForMarkers);
}
function performSearchForMarkers()
{
if(_searchRunning)
{
return;
}
_searchRunning = true;
var bounds = _map.getBounds();
var neLat = bounds.getNorthEast().lat();
var neLng = bounds.getNorthEast().lng();
var swLat = bounds.getSouthWest().lat();
var swLng = bounds.getSouthWest().lng();
var latDistance = neLat - swLat;
var lngDistance = neLng - swLng;
//Check which increment to use for latitude (i.e. 0.001, 0.01, 0.1 or 1 degree increments)
var latDelta;
var latPrecision;
for(var i = 3; i >= 0; i--)
{
latDelta = (1 / Math.pow(10, i));
if((latDistance / latDelta) <= 5 || latDelta == 1)
{
latPrecision = i;
break;
}
}
//Check which increment to use for longitude (i.e. 0.001, 0.01, 0.1 or 1 degree increments)
var lngDelta;
for(var i = 3; i >= 0; i--)
{
lngDelta = (1 / Math.pow(10, i));
if((lngDistance / lngDelta) <= 5 || lngDelta == 1)
{
lngPrecision = i;
break;
}
}
if(latDelta == 0.1){latDelta = 1; latPrecision = 0; }
if(lngDelta == 0.1){lngDelta = 1; lngPrecision = 0; }
var query = "";
for(var i = 0; i <= Math.floor(latDistance / latDelta) + 1; i++)
{
for(var j = 0; j <= Math.floor(lngDistance / lngDelta) + 1; j++)
{
//Some necessary variables
var newLat = neLat - (latDelta * i);
var newLatString = "" + newLat;
var newLatTrunc;
if(newLat < 0){newLatTrunc = Math.ceil(newLat);}
else{newLatTrunc = Math.floor(newLat);}
var newLng = neLng - (lngDelta * j);
var newLngString = "" + newLng;
var newLngTrunc;
if(newLng < 0){newLngTrunc = Math.ceil(newLng);}
else{newLngTrunc = Math.floor(newLng);}
//Construct query
query += "(";
query += "LA:" + coordToAbsDirected(newLatTrunc, "lat");
if(latDelta != 1)
{
query += "+AND+";
query += "LA:" + newLatString.substring(newLatString.indexOf(".") + 1, newLatString.indexOf(".") + latPrecision + 1);
}
query += "+AND+";
query += "LN:" + coordToAbsDirected(newLngTrunc, "lng");
if(lngDelta != 1)
{
query += "+AND+";
query += "LN:" + newLngString.substring(newLngString.indexOf(".") + 1, newLngString.indexOf(".") + lngPrecision + 1);
}
query += ")";
if(i != (Math.floor(latDistance / latDelta) + 1) || j != (Math.floor(lngDistance / lngDelta) + 1)){ query += "+OR+"; }
}
}
//var url = gs.xsltParams.library_name + "?a=q&s=RawQuery&rt=rd&c=" + gs.cgiParams.c + "&s1.rawquery=" + query + "&excerptid=jsonNodes";
var url = gs.xsltParams.library_name;
var data = "a=q&s=RawQuery&rt=rd&c=" + gs.cgiParams.c + "&s1.rawquery=" + query + "&excerptid=jsonNodes";
$.ajax({type:"POST", url:url, data:data})
.success(function(responseText)
{
//console.log("*** responseText (first 250) = " + responseText.substring(0,256));
if(responseText.search("id=\"jsonNodes") != -1)
{
var startIndex = responseText.indexOf(">");
var endIndex = responseText.indexOf("");
var jsonNodes = eval(responseText.substring(startIndex+1, endIndex));
if(jsonNodes && jsonNodes.length > 0)
{
for(var i = 0; i < jsonNodes.length; i++)
{
var doc = jsonNodes[i];
var found = false;
for(var j = 0; j < _docList.ids.length; j++){if(doc.nodeID == _docList.ids[j]){found = true; break;}}
if(!found)
{
_docList[doc.nodeID] = doc;
_docList.ids.push(doc.nodeID);
createMarker(doc, false);
}
}
}
}
else
{
console.log("No JSON information received");
}
_searchRunning = false;
}).fail(function(responseText, textStatus, errorThrown) // fail() has replaced error(), http://api.jquery.com/jquery.ajax/
{
console.log("In map-scripts.performSearchForMarkers(): Got an error in ajax call");
_searchRunning = false;
});
}
function coordToAbsDirected(coord, type)
{
var value = "" + coord;
if(coord < 0)
{
value = value.substring(1);
if(type == "lat")
{
value += "S";
}
else
{
value += "W";
}
}
else
{
if(type == "lat")
{
value += "N";
}
else
{
value += "E";
}
}
return value;
}
function updateMap()
{
var markersOnMap = 0;
var bounds = new google.maps.LatLngBounds();
for(var i = 0; i < _docList.ids.length; i++)
{
var doc = _docList.getDocByIndex(i);
if(doc.parentCL && doc.parentCL.style.display == "none")
{
doc.marker.setVisible(false);
continue;
}
else
{
doc.marker.setVisible(true);
markersOnMap++;
}
bounds.extend(new google.maps.LatLng(doc.lat, doc.lng));
}
if(markersOnMap > 1)
{
_map.fitBounds(bounds);
} else if (markersOnMap == 1) {
// sometimes a single point bounds are too small for the map to display, so use center and zoom instead of fitbounds.
_map.setCenter(bounds.getCenter());
_map.setZoom(18); // arbitrary value that looked nice for my example
}
}
function loopThroughMarkers()
{
if(_docList.ids.length == 0)
{
return;
}
var visibleMarkers = new Array();
for(var i = 0; i < _docList.ids.length; i++)
{
var doc = _docList.getDocByIndex(i);
if(doc.marker.getVisible())
{
visibleMarkers.push(doc);
}
}
if(visibleMarkers.length < 2)
{
clearAllInfoBoxes();
return;
}
clearAllInfoBoxes();
var elem = null;
while(!elem)
{
if(_docList.loopIndex >= visibleMarkers.length)
{
_docList.loopIndex = 0;
}
var doc = visibleMarkers[_docList.loopIndex];
var elem = gs.jqGet("div" + doc.nodeID);
if(elem.length)
{
elem.css("background", "#BBFFBB");
setTimeout(function(){elem.css("background", "");}, 2000);
}
_docList.loopIndex++;
}
doc.marker.markerInfo.open(_map, doc.marker);
}
function attachClickHandler(marker, nodeID)
{
google.maps.event.addListener(marker, 'click', function()
{
document.location.href = gs.xsltParams.library_name + "?a=d&ed=1&c=" + gs.cgiParams.c + "&d=" + nodeID + "&dt=hierarchy&p.a=b&p.sa=&p.s=ClassifierBrowse";
});
}
function focusDocument(id)
{
var doc = _docList[id];
if(doc)
{
clearInterval(_intervalHandle);
_intervalHandle = null;
_map.panTo(new google.maps.LatLng(doc.lat, doc.lng));
clearAllInfoBoxes();
doc.marker.markerInfo.open(_map, doc.marker);
var scrollCheckbox = $("#scrollCheckbox");
if(scrollCheckbox.checked)
{
scrollCheckbox.checked = false;
}
}
}
function clearAllInfoBoxes()
{
for(var i = 0; i < _docList.ids.length; i++)
{
var doc = _docList.getDocByIndex(i);
doc.marker.markerInfo.close();
}
}
function createMarker(doc, mainMarker)
{
var pos = new google.maps.LatLng(doc.lat,doc.lng);
var marker
if(mainMarker)
{
marker = new google.maps.Marker
({
position: pos,
title:doc.title,
map:_map
});
}
else
{
marker = new google.maps.Marker
({
position: pos,
title:doc.title,
map:_map,
icon:"interfaces/" + gs.xsltParams.interface_name + "/images/bluemarker.png"
});
}
var docElement = gs.jqGet("div" + doc.nodeID);
var parent;
if(docElement)
{
parent = docElement.parentNode;
}
while(parent && parent.nodeName != "BODY")
{
if($(parent).attr("id") && $(parent).attr("id").search("divCL") != -1)
{
doc.parentCL = parent;
break;
}
parent = parent.parentNode;
}
var info = new google.maps.InfoWindow({content:doc.title});
marker.markerInfo = info;
doc.marker = marker;
attachClickHandler(marker, doc.nodeID);
}
function getSubClassifier(sectionID)
{
var url = gs.xsltParams.library_name + "?a=b&rt=s&s=ClassifierBrowse&c=" + gs.cgiParams.c + "&cl=" + sectionID + "&excerptid=jsonNodes";
$.ajax(url)
.success(function(responseText)
{
var startIndex = responseText.indexOf(">");
var endIndex = responseText.indexOf("");
var jsonNodes = eval(responseText.substring(startIndex+1, endIndex));
if(jsonNodes && jsonNodes.length > 0)
{
for(var i = 0; i < jsonNodes.length; i++)
{
var doc = jsonNodes[i];
_docList[doc.nodeID] = doc;
_docList.ids.push(doc.nodeID);
createMarker(doc, false);
}
$("#map_canvas").css({"visibility": "visible", "height": ""});
}
updateMap();
})
.error(function()
{
console.log("Error getting subclassifiers");
return;
});
}
function performDistanceSearch(id, lat, lng, degrees)
{
if(parseFloat(lat) > 180 || parseFloat(lat) < -180 || parseFloat(lng) > 180 || parseFloat(lat) < -180)
{
console.log("Latitude or longitude incorrectly formatted");
return;
}
if(lat.indexOf(".") == -1 || lng.indexOf(".") == -1 || (lat.indexOf(".") + 3) >= lat.length || (lng.indexOf(".") + 3) >= lng.length)
{
console.log("Latitude or longitude does not have the required precision for a distance search");
return;
}
var query = "";
for(var i = 0; i < degrees * 2; i++)
{
for (var j = 0; j < degrees * 2; j++)
{
var latDelta = (i - degrees) * 0.01;
var lngDelta = (j - degrees) * 0.01;
query += "(" + getDistanceQueryString(lat, latDelta, 2, "LA", ["N","S"]);
query += "+AND+";
query += getDistanceQueryString(lng, lngDelta, 2, "LN", ["E","W"]) + ")";
if(i != ((degrees * 2) - 1) || j != ((degrees * 2) - 1)){ query += "+OR+"; }
}
}
var inlineTemplate = '\
\
\
\
\
\
\
____________ | \
| \
\
';
var url = gs.xsltParams.library_name + "?a=q&s=RawQuery&rt=rd&c=" + gs.cgiParams.c + "&s1.rawquery=" + query + "&excerptid=nearbyDocs&ilt=" + inlineTemplate.replace(/ /, "%20");
$.ajax(url)
.success(function(response)
{
response = response.replace(/
]*>/g, "");
var nearbyDocsArray = new Array();
var lats = new Array();
var lngs = new Array();
var matches = response.match(/___(-?[0-9\.]*)___/g);
for(var i = 0; i < matches.length; i += 2)
{
var matchLatFloat = parseFloat(matches[i].replace("___", ""));
var matchLngFloat = parseFloat(matches[i+1].replace("___", ""));
lats.push(matchLatFloat);
lngs.push(matchLngFloat);
var distance = Math.sqrt(Math.pow(matchLatFloat - parseFloat(lat), 2) + Math.pow(matchLngFloat - parseFloat(lng), 2)) * (40000.0/360.0);
var distanceString = "" + distance;
distanceString = distanceString.substring(0, 6);
response = response.replace(matches[i] + matches[i+1], distanceString);
}
var index = 0;
var i = 0;
while(true)
{
var distanceStart = response.indexOf("
", index);
if(distanceStart == -1)
{
break;
}
var distanceEnd = response.indexOf(" | ", distanceStart);
var docLinkStart = response.indexOf("
", distanceEnd);
var docLinkEnd = response.indexOf(" | ", docLinkStart);
var dist = response.substring(distanceStart + 4, distanceEnd);
var docLink = response.substring(docLinkStart + 4, docLinkEnd);
_nearbyDocs.push({title:docLink, distance:dist, lat:lats[i], lng:lngs[i++]});
index = docLinkEnd;
}
sortByDistance();
var toggle = $("#nearbyDocumentsToggle");
toggle.attr("src", gs.imageURLs.collapse);
gs.functions.makeToggle(toggle, $("#nearbyDocuments"));
});
}
function sortByDistance()
{
var sortedTable = '
Distance (km) | Document |
';
_nearbyDocs.sort(function(a, b){return (a.distance - b.distance);});
for(var i = 0; i < _nearbyDocs.length; i++)
{
sortedTable += "" + _nearbyDocs[i].distance + ' | ' + _nearbyDocs[i].title + " |
";
}
sortedTable += "
";
$("#nearbyDocuments").html(sortedTable);
}
function sortAlphabetically()
{
var sortedTable = '
Distance (km) | Document |
';
_nearbyDocs.sort(function(a, b)
{
var firstTitleStartIndex = a.title.indexOf(">");
var firstTitleEndIndex = a.title.indexOf("<", firstTitleStartIndex);
var firstTitle = a.title.substring(firstTitleStartIndex + 1, firstTitleEndIndex);
var secondTitleStartIndex = b.title.indexOf(">");
var secondTitleEndIndex = b.title.indexOf("<", secondTitleStartIndex);
var secondTitle = b.title.substring(secondTitleStartIndex + 1, secondTitleEndIndex);
return ((firstTitle.toLowerCase() == secondTitle.toLowerCase()) ? 0 : ((firstTitle.toLowerCase() > secondTitle.toLowerCase()) ? 1 : -1));
});
for(var i = 0; i < _nearbyDocs.length; i++)
{
sortedTable += "" + _nearbyDocs[i].distance + ' | ' + _nearbyDocs[i].title + " |
";
}
sortedTable += "
";
$("#nearbyDocuments").html(sortedTable);
}
function getDistanceQueryString(currentCoord, delta, precision, indexName, dirs)
{
var query = "";
var coordFloat = parseFloat(currentCoord);
var newCoord = "" + (coordFloat + delta);
var beforeDec = newCoord.substring(0, newCoord.indexOf("."));
var dir = dirs[0];
if(coordFloat < 0)
{
dir = dirs[1];
beforeDec = beforeDec.substring(1);
}
beforeDec += dir;
var afterDec = newCoord.substring(newCoord.indexOf(".") + 1, newCoord.indexOf(".") + (precision) + 1);
return indexName + ":" + beforeDec + "+AND+" + indexName + ":" + afterDec;
}
function modifyFunctions()
{
toggleSection = function(sectionID)
{
var section = gs.jqGet("div" + sectionID);
var sectionToggle = gs.jqGet("toggle" + sectionID);
if(sectionToggle == undefined)
{
return;
}
// Test if 'section' exists.
// ==> Because we're using jQuery to do this we need to test the length of the object returned
// http://stackoverflow.com/questions/920236/how-can-i-detect-if-a-selector-returns-null
if(section.length !== 0)
{
if(isExpanded(sectionID))
{
section.css("display", "none");
sectionToggle.attr("src", gs.imageURLs.expand);
if(openClassifiers[sectionID].length !== 0) //if(openClassifiers[sectionID] != undefined)
{
delete openClassifiers[sectionID];
}
}
else
{
section.css("display", "block");
sectionToggle.attr("src", gs.imageURLs.collapse);
openClassifiers[sectionID] = true;
}
updateOpenClassifiers();
updateMap();
}
else
{
httpRequest(sectionID);
}
}
httpRequest = function(sectionID)
{
if(!inProgress[sectionID])
{
inProgress[sectionID] = true;
var sectionToggle = gs.jqGet("toggle" + sectionID);
sectionToggle.attr("src", gs.imageURLs.loading);
var url = gs.xsltParams.library_name + "/collection/" + gs.cgiParams.c + "/browse/" + sectionID.replace(/\./g, "/") + "?excerptid=div" + sectionID;
if(gs.cgiParams.berrybasket == "on")
{
url = url + "&berrybasket=on";
}
if(url.indexOf("#") != -1)
{
url = url.substring(0, url.indexOf("#"));
}
$.ajax(url)
.success(function(responseText)
{
var newDiv = $("
");
var sibling = gs.jqGet("title" + sectionID);
sibling.after(newDiv);
newDiv.html(responseText);
sectionToggle.attr("src", gs.imageURLs.collapse);
openClassifiers[sectionID] = true;
if(gs.cgiParams.berrybasket == "on")
{
checkout();
}
updateOpenClassifiers();
getSubClassifier(sectionID);
})
.error(function()
{
sectionToggle.attr("src", gs.imageURLs.expand);
})
.complete(function()
{
inProgress[sectionID] = false;
busy = false;
});
}
}
}