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 936 - (show annotations) (download) (as text)
Thu Dec 8 19:37:44 2011 UTC (13 years, 3 months ago) by amb
File MIME type: application/javascript
File size: 18043 byte(s)
Move semi-constant strings from the JavaScript to the HTML so that they can be
translated.

1 //
2 // Routino data visualiser web page Javascript
3 //
4 // Part of the Routino routing software.
5 //
6 // This file Copyright 2008-2011 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 "turns",
32 "speed",
33 "weight",
34 "height",
35 "width",
36 "length"
37 ];
38
39
40 //
41 // Junction styles
42 //
43
44 var junction_colours={
45 0: "#FFFFFF",
46 1: "#FF0000",
47 2: "#FFFF00",
48 3: "#00FF00",
49 4: "#8B4513",
50 5: "#00BFFF",
51 6: "#FF69B4",
52 7: "#000000",
53 8: "#000000",
54 9: "#000000"
55 };
56
57 var junction_styles={};
58
59
60 //
61 // Super styles
62 //
63
64 var super_node_style,super_segment_style;
65
66
67 //
68 // Oneway and turn restriction styles
69 //
70
71 var hex={0: "00", 1: "11", 2: "22", 3: "33", 4: "44", 5: "55", 6: "66", 7: "77",
72 8: "88", 9: "99", 10: "AA", 11: "BB", 12: "CC", 13: "DD", 14: "EE", 15: "FF"};
73
74 var turn_restriction_style;
75
76
77 ////////////////////////////////////////////////////////////////////////////////
78 ///////////////////////////////// Map handling /////////////////////////////////
79 ////////////////////////////////////////////////////////////////////////////////
80
81 var map;
82 var layerMap=[], layerVectors, layerBoxes;
83 var epsg4326, epsg900913;
84 var map_args;
85
86 var box;
87
88 //
89 // Initialise the 'map' object
90 //
91
92 function map_init(lat,lon,zoom)
93 {
94 // Map properties (North/South and East/West limits and zoom in/out limits) are now in mapprops.js
95 // Map URLs are now in mapprops.js
96
97 //
98 // Create the map
99 //
100
101 epsg4326=new OpenLayers.Projection("EPSG:4326");
102 epsg900913=new OpenLayers.Projection("EPSG:900913");
103
104 map = new OpenLayers.Map ("map",
105 {
106 controls:[
107 new OpenLayers.Control.Navigation(),
108 new OpenLayers.Control.PanZoomBar(),
109 new OpenLayers.Control.ScaleLine(),
110 new OpenLayers.Control.LayerSwitcher()
111 ],
112
113 projection: epsg900913,
114 displayProjection: epsg4326,
115
116 minZoomLevel: mapprops.zoomout,
117 numZoomLevels: mapprops.zoomin-mapprops.zoomout+1,
118 maxResolution: 156543.0339 / Math.pow(2,mapprops.zoomout),
119
120 maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
121 restrictedExtent: new OpenLayers.Bounds(mapprops.westedge,mapprops.southedge,mapprops.eastedge,mapprops.northedge).transform(epsg4326,epsg900913),
122
123 units: "m"
124 });
125
126 map.events.register("moveend", map, mapMoved);
127
128 // Add map tile layers
129
130 for(var l=0;l < mapprops.mapdata.length;l++)
131 {
132 layerMap[l] = new OpenLayers.Layer.TMS(mapprops.mapdata[l].label,
133 mapprops.mapdata[l].baseurl,
134 {
135 emptyUrl: mapprops.mapdata[l].errorurl,
136 type: 'png',
137 getURL: limitedUrl,
138 displayOutsideMaxExtent: true,
139 buffer: 1
140 });
141 map.addLayer(layerMap[l]);
142 }
143
144 // Get a URL for the tile; limited to map restricted extent.
145
146 function limitedUrl(bounds)
147 {
148 var z = map.getZoom() + map.minZoomLevel;
149
150 if (z>=7 && (bounds.right < map.restrictedExtent.left ||
151 bounds.left > map.restrictedExtent.right ||
152 bounds.top < map.restrictedExtent.bottom ||
153 bounds.bottom > map.restrictedExtent.top))
154 return this.emptyUrl;
155
156 var res = map.getResolution();
157 var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
158 var limit = Math.pow(2, z);
159
160 if (y < 0 || y >= limit)
161 return this.emptyUrl;
162
163 var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
164
165 x = ((x % limit) + limit) % limit;
166 return this.url + z + "/" + x + "/" + y + "." + this.type;
167 }
168
169 // Add a vectors layer
170
171 layerVectors = new OpenLayers.Layer.Vector("Markers");
172 map.addLayer(layerVectors);
173
174 for(var colour in junction_colours)
175 junction_styles[colour]=new OpenLayers.Style({},{stroke: false, pointRadius: 2,fillColor: junction_colours[colour]});
176
177 super_node_style =new OpenLayers.Style({},{stroke: false, pointRadius: 3,fillColor : "#FF0000"});
178 super_segment_style=new OpenLayers.Style({},{fill: false , strokeWidth: 2,strokeColor: "#FF0000"});
179
180 turn_restriction_style=new OpenLayers.Style({},{fill: false, strokeWidth: 2,strokeColor: "#FF0000"});
181
182 // Add a boxes layer
183
184 layerBoxes = new OpenLayers.Layer.Boxes("Boundary");
185 map.addLayer(layerBoxes);
186
187 box=null;
188
189 // Set the map centre to the limited range specified
190
191 map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true));
192 map.maxResolution = map.getResolution();
193
194 // Move the map
195
196 if(lon != 'lon' && lat != 'lat' && zoom != 'zoom')
197 {
198 if(lon<mapprops.westedge) lon=mapprops.westedge;
199 if(lon>mapprops.eastedge) lon=mapprops.eastedge;
200
201 if(lat<mapprops.southedge) lat=mapprops.southedge;
202 if(lat>mapprops.northedge) lat=mapprops.northedge;
203
204 if(zoom<mapprops.zoomout) zoom=mapprops.zoomout;
205 if(zoom>mapprops.zoomin) zoom=mapprops.zoomin;
206
207 var lonlat = new OpenLayers.LonLat(lon,lat).transform(epsg4326,map.getProjectionObject());
208
209 map.moveTo(lonlat,zoom-map.minZoomLevel);
210 }
211 }
212
213
214 //
215 // Map has moved
216 //
217
218 function mapMoved()
219 {
220 var centre = map.getCenter().clone();
221
222 var lonlat = centre.transform(map.getProjectionObject(),epsg4326);
223
224 var zoom = this.getZoom() + map.minZoomLevel;
225
226 map_args="lat=" + lonlat.lat + ";lon=" + lonlat.lon + ";zoom=" + zoom;
227
228 updateCustomURL();
229 }
230
231
232 //
233 // Update custom URL
234 //
235
236 function updateCustomURL()
237 {
238 var router_url=document.getElementById("router_url");
239 var link_url =document.getElementById("link_url");
240 var edit_url =document.getElementById("edit_url");
241
242 router_url.href="customrouter.cgi?" + map_args;
243 link_url.href="customvisualiser.cgi?" + map_args;
244 edit_url.href="http://www.openstreetmap.org/edit?" + map_args;
245 }
246
247
248 ////////////////////////////////////////////////////////////////////////////////
249 /////////////////////////////// Server handling ////////////////////////////////
250 ////////////////////////////////////////////////////////////////////////////////
251
252 //
253 // Display the status
254 //
255
256 function displayStatus(type,subtype,content)
257 {
258 var div_status=document.getElementById("result_status");
259
260 var child=div_status.firstChild;
261
262 do
263 {
264 if(child.id != undefined)
265 child.style.display="none";
266
267 child=child.nextSibling;
268 }
269 while(child != undefined);
270
271 var chosen_status=document.getElementById("result_status_" + type);
272
273 chosen_status.style.display="";
274
275 if(subtype != null)
276 {
277 var format_status=document.getElementById("result_status_" + subtype).innerHTML;
278
279 chosen_status.innerHTML=format_status.replace('#',String(content));
280 }
281 }
282
283
284 //
285 // Display data statistics
286 //
287
288 function displayStatistics()
289 {
290 // Use AJAX to get the statistics
291
292 OpenLayers.loadURL("statistics.cgi",null,null,runStatisticsSuccess);
293 }
294
295
296 //
297 // Success in running data statistics generation.
298 //
299
300 function runStatisticsSuccess(response)
301 {
302 var statistics_data=document.getElementById("statistics_data");
303 var statistics_link=document.getElementById("statistics_link");
304
305 statistics_data.innerHTML="<pre>" + response.responseText + "</pre>";
306
307 statistics_link.style.display="none";
308 }
309
310
311 //
312 // Get the requested data
313 //
314
315 function displayData(datatype)
316 {
317 for(var data in data_types)
318 hideshow_hide(data_types[data]);
319
320 if(datatype != "")
321 hideshow_show(datatype);
322
323 // Delete the old data
324
325 layerVectors.destroyFeatures();
326
327 if(box != null)
328 layerBoxes.removeMarker(box);
329 box=null;
330
331 // Print the status
332
333 displayStatus("no_data");
334
335 // Return if just here to clear the data
336
337 if(datatype == "")
338 return;
339
340 // Get the new data
341
342 var mapbounds=map.getExtent().clone();
343 mapbounds.transform(epsg900913,epsg4326);
344
345 var url="visualiser.cgi";
346
347 url=url + "?lonmin=" + mapbounds.left;
348 url=url + ";latmin=" + mapbounds.bottom;
349 url=url + ";lonmax=" + mapbounds.right;
350 url=url + ";latmax=" + mapbounds.top;
351 url=url + ";data=" + datatype;
352
353 // Use AJAX to get the data
354
355 switch(datatype)
356 {
357 case 'junctions':
358 OpenLayers.loadURL(url,null,null,runJunctionsSuccess,runFailure);
359 break;
360 case 'super':
361 OpenLayers.loadURL(url,null,null,runSuperSuccess,runFailure);
362 break;
363 case 'oneway':
364 OpenLayers.loadURL(url,null,null,runOnewaySuccess,runFailure);
365 break;
366 case 'turns':
367 OpenLayers.loadURL(url,null,null,runTurnsSuccess,runFailure);
368 break;
369 case 'speed':
370 case 'weight':
371 case 'height':
372 case 'width':
373 case 'length':
374 OpenLayers.loadURL(url,null,null,runLimitSuccess,runFailure);
375 break;
376 }
377 }
378
379
380 //
381 // Success in getting the junctions.
382 //
383
384 function runJunctionsSuccess(response)
385 {
386 var lines=response.responseText.split('\n');
387
388 var features=[];
389
390 for(var line=0;line<lines.length;line++)
391 {
392 var words=lines[line].split(' ');
393
394 if(line == 0)
395 {
396 var lat1=words[0];
397 var lon1=words[1];
398 var lat2=words[2];
399 var lon2=words[3];
400
401 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
402
403 box = new OpenLayers.Marker.Box(bounds);
404
405 layerBoxes.addMarker(box);
406 }
407 else if(words[0] != "")
408 {
409 var lat=words[0];
410 var lon=words[1];
411 var count=words[2];
412
413 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
414
415 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
416
417 features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[count]));
418 }
419 }
420
421 layerVectors.addFeatures(features);
422
423 displayStatus("data","junctions",lines.length-2);
424 }
425
426
427 //
428 // Success in getting the super-node and super-segments
429 //
430
431 function runSuperSuccess(response)
432 {
433 var lines=response.responseText.split('\n');
434
435 var features=[];
436
437 var nodepoint;
438
439 for(var line=0;line<lines.length;line++)
440 {
441 var words=lines[line].split(' ');
442
443 if(line == 0)
444 {
445 var lat1=words[0];
446 var lon1=words[1];
447 var lat2=words[2];
448 var lon2=words[3];
449
450 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
451
452 box = new OpenLayers.Marker.Box(bounds);
453
454 layerBoxes.addMarker(box);
455 }
456 else if(words[0] != "")
457 {
458 var lat=words[0];
459 var lon=words[1];
460 var type=words[2];
461
462 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
463
464 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
465
466 if(type == "n")
467 {
468 nodepoint=point;
469
470 features.push(new OpenLayers.Feature.Vector(point,{},super_node_style));
471 }
472 else
473 {
474 var segment = new OpenLayers.Geometry.LineString([nodepoint,point]);
475
476 features.push(new OpenLayers.Feature.Vector(segment,{},super_segment_style));
477 }
478 }
479 }
480
481 layerVectors.addFeatures(features);
482
483 displayStatus("data","super",lines.length-2);
484 }
485
486
487 //
488 // Success in getting the oneway data
489 //
490
491 function runOnewaySuccess(response)
492 {
493 var lines=response.responseText.split('\n');
494
495 var features=[];
496
497 for(var line=0;line<lines.length;line++)
498 {
499 var words=lines[line].split(' ');
500
501 if(line == 0)
502 {
503 var lat1=words[0];
504 var lon1=words[1];
505 var lat2=words[2];
506 var lon2=words[3];
507
508 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
509
510 box = new OpenLayers.Marker.Box(bounds);
511
512 layerBoxes.addMarker(box);
513 }
514 else if(words[0] != "")
515 {
516 var lat1=words[0];
517 var lon1=words[1];
518 var lat2=words[2];
519 var lon2=words[3];
520
521 var lonlat1= new OpenLayers.LonLat(lon1,lat1).transform(epsg4326,epsg900913);
522 var lonlat2= new OpenLayers.LonLat(lon2,lat2).transform(epsg4326,epsg900913);
523
524 //var point1 = new OpenLayers.Geometry.Point(lonlat1.lon,lonlat1.lat);
525 var point2 = new OpenLayers.Geometry.Point(lonlat2.lon,lonlat2.lat);
526
527 var dlat = lonlat2.lat-lonlat1.lat;
528 var dlon = lonlat2.lon-lonlat1.lon;
529 var dist = Math.sqrt(dlat*dlat+dlon*dlon)/10;
530 var ang = Math.atan2(dlat,dlon);
531
532 var point3 = new OpenLayers.Geometry.Point(lonlat1.lon+dlat/dist,lonlat1.lat-dlon/dist);
533 var point4 = new OpenLayers.Geometry.Point(lonlat1.lon-dlat/dist,lonlat1.lat+dlon/dist);
534
535 var segment = new OpenLayers.Geometry.LineString([point2,point3,point4,point2]);
536
537 var r=Math.round(7.5+7.9*Math.cos(ang));
538 var g=Math.round(7.5+7.9*Math.cos(ang+2.0943951));
539 var b=Math.round(7.5+7.9*Math.cos(ang-2.0943951));
540 var colour = "#" + hex[r] + hex[g] + hex[b];
541
542 var style=new OpenLayers.Style({},{strokeWidth: 2,strokeColor: colour});
543
544 features.push(new OpenLayers.Feature.Vector(segment,{},style));
545 }
546 }
547
548 layerVectors.addFeatures(features);
549
550 displayStatus("data","oneway",lines.length-2);
551 }
552
553
554 //
555 // Success in getting the turn restrictions data
556 //
557
558 function runTurnsSuccess(response)
559 {
560 var lines=response.responseText.split('\n');
561
562 var features=[];
563
564 for(var line=0;line<lines.length;line++)
565 {
566 var words=lines[line].split(' ');
567
568 if(line == 0)
569 {
570 var lat1=words[0];
571 var lon1=words[1];
572 var lat2=words[2];
573 var lon2=words[3];
574
575 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
576
577 box = new OpenLayers.Marker.Box(bounds);
578
579 layerBoxes.addMarker(box);
580 }
581 else if(words[0] != "")
582 {
583 var lat1=words[0];
584 var lon1=words[1];
585 var lat2=words[2];
586 var lon2=words[3];
587 var lat3=words[4];
588 var lon3=words[5];
589
590 var lonlat1= new OpenLayers.LonLat(lon1,lat1).transform(epsg4326,epsg900913);
591 var lonlat2= new OpenLayers.LonLat(lon2,lat2).transform(epsg4326,epsg900913);
592 var lonlat3= new OpenLayers.LonLat(lon3,lat3).transform(epsg4326,epsg900913);
593
594 var point1 = new OpenLayers.Geometry.Point(lonlat1.lon,lonlat1.lat);
595 var point2 = new OpenLayers.Geometry.Point(lonlat2.lon,lonlat2.lat);
596 var point3 = new OpenLayers.Geometry.Point(lonlat3.lon,lonlat3.lat);
597
598 var segments = new OpenLayers.Geometry.LineString([point1,point2,point3]);
599
600 features.push(new OpenLayers.Feature.Vector(segments,{},turn_restriction_style));
601 }
602 }
603
604 layerVectors.addFeatures(features);
605
606 displayStatus("data","turns",lines.length-2);
607 }
608
609
610 //
611 // Success in getting the speed/weight/height/width/length limits
612 //
613
614 function runLimitSuccess(response)
615 {
616 var lines=response.responseText.split('\n');
617
618 var features=[];
619
620 var nodelonlat;
621
622 for(var line=0;line<lines.length;line++)
623 {
624 var words=lines[line].split(' ');
625
626 if(line == 0)
627 {
628 var lat1=words[0];
629 var lon1=words[1];
630 var lat2=words[2];
631 var lon2=words[3];
632
633 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
634
635 box = new OpenLayers.Marker.Box(bounds);
636
637 layerBoxes.addMarker(box);
638 }
639 else if(words[0] != "")
640 {
641 var lat=words[0];
642 var lon=words[1];
643 var number=words[2];
644
645 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
646
647 if(number == undefined)
648 {
649 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
650
651 nodelonlat=lonlat;
652
653 features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[1]));
654 }
655 else
656 {
657 var dlat = lonlat.lat-nodelonlat.lat;
658 var dlon = lonlat.lon-nodelonlat.lon;
659 var dist = Math.sqrt(dlat*dlat+dlon*dlon)/60;
660
661 var point = new OpenLayers.Geometry.Point(nodelonlat.lon+dlon/dist,nodelonlat.lat+dlat/dist);
662
663 features.push(new OpenLayers.Feature.Vector(point,{},
664 new OpenLayers.Style({},{externalGraphic: 'icons/limit-' + number + '.png',
665 graphicYOffset: -9,
666 graphicWidth: 19,
667 graphicHeight: 19})));
668 }
669 }
670 }
671
672 layerVectors.addFeatures(features);
673
674 displayStatus("data","limit",lines.length-2);
675 }
676
677
678 //
679 // Failure in getting data.
680 //
681
682 function runFailure(response)
683 {
684 displayStatus("error");
685 }