Routino SVN Repository Browser

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

ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 985 - (hide annotations) (download) (as text)
Sat Mar 24 13:53:53 2012 UTC (13 years ago) by amb
File MIME type: application/javascript
File size: 18968 byte(s)
Process the URL query string in the Javascript not in custom*.cgi.
Refactor a lot of the code for coordinate handling.
Simplify custom*.cgi so that they just redirect to the HTML page (will be
removed in later versions - for existing link compatibility only).

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