source: genesis/nodes/nodemap.html@ 8481

Last change on this file since 8481 was 8481, checked in by rick, 14 years ago

I am forgettting about them. Let's KISS the issue tracker for the time beeing

  • Property svn:keywords set to Id
File size: 21.5 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3<!--
4Author: Rick van der Zwet <info@rickvanderzwet.nl>
5License: BSDLike - http://svn.wirelessleiden.nl/svn/LICENSE.txt
6
7= BUGS/TODO =
8 - Migrate this list to a issue based tracker as soon more people start
9 working on it
10
11 - waarom is er bij enkele nodes wel een (overigens leeg) infoscherm uit
12 Nagios en bij de andere alleen wat basisinfo in een andere opmaak?
13
14 - het contrast tussen pop-up met node/proxy info en de omliggende gebieden
15 (vooral die witte weilanden) is niet erg groot. Donker lijntje van 1 pixel
16 eromheen?
17
18 - blauwe kaartnav (links) blijft niet werken als je knop ingedrukt houdt...
19 het is klik - zoom (of beweeg) en als je verder wil moet je opnieuw
20 klikken.
21
22 - Niet alle nodes staan op de goede plek om de kaart (scheelt soms 30+ meter)
23
24 - De status van de nodes is slechter als was nagios rapporteerd. De nagios
25 deamon lijkt beter te werken als de nodemap deamon.
26
27 - Interlinks staan 'bovenop' waarbij het soms wat moeilijk klikken is,
28 vooral als er uitgezoomd is.
29
30 - Permalink wijst niet naar de juiste locatie/view/zoomlevel.
31
32
33 - Openlayers wms werkt niet.
34
35
36= Wishlist =
37 - is het mogelijk om obv de status van een node een layer te definieren ?
38 (toon mij alles wat OK is, toon mij alles wat problemen heeft, toon mij
39 alle geplande verbindingen etc)
40
41 - Vroeg me af hoe verbindingen kunnen worden ingetekend of verwijderd? Dan
42 kunnen we Nodemap ook gebruiken voor discussie over geplande verbindingen.
43
44 - blauwe kaartnav (links) blijft niet werken als je knop ingedrukt houdt...
45 het is klik - zoom (of beweeg) en als je verder wil moet je opnieuw
46 klikken.`
47
48 - Dekkingsbereik is nog onbekend.
49
50-->
51
52<html xmlns="http://www.w3.org/1999/xhtml">
53 <head>
54 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
55 <title>Wireless Leiden Nodemap using OpenLayers.org and OpenSteetmap.org</title>
56 <style type="text/css">
57 html, body, #basicMap {
58 width: 100%;
59 height: 100%;
60 margin: 0;
61 }
62 </style>
63 <script
64 src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=ABQIAAAAKRiFs2kXKhTkKZkE_ms9rhTdBXm62xfhQU7Dk6ZBFSzYdmSteRQWjLqZhwX8afHvGpd4N3iKql6w8g" type="text/javascript"> </script>
65 <script src="http://openlayers.org/dev/OpenLayers.js" type="text/javascript"> </script>
66 <script type="text/javascript">
67 // <![CDATA[
68 var url_pal3 = "http://maps.google.com/mapfiles/kml/pal3/";
69 var map, rulerControl, clickControl;
70 var mapnik, wms;
71 var svnVersion = '$Id: nodemap.html 8481 2010-09-20 20:57:56Z rick $';
72 var version = '0.10';
73 var projection_wgs = new OpenLayers.Projection("EPSG:4326"); // WGS 1984
74 var projection_smp = new OpenLayers.Projection("EPSG:900913"); // Spherical Mercator Projection
75
76 var current_opacity = 0.5;
77 var max_opacity = 0.9;
78 var min_opacity = 0.1;
79
80 var nodeStatusImg = [];
81 nodeStatusImg.up = 'http://www.google.com/mapfiles/kml/paddle/grn-stars-lv.png';
82 nodeStatusImg.down = 'http://www.google.com/mapfiles/kml/paddle/red-stars-lv.png';
83 nodeStatusImg.planned = 'http://www.google.com/mapfiles/kml/paddle/purple-stars-lv.png';
84 nodeStatusImg.unknown = 'http://www.google.com/mapfiles/kml/paddle/purple-stars-lv.png';
85
86 function log(message) {
87 /* Determine whether Firebug is actually installed and activated before trying to log
88 * Taken from http://code.google.com/p/fbug/source/browse/branches/firebug1.5/lite/firebugx.js
89 */
90 if (window.console && console.firebug) {
91 console.log(message);
92 }
93 }
94
95 function isInterlink(feature) {
96 if (feature.cluster) {
97 return(false);
98 }
99 return (feature.attributes.name.indexOf('Interlink') != -1);
100 }
101
102 function coordConvert(lam, phi) {
103 var lam_deg = Math.floor(lam);
104 var t = (lam - lam_deg) * 60;
105 var lam_min = Math.floor(t);
106 var lam_sec = (t - lam_min) * 60;
107
108 var phi_deg = Math.floor(phi);
109 t = (phi - phi_deg) * 60;
110 var phi_min = Math.floor(t);
111 var phi_sec = (t - phi_min) * 60;
112
113 var url = "http://www.rdnap.nl/cgi-bin/rdetrs.pl?func=etrs2rd&h=0" +
114 "&lam_deg=" + lam_deg +
115 "&lam_min=" + lam_min +
116 "&lam_sec=" + lam_sec +
117 "&phi_deg=" + phi_deg +
118 "&phi_min=" + phi_min +
119 "&phi_sec=" + phi_sec
120 ;
121 return(url);
122 }
123
124 OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
125 defaultHandlerOptions: {
126 'single': true,
127 'double': false,
128 'pixelTolerance': 0,
129 'stopSingle': false,
130 'stopDouble': false
131 },
132
133 initialize: function(options) {
134 this.handlerOptions = OpenLayers.Util.extend(
135 {}, this.defaultHandlerOptions
136 );
137 OpenLayers.Control.prototype.initialize.apply(
138 this, arguments
139 );
140 this.handler = new OpenLayers.Handler.Click(
141 this, {
142 'click': this.trigger
143 }, this.handlerOptions
144 );
145 },
146
147 trigger: function(e) {
148 var lonlat = map.getLonLatFromViewPortPx(e.xy);
149 lonlat = lonlat.transform( projection_smp, projection_wgs);
150 var url = coordConvert(lonlat.lon, lonlat.lat);
151 document.getElementById('coordOutput').href = url;
152 document.getElementById('coordOutput').innerHTML = Math.round(lonlat.lon * 1000) / 1000 + " N, " + Math.round(lonlat.lat * 1000) / 1000 + " E";
153 }
154
155 });
156
157
158 function setOpacity(new_opacity) {
159 current_opacity = new_opacity;
160 mapnik.setOpacity(new_opacity);
161 wms.setOpacity(new_opacity);
162 }
163
164 function changeOpacity(by_opacity) {
165 var new_opacity = current_opacity + by_opacity;
166 new_opacity = Math.min(max_opacity, Math.max(min_opacity, new_opacity));
167 setOpacity(new_opacity);
168 }
169
170 function initMap() {
171 map = new OpenLayers.Map("basicMap");
172
173 var world_bound = new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34);
174 // Development focus maps
175 mapnik = new OpenLayers.Layer.OSM("OpenStreetMap");
176 wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",
177 "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
178
179 // Added extra's
180 var google_sat = new OpenLayers.Layer.Google("Google Satellite" ,
181 { type: G_SATELLITE_MAP,
182 sphericalMercator: true,
183 maxExtent: world_bound,
184 wrapDateLine: false
185 });
186 var google_normal = new OpenLayers.Layer.Google("Google Normal" ,
187 { type: G_NORMAL_MAP,
188 sphericalMercator: true,
189 maxExtent: world_bound,
190 wrapDateLine: false
191 });
192
193
194 map.addLayers([mapnik, wms, google_sat, google_normal]);
195 setOpacity(0.5);
196 defaultFocus();
197
198
199 //var pois = new OpenLayers.Layer.Text( "My Points",
200 // { location:"./textfile.txt",
201 // projection: map.displayProjection
202 // });
203 //map.addLayer(pois);
204
205 //function parseKML(req) {
206 // alert(req.responseText);
207 //};
208 //alert(OpenLayers.loadURL("./kmlfile.kml", "", null, parseKML));
209
210
211 function ignoreInterlink(cluster, feature) {
212 if (isInterlink(feature)) {
213 return(false);
214 } else {
215 return strategy.shouldClusterOrig(cluster, feature); }
216 }
217
218 strategy = new OpenLayers.Strategy.Cluster();
219 strategy.shouldClusterOrig = strategy.shouldCluster;
220 strategy.shouldCluster = ignoreInterlink;
221 strategy.distance = 10;
222 strategy.threshold = 2;
223
224 //OpenLayers.Feature.Vector.style["default"]);
225
226 var symbolizer = new OpenLayers.Style({
227 externalGraphic: "${icon}",
228 pointRadius: "${radius}",
229 fillOpacity: 1,
230 }, { context : {
231 icon : function(feature) {
232 var iconStatus = "DEADCODE";
233 if(feature.cluster) {
234 for (var i = 0; i < feature.cluster.length; i++) {
235 var nodeStatus = feature.cluster[i].attributes.styleUrl.split('_')[2];
236 iconStatus = nodeStatus;
237 // If one if having issues, update the overview icon to reflect this
238 if (nodeStatus == 'unknown' || nodeStatus == 'planned' || nodeStatus == 'down') { break; }
239 }
240 } else {
241 iconStatus = feature.attributes.styleUrl.split('_')[2];
242 }
243 return nodeStatusImg[iconStatus];
244 },
245 radius : function(feature) {
246 var pix = 8;
247 if(feature.cluster) {
248 pix = pix + feature.attributes.count;
249 for (var i = 0; i < feature.cluster.length; i++) {
250 var node = feature.cluster[i];
251 }
252 }
253 return pix;
254 }
255 }
256 });
257
258 var styleMap = new OpenLayers.StyleMap({"default": symbolizer, "select": {pointRadius: 16,fillOpacity: 1}});
259
260 // Hack to get around all kind of caching fails
261 var epoch = new Date().getTime();
262 var kml = new OpenLayers.Layer.GML("KML", "./kmlfile.kml?time=" + epoch,
263 { strategies: [strategy],
264 styleMap: styleMap,
265 format: OpenLayers.Format.KML,
266 formatOptions: {
267 extractStyles: true,
268 extractAttributes: true,
269 maxDepth: 5
270 }
271 });
272 map.addLayer(kml);
273
274 function onPopupClose(evt) {
275 select.unselectAll();
276 }
277
278 function onKMLFeatureSelect(event) {
279 var feature = event.feature;
280 var content = "";
281 if (feature.cluster) {
282 for (var i = 0; i < feature.cluster.length; i++) {
283 var node = feature.cluster[i];
284 iconStatus = node.attributes.styleUrl.split('_')[2];
285 iconImg = nodeStatusImg[iconStatus];
286 content = content + "<h4><img src='" + iconImg + "' />" + node.attributes.name + "</h4>" + node.attributes.description + "<br />";
287 }
288 } else {
289 if (isInterlink(feature)) {
290 content = "<h4>" + feature.attributes.name + "</h4>" + "<br />" + "<em>Link information: " + feature.attributes.description + "</em>";
291 } else {
292 var nagiosRoot = 'http://sunfire.wirelessleiden.nl/nagios';
293 var nodeName = feature.attributes.name.split(' ')[1];
294 var nagiosUrl = nagiosRoot + "/cgi-bin/status.cgi?host=" + nodeName + "&servicestatustypes=28&hoststatustypes=15&noheader=true";
295
296 content = "Status provided by <a href='" + nagiosRoot +
297 "/'>Nagios monitoring system</a><br />" +
298 "<iframe frameborder='0' height='300px' width='700px'" +
299 "src='" + nagiosUrl + "'></iframe>" +
300 "<br />" +
301 "<em>Locatie: " + feature.attributes.description + "</em>";
302 }
303 }
304 popup = new OpenLayers.Popup.FramedCloud("chicken",
305 feature.geometry.getBounds().getCenterLonLat(),
306 new OpenLayers.Size(100,100),
307 content,
308 null, true, onPopupClose);
309 feature.popup = popup;
310 map.addPopup(popup);
311 }
312
313 function onKMLFeatureUnselect(event) {
314 var feature = event.feature;
315 if(feature.popup) {
316 map.removePopup(feature.popup);
317 feature.popup.destroy();
318 delete feature.popup;
319 }
320 }
321
322 function handleMeasurements(event) {
323 // For some reason 'delayed' events get posted even though the object
324 // is deactivated
325 if (!rulerControl.active) {
326 return;
327 }
328 var units = event.units;
329 var order = event.order;
330 var measure = event.measure;
331 var element = document.getElementById('output');
332 out = measure.toFixed(3) + " " + units;
333 if(order == 2) {
334 out += "<sup>2</" + "sup>";
335 } else {
336 }
337 element.innerHTML = out;
338 }
339
340 select = new OpenLayers.Control.SelectFeature(kml);
341 kml.events.on( {
342 "featureselected": onKMLFeatureSelect,
343 "featureunselected": onKMLFeatureUnselect
344 });
345 map.addControl(select);
346 select.activate();
347
348 clickControl = new OpenLayers.Control.Click();
349 map.addControl(clickControl);
350 clickControl.deactivate();
351
352
353 // XXX: Enable if we found some use for it somewhere
354 // var vectors = new OpenLayers.Layer.Vector("Vector Layer");
355 // map.addLayer(vectors);
356 // map.addControl(new OpenLayers.Control.EditingToolbar(vectors));
357
358 map.addControl(new OpenLayers.Control.MousePosition({ 'displayProjection' : projection_wgs }));
359 map.addControl(new OpenLayers.Control.LayerSwitcher());
360 map.addControl(new OpenLayers.Control.OverviewMap());
361 map.addControl(new OpenLayers.Control.Permalink());
362 map.addControl(new OpenLayers.Control.ScaleLine());
363 map.addControl(new OpenLayers.Control.KeyboardDefaults());
364 map.addControl(new OpenLayers.Control.ZoomBox());
365
366
367 //var in_options = {
368 // 'internalProjection': map.baseLayer.projection,
369 // 'externalProjection': new OpenLayers.Projection("EPSG:4326")
370 //};
371 //var wkt = new OpenLayers.Format.WKT(in_options);
372 //var txtFile = new XMLHttpRequest();
373 //txtFile.open("GET", "./wktfile.txt", false);
374 //// txtFile.onreadystatechange = function() {
375 //// if(txtFile.readyState == 4) {
376 //// alert(txtFile.responseText);
377 //// }
378 //// }
379 //txtFile.send(null);
380
381 //var features = wkt.read(txtFile.responseText.replace(/\n/g,''));
382 //var bounds;
383 //
384 //if (features) {
385 // if(features.constructor != Array) {
386 // features = [features];
387 // }
388 // for(var i=0; i<features.length; ++i) {
389 // if (!bounds) {
390 // bounds = features[i].geometry.getBounds();
391 // }
392 // bounds.extend(features[i].geometry.getBounds());
393 // }
394 // vectors.addFeatures(features);
395 // map.zoomToExtent(bounds);
396 //} else {
397 // alert("ERROR in WTK");
398 //}
399
400
401 // style the sketch fancy
402 var sketchSymbolizers = {
403 "Point": {
404 pointRadius: 4,
405 graphicName: "square",
406 fillColor: "white",
407 fillOpacity: 1,
408 strokeWidth: 1,
409 strokeOpacity: 1,
410 strokeColor: "#333333"
411 },
412 "Line": {
413 strokeWidth: 3,
414 strokeOpacity: 1,
415 strokeColor: "#666666",
416 strokeDashstyle: "dash"
417 },
418 "Polygon": {
419 strokeWidth: 2,
420 strokeOpacity: 1,
421 strokeColor: "#666666",
422 fillColor: "white",
423 fillOpacity: 0.3
424 }
425 };
426 var style = new OpenLayers.Style();
427 style.addRules([
428 new OpenLayers.Rule({symbolizer: sketchSymbolizers})
429 ]);
430 var rulerStyleMap = new OpenLayers.StyleMap({"default": style});
431
432 rulerControl = new OpenLayers.Control.Measure(
433 OpenLayers.Handler.Path, {
434 persist: true,
435 handlerOptions: {
436 layerOptions: {styleMap: rulerStyleMap}
437 }
438 }
439 );
440
441 rulerControl.events.on({
442 "measure": handleMeasurements,
443 "measurepartial": handleMeasurements
444 });
445 map.addControl(rulerControl);
446 } // end of init
447
448
449
450 function resize() {
451 size = new OpenLayers.Size(size.w + 10, size.h + 10);
452 icon.setSize(size);
453 }
454
455
456
457 function toggleFieldById(field) {
458 var e = document.getElementById(field);
459 if (e.style.visibility == "hidden") {
460 e.style.visibility = "visible";
461 } else {
462 e.style.visibility = "hidden";
463 }
464 }
465
466
467
468 function toggleClickControl() {
469 toggleFieldById('coordField');
470 if (!clickControl.active) {
471 clickControl.activate();
472 document.getElementById('click').src = url_pal3 + "icon32.png";
473 } else {
474 clickControl.deactivate();
475 document.getElementById('click').src = url_pal3 + "icon28.png";
476 }
477 }
478
479
480 function toggleRulerControl() {
481 if (!rulerControl.active) {
482 rulerControl.activate();
483 document.getElementById('ruler').src = "ruler_on.png";
484 } else {
485 rulerControl.deactivate();
486 document.getElementById('ruler').src = "ruler_off.png";
487 document.getElementById('output').innerHTML = "";
488 }
489 }
490
491
492
493 function defaultFocus() {
494 //XXX: Make me dynamic based on the entries in the KML file
495 map.setCenter(new OpenLayers.LonLat(4.65,52.186).transform( projection_wgs, projection_smp), 12);
496 }
497
498
499
500 function init() {
501 initMap();
502 document.getElementById('version').innerHTML = version;
503 document.getElementById('svnVersion').innerHTML = svnVersion;
504 }
505 // ]]>
506
507</script>
508
509 </head>
510 <body onload="init()">
511 <div id="basicMap">
512 <div id="controller" style="position: absolute; top: 10px; left : 80px; z-index:1004">
513 <img id="ruler" src="ruler_off.png"
514 onclick="toggleRulerControl()" alt="ruler" title="Measure distance between points"/>
515 <img height="22" src="http://maps.google.com/mapfiles/kml/pal3/icon23.png" title="Reset focus" onclick="defaultFocus()" alt="Focus reset" />
516 <img height="22"
517 src="http://maps.google.com/mapfiles/kml/pal3/icon36.png"
518 title="Information" onclick="toggleFieldById('infoField')" alt="information" />
519 <img id="click" height="22"
520 src="http://maps.google.com/mapfiles/kml/pal3/icon28.png"
521 title="Get RD coordinates for use in Genesis" onclick="toggleClickControl()"
522 alt="coordinate converter"/>
523 <div id="output"></div>
524 </div>
525 <div id="legendaField" style="position: absolute; bottom: 00px; left : 70px; z-index:1003; visibility: visible">
526 <table>
527 <tr><td>Node status</td><td>:</td><td>
528 <span style="color: red">Problem</span> -
529 <span style="color: green">OK</span> -
530 <span style="color: purple">Unknown</span> -
531 <span style="color: grey">Planned</span></td></tr>
532 <tr><td>Link status</td><td>:</td><td>
533 <span style="color: red">Problem</span> -
534 <span style="color: green">OK</span> -
535 <span style="color: purple">Unknown</span> -
536 <span style="color: grey">Planned</span></td></tr>
537 </table>
538 </div>
539 <div id="infoField" style="position: absolute; bottom: 40px; left : 10px; z-index:1004; background-color: white; visibility: hidden">
540 <ul>
541 <li>holding down shift, whilst dragging the mouse to do box zooming</li>
542 <li>Keyboard Navigation is enabled</li>
543 <li>Contrast of background: <a title="decrease opacity" href="javascript: changeOpacity(-0.1);">Decrease</a> or <a title="increase opacity" href="javascript: changeOpacity(0.1);">Increase</a></li>
544 <li>Link capacity get displayed by the thickness of the line</li>
545 <li>Link usage get displayed by the opacity of the line</li>
546 </ul>
547<p>Validated by:
548 <a href="http://validator.w3.org/check?uri=referer"><img
549 src="http://www.w3.org/Icons/valid-xhtml10" title="Valid XHTML 1.0 Strict"
550 alt="Valid XHTML 1.0 Strict" height="17" />
551 <a href="http://jslint.com"><img src="http://www.jslint.com/jslintpill.gif" title="Valid JavaScript code" alt="Valid JavaScript code" /></a>
552 <br />
553 Version: <em id='version'></em> - <em id='svnVersion'></em>
554 <br />
555 <br />
556 <small>
557 Written by Rick van der Zwet - &lt;info@rickvanderzwet.nl&gt;<br />
558 Licence: <a href="http://svn.wirelessleiden.nl/svn/LICENSE.txt">BSDlike</a><br /><br />
559 Before summitting bug reports, please look in source code to see if your
560bug is already mentioned in the poor mans bug tracker. Best way to submit a
561bug/fix (patches welcome) is by sending it to <a
562href="mailto:techniek@lijst.wiressleiden.nl?subject=Bug%20Report%20-%20Dynamic%20NodeMap">techniek@lijst.wirelessleiden.nl</a>
563or the author. </small>
564 </p>
565 </div>
566 <div id="coordField" style="position: absolute; bottom: 40px; left : 10px; z-index:1005; background-color: green; visibility: hidden">
567 Click on a location on the map to receive a link to calculate the RD coordinates: <br />
568 <a id="coordOutput" href="#" target="_blank">Click on MAP first</a>
569 </div>
570 </div>
571 </body>
572</html>
Note: See TracBrowser for help on using the repository browser.