Mercurial > hg > STI-GWT
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'> (" + 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 } |