comparison war/scripts/sti/STIMap.js @ 3:cf06b77a8bbd

Committed branch of the e4D repos sti-gwt branch 16384. git-svn-id: http://dev.dariah.eu/svn/repos/eu.dariah.de/ap1/sti-gwt-dariah-geobrowser@36 f2b5be40-def6-11e0-8a09-b3c1cc336c6b
author StefanFunk <StefanFunk@f2b5be40-def6-11e0-8a09-b3c1cc336c6b>
date Tue, 17 Jul 2012 13:34:40 +0000
parents
children 517a6422d1bd
comparison
equal deleted inserted replaced
2:2897af43ccc6 3:cf06b77a8bbd
1 /**
2 * defines the map component of the Spatio Temporal Interface.
3 * it builds a map context with the OpenLayers JavaScript Framework
4 * @param {STICore} core the sti core component, the map component has to deal with
5 * @param {String} window the div id for the window div for the container of the map widget
6 * @param {String} container the div id for the container of the map widget
7 *
8 * @constructor
9 */
10 function STIMap(core,window,container){
11
12 this.core = core;
13 this.window = window;
14 this.container = container;
15 this.openlayersMap;
16 this.baseLayers;
17 this.objectLayer;
18 this.drilldownLayer;
19 this.connectionLayer;
20
21 this.drawPolygon;
22 this.drawCircle;
23 this.selectCountry;
24 this.dragArea;
25 this.selectFeature;
26 this.navigation;
27
28 this.polygon;
29
30 this.selectElementsPlace;
31 this.pointToAdd;
32 this.displayPointSet;
33
34 this.popup;
35 this.lastHovered;
36
37 this.xShift;
38 this.yShift;
39 this.showConnections;
40 this.connections;
41
42 this.mapMouseMove;
43 this.addCrossImage;
44
45 this.initialize();
46
47 }
48
49 STIMap.prototype = {
50
51 /**
52 * initializes the map for the Spatio Temporal Interface.
53 * it includes setting up all layers of the map and defines all map specific interaction possibilities
54 */
55 initialize: function(){
56
57 //OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";
58 var map = this;
59
60 this.pointSelected = false;
61 this.showConnections = false;
62 this.labelDivs = [];
63 this.polygons = [];
64
65 var window = document.getElementById(this.window);
66
67 this.toolbar = document.createElement("div");
68 this.toolbar.setAttribute('class','mapToolbar');
69 window.appendChild(this.toolbar);
70
71 this.drag = document.createElement("div");
72 this.drag.title = "Drag Area: drag a selection area and with left mouse-button";
73 this.drag.setAttribute('class','dragRange');
74 this.toolbar.appendChild(this.drag);
75 this.drag.onclick = function(evt){
76 if( map.activeControl == "drag" ){
77 map.deactivate("drag");
78 }
79 else {
80 map.deactivate(map.activControl);
81 map.activate("drag");
82 }
83 }
84
85 var zoom = document.createElement("div");
86 zoom.title = "Zoom into selection. To undo, go a step back in the History.";
87 zoom.setAttribute('class','zoomRange');
88 this.toolbar.appendChild(zoom);
89 zoom.onclick = function(){
90 map.core.refine();
91 }
92
93 var cancel = document.createElement("div");
94 cancel.title = "Clear Selection";
95 cancel.setAttribute('class','cancelRange');
96 this.toolbar.appendChild(cancel);
97 cancel.onclick = function(){
98 map.core.reset();
99 }
100
101 this.controlLockDiv = document.createElement("div");
102 this.controlLockDiv.setAttribute('class','controlLock');
103 window.appendChild(this.controlLockDiv);
104
105 this.leftTagCloudDiv = document.createElement("div");
106 this.leftTagCloudDiv.setAttribute('class','tagCloudDiv');
107 window.appendChild(this.leftTagCloudDiv);
108
109 this.rightTagCloudDiv = document.createElement("div");
110 this.rightTagCloudDiv.setAttribute('class','tagCloudDiv');
111 window.appendChild(this.rightTagCloudDiv);
112
113 this.pointClickDiv = document.createElement("div");
114 this.pointClickDiv.setAttribute('class','pointClickDiv');
115 window.appendChild(this.pointClickDiv);
116
117 var pointClickDivBackground = document.createElement("div");
118 pointClickDivBackground.setAttribute('class','pointClickDivBackground');
119 this.pointClickDiv.appendChild(pointClickDivBackground);
120
121 this.objectLayer = new OpenLayers.Layer.Vector("Data Objects", {
122 projection: "EPSG:4326"
123 });
124 this.connectionLayer = new OpenLayers.Layer.Vector("Connections", {
125 projection: "EPSG:4326"
126 });
127 this.drilldownLayer = new OpenLayers.Layer.Vector("Drilldown", {
128 projection: "EPSG:4326"
129 });
130 this.parseBaseLayers("layers.xml");
131
132 this.navigation = new OpenLayers.Control.Navigation({
133 zoomWheelEnabled: true
134 });
135 this.navigation.defaultDblClick = function(evt){
136 var newCenter = this.map.getLonLatFromViewPortPx(evt.xy);
137 this.map.setCenter(newCenter, this.map.zoom + 1);
138 map.drawObjectLayer(true);
139 setMapZoom(this.map.zoom/this.map.numZoomLevels);
140 }
141 this.navigation.wheelUp = function(evt){
142 this.wheelChange(evt, 1);
143 map.drawObjectLayer(true);
144 setMapZoom(this.map.zoom/this.map.numZoomLevels);
145 }
146 this.navigation.wheelDown = function(evt){
147 this.wheelChange(evt, -1);
148 map.drawObjectLayer(true);
149 setMapZoom(this.map.zoom/this.map.numZoomLevels);
150 }
151
152 var options = {
153 controls: [this.navigation, new OpenLayers.Control.ScaleLine()],
154 projection: new OpenLayers.Projection("EPSG:900913"),
155 displayProjection: new OpenLayers.Projection("EPSG:4326"),
156 units: "m",
157 minZoomLevel: 1,
158 maxZoomLevel: 17,
159 numZoomLevels: 17,
160 maxResolution: 78271.51695,
161 maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
162 };
163 this.openlayersMap = new OpenLayers.Map(this.container, options);
164 for (var i = 0; i < this.baseLayers.length; i++)
165 this.openlayersMap.addLayers([this.baseLayers[i]]);
166 this.openlayersMap.fractionalZoom = false;
167 this.activeControl = "navigate";
168
169 var bounds = new OpenLayers.Bounds(boundaries.minLon, boundaries.minLat, boundaries.maxLon, boundaries.maxLat);
170 var projectionBounds = bounds.transform(this.openlayersMap.displayProjection, this.openlayersMap.projection);
171 this.openlayersMap.zoomToExtent(projectionBounds);
172 this.openlayersMap.addLayers([this.connectionLayer, this.objectLayer, this.drilldownLayer]);
173
174 // places the toolbar inside the window
175 var placeToolbar = function(){
176 map.toolbar.style.visibility = "visible";
177 var left = 0;
178 var top = 0;
179 if( map.polygons.length > 0 ){
180 map.drag.style.visibility = "visible";
181 for (var i = 0; i < map.polygons.length; i++){
182 for (var j = 0; j < map.polygons[i].components.length; j++){
183 var vertices = map.polygons[i].components[j].getVertices();
184 for (var k = 0; k < vertices.length; k++){
185 var lonlat = new OpenLayers.LonLat( vertices[k].x, vertices[k].y );
186 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat);
187 if( pixel.x > left ){
188 left = pixel.x;
189 top = pixel.y;
190 }
191 }
192 }
193 }
194 map.toolbar.style.width = "69px";
195 map.toolbar.style.left = left+"px";
196 map.toolbar.style.top = (top-map.toolbar.offsetHeight/2)+"px";
197 }
198 else {
199 map.drag.style.visibility = "hidden";
200 map.toolbar.style.width = "47px";
201 map.toolbar.style.left = (map.pointClickDiv.offsetLeft + map.pointClickDiv.offsetWidth - map.toolbar.offsetWidth)+"px";
202 map.toolbar.style.top = map.pointClickDiv.offsetTop+"px";
203 }
204 }
205
206 this.openlayersMap.div.onmousedown = function(){
207 map.toolbar.style.visibility = "hidden";
208 map.drag.style.visibility = "hidden";
209 }
210 this.openlayersMap.div.onmouseup = function(){
211 if( map.polygons.length > 0 ){
212 placeToolbar();
213 }
214 }
215
216 // manages selection of elements if a polygon was drawn
217 var drawnPolygonHandler = function(polygon){
218 if( map.displayPointSet == undefined ){
219 return;
220 }
221 map.polygon = polygon;
222 var polygonArea;
223 if (polygon instanceof OpenLayers.Geometry.Polygon)
224 polygonArea = new OpenLayers.Geometry.MultiPolygon([polygon]);
225 else
226 if (polygon instanceof OpenLayers.Geometry.MultiPolygon)
227 polygonArea = polygon;
228 var points = map.displayPointSet[Math.floor(map.openlayersMap.getZoom()+0.05)];
229 var polygons = polygonArea.components;
230 var innerPoints = [];
231 for (var i = 0; i < points.length; i++)
232 for (var j = 0; j < polygons.length; j++)
233 if (polygons[j].containsPoint(points[i].pointFeature.geometry)) {
234 innerPoints.push(points[i]);
235 continue;
236 }
237 map.updateByPlace(innerPoints, 0);
238 map.drilldownLayer.addFeatures([new OpenLayers.Feature.Vector(polygon)]);
239 map.polygons = polygons;
240 placeToolbar();
241 switchToNavigation();
242 }
243
244 // resets the core
245 var snapper = function(){
246 map.core.reset();
247 }
248
249 if( this.core.props.polygonSelect ){
250 this.drawPolygon = new OpenLayers.Control.DrawFeature(map.drilldownLayer, OpenLayers.Handler.Polygon, {
251 displayClass: "olControlDrawFeaturePolygon",
252 title: "Polygon Drilldown",
253 callbacks: {
254 "done": drawnPolygonHandler,
255 "create": snapper
256 }
257 });
258 this.openlayersMap.addControl(this.drawPolygon);
259 }
260
261 if( this.core.props.circleSelect ){
262 this.drawCircle = new OpenLayers.Control.DrawFeature(map.drilldownLayer, OpenLayers.Handler.RegularPolygon, {
263 displayClass: "olControlDrawFeaturePolygon",
264 title: "Cirlce Drilldown",
265 handlerOptions: {
266 sides: 40
267 },
268 callbacks: {
269 "done": drawnPolygonHandler,
270 "create": snapper
271 }
272 });
273 this.openlayersMap.addControl(this.drawCircle);
274 }
275
276 if( this.core.props.polygonSelect || this.core.props.circleSelect ){
277 this.dragArea = new OpenLayers.Control.DragFeature(map.drilldownLayer, {
278 onStart: function(){
279 map.toolbar.style.visibility = "hidden";
280 },
281 onComplete: function(feature){
282 drawnPolygonHandler(feature.geometry);
283 }
284 });
285 this.openlayersMap.addControl(this.dragArea);
286 }
287
288 if( this.core.props.historicMaps && this.core.props.countrySelect ){
289 this.selectCountry = new OpenLayers.Control.GetFeature({
290 protocol: OpenLayers.Protocol.WFS.fromWMSLayer(map.openlayersMap.baseLayer)
291 });
292 this.selectCountry.events.register("featureselected", this, function(e){
293 if (map.pointSelected){
294 map.pointSelected = false;
295 }
296 else {
297 drawnPolygonHandler(e.feature.geometry);
298 }
299 });
300 this.selectCountry.events.register("featureunselected", this, function(e){
301 snapper();
302 });
303 this.openlayersMap.addControl(this.selectCountry);
304 }
305
306 // changes selection between labels (click, hover)
307 var changeLabelSelection = function(point,label,update){
308 if( update && map.lastLabel.div == label.div ){
309 return;
310 }
311 var k = point.search;
312 var color0 = 'rgb('+colors[k].r0+','+colors[k].g0+','+colors[k].b0+')';
313 var color1 = colors[k].hex;
314 if( update ){
315 map.lastLabel.div.style.color = color0;
316 map.lastLabel.div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em "+color1;
317 map.lastLabel.div.style.textDecoration = "none";
318 map.lastLabel.selected = false;
319 }
320 map.lastLabel = label;
321 label.selected = true;
322 label.div.style.color = color1;
323 label.div.style.textDecoration = "underline";
324 label.div.style.textShadow = "0 0 0.1em white, 0 0 0.1em white, 0 0 0.1em white, 0 0 0.1em "+color1;
325 // label.div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em "+color1;
326 label.div.style.filter = "glow(color="+color1+", strength=3) DropShadow(Color=#292929, OffX=1, OffY=-1, Positive=1) DropShadow(Color=#292929, OffX=-1, OffY=-1, Positive=1) DropShadow(Color=#292929, OffX=1, OffY=1, Positive=1) DropShadow(Color=#292929, OffX=-1, OffY=1, Positive=1) blur(add=false, direction=0, strength=1) blur(add=false, direction=90, strength=1) blur(add=false, direction=180, strength=1) blur(add=false, direction=270, strength=1)";
327 map.updateByPlaceLabel(point,label.elements,0);
328 }
329
330 var getLevelOfDetail = function(){
331 var zoom = map.openlayersMap.getZoom();
332 if( zoom <= 1 ){
333 return 0;
334 }
335 else if( zoom <= 3 ){
336 return 1;
337 }
338 else if( zoom <= 8 ){
339 return 2;
340 }
341 else {
342 return 3;
343 }
344 }
345
346 // calculates the tag cloud
347 var calculateTagCloud = function(){
348 var elements = map.lastHovered.elements;
349 var labels = [];
350 var levelOfDetail = getLevelOfDetail();
351 for( var i=0; i<elements.length; i++ ){
352 var found = false;
353 var label = elements[i].getPlace(levelOfDetail);
354 if( label == "" ){
355 label = "unknown";
356 }
357 for( var j=0; j<labels.length; j++ ){
358 if( labels[j].place == label ){
359 labels[j].elements.push(elements[i]);
360 found = true;
361 break;
362 }
363 }
364 if( !found ){
365 labels.push( { place: label, elements: new Array(elements[i]) } );
366 }
367 }
368 var sortBySize = function(label1, label2){
369 if (label1.elements.length > label2.elements.length){
370 return -1;
371 }
372 return 1;
373 }
374 labels.sort(sortBySize);
375 if( labels.length+1 > tagCloudLabels ){
376 var c = [];
377 for( var i=tagCloudLabels-2; i<labels.length; i++ ){
378 c = c.concat(labels[i].elements);
379 }
380 labels = labels.slice(0,tagCloudLabels-2);
381 labels.push( { place: "others", elements: c } );
382 }
383 if( labels.length > 1 ){
384 labels.push( { place: "all", elements: elements } );
385 }
386 else if( labels[0].place == "unknown" ){
387 labels[0].place = "all";
388 }
389 map.labels = labels;
390
391 var k = map.lastHovered.search;
392 var color = 'rgb('+colors[k].r0+','+colors[k].g0+','+colors[k].b0+')';
393 var shadow = colors[k].hex;0
394 var clickFunction = function(point,label){
395 label.div.onclick = function(){
396 if( map.pointSelected ){
397 changeLabelSelection(point,label,true);
398 }
399 }
400 label.div.onmouseover = function(){
401 if( map.pointSelected && !label.selected ){
402 label.div.style.textShadow = "0 -1px "+shadow+", 1px 0 "+shadow+", 0 1px "+shadow+", -1px 0 "+shadow;
403 label.div.style.filter = "glow(color="+shadow+", strength=2) blur(add=false, direction=135, strength=1) blur(add=false, direction=45, strength=1)";
404 map.updateByPlaceLabel(point,label.elements,1);
405 }
406 }
407 label.div.onmouseout = function(){
408 if( map.pointSelected && !label.selected ){
409 label.div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em "+shadow;
410 label.div.style.filter = "glow(color="+shadow+", strength=3) DropShadow(Color=#292929, OffX=1, OffY=-1, Positive=1) DropShadow(Color=#292929, OffX=-1, OffY=-1, Positive=1) DropShadow(Color=#292929, OffX=1, OffY=1, Positive=1) DropShadow(Color=#292929, OffX=-1, OffY=1, Positive=1) blur(add=false, direction=0, strength=1) blur(add=false, direction=90, strength=1) blur(add=false, direction=180, strength=1) blur(add=false, direction=270, strength=1)";
411 map.updateByPlaceLabel(point,label.elements,2);
412 }
413 }
414 }
415 for( var i=0; i<map.labels.length; i++ ){
416 var l = map.labels[i];
417 l.selected = false;
418 var div = document.createElement("div");
419 div.setAttribute('class','tagCloudItem');
420 div.style.color = color;
421 var fs = 2*l.elements.length/1000;
422 if( l.place == "all" ){
423 fs = 0;
424 }
425 if( fs > 2 ){
426
427
428 fs = 2;
429 }
430
431
432
433
434
435 window.appendChild(div);
436 div.style.fontSize = (1+fs)+"em";
437 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em "+shadow;
438 div.style.filter = "glow(color="+shadow+", strength=3) DropShadow(Color=#292929, OffX=1, OffY=-1, Positive=1) DropShadow(Color=#292929, OffX=-1, OffY=-1, Positive=1) DropShadow(Color=#292929, OffX=1, OffY=1, Positive=1) DropShadow(Color=#292929, OffX=-1, OffY=1, Positive=1) blur(add=false, direction=0, strength=1) blur(add=false, direction=90, strength=1) blur(add=false, direction=180, strength=1) blur(add=false, direction=270, strength=1)";
439 div.innerHTML = l.place + "<span style='font-size:"+(1-fs/(1+fs))+"em'>&nbsp;(" + l.elements.length + ")</span>";
440 l.div = div;
441 var point = map.lastHovered;
442 clickFunction(point,l);
443 }
444 var createDiv = function( mod, div ){
445 var height = 0;
446 var width = 0;
447 for( var i=0; i<map.labels.length; i++ ){
448 if( i%2 == mod ){
449 height += map.labels[i].div.offsetHeight;
450 if( map.labels[i].div.offsetWidth > width ){
451 width = map.labels[i].div.offsetWidth;
452 }
453 if( i>1 ){
454 height += 5;
455 }
456 }
457 }
458 div.style.width = width+"px";
459 div.style.height = height+"px";
460 height = 0;
461 for( var i=0; i<map.labels.length; i++ ){
462 if( i%2 == mod ){
463 var h = map.labels[i].div.offsetHeight;
464 div.appendChild(map.labels[i].div);
465 if( mod == 0 ){
466 map.labels[i].div.style.right = "0px";
467 }
468 else {
469 map.labels[i].div.style.left = "0px";
470 }
471 map.labels[i].div.style.top = height+"px";
472 height += h+5;
473 }
474 }
475 }
476 map.leftTagCloudDiv.innerHTML = "";
477 map.rightTagCloudDiv.innerHTML = "";
478 createDiv(0,map.leftTagCloudDiv);
479 createDiv(1,map.rightTagCloudDiv);
480 map.placeTagCloud(map.lastHovered);
481 }
482
483 // manages hover selection of point objects
484 var hoverSelect = function(event){
485 if( map.pointSelected ){
486 return;
487 }
488 map.core.undoHover(true);
489 var index = event.feature.index;
490 map.lastHovered = map.displayPointSet[Math.floor(map.openlayersMap.getZoom()+0.05)][index];
491 calculateTagCloud();
492 map.updateByPlace([map.lastHovered], 1);
493 };
494 var hoverUnselect = function(event){
495 map.hoverUnselect();
496 };
497 var highlightCtrl = new OpenLayers.Control.SelectFeature(this.objectLayer, {
498 hover: true,
499 highlightOnly: true,
500 renderIntent: "temporary",
501 eventListeners: {
502 featurehighlighted: hoverSelect,
503 featureunhighlighted: hoverUnselect
504 }
505 });
506 this.openlayersMap.addControl(highlightCtrl);
507 highlightCtrl.activate();
508
509 this.selectFeature = new OpenLayers.Control.SelectFeature(this.objectLayer);
510
511 // manages click selection of point objects
512 var onFeatureSelect = function(event){
513 if( map.pointSelected ){
514 return;
515 }
516 hoverUnselect();
517 map.openlayersMap.setCenter(event.feature.geometry.getBounds().getCenterLonLat());
518 var index = event.feature.index;
519 var point = map.displayPointSet[Math.floor(map.openlayersMap.getZoom()+0.05)][index];
520 map.placeTagCloud(point);
521 map.pointClickDiv.style.visibility = "visible";
522 map.polygons = [];
523 placeToolbar();
524 changeLabelSelection(point,map.labels[map.labels.length-1],false);
525 }
526 this.objectLayer.events.on({ "featureselected": onFeatureSelect });
527 this.openlayersMap.addControl(this.selectFeature);
528 this.selectFeature.activate();
529
530 if( this.core.props.addElements ){
531 this.addCrossImage = document.createElement("img");
532 this.addCrossImage.src = "images/cross.png";
533 this.addCrossImage.setAttribute('class','addCross');
534 this.addCrossImage.style.visibility = "hidden";
535 window.appendChild(this.addCrossImage);
536
537 this.addCrossImage.onclick = function(e){
538 var mousePos = getMousePosition(e);
539 var pixel = new OpenLayers.Pixel(
540 mousePos.left - window.offsetLeft,
541 mousePos.top - window.offsetTop
542 );
543 var position = map.openlayersMap.getLonLatFromPixel(pixel);
544 var point = new OpenLayers.Geometry.Point(
545 position.lon,
546 position.lat
547 );
548 if (map.pointToAdd != null){
549 map.drilldownLayer.removeFeatures([map.pointToAdd]);
550 }
551 map.pointToAdd = new OpenLayers.Feature.Vector(point);
552 map.drilldownLayer.addFeatures([map.pointToAdd]);
553 point.transform(map.openlayersMap.projection, map.openlayersMap.displayProjection);
554 setAddElementContext(point.x,point.y,mousePos.left,mousePos.top,window.offsetWidth,window.offsetHeight);
555 }
556
557 // manages movement of the add cross
558 this.mapMouseMove = function(e){
559 var mousePos = getMousePosition(e);
560 var left = mousePos.left - window.offsetLeft - 7;
561 var top = mousePos.top - window.offsetTop - 6;
562 var visibility = map.addCrossImage.style.visibility;
563 if( left < 0 || left+14 > window.offsetWidth || top < 0 || top+12 > window.offsetHeight ){
564 if( visibility == "visible" ){
565 map.addCrossImage.style.visibility = "hidden";
566 }
567 }
568 else {
569 if( visibility == "hidden" ){
570 map.addCrossImage.style.visibility = "visible";
571 }
572 map.addCrossImage.style.left = left+"px";
573 map.addCrossImage.style.top = top+"px";
574 }
575 }
576 }
577
578 if( this.core.props.historicMaps ){
579 this.setCanvas();
580 }
581
582 },
583
584 /**
585 * parses all base layers in a given xmlFile and initializes google and osm layers
586 * @param {String} xmlFile the name of the file to parse
587 */
588 parseBaseLayers: function(xmlFile){
589 this.baseLayers = [];
590 if( this.core.props.historicMaps ){
591 var xmlhttp = false;
592 if (!xmlhttp)
593 try {
594 xmlhttp = new XMLHttpRequest();
595 }
596 catch (e) {
597 xmlhttp = false;
598 }
599 if (typeof ActiveXObject != "undefined") {
600 if (!xmlhttp)
601 try {
602 xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
603 }
604 catch (e) {
605 xmlhttp = false;
606 }
607 if (!xmlhttp)
608 try {
609 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
610 }
611 catch (e) {
612 xmlhttp = false;
613 }
614 }
615 if (!xmlhttp)
616 try {
617 xmlhttp = createRequest();
618 }
619 catch (e) {
620 xmlhttp = false;
621 }
622
623 xmlhttp.open("GET", xmlFile, false);
624 xmlhttp.send("");
625 xmlDoc = xmlhttp.responseXML;
626
627 var wmsLayers = xmlDoc.getElementsByTagName("wms");
628 for (i = 0; i < wmsLayers.length; i++) {
629 var name = wmsLayers[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
630 var server = wmsLayers[i].getElementsByTagName("server")[0].childNodes[0].nodeValue;
631 var layer = wmsLayers[i].getElementsByTagName("layer")[0].childNodes[0].nodeValue;
632 var format = wmsLayers[i].getElementsByTagName("format")[0].childNodes[0].nodeValue;
633 var transparency = wmsLayers[i].getElementsByTagName("transparency")[0].childNodes[0].nodeValue;
634 var layer = new OpenLayers.Layer.WMS(name, server, {
635 layers: layer,
636 format: format,
637 transparent: transparency
638 }, {
639 isBaseLayer: true
640 });
641 this.baseLayers.push(layer);
642 }
643 }
644
645
646 if( this.core.props.googleMaps ){
647 this.baseLayers.push( new OpenLayers.Layer.Google("Google Physical", {type: G_PHYSICAL_MAP, 'sphericalMercator': true} ) );
648 this.baseLayers.push( new OpenLayers.Layer.Google( 'Google Streets', { 'sphericalMercator': true } ) );
649 this.baseLayers.push( new OpenLayers.Layer.Google( 'Google Satellite', { type: G_SATELLITE_MAP, 'sphericalMercator': true } ) );
650 this.baseLayers.push( new OpenLayers.Layer.Google( 'Google Hybrid', { type: G_HYBRID_MAP, 'sphericalMercator': true } ) );
651 }
652
653 if( this.core.props.bingMaps ){
654 this.baseLayers.push( new OpenLayers.Layer.VirtualEarth("Bing Streets", { type: VEMapStyle.Shaded, 'sphericalMercator': true } ) );
655 this.baseLayers.push( new OpenLayers.Layer.VirtualEarth("Bing Aerial", { type: VEMapStyle.Aerial, 'sphericalMercator': true } ) );
656 this.baseLayers.push( new OpenLayers.Layer.VirtualEarth("Bing Hybrid", { type: VEMapStyle.Hybrid, 'sphericalMercator': true } ) );
657 }
658 /*
659 if( this.core.props.osmMaps ){
660 this.baseLayers.push( new OpenLayers.Layer.OSM( 'Open Street Map' ) );
661 this.baseLayers.push( new OpenLayers.Layer.OSM( 'OSM Tiles@Home', 'http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png' ) );
662 }
663 */
664 },
665
666 /**
667 * sets the background canvas of the map window (or resets it after resizing the browser window)
668 */
669 setCanvas: function(){
670 var mapWindow = document.getElementById(this.window);
671 var cv = document.getElementById("mapCanvas");
672 if (cv == null) {
673 cv = document.createElement("canvas");
674 cv.id = "mapCanvas";
675 mapWindow.appendChild(cv);
676 }
677 cv.width = document.getElementById(this.container).clientWidth;
678 cv.height = document.getElementById(this.container).clientHeight;
679 if (!cv.getContext && G_vmlCanvasManager)
680 cv = G_vmlCanvasManager.initElement(cv);
681 var ctx = cv.getContext('2d');
682 var gradient = ctx.createLinearGradient(0, 0, 0, cv.height);
683 gradient.addColorStop(0, '#8bafd8');
684 gradient.addColorStop(1, '#355272');
685 ctx.fillStyle = gradient;
686 ctx.fillRect(0, 0, cv.width, cv.height);
687 },
688
689 /**
690 * draws the object layer.
691 * @param {boolean} zoom if there was a zoom; if not, the new boundary of the map is calculated
692 */
693 drawObjectLayer: function(zoom){
694 if( this.displayPointSet == undefined ){
695 return;
696 }
697 this.hoverUnselect();
698 this.objectLayer.removeAllFeatures();
699 if (!zoom) {
700 var minLat, maxLat, minLon, maxLon;
701 var points = this.displayPointSet[this.openlayersMap.getNumZoomLevels() - 1];
702 for (var i = 0; i < points.length; i++) {
703 var point = points[i];
704 if (!minLon || point.originX < minLon)
705 minLon = point.originX;
706 if (!maxLon || point.originX > maxLon)
707 maxLon = point.originX;
708 if (!minLat || point.originY < minLat)
709 minLat = point.originY;
710 if (!maxLat || point.originY > maxLat)
711 maxLat = point.originY;
712 }
713 if (minLon == maxLon && minLat == maxLat) {
714 this.openlayersMap.setCenter(new OpenLayers.LonLat(minLon, minLat));
715 }
716 else {
717 var gapX = 0.1 * ( maxLon - minLon );
718 var gapY = 0.1 * ( maxLat - minLat );
719 this.openlayersMap.zoomToExtent(new OpenLayers.Bounds(minLon-gapX, minLat-gapY, maxLon+gapX, maxLat+gapY));
720 this.openlayersMap.zoomTo(Math.floor(this.openlayersMap.getZoom()+0.05));
721 }
722 setMapZoom(this.openlayersMap.getZoom()/this.openlayersMap.numZoomLevels);
723 if( this.openlayersMap.getZoom() == this.openlayersMap.numZoomLevels - 1 ){
724 this.openlayersMap.zoomTo(2);
725 setMapZoom(2/this.openlayersMap.numZoomLevels);
726 }
727 }
728
729 var points = this.displayPointSet[Math.floor(this.openlayersMap.getZoom()+0.05)];
730 for (var i = 0; i < points.length; i++) {
731 var resolution = this.openlayersMap.getResolution();
732 var p = points[i];
733 var x = p.originX + resolution * p.shiftX;
734 var y = p.originY + resolution * p.shiftY;
735 p.pointFeature.geometry.x = x;
736 p.pointFeature.geometry.y = y;
737 p.olPointFeature.geometry.x = x;
738 p.olPointFeature.geometry.y = y;
739 this.objectLayer.addFeatures([p.pointFeature]);
740 this.objectLayer.addFeatures([p.olPointFeature]);
741 }
742
743 var dist = function(p1,p2){
744 return Math.sqrt( (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) );
745 }
746
747 for (var i = 0; i < this.connections.length; i++)
748 this.connections[i] = [];
749 var slices = this.core.timeplot.getSlices();
750 for (var i = 0; i < slices.length; i++) {
751 for (var j = 0; j < slices[i].elements.length; j++) {
752 var e = slices[i].elements[j];
753 if (e.length == 0)
754 continue;
755 var points = [];
756 for (var k = 0; k < e.length; k++) {
757 var point = e[k].pointobjects[Math.floor(this.openlayersMap.getZoom())].pointFeature.geometry;
758 if( points.indexOf(point) == -1 ){
759 points.push(point);
760 }
761 }
762 var matrix = new AdjMatrix(points.length);
763 for (var k = 0; k < points.length-1; k++) {
764 for (var l = k+1; l < points.length; l++) {
765 matrix.setEdge(k,l,dist(points[k],points[l]));
766 }
767 }
768 var tree = Prim(matrix);
769 var lines = [];
770 for( var z=0; z<tree.length; z++ ){
771 lines.push(new OpenLayers.Geometry.LineString(new Array(points[tree[z].v1],points[tree[z].v2])));
772 }
773 this.connections[j].push({
774 first: e[0].pointobjects[Math.floor(this.openlayersMap.getZoom()+0.05)].pointFeature.geometry,
775 last: e[e.length-1].pointobjects[Math.floor(this.openlayersMap.getZoom()+0.05)].pointFeature.geometry,
776 lines: lines,
777 time: slices[i].date
778 });
779 }
780 }
781 this.updateMap();
782 },
783
784 /**
785 * initializes the object layer.
786 * all point representations for all zoom levels are calculated and initialized
787 * @param {DataSet[]} dataSets the datasets which contain all objects to display on the map
788 */
789 initObjectLayer: function(dataSets){
790
791 this.clearMap();
792
793 var map = this;
794
795 var getPointCluster = function(dataSets){
796
797 maximumRadius = minimumRadius;
798 var zoomLevels = map.openlayersMap.getNumZoomLevels();
799 var getMaxRadius = function(size){
800 var exponent = 0;
801 while (Math.pow(classBase, exponent) < size)
802 exponent++;
803 return minimumRadius + exponent;
804 }
805
806 var dd = new HierarchicalClustering(-20037508.34,-20037508.34,20037508.34,20037508.34);
807 for (var i = 0; i < dataSets.length; i++){
808 for (var j = 0; j < dataSets[i].objects.length; j++) {
809 var p = new OpenLayers.Geometry.Point(dataSets[i].objects[j].longitude, dataSets[i].objects[j].latitude, null);
810 p.transform(map.openlayersMap.displayProjection, map.openlayersMap.projection);
811 var point = new Vertex(Math.floor(p.x), Math.floor(p.y));
812 var objects = [];
813 for( var k=0; k<dataSets.length; k++ ){
814 objects.push([]);
815 }
816 objects[i].push(dataSets[i].objects[j]);
817 point.setElements(objects);
818 dd.add(point);
819 }
820 var r = getMaxRadius(dataSets[i].objects.length);
821 if( r > maximumRadius ){
822 maximumRadius = r;
823 maximumPoints = dataSets[i].objects.length;
824 }
825 }
826
827 var displayPoints = [];
828 for (var i = 0; i < zoomLevels; i++) {
829 var points = [];
830 var resolution = map.openlayersMap.getResolutionForZoom(zoomLevels - i - 1);
831 dd.mergeForResolution(resolution);
832 for (var j = 0; j < dd.vertices.length; j++) {
833 var point = dd.vertices[j];
834 if( !point.legal ){
835 continue;
836 }
837 var balls = [];
838 for (var k = 0; k < point.elements.length; k++){
839 if (point.elements[k].length > 0){
840 balls.push({
841 search: k,
842 elements: point.elements[k],
843 radius: point.radii[k]
844 });
845 }
846 }
847 var orderBalls = function( b1, b2 ){
848 if ( b1.radius > b2.radius ){
849 return -1;
850 }
851 if ( b2.radius > b1.radius ){
852 return 1;
853 }
854 return 0;
855 }
856 if (balls.length == 1) {
857 points.push(new DisplayPointObject(point.x, point.y, 0, 0, balls[0].elements, balls[0].radius, balls[0].search));
858 }
859 else
860 if (balls.length == 2) {
861 var r1 = balls[0].radius;
862 var r2 = balls[1].radius;
863 points.push(new DisplayPointObject(point.x, point.y, -1*r2, 0, balls[0].elements, r1, balls[0].search));
864 points.push(new DisplayPointObject(point.x, point.y, r1, 0, balls[1].elements, r2, balls[1].search));
865 }
866 else
867 if (balls.length == 3) {
868 var r1 = balls[0].radius;
869 var r2 = balls[1].radius;
870 var r3 = balls[2].radius;
871 var d = (2 / 3 * Math.sqrt(3) - 1) / 2;
872 points.push(new DisplayPointObject(point.x, point.y, -2*d*r1-r1, 0, balls[0].elements, r1, balls[0].search));
873 points.push(new DisplayPointObject(point.x, point.y, r2/2, r2, balls[1].elements, r2, balls[1].search));
874 points.push(new DisplayPointObject(point.x, point.y, r3/2, -1*r3, balls[2].elements, r3, balls[2].search));
875 }
876 else
877 if (balls.length == 4) {
878 balls.sort(orderBalls);
879 var r1 = balls[0].radius;
880 var r2 = balls[1].radius;
881 var r3 = balls[2].radius;
882 var r4 = balls[3].radius;
883 var d = (Math.sqrt(2) - 1)*r2;
884 points.push(new DisplayPointObject(point.x, point.y, -1*d-r2, 0, balls[0].elements, r1, balls[0].search));
885 points.push(new DisplayPointObject(point.x, point.y, r1-r2, -1*d-r4, balls[3].elements, r4, balls[3].search));
886 points.push(new DisplayPointObject(point.x, point.y, r1-r2, d+r3, balls[2].elements, r3, balls[2].search));
887 points.push(new DisplayPointObject(point.x, point.y, d+r1, 0, balls[1].elements, r2, balls[1].search));
888 }
889 }
890 displayPoints.push(points);
891 }
892 return displayPoints.reverse();
893
894 }
895
896 this.connections = [];
897 for (var i = 0; i < dataSets.length; i++) {
898 this.connections.push([]);
899 for (var j = 0; j < dataSets[i].objects.length; j++){
900 dataSets[i].objects[j].pointobjects = [];
901 }
902 }
903
904 this.displayPointSet = getPointCluster(dataSets);
905
906 if( this.connections.length == 0 || this.displayPointSet.length == 0 ){
907 return;
908 }
909
910 for (var i = 0; i < this.displayPointSet.length; i++)
911 for (var j = 0; j < this.displayPointSet[i].length; j++) {
912 var point = this.displayPointSet[i][j];
913 for (var k = 0; k < point.elements.length; k++)
914 point.elements[k].pointobjects.push(point);
915 var style = {
916 fillColor: 'rgb(' + colors[point.search].r0 + ',' + colors[point.search].g0 + ',' + colors[point.search].b0 + ')',
917 fillOpacity: 1,
918 strokeWidth: 1,
919 strokeColor: 'rgb(' + colors[point.search].r1 + ',' + colors[point.search].g1 + ',' + colors[point.search].b1 + ')',
920 stroke: false,
921 pointRadius: point.radius
922 };
923 var pointGeometry = new OpenLayers.Geometry.Point(point.originX, point.originY, null);
924 var pointFeature = new OpenLayers.Feature.Vector(pointGeometry);
925 pointFeature.style = style;
926 pointFeature.index = j;
927 point.setPointFeature(pointFeature);
928 var olStyle = {
929 fillColor: 'rgb(' + colors[point.search].r1 + ',' + colors[point.search].g1 + ',' + colors[point.search].b1 + ')',
930 fillOpacity: 1,
931 stroke: false,
932 pointRadius: 0
933 };
934 var olPointGeometry = new OpenLayers.Geometry.Point(point.originX, point.originY, null);
935 var olPointFeature = new OpenLayers.Feature.Vector(olPointGeometry);
936 olPointFeature.style = olStyle;
937 olPointFeature.index = j;
938 point.setOlPointFeature(olPointFeature);
939 }
940
941 this.drawObjectLayer(false);
942
943 },
944
945 /**
946 * hides all tagCloud and pointclick divs
947 */
948 setVisibility: function(visibility){
949 this.toolbar.style.visibility = visibility;
950 this.leftTagCloudDiv.style.visibility = visibility;
951 this.rightTagCloudDiv.style.visibility = visibility;
952 this.pointClickDiv.style.visibility = visibility;
953 },
954
955 /**
956 * resets the map by destroying all additional elements except the point objects, which are replaced
957 */
958 resetMap: function(){
959 this.connectionLayer.destroyFeatures();
960 this.drilldownLayer.destroyFeatures();
961 this.controlLockDiv.style.visibility = "hidden";
962 this.selectFeature.unselectAll();
963 this.resetPoints();
964 this.deactivate("drag");
965 this.drag.style.visibility = "hidden";
966 this.setVisibility("hidden");
967 this.pointSelected = false;
968 this.polygons = [];
969 },
970
971 /**
972 * resets the map by destroying all elements
973 */
974 clearMap: function(){
975 this.connectionLayer.destroyFeatures();
976 this.drilldownLayer.destroyFeatures();
977 this.objectLayer.destroyFeatures();
978 delete this.displayPointSet;
979 this.displayPointSet = undefined;
980 },
981
982 /**
983 * updates the proportional selection status of a point object
984 * @param {PointObject} point the point to update
985 * @param {OpenLayers.Geometry.Polygon} polygon the actual displayed map polygon
986 */
987 updatePoint: function(point,polygon){
988 var pFull = 0;
989 var pRest = 0;
990 for (var j = 0; j < point.elements.length; j++) {
991 var o = point.elements[j];
992 if (o.percentage == 1 || ( o.hoverSelect && this.lastHovered == undefined ) ) {
993 pFull++;
994 }
995 else {
996 pRest += o.percentage;
997 }
998 }
999 var drawOl = false;
1000 var draw = false;
1001 var pf = point.pointFeature;
1002 var olf = point.olPointFeature;
1003 if (pFull == 0 && olf.style.pointRadius != 0) {
1004 olf.style.pointRadius = 0;
1005 drawOl = true;
1006 }
1007 else if (pFull > 0) {
1008 /*
1009 var noer = pf.style.pointRadius - minimumRadius;
1010 var olpr = Math.floor(pFull / point.elements.length * noer) + minimumRadius;
1011 if (olpr != olf.style.pointRadius) {
1012 olf.style.pointRadius = olpr;
1013 drawOl = true;
1014 }
1015 */
1016 olf.style.pointRadius = getRadius(pFull);
1017 drawOl = true;
1018 }
1019 if (point.percentage != pRest) {
1020 point.percentage = pRest;
1021 draw = true;
1022 var p;
1023 if (pRest == 0){
1024 p = 0;
1025 }
1026 else {
1027 p = pRest / (point.elements.length - pFull);
1028 }
1029 var s = point.search;
1030 var r = colors[s].r0 + Math.round(p * (colors[s].r1 - colors[s].r0));
1031 var g = colors[s].g0 + Math.round(p * (colors[s].g1 - colors[s].g0));
1032 var b = colors[s].b0 + Math.round(p * (colors[s].b1 - colors[s].b0));
1033 point.pointFeature.style.fillColor = 'rgb(' + r + ',' + g + ',' + b + ')';
1034 }
1035 if (polygon.containsPoint(point.pointFeature.geometry)) {
1036 if (draw || drawOl) {
1037 this.objectLayer.drawFeature(point.pointFeature);
1038 this.objectLayer.drawFeature(point.olPointFeature);
1039 }
1040 }
1041 },
1042
1043 /**
1044 * updates the the object layer of the map after selections had been executed in timeplot or table or zoom level has changed
1045 */
1046 updateMap: function(){
1047 var points = this.displayPointSet[Math.floor(this.openlayersMap.getZoom()+0.05)];
1048 var polygon = this.openlayersMap.getExtent().toGeometry();
1049 for (var i = 0; i < points.length; i++) {
1050 this.updatePoint(points[i],polygon);
1051 }
1052 this.displayConnections();
1053 },
1054
1055 /**
1056 * resets the point objects depending on the actual zoom level in basic style
1057 */
1058 resetPoints: function(){
1059 if( this.displayPointSet != undefined ){
1060 if( this.displayPointSet.length == 0 ){
1061 return;
1062 }
1063 var points = this.displayPointSet[Math.floor(this.openlayersMap.getZoom()+0.05)];
1064 for (var i = 0; i < points.length; i++) {
1065 var j = points[i].search;
1066 points[i].pointFeature.style.fillColor = 'rgb(' + colors[j].r0 + ',' + colors[j].g0 + ',' + colors[j].b0 + ')';
1067 points[i].olPointFeature.style.pointRadius = 0;
1068 }
1069 this.objectLayer.redraw();
1070 }
1071 },
1072
1073 /**
1074 * updates the data objects percentages after a selection on the map had been performed
1075 * @param {PointObject[]} pointObjects the point objects that corresponds to the selection
1076 * @param {boolean} hover if it was a hover selection
1077 */
1078 updateByPlace: function(pointObjects, hover){
1079 if (hover == 0) {
1080 this.core.reset();
1081 }
1082 for (var i = 0; i < pointObjects.length; i++) {
1083 var s = pointObjects[i].search;
1084 var c = colors[s].hex;
1085 if (hover == 1) {
1086 pointObjects[i].pointFeature.style.stroke = true;
1087 for (var j = 0; j < pointObjects[i].elements.length; j++) {
1088 pointObjects[i].elements[j].setHover(true);
1089 }
1090 }
1091 else
1092 if (hover == 2) {
1093 pointObjects[i].pointFeature.style.stroke = false;
1094 for (var j = 0; j < pointObjects[i].elements.length; j++) {
1095 pointObjects[i].elements[j].setHover(false);
1096 }
1097 }
1098 else {
1099 pointObjects[i].pointFeature.style.fillColor = c;
1100 pointObjects[i].pointFeature.style.stroke = false;
1101 for (var j = 0; j < pointObjects[i].elements.length; j++) {
1102 pointObjects[i].elements[j].setHover(false);
1103 pointObjects[i].elements[j].setPercentage(1);
1104 }
1105 }
1106 this.objectLayer.drawFeature(pointObjects[i].pointFeature);
1107 this.objectLayer.drawFeature(pointObjects[i].olPointFeature);
1108 }
1109 if( hover == 0 ){
1110 this.core.updateTimeAndTable(false);
1111 }
1112 else {
1113 this.core.updateTimeAndTable(true);
1114 }
1115 },
1116
1117 /**
1118 * updates the data objects percentages after a selection on the map by clicking on a place label
1119 * @param {PointObject} point the point object that corresponds to the label selection
1120 * @param {DataObject[]} elements the data objects corresponding to the selected label
1121 * @param {boolean} hover if it was a hover selection
1122 */
1123 updateByPlaceLabel: function(point,elements,hover){
1124 if( hover == 0 ){
1125 this.core.reset();
1126 }
1127 this.controlLockDiv.style.visibility = "visible";
1128 for (var j = 0; j < elements.length; j++) {
1129 if( hover == 0 ){
1130 elements[j].setPercentage(1);
1131 }
1132 else if( hover == 1 ){
1133 elements[j].hoverSelect = true;
1134 }
1135 else if( hover == 2 ){
1136 elements[j].hoverSelect = false;
1137 }
1138 }
1139 this.setVisibility("visible");
1140 this.pointSelected = true;
1141 this.updatePoint(point,this.openlayersMap.getExtent().toGeometry());
1142 if( hover == 0 ){
1143 this.core.updateTimeAndTable(false);
1144 }
1145 else {
1146 this.core.updateTimeAndTable(true);
1147 }
1148 },
1149
1150 /**
1151 * displays connections between data objects
1152 */
1153 displayConnections: function(){
1154 var ltm = this.core.timeplot.leftFlagTime;
1155 var rtm = this.core.timeplot.rightFlagTime;
1156 if (ltm == undefined || ltm == null){
1157 return;
1158 }
1159 else {
1160 ltm = ltm.getTime();
1161 rtm = rtm.getTime();
1162 }
1163 this.connectionLayer.destroyFeatures();
1164 if (this.showConnections) {
1165 for (var i = 0; i < this.connections.length; i++) {
1166 var c = colors[i];
1167 var style = {
1168 strokeColor: 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')',
1169 strokeOpacity: 0.5,
1170 strokeWidth: 3
1171 };
1172 var pointsToConnect = [];
1173 var last = undefined;
1174 for (var j = 0; j < this.connections[i].length; j++) {
1175 var c = this.connections[i][j];
1176 var ct = c.time.getTime();
1177 if (ct >= ltm && ct <= rtm) {
1178 if( last != undefined ){
1179 var line = new OpenLayers.Geometry.LineString(new Array(last,c.first));
1180 this.connectionLayer.addFeatures([new OpenLayers.Feature.Vector(line, null, style)]);
1181 }
1182 for( var k=0; k<c.lines.length; k++ ){
1183 this.connectionLayer.addFeatures([new OpenLayers.Feature.Vector(c.lines[k], null, style)]);
1184 }
1185 last = c.last;
1186 }
1187 }
1188 }
1189 this.connectionLayer.redraw();
1190 }
1191 },
1192
1193 /**
1194 * causes deselection of a hovered point object
1195 */
1196 hoverUnselect: function(){
1197 if( this.pointSelected ){
1198 return;
1199 }
1200 if (this.lastHovered != undefined) {
1201 this.leftTagCloudDiv.style.visibility = "hidden";
1202 this.rightTagCloudDiv.style.visibility = "hidden";
1203 this.updateByPlace([this.lastHovered], 2);
1204 this.lastHovered = undefined;
1205 }
1206 },
1207
1208 /**
1209 * places the tagCloud divs inside the map window
1210 * @param {PointObject} point the point object that corresponds to the tagCloud
1211 */
1212 placeTagCloud: function( point ){
1213 var lonlat = new OpenLayers.LonLat( point.pointFeature.geometry.x, point.pointFeature.geometry.y );
1214 var pixel = this.openlayersMap.getPixelFromLonLat(lonlat);
1215 var radius = point.pointFeature.style.pointRadius;
1216 var window = document.getElementById(this.window);
1217 var lw = this.leftTagCloudDiv.offsetWidth;
1218 var rw = this.rightTagCloudDiv.offsetWidth;
1219 var lp = false;
1220 var rp = false;
1221 if( pixel.x - radius - lw -5 < 0 ){
1222 lp = true;
1223 if( pixel.x + radius + lw + rw + 10 > window.offsetWidth ){
1224 rp = true;
1225 }
1226 }
1227 else if( pixel.x + radius + rw + 5 > window.offsetWidth ){
1228 rp = true;
1229 if( pixel.x - radius - lw - rw - 10 < 0 ){
1230 lp = true;
1231 }
1232 }
1233 if( !lp && !rp ){
1234 this.leftTagCloudDiv.style.left = (pixel.x-radius-lw-5)+"px";
1235 this.rightTagCloudDiv.style.left = (pixel.x+radius+5)+"px";
1236 }
1237 else if( lp && !rp ){
1238 this.leftTagCloudDiv.style.left = (pixel.x+radius+5)+"px";
1239 this.rightTagCloudDiv.style.left = (pixel.x+radius+lw+10)+"px";
1240 }
1241 else if( !lp && rp ){
1242 this.leftTagCloudDiv.style.left = (pixel.x-radius-lw-rw-10)+"px";
1243 this.rightTagCloudDiv.style.left = (pixel.x-radius-rw-5)+"px";
1244 }
1245 var lh = this.leftTagCloudDiv.offsetHeight;
1246 var rh = this.rightTagCloudDiv.offsetHeight;
1247 var lt = pixel.y - lh/2;
1248 var rt = pixel.y - rh/2;
1249 if( lt < 0 ){
1250 lt = 0;
1251 }
1252 else if( lt + lh > window.offsetHeight ){
1253 lt = window.offsetHeight - lh;
1254 }
1255 if( rt < 0 ){
1256 rt = 0;
1257 }
1258 else if( rt + rh > window.offsetHeight ){
1259 rt = window.offsetHeight - rh;
1260 }
1261 this.leftTagCloudDiv.style.top = lt+"px";
1262 this.rightTagCloudDiv.style.top = rt+"px";
1263 this.leftTagCloudDiv.style.visibility = "visible";
1264 this.rightTagCloudDiv.style.visibility = "visible";
1265
1266 this.pointClickDiv.style.height = (lh+45)+"px";
1267 this.pointClickDiv.style.width = (lw+rw+2*radius+70)+"px";
1268 this.pointClickDiv.style.left = (this.leftTagCloudDiv.offsetLeft-30)+"px";
1269 this.pointClickDiv.style.top = (lt-30)+"px";
1270 },
1271
1272 /**
1273 * activates a specific map control
1274 * @param {String} status the identifier of the control to activate
1275 */
1276 activate: function(status){
1277 this.activeControl = status;
1278 if( status == "drag" ){
1279 this.dragArea.activate();
1280 this.drilldownLayer.setZIndex(parseInt(this.objectLayer.getZIndex())+1);
1281 this.drag.style.backgroundImage = "url(images/dragger-click.png)";
1282 }
1283 else if( status == "polygon" ){
1284 this.drawPolygon.activate();
1285 }
1286 else if( status == "circle" ){
1287 this.drawCircle.activate();
1288 }
1289 else if( status == "country" ){
1290 this.selectCountry.activate();
1291 }
1292 else if( status == "add" ){
1293 document.onmousemove = this.mapMouseMove;
1294 }
1295 },
1296
1297 /**
1298 * deactivates a specific map control
1299 * @param {String} status the identifier of the control to deactivate
1300 */
1301 deactivate: function(status){
1302 if( status == "drag" ){
1303 this.dragArea.deactivate();
1304 this.drilldownLayer.setZIndex(parseInt(this.objectLayer.getZIndex())-1);
1305 this.drag.style.backgroundImage = "url(images/dragger.png)";
1306 }
1307 else if( status == "polygon" ){
1308 this.drawPolygon.deactivate();
1309 }
1310 else if( status == "circle" ){
1311 this.drawCircle.deactivate();
1312 }
1313 else if( status == "country" ){
1314 this.selectCountry.deactivate();
1315 }
1316 else if( status == "add" ){
1317 document.onmousemove = null;
1318 this.addCrossImage.style.visibility = "hidden";
1319 }
1320 },
1321
1322 /**
1323 * inverts the show connection status
1324 * @return boolean value if connections are enabled or not
1325 */
1326 connectionsClick: function(){
1327 this.showConnections = !this.showConnections;
1328 this.displayConnections();
1329 return this.showConnections;
1330 },
1331
1332 /**
1333 * performs a zoom on the map
1334 * @param {int} delta the change of zoom levels
1335 */
1336 zoom: function( delta ){
1337 if( this.pointSelected ){
1338 return false;
1339 }
1340 var zoom = delta*this.openlayersMap.numZoomLevels;
1341 if( this.openlayersMap.baseLayer instanceof OpenLayers.Layer.WMS ){
1342 this.openlayersMap.zoomTo(zoom);
1343 }
1344 else {
1345 this.openlayersMap.zoomTo(Math.round(zoom));
1346
1347 }
1348 this.drawObjectLayer(true);
1349 return true;
1350 },
1351
1352 setMap: function(index){
1353 if (this.baseLayers[index] instanceof OpenLayers.Layer.WMS) {
1354 this.openlayersMap.fractionalZoom = true;
1355 this.selectCountry.protocol = OpenLayers.Protocol.WFS.fromWMSLayer(this.baseLayers[index]);
1356 }
1357 else {
1358 this.openlayersMap.fractionalZoom = false;
1359 }
1360 this.openlayersMap.zoomTo(Math.floor(this.openlayersMap.getZoom()+0.05));
1361 this.openlayersMap.setBaseLayer(this.baseLayers[index]);
1362 },
1363
1364 configure: function(zoom,cLon,cLat,mapId){
1365 this.openlayersMap.zoomTo(zoom);
1366 this.drawObjectLayer(true);
1367 this.setMap(mapId);
1368 this.openlayersMap.setCenter(new OpenLayers.LonLat(cLon,cLat));
1369 setMapZoom(this.openlayersMap.zoom/this.openlayersMap.numZoomLevels);
1370 }
1371
1372 }