source: main/trunk/greenstone3/web/interfaces/oran/js/map-scripts.js@ 25023

Last change on this file since 25023 was 25023, checked in by sjm84, 12 years ago

Added the map scripts file to the main code

  • Property svn:executable set to *
File size: 17.8 KB
Line 
1var _docList = new Array();
2_docList.ids = new Array();
3_docList.getDocByIndex = function(index)
4{
5 return _docList[_docList.ids[index]];
6};
7
8var _map;
9var _intervalHandle;
10var _baseURL = document.URL.substring(0, document.URL.indexOf("?") + 1);
11var _retrievedClassifiers = new Array();
12var _preventLoopingSingleMarker = false;
13var _searchRunning = false;
14var _nearbyDocs = new Array();
15
16function initializeMapScripts()
17{
18 modifyFunctions();
19
20 setUpMap();
21
22 var jsonNodeDiv = document.getElementById("jsonNodes");
23 if(jsonNodeDiv)
24 {
25 var jsonNodes = eval(jsonNodeDiv.innerHTML);
26 if(jsonNodes && jsonNodes.length > 0)
27 {
28 for(var i = 0; i < jsonNodes.length; i++)
29 {
30 _docList[jsonNodes[i].nodeID] = jsonNodes[i];
31 _docList.ids.push(jsonNodes[i].nodeID);
32 createMarker(jsonNodes[i], true);
33 }
34 updateMap();
35 }
36 }
37
38 _docList.loopIndex = 0;
39
40 if(_docList.ids.length > 1)
41 {
42 _intervalHandle = setInterval(loopThroughMarkers, 2000);
43 }
44}
45
46function setUpMap()
47{
48 var myOptions =
49 {
50 zoom: 2,
51 center: new google.maps.LatLng(0, 0),
52 mapTypeId: google.maps.MapTypeId.HYBRID
53 };
54 _map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
55 google.maps.event.addListener(_map, 'bounds_changed', performSearchForMarkers);
56}
57
58function performSearchForMarkers()
59{
60 if(_searchRunning)
61 {
62 return;
63 }
64
65 _searchRunning = true;
66
67 var bounds = _map.getBounds();
68
69 var neLat = bounds.getNorthEast().lat();
70 var neLng = bounds.getNorthEast().lng();
71 var swLat = bounds.getSouthWest().lat();
72 var swLng = bounds.getSouthWest().lng();
73
74 var latDistance = neLat - swLat;
75 var lngDistance = neLng - swLng;
76
77 console.log("neLat = " + neLat + " neLng = " + neLng + " swLat = " + swLat + " swLng = " + swLng + " latDistance = " + latDistance + " lngDistance = " + lngDistance);
78
79 //Check which increment to use for latitude (i.e. 0.001, 0.01, 0.1 or 1 degree increments)
80 var latDelta;
81 var latPrecision;
82 for(var i = 3; i >= 0; i--)
83 {
84 latDelta = (1 / Math.pow(10, i));
85 if((latDistance / latDelta) <= 5 || latDelta == 1)
86 {
87 latPrecision = i;
88 break;
89 }
90 }
91
92 //Check which increment to use for longitude (i.e. 0.001, 0.01, 0.1 or 1 degree increments)
93 var lngDelta;
94 for(var i = 3; i >= 0; i--)
95 {
96 lngDelta = (1 / Math.pow(10, i));
97 if((lngDistance / lngDelta) <= 5 || lngDelta == 1)
98 {
99 lngPrecision = i;
100 break;
101 }
102 }
103
104 if(latDelta == 0.1){latDelta = 1; latPrecision = 0;}
105 if(lngDelta == 0.1){lngDelta = 1; lngPrecision = 0;}
106
107 var query = "";
108 for(var i = 0; i <= Math.floor(latDistance / latDelta) + 1; i++)
109 {
110 for(var j = 0; j <= Math.floor(lngDistance / lngDelta) + 1; j++)
111 {
112 //Some necessary variables
113 var newLat = neLat - (latDelta * i);
114 var newLatString = "" + newLat;
115 var newLatTrunc;
116 if(newLat < 0){newLatTrunc = Math.ceil(newLat);}
117 else{newLatTrunc = Math.floor(newLat);}
118
119 var newLng = neLng - (lngDelta * j);
120 var newLngString = "" + newLng;
121 var newLngTrunc;
122 if(newLng < 0){newLngTrunc = Math.ceil(newLng);}
123 else{newLngTrunc = Math.floor(newLng);}
124
125 //Construct query
126 query += "(";
127 query += "LA:" + coordToAbsDirected(newLatTrunc, "lat");
128 if(latDelta != 1)
129 {
130 query += "+AND+";
131 query += "LA:" + newLatString.substring(newLatString.indexOf(".") + 1, newLatString.indexOf(".") + latPrecision + 1);
132 }
133 query += "+AND+";
134 query += "LN:" + coordToAbsDirected(newLngTrunc, "lng");
135 if(lngDelta != 1)
136 {
137 query += "+AND+";
138 query += "LN:" + newLngString.substring(newLngString.indexOf(".") + 1, newLngString.indexOf(".") + lngPrecision + 1);
139 }
140 query += ")";
141
142 if(i != (Math.floor(latDistance / latDelta) + 1) || j != (Math.floor(lngDistance / lngDelta) + 1)){ query += "+OR+"; }
143 }
144 }
145
146 var ajax = new gs.functions.ajaxRequest();
147 ajax.open("GET", _baseURL + "a=q&s=RawQuery&rt=rd&c=" + gs.cgiParams.c + "&s1.rawquery=" + query + "&excerptid=jsonNodes", true);
148 ajax.onreadystatechange = function()
149 {
150 if(ajax.readyState == 4 && ajax.status == 200)
151 {
152 if(ajax.responseText.search("id=\"jsonNodes") != -1)
153 {
154 var startIndex = ajax.responseText.indexOf(">");
155 var endIndex = ajax.responseText.indexOf("</");
156
157 var jsonNodes = eval(ajax.responseText.substring(startIndex+1, endIndex));
158 if(jsonNodes && jsonNodes.length > 0)
159 {
160 for(var i = 0; i < jsonNodes.length; i++)
161 {
162 var doc = jsonNodes[i];
163
164 var found = false;
165 for(var j = 0; j < _docList.ids.length; j++){if(doc.nodeID == _docList.ids[j]){found = true; break;}}
166
167 if(!found)
168 {
169 _docList[doc.nodeID] = doc;
170 _docList.ids.push(doc.nodeID);
171
172 createMarker(doc, false);
173 }
174 }
175 }
176 }
177 else
178 {
179 console.log("No JSON information received");
180 }
181
182 _searchRunning = false;
183 }
184 }
185 ajax.send();
186}
187
188function coordToAbsDirected(coord, type)
189{
190 var value = "" + coord;
191 if(coord < 0)
192 {
193 value = value.substring(1);
194 if(type == "lat")
195 {
196 value += "S";
197 }
198 else
199 {
200 value += "W";
201 }
202 }
203 else
204 {
205 if(type == "lat")
206 {
207 value += "N";
208 }
209 else
210 {
211 value += "E";
212 }
213 }
214
215 return value;
216}
217
218function updateMap()
219{
220 var north = -180;
221 var east = -180;
222 var south = 180;
223 var west = 180;
224
225 var markersOnMap = 0;
226 for(var i = 0; i < _docList.ids.length; i++)
227 {
228 var doc = _docList.getDocByIndex(i);
229
230 if(doc.parentCL && doc.parentCL.style.display == "none")
231 {
232 doc.marker.setVisible(false);
233 continue;
234 }
235 else
236 {
237 doc.marker.setVisible(true);
238 markersOnMap++;
239 }
240
241 if(doc.lat > north)
242 {
243 north = doc.lat;
244 }
245 if(doc.lat < south)
246 {
247 south = doc.lat;
248 }
249 if(doc.lng > east)
250 {
251 east = doc.lng;
252 }
253 if(doc.lng < west)
254 {
255 west = doc.lng;
256 }
257 }
258
259 //As there is always 2 possible bounding boxes we want the smaller of the two
260 if(east - west > 180)
261 {
262 var temp = east;
263 east = west;
264 west = temp;
265 }
266
267 var bounds;
268 if(markersOnMap > 0)
269 {
270 bounds = new google.maps.LatLngBounds(new google.maps.LatLng(south, west), new google.maps.LatLng(north, east));
271 _map.fitBounds(bounds);
272 }
273}
274
275function loopThroughMarkers()
276{
277 if(_docList.ids.length == 0)
278 {
279 return;
280 }
281
282 var visibleMarkers = new Array();
283 for(var i = 0; i < _docList.ids.length; i++)
284 {
285 var doc = _docList.getDocByIndex(i);
286 if(doc.marker.getVisible())
287 {
288 visibleMarkers.push(doc);
289 }
290 }
291
292 if(visibleMarkers.length < 2)
293 {
294 clearAllInfoBoxes();
295 return;
296 }
297
298 if(_docList.loopIndex >= visibleMarkers.length)
299 {
300 _docList.loopIndex = 0;
301 }
302
303 clearAllInfoBoxes();
304
305 var doc = visibleMarkers[_docList.loopIndex];
306 var elem = document.getElementById("div" + doc.nodeID);
307 if(elem)
308 {
309 elem.style.background = "#BBFFBB";
310 setTimeout(function(){elem.style.background = "";}, 2000);
311 }
312 doc.marker.markerInfo.open(_map, doc.marker);
313
314 _docList.loopIndex++;
315}
316
317function attachClickHandler(marker, nodeID)
318{
319 google.maps.event.addListener(marker, 'click', function()
320 {
321 document.location.href = _baseURL + "a=d&ed=1&c=" + gs.cgiParams.c + "&d=" + nodeID + "&dt=hierarchy&p.a=b&p.sa=&p.s=ClassifierBrowse";
322 });
323}
324
325function focusDocument(id)
326{
327 var doc = _docList[id];
328 if(doc)
329 {
330 clearInterval(_intervalHandle);
331 _map.panTo(new google.maps.LatLng(doc.lat, doc.lng));
332 clearAllInfoBoxes();
333 doc.marker.markerInfo.open(_map, doc.marker);
334 }
335}
336
337function clearAllInfoBoxes()
338{
339 for(var i = 0; i < _docList.ids.length; i++)
340 {
341 var doc = _docList.getDocByIndex(i);
342 doc.marker.markerInfo.close();
343 }
344}
345
346function createMarker(doc, mainMarker)
347{
348 var pos = new google.maps.LatLng(doc.lat,doc.lng);
349 var marker
350 if(mainMarker)
351 {
352 marker = new google.maps.Marker
353 ({
354 position: pos,
355 title:doc.title,
356 map:_map,
357 icon:"interfaces/" + gs.xsltParams.interface_name + "/images/bluemarker.png"
358 });
359 }
360 else
361 {
362 marker = new google.maps.Marker
363 ({
364 position: pos,
365 title:doc.title,
366 map:_map
367 });
368 }
369
370 var docElement = document.getElementById("div" + doc.nodeID);
371 var parent;
372 if(docElement)
373 {
374 parent = docElement.parentNode;
375 }
376
377 while(parent && parent.nodeName != "BODY")
378 {
379 if(parent.getAttribute("id") && parent.getAttribute("id").search("divCL") != -1)
380 {
381 doc.parentCL = parent;
382 break;
383 }
384
385 parent = parent.parentNode;
386 }
387
388 var info = new google.maps.InfoWindow({content:doc.title});
389 marker.markerInfo = info;
390 doc.marker = marker;
391
392 attachClickHandler(marker, doc.nodeID);
393}
394
395function getSubClassifier(sectionID)
396{
397 var ajax = new gs.functions.ajaxRequest();
398 ajax.open("GET", _baseURL + "a=b&rt=s&s=ClassifierBrowse&c=" + gs.cgiParams.c + "&cl=" + sectionID + "&excerptid=jsonNodes", true);
399 ajax.onreadystatechange = function()
400 {
401 if(ajax.readyState == 4 && ajax.status == 200)
402 {
403 var startIndex = ajax.responseText.indexOf(">");
404 var endIndex = ajax.responseText.indexOf("</");
405
406 var jsonNodes = eval(ajax.responseText.substring(startIndex+1, endIndex));
407 if(jsonNodes && jsonNodes.length > 0)
408 {
409 for(var i = 0; i < jsonNodes.length; i++)
410 {
411 var doc = jsonNodes[i];
412 _docList[doc.nodeID] = doc;
413 _docList.ids.push(doc.nodeID);
414
415 createMarker(doc, false);
416 }
417 }
418
419 updateMap();
420 }
421 else if(ajax.readyState == 4)
422 {
423 console.log("Error getting subclassifiers");
424 return;
425 }
426 }
427 ajax.send();
428}
429
430function performDistanceSearch(id, lat, lng, degrees)
431{
432 if(parseFloat(lat) > 180 || parseFloat(lat) < -180 || parseFloat(lng) > 180 || parseFloat(lat) < -180)
433 {
434 console.log("Latitude or longitude incorrectly formatted");
435 return;
436 }
437
438 if(lat.indexOf(".") == -1 || lng.indexOf(".") == -1 || (lat.indexOf(".") + 3) >= lat.length || (lng.indexOf(".") + 3) >= lng.length)
439 {
440 console.log("Latitude or longitude does not have the required precision for a distance search");
441 return;
442 }
443
444 var query = "";
445 for(var i = 0; i < degrees * 2; i++)
446 {
447 for (var j = 0; j < degrees * 2; j++)
448 {
449 var latDelta = (i - degrees) * 0.01;
450 var lngDelta = (j - degrees) * 0.01;
451
452 query += "(" + getDistanceQueryString(lat, latDelta, 2, "LA", ["N","S"]);
453 query += "+AND+";
454 query += getDistanceQueryString(lng, lngDelta, 2, "LN", ["E","W"]) + ")";
455
456 if(i != ((degrees * 2) - 1) || j != ((degrees * 2) - 1)){ query += "+OR+"; }
457 }
458 }
459
460 var inlineTemplate = '\
461 <xsl:template match="/" priority="5">\
462 <table id="nearbyDocs">\
463 <tr>\
464 <th><a href="javascript:sortByDistance();">Distance (km)</a></th><th><a href="javascript:sortAlphabetically();">Document</a></th>\
465 </tr>\
466 <xsl:apply-templates select="//documentNode"/>\
467 </table>\
468 </xsl:template>\
469 \
470 <xsl:template match="documentNode" priority="5">\
471 <tr>\
472 <td>___<gsf:metadata name="Latitude"/>______<gsf:metadata name="Longitude"/>___</td>\
473 <td><gsf:link type="document"><gsf:metadata name="Title"/></gsf:link></td>\
474 </tr>\
475 </xsl:template>';
476
477 var ajax = new gs.functions.ajaxRequest();
478 ajax.open("GET", _baseURL + "a=q&s=RawQuery&rt=rd&c=" + gs.cgiParams.c + "&s1.rawquery=" + query + "&excerptid=nearbyDocs&ilt=" + inlineTemplate.replace(/ /, "%20"), true);
479 ajax.onreadystatechange = function()
480 {
481 if(ajax.readyState == 4 && ajax.status == 200)
482 {
483 var response = ajax.responseText;
484 response = response.replace(/<img src="[^"]*map_marker.png"[^>]*>/g, "");
485
486 console.log(ajax.responseText);
487
488 var nearbyDocsArray = new Array();
489
490 var lats = new Array();
491 var lngs = new Array();
492
493 var matches = response.match(/___(-?[0-9\.]*)___/g);
494 for(var i = 0; i < matches.length; i += 2)
495 {
496 var matchLatFloat = parseFloat(matches[i].replace("___", ""));
497 var matchLngFloat = parseFloat(matches[i+1].replace("___", ""));
498
499 lats.push(matchLatFloat);
500 lngs.push(matchLngFloat);
501
502 var distance = Math.sqrt(Math.pow(matchLatFloat - parseFloat(lat), 2) + Math.pow(matchLngFloat - parseFloat(lng), 2)) * (40000.0/360.0);
503 var distanceString = "" + distance;
504 distanceString = distanceString.substring(0, 6);
505
506 response = response.replace(matches[i] + matches[i+1], distanceString);
507 }
508
509 var index = 0;
510 var i = 0;
511 while(true)
512 {
513 var distanceStart = response.indexOf("<td>", index);
514 if(distanceStart == -1)
515 {
516 break;
517 }
518 var distanceEnd = response.indexOf("</td>", distanceStart);
519
520 var docLinkStart = response.indexOf("<td>", distanceEnd);
521 var docLinkEnd = response.indexOf("</td>", docLinkStart);
522
523 var dist = response.substring(distanceStart + 4, distanceEnd);
524 var docLink = response.substring(docLinkStart + 4, docLinkEnd);
525
526 _nearbyDocs.push({title:docLink, distance:dist, lat:lats[i], lng:lngs[i++]});
527
528 index = docLinkEnd;
529 }
530
531 sortByDistance();
532
533 var toggle = document.getElementById("nearbyDocumentsToggle");
534 toggle.setAttribute("src", gs.imageURLs.collapse);
535 gs.functions.makeToggle(toggle, document.getElementById("nearbyDocuments"));
536 }
537 }
538 ajax.send();
539}
540
541function sortByDistance()
542{
543 var sortedTable = '<table id="nearbyDocs"><tr><th><a href="javascript:;">Distance (km)</a></th><th><a href="javascript:sortAlphabetically();">Document</a></th></tr>';
544 _nearbyDocs.sort(function(a, b){return (a.distance - b.distance);});
545 for(var i = 0; i < _nearbyDocs.length; i++)
546 {
547 sortedTable += "<tr><td>" + _nearbyDocs[i].distance + '</td><td onmouseover="_map.setCenter(new google.maps.LatLng(' + _nearbyDocs[i].lat + ',' + _nearbyDocs[i].lng + '))">' + _nearbyDocs[i].title + "</td></tr>";
548 }
549 sortedTable += "</table>";
550
551 document.getElementById("nearbyDocuments").innerHTML = sortedTable;
552}
553
554function sortAlphabetically()
555{
556 var sortedTable = '<table id="nearbyDocs"><tr><th><a href="javascript:sortByDistance();">Distance (km)</a></th><th><a href="javascript:;">Document</a></th></tr>';
557 _nearbyDocs.sort(function(a, b)
558 {
559 var firstTitleStartIndex = a.title.indexOf(">");
560 var firstTitleEndIndex = a.title.indexOf("<", firstTitleStartIndex);
561 var firstTitle = a.title.substring(firstTitleStartIndex + 1, firstTitleEndIndex);
562 var secondTitleStartIndex = b.title.indexOf(">");
563 var secondTitleEndIndex = b.title.indexOf("<", secondTitleStartIndex);
564 var secondTitle = b.title.substring(secondTitleStartIndex + 1, secondTitleEndIndex);
565 return ((firstTitle.toLowerCase() == secondTitle.toLowerCase()) ? 0 : ((firstTitle.toLowerCase() > secondTitle.toLowerCase()) ? 1 : -1));
566 });
567 for(var i = 0; i < _nearbyDocs.length; i++)
568 {
569 sortedTable += "<tr><td>" + _nearbyDocs[i].distance + '</td><td onmouseover="_map.setCenter(new google.maps.LatLng(' + _nearbyDocs[i].lat + ',' + _nearbyDocs[i].lng + '))">' + _nearbyDocs[i].title + "</td></tr>";
570 }
571 sortedTable += "</table>";
572
573 document.getElementById("nearbyDocuments").innerHTML = sortedTable;
574}
575
576function getDistanceQueryString(currentCoord, delta, precision, indexName, dirs)
577{
578 var query = "";
579 var coordFloat = parseFloat(currentCoord);
580
581 var newCoord = "" + (coordFloat + delta);
582 var beforeDec = newCoord.substring(0, newCoord.indexOf("."));
583
584 var dir = dirs[0];
585 if(coordFloat < 0)
586 {
587 dir = dirs[1];
588 beforeDec = beforeDec.substring(1);
589 }
590 beforeDec += dir;
591
592 var afterDec = newCoord.substring(newCoord.indexOf(".") + 1, newCoord.indexOf(".") + (precision) + 1);
593
594 return indexName + ":" + beforeDec + "+AND+" + indexName + ":" + afterDec;
595}
596
597function modifyFunctions()
598{
599 toggleSection = function(sectionID)
600 {
601 var section = document.getElementById("div" + sectionID);
602 var sectionToggle = document.getElementById("toggle" + sectionID);
603
604 if(sectionToggle == undefined)
605 {
606 return;
607 }
608
609 if(section)
610 {
611 if(isExpanded(sectionID))
612 {
613 section.style.display = "none";
614 sectionToggle.setAttribute("src", gs.imageURLs.expand);
615
616 if(openClassifiers[sectionID] != undefined)
617 {
618 delete openClassifiers[sectionID];
619 }
620 }
621 else
622 {
623 section.style.display = "block";
624 sectionToggle.setAttribute("src", gs.imageURLs.collapse);
625 openClassifiers[sectionID] = true;
626 }
627 updateOpenClassifiers();
628 updateMap();
629 }
630 else
631 {
632 httpRequest(sectionID);
633 }
634 }
635
636 httpRequest = function(sectionID)
637 {
638 if(!inProgress[sectionID])
639 {
640 inProgress[sectionID] = true;
641 var httpRequest = new gs.functions.ajaxRequest();
642
643 var sectionToggle = document.getElementById("toggle" + sectionID);
644 sectionToggle.setAttribute("src", gs.imageURLs.loading);
645
646 var url = document.URL;
647 url = url.replace(/(&|\?)cl=[a-z\.0-9]+/gi, "$1cl=" + sectionID + "&excerptid=div" + sectionID);
648
649 if(gs.cgiParams.berryBasket == "on")
650 {
651 url = url + "&berrybasket=on";
652 }
653
654 if(url.indexOf("#") != -1)
655 {
656 url = url.substring(0, url.indexOf("#"));
657 }
658 httpRequest.open('GET', url, true);
659 httpRequest.onreadystatechange = function()
660 {
661 if (httpRequest.readyState == 4)
662 {
663 if (httpRequest.status == 200)
664 {
665 var newDiv = document.createElement("div");
666 var sibling = document.getElementById("title" + sectionID);
667 var parent = sibling.parentNode;
668 if(sibling.nextSibling)
669 {
670 parent.insertBefore(newDiv, sibling.nextSibling);
671 }
672 else
673 {
674 parent.appendChild(newDiv);
675 }
676
677 newDiv.innerHTML = httpRequest.responseText;
678 sectionToggle.setAttribute("src", gs.imageURLs.collapse);
679 openClassifiers[sectionID] = true;
680
681 if(gs.cgiParams.berryBasket == "on")
682 {
683 checkout();
684 }
685 updateOpenClassifiers();
686 getSubClassifier(sectionID);
687 }
688 else
689 {
690 sectionToggle.setAttribute("src", gs.imageURLs.expand);
691 }
692 inProgress[sectionID] = false;
693 busy = false;
694 }
695 }
696 httpRequest.send();
697 }
698 }
699}
Note: See TracBrowser for help on using the repository browser.