source: main/trunk/greenstone3/web/interfaces/default_old/js/map-scripts.js@ 29861

Last change on this file since 29861 was 29861, checked in by Georgiy Litvinov, 9 years ago

renamed interfaces

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