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