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/router.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 936 - (hide 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: 36348 byte(s)
Move semi-constant strings from the JavaScript to the HTML so that they can be
translated.

1 amb 569 //
2     // Routino router web page Javascript
3     //
4     // Part of the Routino routing software.
5     //
6 amb 622 // This file Copyright 2008-2011 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 amb 574
23 amb 577 // Make a deep copy of the routino profile.
24 amb 569
25 amb 577 var routino_default={};
26     for(var l1 in routino)
27     if(typeof(routino[l1])!='object')
28     routino_default[l1]=routino[l1];
29     else
30     {
31     routino_default[l1]={};
32     for(var l2 in routino[l1])
33     if(typeof(routino[l1][l2])!='object')
34     routino_default[l1][l2]=Number(routino[l1][l2]);
35     else
36     {
37     routino_default[l1][l2]={};
38     for(var l3 in routino[l1][l2])
39     routino_default[l1][l2][l3]=Number(routino[l1][l2][l3]);
40     }
41     }
42    
43    
44     ////////////////////////////////////////////////////////////////////////////////
45     //////////////////////////////// Form handling /////////////////////////////////
46     ////////////////////////////////////////////////////////////////////////////////
47    
48 amb 569 //
49     // Form initialisation - fill in the uninitialised parts
50     //
51    
52     function form_init()
53     {
54 amb 577 // Update the routino variable with the URL settings (from the HTML).
55 amb 569
56 amb 577 for(var lang=0;lang< document.forms["form"].elements["language"].length;lang++)
57     if(document.forms["form"].elements["language"][lang].checked)
58     formSetLanguage(document.forms["form"].elements["language"][lang].value);
59 amb 569
60 amb 577 var transport=null;
61    
62     for(var key in routino.transports)
63     if(document.forms["form"].elements["transport"][routino.transports[key]-1].checked)
64     transport=key;
65    
66     if(transport==null)
67     formSetTransport(routino.transport);
68 amb 569 else
69     {
70 amb 577 routino.transport=transport;
71    
72     for(var key in routino.profile_highway)
73 amb 569 {
74     if(document.forms["form"].elements["highway-" + key].value=="")
75 amb 577 document.forms["form"].elements["highway-" + key].value=routino.profile_highway[key][routino.transport];
76 amb 569 else
77     formSetHighway(key);
78     }
79    
80 amb 577 for(var key in routino.profile_speed)
81 amb 569 {
82     if(document.forms["form"].elements["speed-" + key].value=="")
83 amb 577 document.forms["form"].elements["speed-" + key].value=routino.profile_speed[key][routino.transport];
84 amb 569 else
85     formSetSpeed(key);
86     }
87    
88 amb 577 for(var key in routino.profile_property)
89 amb 574 {
90     if(document.forms["form"].elements["property-" + key].value=="")
91 amb 577 document.forms["form"].elements["property-" + key].value=routino.profile_property[key][routino.transport];
92 amb 574 else
93     formSetProperty(key);
94     }
95    
96 amb 577 for(var key in routino.restrictions)
97 amb 569 {
98 amb 622 if(key=="oneway" || key=="turns")
99 amb 569 formSetRestriction(key);
100     else
101     {
102 amb 574 if(document.forms["form"].elements["restrict-" + key].value=="")
103 amb 577 document.forms["form"].elements["restrict-" + key].value=routino.profile_restrictions[key][routino.transport];
104 amb 569 else
105     formSetRestriction(key);
106     }
107     }
108     }
109    
110 amb 577 // Delete the extra empty waypoints
111    
112     var filled=0;
113    
114 amb 574 for(var marker=nmarkers;marker>=1;marker--)
115     {
116     var lon=document.forms["form"].elements["lon" + marker].value;
117     var lat=document.forms["form"].elements["lat" + marker].value;
118 amb 569
119 amb 574 if(lon != "" && lat != "")
120 amb 577 {
121     filled++;
122 amb 574 markerAddMap(marker);
123 amb 577 }
124     else if(filled==0)
125 amb 574 markerRemove(marker);
126     }
127 amb 569
128 amb 577 // Get the home location cookie and compare to each waypoint
129    
130     var cookies=document.cookie.split('; ');
131    
132     for(var cookie=0;cookie<cookies.length;cookie++)
133     if(cookies[cookie].substr(0,"Routino-home".length)=="Routino-home")
134     {
135     var data=cookies[cookie].split(/[=:;]/);
136    
137     if(data[1]=="lon") homelon=Number(data[2]);
138     if(data[3]=="lat") homelat=Number(data[4]);
139     }
140    
141     if(homelon!=null && homelat!=null)
142     {
143     for(var marker=nmarkers;marker>=1;marker--)
144     {
145     var lon=document.forms["form"].elements["lon" + marker].value;
146     var lat=document.forms["form"].elements["lat" + marker].value;
147    
148     if(lon==homelon && lat==homelat)
149     updateIcon(marker);
150     }
151    
152     // If the first location is empty and the cookie is set then fill it.
153    
154     if(document.forms["form"].elements["lon1"].value=="" && document.forms["form"].elements["lat1"].value=="")
155     {
156     document.forms["form"].elements["lon1"].value=homelon;
157     document.forms["form"].elements["lat1"].value=homelat;
158    
159     markerAddMap(1);
160     }
161     }
162    
163 amb 569 updateCustomURL();
164     }
165    
166    
167     //
168 amb 577 // Change of language in the form
169     //
170    
171     function formSetLanguage(type)
172     {
173     routino.language=type;
174    
175     updateCustomURL();
176     }
177    
178    
179     //
180 amb 569 // Change of transport in the form
181     //
182    
183     function formSetTransport(type)
184     {
185 amb 577 routino.transport=type;
186 amb 569
187 amb 577 for(var key in routino.transports)
188     document.forms["form"].elements["transport"][routino.transports[key]-1].checked=(key==routino.transport);
189 amb 569
190 amb 577 for(var key in routino.profile_highway)
191     document.forms["form"].elements["highway-" + key].value=routino.profile_highway[key][routino.transport];
192 amb 569
193 amb 577 for(var key in routino.profile_speed)
194     document.forms["form"].elements["speed-" + key].value=routino.profile_speed[key][routino.transport];
195 amb 569
196 amb 577 for(var key in routino.profile_property)
197     document.forms["form"].elements["property-" + key].value=routino.profile_property[key][routino.transport];
198 amb 569
199 amb 577 for(var key in routino.restrictions)
200 amb 569 {
201 amb 622 if(key=="oneway" || key=="turns")
202 amb 577 document.forms["form"].elements["restrict-" + key].checked=routino.profile_restrictions[key][routino.transport];
203 amb 569 else
204 amb 577 document.forms["form"].elements["restrict-" + key].value=routino.profile_restrictions[key][routino.transport];
205 amb 569 }
206    
207     paramschanged=true;
208    
209     updateCustomURL();
210     }
211    
212    
213     //
214     // Change of highway in the form
215     //
216    
217     function formSetHighway(type)
218     {
219 amb 577 routino.profile_highway[type][routino.transport]=document.forms["form"].elements["highway-" + type].value;
220 amb 569
221     paramschanged=true;
222    
223     updateCustomURL();
224     }
225    
226    
227     //
228     // Change of Speed in the form
229     //
230    
231     function formSetSpeed(type)
232     {
233 amb 577 routino.profile_speed[type][routino.transport]=document.forms["form"].elements["speed-" + type].value;
234 amb 569
235     paramschanged=true;
236    
237     updateCustomURL();
238     }
239    
240    
241     //
242 amb 574 // Change of Property in the form
243     //
244    
245     function formSetProperty(type)
246     {
247 amb 577 routino.profile_property[type][routino.transport]=document.forms["form"].elements["property-" + type].value;
248 amb 574
249     paramschanged=true;
250    
251     updateCustomURL();
252     }
253    
254    
255     //
256 amb 622 // Change of Restriction rule in the form
257 amb 569 //
258    
259     function formSetRestriction(type)
260     {
261 amb 622 if(type=="oneway" || type=="turns")
262 amb 577 routino.profile_restrictions[type][routino.transport]=document.forms["form"].elements["restrict-" + type].checked;
263 amb 569 else
264 amb 577 routino.profile_restrictions[type][routino.transport]=document.forms["form"].elements["restrict-" + type].value;
265 amb 569
266     paramschanged=true;
267    
268     updateCustomURL();
269     }
270    
271    
272     //
273 amb 577 // Set the feature coordinates from the form when the form changes.
274     //
275    
276     function formSetCoords(marker)
277     {
278     var lonlat=map.getCenter().clone();
279    
280     lonlat.transform(map.getProjectionObject(),epsg4326);
281    
282     var lon=document.forms["form"].elements["lon" + marker].value;
283     var lat=document.forms["form"].elements["lat" + marker].value;
284    
285     if(lon!="")
286     {
287     if(lon<-180) lon=-180;
288     if(lon>+180) lon=+180;
289     lonlat.lon=lon;
290     }
291    
292     if(lat!="")
293     {
294     if(lat<-90 ) lat=-90 ;
295     if(lat>+90 ) lat=+90 ;
296     lonlat.lat=lat;
297     }
298    
299     var point = lonlat.clone();
300    
301     point.transform(epsg4326,map.getProjectionObject());
302    
303     markers[marker].move(point);
304    
305     markersmoved=true;
306    
307     coordsSetForm(marker);
308     }
309    
310    
311     //
312     // Set the feature coordinates in the form.
313     //
314    
315     function coordsSetForm(marker)
316     {
317     var lonlat = new OpenLayers.LonLat(markers[marker].geometry.x, markers[marker].geometry.y);
318     lonlat.transform(map.getProjectionObject(),epsg4326);
319    
320     var lon=format5f(lonlat.lon);
321     var lat=format5f(lonlat.lat);
322    
323     document.forms["form"].elements["lon" + marker].value=lon;
324     document.forms["form"].elements["lat" + marker].value=lat;
325    
326     updateIcon(marker);
327    
328     updateCustomURL();
329     }
330    
331    
332     //
333     // Format a number in printf("%.5f") format.
334     //
335    
336     function format5f(number)
337     {
338     var newnumber=Math.floor(number*100000+0.5);
339     var delta=0;
340    
341     if(newnumber>=0 && newnumber<100000) delta= 100000;
342     if(newnumber<0 && newnumber>-100000) delta=-100000;
343    
344     var string=String(newnumber+delta);
345    
346     var intpart =string.substring(0,string.length-5);
347     var fracpart=string.substring(string.length-5,string.length);
348    
349     if(delta>0) intpart="0";
350     if(delta<0) intpart="-0";
351    
352     return(intpart + "." + fracpart);
353     }
354    
355    
356     //
357     // Build a set of URL arguments
358     //
359    
360     function buildURLArguments(all)
361     {
362     var url="?";
363    
364     url=url + "transport=" + routino.transport;
365    
366     for(var marker=1;marker<=vismarkers;marker++)
367     if(markers[marker].style.display == "" || all)
368     {
369     url=url + ";lon" + marker + "=" + document.forms["form"].elements["lon" + marker].value;
370     url=url + ";lat" + marker + "=" + document.forms["form"].elements["lat" + marker].value;
371     }
372    
373     for(var key in routino.profile_highway)
374     if(routino.profile_highway[key][routino.transport]!=routino_default.profile_highway[key][routino.transport])
375     url=url + ";highway-" + key + "=" + routino.profile_highway[key][routino.transport];
376    
377     for(var key in routino.profile_speed)
378     if(routino.profile_speed[key][routino.transport]!=routino_default.profile_speed[key][routino.transport])
379     url=url + ";speed-" + key + "=" + routino.profile_speed[key][routino.transport];
380    
381     for(var key in routino.profile_property)
382     if(routino.profile_property[key][routino.transport]!=routino_default.profile_property[key][routino.transport])
383     url=url + ";property-" + key + "=" + routino.profile_property[key][routino.transport];
384    
385     for(var key in routino.restrictions)
386     if(routino.profile_restrictions[key][routino.transport]!=routino_default.profile_restrictions[key][routino.transport])
387     url=url + ";" + key + "=" + routino.profile_restrictions[key][routino.transport];
388    
389     if(routino.language)
390     url=url + ";language=" + routino.language;
391    
392     return(url);
393     }
394    
395    
396     //
397 amb 569 // Update custom URL
398     //
399    
400     function updateCustomURL()
401     {
402 amb 574 var visualiser_url=document.getElementById("visualiser_url");
403 amb 577 var link_url =document.getElementById("link_url");
404     var edit_url =document.getElementById("edit_url");
405 amb 569
406 amb 574 visualiser_url.href="customvisualiser.cgi?" + map_args;
407 amb 577 link_url.href="customrouter.cgi" + buildURLArguments(1) + ";" + map_args;
408     edit_url.href="http://www.openstreetmap.org/edit?" + map_args;
409 amb 569 }
410    
411    
412     //
413     // Block the use of the return key to submit the form
414     //
415    
416     function block_return_key()
417     {
418     var form=document.getElementById("form");
419    
420     if(form.addEventListener)
421     form.addEventListener('keyup', discardReturnKey, false);
422     else if(form.attachEvent)
423     form.attachEvent('keyup', discardReturnKey); // Internet Explorer
424     }
425    
426     //
427     // Function to discard the return key if pressed
428     //
429    
430     function discardReturnKey(ev)
431     {
432     if(ev.keyCode==13)
433     return(false);
434    
435     return(true);
436     }
437    
438    
439 amb 577 ////////////////////////////////////////////////////////////////////////////////
440     ///////////////////////////////// Map handling /////////////////////////////////
441     ////////////////////////////////////////////////////////////////////////////////
442 amb 569
443     var map;
444 amb 933 var layerMap=[], layerVectors, layerGPX;
445 amb 569 var epsg4326, epsg900913;
446 amb 574 var map_args;
447 amb 569
448     //
449     // Initialise the 'map' object
450     //
451    
452     function map_init(lat,lon,zoom)
453     {
454 amb 935 // Map properties (North/South and East/West limits and zoom in/out limits) are now in mapprops.js
455 amb 933 // Map URLs are now in mapprops.js
456 amb 577
457 amb 569 //
458     // Create the map
459     //
460    
461     epsg4326=new OpenLayers.Projection("EPSG:4326");
462     epsg900913=new OpenLayers.Projection("EPSG:900913");
463    
464     map = new OpenLayers.Map ("map",
465     {
466     controls:[
467     new OpenLayers.Control.Navigation(),
468     new OpenLayers.Control.PanZoomBar(),
469     new OpenLayers.Control.ScaleLine(),
470     new OpenLayers.Control.LayerSwitcher()
471     ],
472    
473     projection: epsg900913,
474     displayProjection: epsg4326,
475    
476 amb 933 minZoomLevel: mapprops.zoomout,
477     numZoomLevels: mapprops.zoomin-mapprops.zoomout+1,
478     maxResolution: 156543.0339 / Math.pow(2,mapprops.zoomout),
479 amb 569
480 amb 577 maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
481 amb 933 restrictedExtent: new OpenLayers.Bounds(mapprops.westedge,mapprops.southedge,mapprops.eastedge,mapprops.northedge).transform(epsg4326,epsg900913),
482 amb 569
483     units: "m"
484     });
485    
486     map.events.register("moveend", map, mapMoved);
487    
488 amb 933 // Add map tile layers
489 amb 569
490 amb 933 for(var l=0;l < mapprops.mapdata.length;l++)
491     {
492     layerMap[l] = new OpenLayers.Layer.TMS(mapprops.mapdata[l].label,
493     mapprops.mapdata[l].baseurl,
494     {
495     emptyUrl: mapprops.mapdata[l].errorurl,
496     type: 'png',
497     getURL: limitedUrl,
498     displayOutsideMaxExtent: true,
499     buffer: 1
500     });
501     map.addLayer(layerMap[l]);
502     }
503 amb 569
504 amb 577 // Get a URL for the tile; limited to map restricted extent.
505 amb 569
506     function limitedUrl(bounds)
507     {
508     var z = map.getZoom() + map.minZoomLevel;
509    
510 amb 577 if (z>=7 && (bounds.right < map.restrictedExtent.left ||
511     bounds.left > map.restrictedExtent.right ||
512     bounds.top < map.restrictedExtent.bottom ||
513     bounds.bottom > map.restrictedExtent.top))
514 amb 569 return this.emptyUrl;
515    
516     var res = map.getResolution();
517     var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
518     var limit = Math.pow(2, z);
519    
520     if (y < 0 || y >= limit)
521     return this.emptyUrl;
522    
523     var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
524    
525     x = ((x % limit) + limit) % limit;
526     return this.url + z + "/" + x + "/" + y + "." + this.type;
527     }
528    
529     // Define a GPX layer but don't add it yet
530    
531     layerGPX={shortest: null, quickest: null};
532    
533     gpx_style={shortest: new OpenLayers.Style({},{strokeWidth: 3, strokeColor: "#00FF00"}),
534     quickest: new OpenLayers.Style({},{strokeWidth: 3, strokeColor: "#0000FF"})};
535    
536     // Add a vectors layer
537    
538     layerVectors = new OpenLayers.Layer.Vector("Markers");
539     map.addLayer(layerVectors);
540    
541     // A set of markers
542    
543 amb 574 nmarkers=99;
544     vismarkers=0;
545     markers={};
546 amb 569 markersmoved=false;
547     paramschanged=false;
548    
549 amb 574 for(var marker=1;marker<=nmarkers;marker++)
550 amb 569 {
551 amb 572 if(document.forms["form"].elements["lon" + marker] != undefined)
552     {
553     markers[marker] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0),{},
554     new OpenLayers.Style({},{externalGraphic: 'icons/marker-' + marker + '-red.png',
555 amb 574 fillColor: "white",
556 amb 572 graphicYOffset: -25,
557     graphicWidth: 21,
558     graphicHeight: 25,
559     display: "none"}));
560 amb 569
561 amb 572 layerVectors.addFeatures([markers[marker]]);
562     }
563 amb 574 else
564     {
565     nmarkers=marker-1;
566     vismarkers=marker-1;
567     break;
568     }
569 amb 569 }
570    
571     // A function to drag the markers
572    
573     var drag = new OpenLayers.Control.DragFeature(layerVectors,
574     {onDrag: dragMove,
575     onComplete: dragComplete });
576     map.addControl(drag);
577     drag.activate();
578    
579     // Markers to highlight a selected point
580    
581 amb 577 for(var highlight in highlights)
582 amb 569 {
583     highlights[highlight] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0),{},
584 amb 577 new OpenLayers.Style({},{strokeColor: route_dark_colours[highlight],
585 amb 574 fillColor: "white",
586 amb 569 pointRadius: 10,
587     strokeWidth: 4,
588     fillOpacity: 0,
589     display: "none"}));
590    
591     layerVectors.addFeatures([highlights[highlight]]);
592     }
593    
594 amb 574 // A popup for routing results
595    
596 amb 577 for(var popup in popups)
597     popups[popup] = createPopup(popup);
598 amb 574
599 amb 572 // Set the map centre to the limited range specified
600    
601 amb 577 map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true));
602 amb 572 map.maxResolution = map.getResolution();
603    
604 amb 569 // Move the map
605    
606     if(lon != 'lon' && lat != 'lat' && zoom != 'zoom')
607     {
608 amb 933 if(lon<mapprops.westedge) lon=mapprops.westedge;
609     if(lon>mapprops.eastedge) lon=mapprops.eastedge;
610    
611     if(lat<mapprops.southedge) lat=mapprops.southedge;
612     if(lat>mapprops.northedge) lat=mapprops.northedge;
613    
614     if(zoom<mapprops.zoomout) zoom=mapprops.zoomout;
615     if(zoom>mapprops.zoomin) zoom=mapprops.zoomin;
616    
617 amb 569 var lonlat = new OpenLayers.LonLat(lon,lat).transform(epsg4326,map.getProjectionObject());
618    
619     map.moveTo(lonlat,zoom-map.minZoomLevel);
620     }
621     }
622    
623    
624     //
625     // Map has moved
626     //
627    
628     function mapMoved()
629     {
630     var centre = map.getCenter().clone();
631    
632     var lonlat = centre.transform(map.getProjectionObject(),epsg4326);
633    
634     var zoom = this.getZoom() + map.minZoomLevel;
635    
636 amb 574 map_args="lat=" + lonlat.lat + ";lon=" + lonlat.lon + ";zoom=" + zoom;
637 amb 569
638 amb 574 updateCustomURL();
639 amb 569 }
640    
641    
642     //
643     // OpenLayers.Control.DragFeature callback for a drag occuring.
644     //
645    
646     function dragMove(feature,pixel)
647     {
648 amb 574 for(var marker in markers)
649 amb 569 if(feature==markers[marker])
650     {
651     markersmoved=true;
652    
653     coordsSetForm(marker);
654     }
655     }
656    
657    
658     //
659     // OpenLayers.Control.DragFeature callback for completing a drag.
660     //
661    
662     function dragComplete(feature,pixel)
663     {
664 amb 574 for(var marker in markers)
665 amb 569 if(feature==markers[marker])
666     {
667     markersmoved=true;
668    
669     coordsSetForm(marker);
670     }
671     }
672    
673    
674 amb 577 ////////////////////////////////////////////////////////////////////////////////
675     /////////////////////////////// Marker handling ////////////////////////////////
676     ////////////////////////////////////////////////////////////////////////////////
677    
678     var nmarkers, vismarkers, markers, markersmoved, paramschanged;
679     var homelat=null, homelon=null;
680    
681    
682 amb 569 //
683 amb 574 // Toggle a marker on the map.
684 amb 569 //
685    
686 amb 574 function markerToggleMap(marker)
687 amb 569 {
688 amb 577 if(markers[marker].style.display == "")
689 amb 574 markerRemoveMap(marker);
690     else
691     markerAddMap(marker);
692     }
693    
694    
695     //
696     // Show a marker on the map.
697     //
698    
699     function markerAddMap(marker)
700     {
701 amb 577 markers[marker].style.display = "";
702 amb 574
703     formSetCoords(marker);
704    
705 amb 577 updateIcon(marker);
706 amb 574
707     markersmoved=true;
708     }
709    
710    
711     //
712     // Remove a marker from the map.
713     //
714    
715     function markerRemoveMap(marker)
716     {
717 amb 577 markers[marker].style.display = "none";
718 amb 574
719 amb 577 updateIcon(marker);
720 amb 574
721 amb 577 markersmoved=true;
722     }
723 amb 574
724 amb 577
725     //
726     // Centre the marker on the map
727     //
728    
729     function markerCentre(marker)
730     {
731     document.forms["form"].elements["lon" + marker].value="";
732     document.forms["form"].elements["lat" + marker].value="";
733    
734     formSetCoords(marker);
735    
736 amb 574 markersmoved=true;
737     }
738    
739    
740     //
741     // Clear the current marker.
742     //
743    
744     function markerRemove(marker)
745     {
746     for(var marker2=marker;marker2<vismarkers;marker2++)
747 amb 569 {
748 amb 574 document.forms["form"].elements["lon" + marker2].value=document.forms["form"].elements["lon" + (marker2+1)].value;
749     document.forms["form"].elements["lat" + marker2].value=document.forms["form"].elements["lat" + (marker2+1)].value;
750    
751     if(markers[marker2+1].style.display=="")
752     markerAddMap(marker2);
753     else
754     markerRemoveMap(marker2);
755 amb 569 }
756 amb 574
757     markerRemoveMap(vismarkers);
758    
759     var marker_tr=document.getElementById("point" + vismarkers);
760    
761     marker_tr.style.display="none";
762    
763     vismarkers--;
764    
765     if(vismarkers==1)
766     markerAddAfter(1);
767    
768     updateCustomURL();
769     }
770    
771    
772     //
773     // Add a marker before the current one.
774     //
775    
776     function markerAddBefore(marker)
777     {
778     if(vismarkers==nmarkers || marker==1)
779     return false;
780    
781     vismarkers++;
782    
783     var marker_tr=document.getElementById("point" + vismarkers);
784    
785     marker_tr.style.display="";
786    
787     for(var marker2=vismarkers;marker2>marker;marker2--)
788 amb 569 {
789 amb 574 document.forms["form"].elements["lon" + marker2].value=document.forms["form"].elements["lon" + (marker2-1)].value;
790     document.forms["form"].elements["lat" + marker2].value=document.forms["form"].elements["lat" + (marker2-1)].value;
791 amb 569
792 amb 574 if(markers[marker2-1].style.display=="")
793     markerAddMap(marker2);
794     else
795     markerRemoveMap(marker2);
796     }
797 amb 569
798 amb 574 document.forms["form"].elements["lon" + marker].value="";
799     document.forms["form"].elements["lat" + marker].value="";
800     markers[marker].style.display="none";
801 amb 569
802 amb 574 markerRemoveMap(marker);
803    
804     updateCustomURL();
805     }
806    
807    
808     //
809     // Add a marker after the current one.
810     //
811    
812     function markerAddAfter(marker)
813     {
814     if(vismarkers==nmarkers)
815     return false;
816    
817     vismarkers++;
818    
819     var marker_tr=document.getElementById("point" + vismarkers);
820    
821     marker_tr.style.display="";
822    
823     for(var marker2=vismarkers;marker2>(marker+1);marker2--)
824     {
825     document.forms["form"].elements["lon" + marker2].value=document.forms["form"].elements["lon" + (marker2-1)].value;
826     document.forms["form"].elements["lat" + marker2].value=document.forms["form"].elements["lat" + (marker2-1)].value;
827    
828     if(markers[marker2-1].style.display=="")
829     markerAddMap(marker2);
830     else
831     markerRemoveMap(marker2);
832 amb 569 }
833    
834 amb 574 document.forms["form"].elements["lon" + (marker+1)].value="";
835     document.forms["form"].elements["lat" + (marker+1)].value="";
836     markers[marker+1].style.display="none";
837 amb 569
838 amb 574 markerRemoveMap(marker+1);
839    
840     updateCustomURL();
841 amb 569 }
842    
843    
844     //
845 amb 577 // Set this marker as the home location.
846     //
847    
848     function markerHome(marker)
849     {
850     if(markerHomeCookie(marker))
851     for(marker=1;marker<=nmarkers;marker++)
852     updateIcon(marker);
853     }
854    
855    
856     //
857     // Update an icon to set colours and home or normal marker.
858     //
859    
860     function updateIcon(marker)
861     {
862     var lon=document.forms["form"].elements["lon" + marker].value;
863     var lat=document.forms["form"].elements["lat" + marker].value;
864    
865     if(lon==homelon && lat==homelat)
866     {
867     if(markers[marker].style.display=="")
868     document.images["waypoint" + marker].src="icons/marker-home-red.png";
869     else
870     document.images["waypoint" + marker].src="icons/marker-home-grey.png";
871    
872     markers[marker].style.externalGraphic="icons/marker-home-red.png";
873     }
874     else
875     {
876     if(markers[marker].style.display=="")
877     document.images["waypoint" + marker].src="icons/marker-" + marker + "-red.png";
878     else
879     document.images["waypoint" + marker].src="icons/marker-" + marker + "-grey.png";
880    
881     markers[marker].style.externalGraphic="icons/marker-" + marker + "-red.png";
882     }
883    
884     layerVectors.drawFeature(markers[marker]);
885     }
886    
887    
888     //
889     // Set or clear the home marker icon
890     //
891    
892     function markerHomeCookie(marker)
893     {
894     var lon=document.forms["form"].elements["lon" + marker].value;
895     var lat=document.forms["form"].elements["lat" + marker].value;
896    
897     if(lon=="" || lat=="")
898     return(false);
899    
900     var cookie;
901     var date = new Date();
902    
903     if((homelat==null && homelon==null) ||
904     (homelat!=lat && homelon!=lon))
905     {
906     cookie="Routino-home=lon:" + lon + ":lat:" + lat;
907    
908     date.setUTCFullYear(date.getUTCFullYear()+5);
909    
910     homelat=lat;
911     homelon=lon;
912     }
913     else
914     {
915     cookie="Routino-home=unset";
916    
917     date.setUTCFullYear(date.getUTCFullYear()-1);
918    
919     homelat=null;
920     homelon=null;
921     }
922    
923     document.cookie=cookie + ";expires=" + date.toGMTString();
924    
925     return(true);
926     }
927    
928    
929     //
930 amb 574 // Move this marker up.
931     //
932    
933     function markerMoveUp(marker)
934     {
935     if(marker==1)
936     return false;
937    
938     markerSwap(marker,marker-1);
939     }
940    
941    
942     //
943     // Move this marker down.
944     //
945    
946     function markerMoveDown(marker)
947     {
948     if(marker==vismarkers)
949     return false;
950    
951     markerSwap(marker,marker+1);
952     }
953    
954    
955     //
956     // Swap a pair of markers.
957     //
958    
959     function markerSwap(marker1,marker2)
960     {
961     var lon=document.forms["form"].elements["lon" + marker1].value;
962     var lat=document.forms["form"].elements["lat" + marker1].value;
963     var display=markers[marker1].style.display;
964    
965     document.forms["form"].elements["lon" + marker1].value=document.forms["form"].elements["lon" + marker2].value;
966     document.forms["form"].elements["lat" + marker1].value=document.forms["form"].elements["lat" + marker2].value;
967     if(markers[marker2].style.display=="")
968     markerAddMap(marker1);
969     else
970     markerRemoveMap(marker1);
971    
972     document.forms["form"].elements["lon" + marker2].value=lon;
973     document.forms["form"].elements["lat" + marker2].value=lat;
974     if(display=="")
975     markerAddMap(marker2);
976     else
977     markerRemoveMap(marker2);
978    
979     updateCustomURL();
980     }
981    
982    
983     //
984     // Reverse the markers.
985     //
986    
987     function markersReverse()
988     {
989     for(var marker=1;marker<=vismarkers/2;marker++)
990     markerSwap(marker,vismarkers+1-marker);
991    
992     updateCustomURL();
993     }
994    
995    
996 amb 577 ////////////////////////////////////////////////////////////////////////////////
997     //////////////////////////// Route results handling ////////////////////////////
998     ////////////////////////////////////////////////////////////////////////////////
999    
1000     var route_light_colours={shortest: "#60C060", quickest: "#6060C0"};
1001     var route_dark_colours ={shortest: "#408040", quickest: "#404080"};
1002    
1003     var highlights={shortest: null, quickest: null};
1004     var popups={shortest: null, quickest: null};
1005     var routepoints={shortest: {}, quickest: {}};
1006     var gpx_style={shortest: null, quickest: null};
1007    
1008 amb 574 //
1009 amb 577 // Zoom to a specific item in the route
1010 amb 569 //
1011    
1012 amb 577 function zoomTo(type,line)
1013 amb 569 {
1014 amb 577 var lonlat = new OpenLayers.LonLat(routepoints[type][line].lon,routepoints[type][line].lat).transform(epsg4326,map.getProjectionObject());
1015 amb 569
1016 amb 577 map.moveTo(lonlat,map.numZoomLevels-2);
1017 amb 569 }
1018    
1019    
1020     //
1021 amb 577 // Highlight a specific item in the route
1022 amb 569 //
1023    
1024 amb 577 function highlight(type,line)
1025 amb 569 {
1026 amb 577 if(line==-1)
1027     {
1028     highlights[type].style.display = "none";
1029 amb 569
1030 amb 577 drawPopup(popups[type],null);
1031 amb 569 }
1032 amb 577 else
1033 amb 569 {
1034 amb 577 // Marker
1035 amb 569
1036 amb 577 var lonlat = new OpenLayers.LonLat(routepoints[type][line].lon,routepoints[type][line].lat).transform(epsg4326,map.getProjectionObject());
1037 amb 569
1038 amb 577 highlights[type].move(lonlat);
1039 amb 569
1040 amb 577 if(highlights[type].style.display = "none")
1041     highlights[type].style.display = "";
1042 amb 569
1043 amb 577 // Popup
1044 amb 569
1045 amb 577 drawPopup(popups[type],"<table>" + routepoints[type][line].html + "</table>");
1046     }
1047    
1048     layerVectors.drawFeature(highlights[type]);
1049 amb 569 }
1050    
1051    
1052     //
1053 amb 577 // Create a popup - not using OpenLayers because want it fixed on screen not fixed on map.
1054 amb 569 //
1055    
1056 amb 577 function createPopup(type)
1057 amb 569 {
1058 amb 577 var popup=document.createElement('div');
1059 amb 569
1060 amb 577 popup.className = "popup";
1061 amb 569
1062 amb 577 popup.innerHTML = "<span></span>";
1063 amb 569
1064 amb 577 popup.style.display = "none";
1065 amb 569
1066 amb 577 popup.style.position = "fixed";
1067     popup.style.top = "-4000px";
1068     popup.style.left = "-4000px";
1069     popup.style.zIndex = "100";
1070 amb 569
1071 amb 577 popup.style.padding = "5px";
1072 amb 569
1073 amb 577 popup.style.opacity=0.85;
1074     popup.style.backgroundColor=route_light_colours[type];
1075     popup.style.border="4px solid " + route_dark_colours[type];
1076 amb 569
1077 amb 577 document.body.appendChild(popup);
1078 amb 569
1079 amb 577 return(popup);
1080 amb 569 }
1081    
1082    
1083     //
1084 amb 577 // Draw a popup - not using OpenLayers because want it fixed on screen not fixed on map.
1085 amb 569 //
1086    
1087 amb 577 function drawPopup(popup,html)
1088 amb 569 {
1089 amb 577 if(html==null)
1090 amb 569 {
1091 amb 577 popup.style.display="none";
1092     return;
1093     }
1094 amb 574
1095 amb 577 if(popup.style.display=="none")
1096 amb 569 {
1097 amb 577 var map_div=document.getElementById("map");
1098 amb 569
1099 amb 577 popup.style.left =map_div.offsetParent.offsetLeft+map_div.offsetLeft+60 + "px";
1100     popup.style.top = map_div.offsetTop +30 + "px";
1101     popup.style.width =map_div.clientWidth-100 + "px";
1102 amb 574
1103 amb 577 popup.style.display="";
1104 amb 569 }
1105    
1106 amb 577 popup.innerHTML=html;
1107 amb 569 }
1108    
1109    
1110     //
1111 amb 577 // Remove a GPX trace
1112 amb 569 //
1113    
1114 amb 577 function removeGPXTrace(type)
1115 amb 569 {
1116 amb 577 map.removeLayer(layerGPX[type]);
1117     layerGPX[type].destroy();
1118     layerGPX[type]=null;
1119 amb 569
1120 amb 577 displayStatus(type,"no_info");
1121 amb 569
1122 amb 577 var div_links=document.getElementById(type + "_links");
1123     div_links.style.display = "none";
1124 amb 569
1125 amb 577 var div_route=document.getElementById(type + "_route");
1126     div_route.innerHTML = "";
1127 amb 569
1128 amb 577 hideshow_hide(type);
1129     }
1130 amb 569
1131 amb 574
1132 amb 577 ////////////////////////////////////////////////////////////////////////////////
1133     /////////////////////////////// Server handling ////////////////////////////////
1134     ////////////////////////////////////////////////////////////////////////////////
1135 amb 569
1136     //
1137     // Display data statistics
1138     //
1139    
1140     function displayStatistics()
1141     {
1142     // Use AJAX to get the statistics
1143    
1144     OpenLayers.loadURL("statistics.cgi",null,null,runStatisticsSuccess);
1145     }
1146    
1147    
1148     //
1149 amb 577 // Success in running data statistics generation.
1150 amb 569 //
1151    
1152     function runStatisticsSuccess(response)
1153     {
1154     var statistics_data=document.getElementById("statistics_data");
1155     var statistics_link=document.getElementById("statistics_link");
1156    
1157     statistics_data.innerHTML="<pre>" + response.responseText + "</pre>";
1158    
1159     statistics_link.style.display="none";
1160     }
1161    
1162    
1163     //
1164 amb 577 // Submit form - perform the routing
1165 amb 569 //
1166    
1167     function findRoute(type)
1168     {
1169     tab_select("results");
1170    
1171 amb 572 hideshow_hide('help_options');
1172 amb 569 hideshow_hide('shortest');
1173     hideshow_hide('quickest');
1174    
1175 amb 577 displayStatus("result","running");
1176 amb 569
1177     var url="router.cgi" + buildURLArguments(0) + ";type=" + type;
1178    
1179     // Destroy the existing layer(s)
1180    
1181     if(markersmoved || paramschanged)
1182     {
1183     if(layerGPX.shortest!=null)
1184     removeGPXTrace("shortest");
1185     if(layerGPX.quickest!=null)
1186     removeGPXTrace("quickest");
1187     markersmoved=false;
1188     paramschanged=false;
1189     }
1190     else if(layerGPX[type]!=null)
1191     removeGPXTrace(type);
1192    
1193     // Use AJAX to run the router
1194    
1195     routing_type=type;
1196    
1197     OpenLayers.loadURL(url,null,null,runRouterSuccess,runRouterFailure);
1198     }
1199    
1200    
1201     //
1202     // Success in running router.
1203     //
1204    
1205     function runRouterSuccess(response)
1206     {
1207     var lines=response.responseText.split('\n');
1208    
1209     var uuid=lines[0];
1210 amb 935 var cpuinfo=lines[1]; // not used
1211     var distinfo=lines[2]; // not used
1212     var message=lines[3]; // content not used
1213 amb 569
1214 amb 629 var link;
1215    
1216 amb 569 // Update the status message
1217    
1218     if(message!="")
1219     {
1220 amb 577 displayStatus("result","error");
1221 amb 572 hideshow_show('help_route');
1222 amb 629
1223     link=document.getElementById("router_log_error");
1224     link.href="results.cgi?uuid=" + uuid + ";type=router;format=log";
1225    
1226 amb 569 return;
1227     }
1228     else
1229     {
1230 amb 577 displayStatus("result","complete");
1231 amb 572 hideshow_hide('help_route');
1232 amb 629
1233     link=document.getElementById("router_log_complete");
1234     link.href="results.cgi?uuid=" + uuid + ";type=router;format=log";
1235 amb 569 }
1236    
1237     // Update the routing result message
1238    
1239 amb 577 link=document.getElementById(routing_type + "_html");
1240     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=html";
1241     link=document.getElementById(routing_type + "_gpx_track");
1242     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track";
1243     link=document.getElementById(routing_type + "_gpx_route");
1244     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-route";
1245     link=document.getElementById(routing_type + "_text_all");
1246     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text-all";
1247     link=document.getElementById(routing_type + "_text");
1248     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text";
1249 amb 569
1250 amb 577 var div_links=document.getElementById(routing_type + "_links");
1251     div_links.style.display = "";
1252 amb 569
1253     // Add a GPX layer
1254    
1255     var url="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track";
1256    
1257     layerGPX[routing_type] = new OpenLayers.Layer.GML("GPX (" + routing_type + ")", url,
1258     {
1259     format: OpenLayers.Format.GPX,
1260     style: gpx_style[routing_type],
1261     projection: map.displayProjection
1262     });
1263    
1264     map.addLayer(layerGPX[routing_type]);
1265    
1266     hideshow_show(routing_type);
1267    
1268     displayResult(routing_type,uuid);
1269     }
1270    
1271    
1272     //
1273     // Failure in running router.
1274     //
1275    
1276     function runRouterFailure(response)
1277     {
1278 amb 577 displayStatus("result","failed");
1279 amb 569 }
1280    
1281    
1282     //
1283 amb 577 // Display the status
1284     //
1285    
1286     function displayStatus(type,subtype,content)
1287     {
1288     var div_status=document.getElementById(type + "_status");
1289    
1290     var child=div_status.firstChild;
1291    
1292     do
1293     {
1294     if(child.id != undefined)
1295     child.style.display="none";
1296    
1297     child=child.nextSibling;
1298     }
1299     while(child != undefined);
1300    
1301 amb 936 var chosen_status=document.getElementById(type + "_status_" + subtype);
1302 amb 577
1303 amb 936 chosen_status.style.display="";
1304 amb 577
1305     if(content != null)
1306 amb 936 chosen_status.innerHTML=content;
1307 amb 577 }
1308    
1309    
1310     //
1311 amb 569 // Display the route
1312     //
1313    
1314     function displayResult(type,uuid)
1315     {
1316     routing_type = type;
1317    
1318     // Add the route
1319    
1320 amb 577 var url="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=html";
1321 amb 569
1322     // Use AJAX to get the route
1323    
1324     OpenLayers.loadURL(url,null,null,getRouteSuccess,getRouteFailure);
1325     }
1326    
1327    
1328     //
1329     // Success in getting route.
1330     //
1331    
1332     function getRouteSuccess(response)
1333     {
1334     var lines=response.responseText.split('\n');
1335 amb 577 var div_route=document.getElementById(routing_type + "_route");
1336 amb 569
1337 amb 577 routepoints[routing_type]=[];
1338 amb 569
1339 amb 577 var points=routepoints[routing_type];
1340 amb 569
1341 amb 577 var table=0;
1342     var point=0;
1343     var total_table,total_word;
1344 amb 569
1345 amb 577 for(var line=0;line<lines.length;line++)
1346 amb 569 {
1347 amb 577 var thisline=lines[line];
1348 amb 569
1349 amb 577 if(table==0)
1350     {
1351     if(thisline.match('<table>'))
1352     table=1;
1353     else
1354     continue;
1355     }
1356 amb 574
1357 amb 577 if(thisline.match('</table>'))
1358     break;
1359    
1360     if(thisline.match('<tr class=\'([a-z])\'>'))
1361 amb 569 {
1362 amb 577 var rowtype=RegExp.$1;
1363 amb 569
1364 amb 577 if(rowtype=='c')
1365     {
1366     thisline.match('<td class=\'r\'> *([-0-9.]+) *([-0-9.]+)');
1367     points[point]={lat: Number(RegExp.$1), lon: Number(RegExp.$2), html: "", highway: "", distance: "", total: ""};
1368 amb 574
1369 amb 577 point++;
1370     }
1371     else if(rowtype=='n')
1372     {
1373     points[point-1].html += thisline;
1374     }
1375     else if(rowtype=='s')
1376     {
1377     thisline.match('<span class=\'h\'>([^<]+)</span>');
1378     points[point-1].highway = RegExp.$1;
1379 amb 574
1380 amb 577 thisline.match('<span class=\'d\'>([^<]+)</span>');
1381     points[point-1].distance = RegExp.$1;
1382 amb 574
1383 amb 577 thisline.match('(<span class=\'j\'>[^<]+</span>)');
1384     points[point-1].total = RegExp.$1;
1385    
1386     thisline.match('^(.*).<span class=\'j\'>');
1387    
1388     points[point-1].html += RegExp.$1;
1389     }
1390     else if(rowtype=='t')
1391     {
1392     points[point-1].html += thisline;
1393    
1394     thisline.match('^(.*<td class=\'r\'>)');
1395     total_table = RegExp.$1;
1396    
1397     thisline.match('<td class=\'l\'>([^<]+)<');
1398     total_word = RegExp.$1;
1399    
1400     thisline.match('<span class=\'j\'>([^<]+)</span>');
1401     points[point-1].total = RegExp.$1;
1402     }
1403 amb 569 }
1404     }
1405    
1406 amb 935 displayStatus(routing_type,"info",points[point-1].total.bold());
1407    
1408 amb 577 var result="<table onmouseout='highlight(\"" + routing_type + "\",-1)'>";
1409    
1410     for(var p=0;p<point-1;p++)
1411     {
1412     points[p].html += total_table + points[p].total;
1413    
1414     result=result + "<tr onclick='zoomTo(\"" + routing_type + "\"," + p + ")'" +
1415     " onmouseover='highlight(\"" + routing_type + "\"," + p + ")'>" +
1416     "<td class='distance' title='" + points[p].distance + "'>#" + (p+1) +
1417     "<td class='highway'>" + points[p].highway;
1418     }
1419    
1420     result=result + "<tr onclick='zoomTo(\"" + routing_type + "\"," + p + ")'" +
1421     " onmouseover='highlight(\"" + routing_type + "\"," + p + ")'>" +
1422     "<td colspan='2'>" + total_word + " " + points[p].total;
1423    
1424 amb 569 result=result + "</table>";
1425    
1426 amb 577 div_route.innerHTML=result;
1427 amb 569 }
1428    
1429    
1430     //
1431     // Failure in getting route.
1432     //
1433    
1434     function getRouteFailure(response)
1435     {
1436 amb 577 var div_route=document.getElementById(routing_type + "_route");
1437     div_route.innerHTML = "";
1438 amb 569 }