Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/web/www/routino/visualiser.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations) (download) (as text)
Wed Dec 29 10:25:14 2010 UTC (14 years, 2 months ago) by amb
File MIME type: application/javascript
File size: 17058 byte(s)
Added the uncontrolled (not auto-generated) files from routino-1.4.

1 //
2 // Routino data visualiser web page Javascript
3 //
4 // Part of the Routino routing software.
5 //
6 // This file Copyright 2008-2010 Andrew M. Bishop
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 //
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21
22
23 //
24 // Data types
25 //
26
27 var data_types=[
28 "junctions",
29 "super",
30 "oneway",
31 "speed",
32 "weight",
33 "height",
34 "width",
35 "length"
36 ];
37
38
39 //
40 // Junction styles
41 //
42
43 var junction_colours={
44 0: "#FFFFFF",
45 1: "#FF0000",
46 2: "#FFFF00",
47 3: "#00FF00",
48 4: "#8B4513",
49 5: "#00BFFF",
50 6: "#FF69B4",
51 7: "#000000",
52 8: "#000000",
53 9: "#000000"
54 };
55
56 var junction_styles={};
57
58
59 //
60 // Super styles
61 //
62
63 var super_node_style,super_segment_style;
64
65
66 //
67 // Oneway styles
68 //
69
70 var hex={0: "00", 1: "11", 2: "22", 3: "33", 4: "44", 5: "55", 6: "66", 7: "77",
71 8: "88", 9: "99", 10: "AA", 11: "BB", 12: "CC", 13: "DD", 14: "EE", 15: "FF"};
72
73
74 ////////////////////////////////////////////////////////////////////////////////
75 ///////////////////////////////// Map handling /////////////////////////////////
76 ////////////////////////////////////////////////////////////////////////////////
77
78 var map;
79 var layerMapOSM, layerVectors, layerBoxes;
80 var epsg4326, epsg900913;
81 var map_args;
82
83 var box;
84
85 //
86 // Initialise the 'map' object
87 //
88
89 function map_init(lat,lon,zoom)
90 {
91 // Default configuration:
92 // UK coordinate range
93 // West -11.0, South 49.5, East 2.0, North 61.0
94 // Zoom level 4 to 15
95
96 // EDIT THIS below to change the visible map limits
97
98 var westedge = -11.0; // Minimum longitude (degrees)
99 var eastedge = 2.0; // Maximum longitude (degrees)
100 var southedge = 49.5; // Minimum latitude (degrees)
101 var northedge = 61.0; // Maximum latitude (degrees)
102 var zoomout = 4; // Minimum zoom
103 var zoomin = 15; // Maximum zoom
104
105 // EDIT THIS above to change the visible map limits
106
107 //
108 // Create the map
109 //
110
111 epsg4326=new OpenLayers.Projection("EPSG:4326");
112 epsg900913=new OpenLayers.Projection("EPSG:900913");
113
114 map = new OpenLayers.Map ("map",
115 {
116 controls:[
117 new OpenLayers.Control.Navigation(),
118 new OpenLayers.Control.PanZoomBar(),
119 new OpenLayers.Control.ScaleLine(),
120 new OpenLayers.Control.LayerSwitcher()
121 ],
122
123 projection: epsg900913,
124 displayProjection: epsg4326,
125
126 minZoomLevel: zoomout,
127 numZoomLevels: zoomin-zoomout+1,
128 maxResolution: 156543.0339 / Math.pow(2,zoomout),
129
130 maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
131 restrictedExtent: new OpenLayers.Bounds(westedge,southedge,eastedge,northedge).transform(epsg4326,epsg900913),
132
133 units: "m"
134 });
135
136 map.events.register("moveend", map, mapMoved);
137
138 // Add a map tile layer (OpenStreetMap tiles, direct access)
139
140 layerMapOSM = new OpenLayers.Layer.TMS("Original OSM map",
141 "http://tile.openstreetmap.org/",
142 {
143 emptyUrl: "http://openstreetmap.org/openlayers/img/404.png",
144 type: 'png',
145 getURL: limitedUrl,
146 displayOutsideMaxExtent: true,
147 buffer: 1
148 });
149 map.addLayer(layerMapOSM);
150
151 // Get a URL for the tile; limited to map restricted extent.
152
153 function limitedUrl(bounds)
154 {
155 var z = map.getZoom() + map.minZoomLevel;
156
157 if (z>=7 && (bounds.right < map.restrictedExtent.left ||
158 bounds.left > map.restrictedExtent.right ||
159 bounds.top < map.restrictedExtent.bottom ||
160 bounds.bottom > map.restrictedExtent.top))
161 return this.emptyUrl;
162
163 var res = map.getResolution();
164 var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
165 var limit = Math.pow(2, z);
166
167 if (y < 0 || y >= limit)
168 return this.emptyUrl;
169
170 var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
171
172 x = ((x % limit) + limit) % limit;
173 return this.url + z + "/" + x + "/" + y + "." + this.type;
174 }
175
176 // Add a vectors layer
177
178 layerVectors = new OpenLayers.Layer.Vector("Markers");
179 map.addLayer(layerVectors);
180
181 for(var colour in junction_colours)
182 junction_styles[colour]=new OpenLayers.Style({},{stroke: false, pointRadius: 2,fillColor: junction_colours[colour]});
183
184 super_node_style =new OpenLayers.Style({},{stroke: false, pointRadius: 3,fillColor : "#FF0000"});
185 super_segment_style=new OpenLayers.Style({},{fill: false , strokeWidth: 2,strokeColor: "#FF0000"});
186
187 // Add a boxes layer
188
189 layerBoxes = new OpenLayers.Layer.Boxes("Boundary");
190 map.addLayer(layerBoxes);
191
192 box=null;
193
194 // Set the map centre to the limited range specified
195
196 map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true));
197 map.maxResolution = map.getResolution();
198
199 // Move the map
200
201 if(lon != 'lon' && lat != 'lat' && zoom != 'zoom')
202 {
203 var lonlat = new OpenLayers.LonLat(lon,lat).transform(epsg4326,map.getProjectionObject());
204
205 map.moveTo(lonlat,zoom-map.minZoomLevel);
206 }
207 }
208
209
210 //
211 // Map has moved
212 //
213
214 function mapMoved()
215 {
216 var centre = map.getCenter().clone();
217
218 var lonlat = centre.transform(map.getProjectionObject(),epsg4326);
219
220 var zoom = this.getZoom() + map.minZoomLevel;
221
222 map_args="lat=" + lonlat.lat + ";lon=" + lonlat.lon + ";zoom=" + zoom;
223
224 updateCustomURL();
225 }
226
227
228 //
229 // Update custom URL
230 //
231
232 function updateCustomURL()
233 {
234 var router_url=document.getElementById("router_url");
235 var link_url =document.getElementById("link_url");
236 var edit_url =document.getElementById("edit_url");
237
238 router_url.href="customrouter.cgi?" + map_args;
239 link_url.href="customvisualiser.cgi?" + map_args;
240 edit_url.href="http://www.openstreetmap.org/edit?" + map_args;
241 }
242
243
244 ////////////////////////////////////////////////////////////////////////////////
245 /////////////////////////////// Server handling ////////////////////////////////
246 ////////////////////////////////////////////////////////////////////////////////
247
248 //
249 // Display data statistics
250 //
251
252 function displayStatistics()
253 {
254 // Use AJAX to get the statistics
255
256 OpenLayers.loadURL("statistics.cgi",null,null,runStatisticsSuccess);
257 }
258
259
260 //
261 // Success in running data statistics generation.
262 //
263
264 function runStatisticsSuccess(response)
265 {
266 var statistics_data=document.getElementById("statistics_data");
267 var statistics_link=document.getElementById("statistics_link");
268
269 statistics_data.innerHTML="<pre>" + response.responseText + "</pre>";
270
271 statistics_link.style.display="none";
272 }
273
274
275 //
276 // Get the requested data
277 //
278
279 function displayData(datatype)
280 {
281 for(var data in data_types)
282 hideshow_hide(data_types[data]);
283
284 if(datatype != "")
285 hideshow_show(datatype);
286
287 // Delete the old data
288
289 layerVectors.destroyFeatures();
290
291 if(box != null)
292 layerBoxes.removeMarker(box);
293 box=null;
294
295 // Print the status
296
297 var div_status=document.getElementById("result_status");
298 div_status.innerHTML = "No data displayed";
299
300 // Return if just here to clear the data
301
302 if(datatype == "")
303 return;
304
305 // Get the new data
306
307 var mapbounds=map.getExtent().clone();
308 mapbounds.transform(epsg900913,epsg4326);
309
310 var url="visualiser.cgi";
311
312 url=url + "?lonmin=" + mapbounds.left;
313 url=url + ";latmin=" + mapbounds.bottom;
314 url=url + ";lonmax=" + mapbounds.right;
315 url=url + ";latmax=" + mapbounds.top;
316 url=url + ";data=" + datatype;
317
318 // Print the status
319
320 div_status.innerHTML = "Fetching " + datatype + " data ...";
321
322 // Use AJAX to get the data
323
324 switch(datatype)
325 {
326 case 'junctions':
327 OpenLayers.loadURL(url,null,null,runJunctionsSuccess,runFailure);
328 break;
329 case 'super':
330 OpenLayers.loadURL(url,null,null,runSuperSuccess,runFailure);
331 break;
332 case 'oneway':
333 OpenLayers.loadURL(url,null,null,runOnewaySuccess,runFailure);
334 break;
335 case 'speed':
336 case 'weight':
337 case 'height':
338 case 'width':
339 case 'length':
340 OpenLayers.loadURL(url,null,null,runLimitSuccess,runFailure);
341 break;
342 }
343 }
344
345
346 //
347 // Success in getting the junctions.
348 //
349
350 function runJunctionsSuccess(response)
351 {
352 var lines=response.responseText.split('\n');
353
354 // This won't update the browser window
355 // var div_status=document.getElementById("result_status");
356 // div_status.innerHTML = "Processing " + (lines.length-2) + " junctions ...";
357
358 var features=[];
359
360 for(var line=0;line<lines.length;line++)
361 {
362 var words=lines[line].split(' ');
363
364 if(line == 0)
365 {
366 var lat1=words[0];
367 var lon1=words[1];
368 var lat2=words[2];
369 var lon2=words[3];
370
371 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
372
373 box = new OpenLayers.Marker.Box(bounds);
374
375 layerBoxes.addMarker(box);
376 }
377 else if(words[0] != "")
378 {
379 var lat=words[0];
380 var lon=words[1];
381 var count=words[2];
382
383 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
384
385 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
386
387 features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[count]));
388 }
389 }
390
391 layerVectors.addFeatures(features);
392
393 var div_status=document.getElementById("result_status");
394 div_status.innerHTML = "Processed " + (lines.length-2) + " junctions";
395 }
396
397
398 //
399 // Success in getting the super-node and super-segments
400 //
401
402 function runSuperSuccess(response)
403 {
404 var lines=response.responseText.split('\n');
405
406 // This won't update the browser window
407 // var div_status=document.getElementById("result_status");
408 // div_status.innerHTML = "Processing " + (lines.length-2) + " super-nodes/segments ...";
409
410 var features=[];
411
412 var nodepoint;
413
414 for(var line=0;line<lines.length;line++)
415 {
416 var words=lines[line].split(' ');
417
418 if(line == 0)
419 {
420 var lat1=words[0];
421 var lon1=words[1];
422 var lat2=words[2];
423 var lon2=words[3];
424
425 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
426
427 box = new OpenLayers.Marker.Box(bounds);
428
429 layerBoxes.addMarker(box);
430 }
431 else if(words[0] != "")
432 {
433 var lat=words[0];
434 var lon=words[1];
435 var type=words[2];
436
437 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
438
439 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
440
441 if(type == "n")
442 {
443 nodepoint=point;
444
445 features.push(new OpenLayers.Feature.Vector(point,{},super_node_style));
446 }
447 else
448 {
449 var segment = new OpenLayers.Geometry.LineString([nodepoint,point]);
450
451 features.push(new OpenLayers.Feature.Vector(segment,{},super_segment_style));
452 }
453 }
454 }
455
456 layerVectors.addFeatures(features);
457
458 var div_status=document.getElementById("result_status");
459 div_status.innerHTML = "Processed " + (lines.length-2) + " super-nodes/segments";
460 }
461
462
463 //
464 // Success in getting the oneway data
465 //
466
467 function runOnewaySuccess(response)
468 {
469 var lines=response.responseText.split('\n');
470
471 // This won't update the browser window
472 // var div_status=document.getElementById("result_status");
473 // div_status.innerHTML = "Processing " + (lines.length-2) + " oneway segments ...";
474
475 var features=[];
476
477 for(var line=0;line<lines.length;line++)
478 {
479 var words=lines[line].split(' ');
480
481 if(line == 0)
482 {
483 var lat1=words[0];
484 var lon1=words[1];
485 var lat2=words[2];
486 var lon2=words[3];
487
488 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
489
490 box = new OpenLayers.Marker.Box(bounds);
491
492 layerBoxes.addMarker(box);
493 }
494 else if(words[0] != "")
495 {
496 var lat1=words[0];
497 var lon1=words[1];
498 var lat2=words[2];
499 var lon2=words[3];
500
501 var lonlat1= new OpenLayers.LonLat(lon1,lat1).transform(epsg4326,epsg900913);
502 var lonlat2= new OpenLayers.LonLat(lon2,lat2).transform(epsg4326,epsg900913);
503
504 //var point1 = new OpenLayers.Geometry.Point(lonlat1.lon,lonlat1.lat);
505 var point2 = new OpenLayers.Geometry.Point(lonlat2.lon,lonlat2.lat);
506
507 var dlat = lonlat2.lat-lonlat1.lat;
508 var dlon = lonlat2.lon-lonlat1.lon;
509 var dist = Math.sqrt(dlat*dlat+dlon*dlon)/10;
510 var ang = Math.atan2(dlat,dlon);
511
512 var point3 = new OpenLayers.Geometry.Point(lonlat1.lon+dlat/dist,lonlat1.lat-dlon/dist);
513 var point4 = new OpenLayers.Geometry.Point(lonlat1.lon-dlat/dist,lonlat1.lat+dlon/dist);
514
515 var segment = new OpenLayers.Geometry.LineString([point2,point3,point4,point2]);
516
517 var r=Math.round(7.5+7.9*Math.cos(ang));
518 var g=Math.round(7.5+7.9*Math.cos(ang+2.0943951));
519 var b=Math.round(7.5+7.9*Math.cos(ang-2.0943951));
520 var colour = "#" + hex[r] + hex[g] + hex[b];
521
522 var style=new OpenLayers.Style({},{strokeWidth: 2,strokeColor: colour});
523
524 features.push(new OpenLayers.Feature.Vector(segment,{},style));
525 }
526 }
527
528 layerVectors.addFeatures(features);
529
530 var div_status=document.getElementById("result_status");
531 div_status.innerHTML = "Processed " + (lines.length-2) + " oneway segments";
532 }
533
534
535 //
536 // Success in getting the speed/weight/height/width/length limits
537 //
538
539 function runLimitSuccess(response)
540 {
541 var lines=response.responseText.split('\n');
542
543 // This won't update the browser window
544 // var div_status=document.getElementById("result_status");
545 // div_status.innerHTML = "Processing " + (lines.length-2) + " limits ...";
546
547 var features=[];
548
549 var nodelonlat;
550
551 for(var line=0;line<lines.length;line++)
552 {
553 var words=lines[line].split(' ');
554
555 if(line == 0)
556 {
557 var lat1=words[0];
558 var lon1=words[1];
559 var lat2=words[2];
560 var lon2=words[3];
561
562 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
563
564 box = new OpenLayers.Marker.Box(bounds);
565
566 layerBoxes.addMarker(box);
567 }
568 else if(words[0] != "")
569 {
570 var lat=words[0];
571 var lon=words[1];
572 var number=words[2];
573
574 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
575
576 if(number == undefined)
577 {
578 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
579
580 nodelonlat=lonlat;
581
582 features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[1]));
583 }
584 else
585 {
586 var dlat = lonlat.lat-nodelonlat.lat;
587 var dlon = lonlat.lon-nodelonlat.lon;
588 var dist = Math.sqrt(dlat*dlat+dlon*dlon)/60;
589
590 var point = new OpenLayers.Geometry.Point(nodelonlat.lon+dlon/dist,nodelonlat.lat+dlat/dist);
591
592 features.push(new OpenLayers.Feature.Vector(point,{},
593 new OpenLayers.Style({},{externalGraphic: 'icons/limit-' + number + '.png',
594 graphicYOffset: -9,
595 graphicWidth: 19,
596 graphicHeight: 19})));
597 }
598 }
599 }
600
601 layerVectors.addFeatures(features);
602
603 var div_status=document.getElementById("result_status");
604 div_status.innerHTML = "Processed " + (lines.length-2) + " limits";
605 }
606
607
608 //
609 // Failure in getting data.
610 //
611
612 function runFailure(response)
613 {
614 var div_status=document.getElementById("result_status");
615 div_status.innerHTML = "Failed to get visualiser data!";
616
617 window.alert("Failed to get visualiser data!\n" + response.statusText);
618 }