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.openlayers.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1516 - (hide annotations) (download) (as text)
Sat Mar 1 12:06:37 2014 UTC (11 years, 1 month ago) by amb
File MIME type: application/javascript
File size: 51363 byte(s)
Updated to version 2.13.1 of OpenLayers (also 2.12 still supported).

1 amb 569 //
2     // Routino router web page Javascript
3     //
4     // Part of the Routino routing software.
5     //
6 amb 1483 // This file Copyright 2008-2014 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 987 var vismarkers, markers, markersmoved, paramschanged;
24 amb 985 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 amb 1483 if(typeof(routino[l1])!="object")
36 amb 577 routino_default[l1]=routino[l1];
37     else
38     {
39     routino_default[l1]={};
40     for(var l2 in routino[l1])
41 amb 1483 if(typeof(routino[l1][l2])!="object")
42 amb 577 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 amb 1012 for(var marker=1;marker<=mapprops.maxmarkers;marker++)
55 amb 985 {
56     routino.point[marker]={};
57    
58     routino.point[marker].lon="";
59     routino.point[marker].lat="";
60 amb 1001 routino.point[marker].search="";
61 amb 985 routino.point[marker].active=false;
62 amb 1034 routino.point[marker].used=false;
63 amb 1036 routino.point[marker].home=false;
64 amb 985 }
65    
66     // Process the URL query string and extract the arguments
67    
68     var legal={"^lon" : "^[-0-9.]+$",
69     "^lat" : "^[-0-9.]+$",
70     "^zoom" : "^[0-9]+$",
71    
72     "^lon[1-9]" : "^[-0-9.]+$",
73     "^lat[1-9]" : "^[-0-9.]+$",
74 amb 1001 "^search[1-9]" : "^.+$",
75 amb 985 "^transport" : "^[a-z]+$",
76     "^highway-[a-z]+" : "^[0-9.]+$",
77     "^speed-[a-z]+" : "^[0-9.]+$",
78     "^property-[a-z]+" : "^[0-9.]+$",
79     "^oneway" : "^(1|0|true|false|on|off)$",
80     "^turns" : "^(1|0|true|false|on|off)$",
81     "^weight" : "^[0-9.]+$",
82     "^height" : "^[0-9.]+$",
83     "^width" : "^[0-9.]+$",
84     "^length" : "^[0-9.]+$",
85    
86     "^language" : "^[-a-zA-Z]+$"};
87    
88     var args={};
89    
90     if(location.search.length>1)
91     {
92     var query,queries;
93    
94     query=location.search.replace(/^\?/,"");
95 amb 1483 query=query.replace(/;/g,"&");
96     queries=query.split("&");
97 amb 985
98     for(var i=0;i<queries.length;i++)
99     {
100     queries[i].match(/^([^=]+)(=(.*))?$/);
101    
102 amb 1483 var k=RegExp.$1;
103 amb 1484 var v=decodeURIComponent(RegExp.$3);
104 amb 985
105     for(var l in legal)
106     {
107     if(k.match(RegExp(l)) && v.match(RegExp(legal[l])))
108     args[k]=v;
109     }
110     }
111     }
112    
113    
114 amb 987 //
115     // Fill in the HTML - add the missing waypoints
116     //
117    
118 amb 1035 function html_init() // called from router.html
119 amb 987 {
120     var waypoints=document.getElementById("waypoints");
121 amb 1005
122 amb 987 var waypoint_html=waypoints.rows[0].innerHTML;
123 amb 1005 waypoints.deleteRow(0);
124 amb 987
125 amb 1005 var searchresults_html=waypoints.rows[0].innerHTML;
126 amb 987 waypoints.deleteRow(0);
127    
128 amb 1012 for(var marker=mapprops.maxmarkers;marker>=1;marker--)
129 amb 987 {
130 amb 1005 var searchresults=waypoints.insertRow(0);
131 amb 1011
132 amb 1037 searchresults.style.display="none";
133 amb 1005 searchresults.id="searchresults" + marker;
134 amb 1483 searchresults.innerHTML=searchresults_html.split("XXX").join(marker);
135 amb 987
136 amb 1011 var waypoint=waypoints.insertRow(0);
137 amb 1005
138 amb 1037 waypoint.style.display="none";
139 amb 1005 waypoint.id="waypoint" + marker;
140 amb 1483 waypoint.innerHTML=waypoint_html.split("XXX").join(marker);
141 amb 987 }
142     }
143    
144    
145 amb 577 ////////////////////////////////////////////////////////////////////////////////
146     //////////////////////////////// Form handling /////////////////////////////////
147     ////////////////////////////////////////////////////////////////////////////////
148    
149 amb 569 //
150     // Form initialisation - fill in the uninitialised parts
151     //
152    
153 amb 1035 function form_init() // called from router.html
154 amb 569 {
155 amb 985 // Fill in the waypoints
156 amb 569
157 amb 1039 vismarkers=0;
158 amb 569
159 amb 1012 for(var marker=mapprops.maxmarkers;marker>=1;marker--)
160 amb 569 {
161 amb 985 var lon=args["lon" + marker];
162     var lat=args["lat" + marker];
163 amb 1001 var search=args["search" + marker];
164 amb 577
165 amb 1493 if(lon !== undefined && lat !== undefined && search !== undefined && lon !== "" && lat !== "" && search !== "")
166 amb 569 {
167 amb 1037 markerAddForm(marker);
168    
169 amb 1001 formSetSearch(marker,search);
170 amb 1032 formSetCoords(marker,lon,lat);
171 amb 569
172 amb 1032 markerAddMap(marker);
173    
174 amb 1001 markerSearch(marker);
175    
176 amb 1039 vismarkers++;
177 amb 569 }
178 amb 1493 else if(lon !== undefined && lat !== undefined && lon !== "" && lat !== "")
179 amb 1001 {
180 amb 1037 markerAddForm(marker);
181    
182 amb 1032 formSetCoords(marker,lon,lat);
183 amb 1001
184 amb 1032 markerAddMap(marker);
185    
186 amb 1001 markerCoords(marker);
187    
188 amb 1039 vismarkers++;
189 amb 1001 }
190 amb 1493 else if(search !== undefined && search !== "")
191 amb 1001 {
192 amb 1037 markerAddForm(marker);
193    
194 amb 1001 formSetSearch(marker,search);
195    
196     markerSearch(marker);
197    
198     DoSearch(marker);
199    
200 amb 1039 vismarkers++;
201 amb 1001 }
202 amb 1039 else if(vismarkers || marker<=2)
203     {
204 amb 1037 markerAddForm(marker);
205 amb 1016
206 amb 1039 vismarkers++;
207     }
208    
209 amb 1016 var searchfield=document.forms["form"].elements["search" + marker];
210    
211     if(searchfield.addEventListener)
212 amb 1483 searchfield.addEventListener("keyup", searchOnReturnKey, false);
213 amb 1016 else if(searchfield.attachEvent)
214 amb 1483 searchfield.attachEvent("keyup", searchOnReturnKey); // Internet Explorer
215 amb 985 }
216 amb 569
217 amb 985 // Update the transport type with the URL settings which updates all HTML forms to defaults.
218 amb 574
219 amb 985 var transport=routino.transport;
220 amb 569
221 amb 1493 if(args["transport"] !== undefined)
222 amb 985 transport=args["transport"];
223 amb 577
224 amb 985 formSetTransport(transport);
225 amb 577
226 amb 985 // Update the HTML with the URL settings
227    
228 amb 1493 if(args["language"] !== undefined)
229 amb 985 formSetLanguage(args["language"]);
230    
231     for(var key in routino.profile_highway)
232 amb 1493 if(args["highway-" + key] !== undefined)
233 amb 985 formSetHighway(key,args["highway-" + key]);
234    
235     for(var key in routino.profile_speed)
236 amb 1493 if(args["speed-" + key] !== undefined)
237 amb 985 formSetSpeed(key,args["speed-" + key]);
238    
239     for(var key in routino.profile_property)
240 amb 1493 if(args["property-" + key] !== undefined)
241 amb 985 formSetProperty(key,args["property-" + key]);
242    
243     for(var key in routino.restrictions)
244 amb 574 {
245 amb 985 if(key=="oneway" || key=="turns")
246 amb 577 {
247 amb 1493 if(args[key] !== undefined)
248 amb 985 formSetRestriction(key,args[key]);
249 amb 577 }
250 amb 985 else
251     {
252 amb 1493 if(args["restrict-" + key] !== undefined)
253 amb 985 formSetRestriction(key,args["restrict-" + key]);
254     }
255 amb 574 }
256 amb 569
257 amb 577 // Get the home location cookie and compare to each waypoint
258    
259 amb 1483 var cookies=document.cookie.split("; ");
260 amb 577
261     for(var cookie=0;cookie<cookies.length;cookie++)
262     if(cookies[cookie].substr(0,"Routino-home".length)=="Routino-home")
263     {
264     var data=cookies[cookie].split(/[=:;]/);
265    
266     if(data[1]=="lon") homelon=Number(data[2]);
267     if(data[3]=="lat") homelat=Number(data[4]);
268     }
269    
270 amb 1493 if(homelon!==null && homelat!==null)
271 amb 577 {
272 amb 1039 for(var m=1;m<=vismarkers;m++)
273     markerCheckHome(m);
274 amb 577
275     // If the first location is empty and the cookie is set then fill it.
276    
277 amb 1034 if(!routino.point[1].used)
278 amb 1036 markerMoveHome(1);
279 amb 577 }
280 amb 1486
281     updateURLs();
282 amb 569 }
283    
284    
285     //
286 amb 1016 // Function to perform the search if the return key is pressed.
287     // (using 'onchange' only triggers once and is confusing when clicking outside the field).
288     //
289    
290     function searchOnReturnKey(ev)
291     {
292     if(ev.keyCode==13)
293     if(this.name.match(/^search([0-9]+)$/))
294     formSetSearch(RegExp.$1);
295    
296     return(true);
297     }
298    
299    
300     //
301 amb 577 // Change of language in the form
302     //
303    
304 amb 1035 function formSetLanguage(value) // called from router.html (with no arguments)
305 amb 577 {
306 amb 1493 if(value === undefined)
307 amb 985 {
308     for(var lang=0;lang<document.forms["form"].elements["language"].length;lang++)
309     if(document.forms["form"].elements["language"][lang].checked)
310     routino.language=document.forms["form"].elements["language"][lang].value;
311     }
312     else
313     {
314     for(var lang=0;lang<document.forms["form"].elements["language"].length;lang++)
315     if(document.forms["form"].elements["language"][lang].value==value)
316     document.forms["form"].elements["language"][lang].checked=true;
317     else
318     document.forms["form"].elements["language"][lang].checked=false;
319 amb 577
320 amb 985 routino.language=value;
321     }
322 amb 1486
323     updateURLs();
324 amb 577 }
325    
326    
327     //
328 amb 569 // Change of transport in the form
329     //
330    
331 amb 1035 function formSetTransport(value) // called from router.html
332 amb 569 {
333 amb 985 routino.transport=value;
334 amb 569
335 amb 577 for(var key in routino.transports)
336     document.forms["form"].elements["transport"][routino.transports[key]-1].checked=(key==routino.transport);
337 amb 569
338 amb 577 for(var key in routino.profile_highway)
339     document.forms["form"].elements["highway-" + key].value=routino.profile_highway[key][routino.transport];
340 amb 569
341 amb 577 for(var key in routino.profile_speed)
342     document.forms["form"].elements["speed-" + key].value=routino.profile_speed[key][routino.transport];
343 amb 569
344 amb 577 for(var key in routino.profile_property)
345     document.forms["form"].elements["property-" + key].value=routino.profile_property[key][routino.transport];
346 amb 569
347 amb 577 for(var key in routino.restrictions)
348 amb 569 {
349 amb 622 if(key=="oneway" || key=="turns")
350 amb 577 document.forms["form"].elements["restrict-" + key].checked=routino.profile_restrictions[key][routino.transport];
351 amb 569 else
352 amb 577 document.forms["form"].elements["restrict-" + key].value=routino.profile_restrictions[key][routino.transport];
353 amb 569 }
354    
355     paramschanged=true;
356 amb 1486
357     updateURLs();
358 amb 569 }
359    
360    
361     //
362     // Change of highway in the form
363     //
364    
365 amb 1035 function formSetHighway(type,value) // called from router.html (with one argument)
366 amb 569 {
367 amb 1515 if(value == '+')
368 amb 985 {
369 amb 1515 value=routino.profile_highway[type][routino.transport];
370     value=10*Math.floor(value/10)+10;
371 amb 985 }
372 amb 1515 else if(value == '-')
373     {
374     value=routino.profile_highway[type][routino.transport]-10;
375     value=10*Math.ceil(value/10)-10;
376     }
377     else if(value == '=')
378     value=document.forms["form"].elements["highway-" + type].value;
379 amb 569
380 amb 1515 value=Number(value);
381     if(isNaN(value)) value= 50;
382     if(value>100) value=100;
383     if(value< 0) value= 0;
384    
385     document.forms["form"].elements["highway-" + type].value=value;
386     routino.profile_highway[type][routino.transport]=value;
387    
388 amb 569 paramschanged=true;
389 amb 1486
390     updateURLs();
391 amb 569 }
392    
393    
394     //
395     // Change of Speed in the form
396     //
397    
398 amb 1035 function formSetSpeed(type,value) // called from router.html (with one argument)
399 amb 569 {
400 amb 1515 if(value == '+')
401 amb 985 {
402 amb 1515 value=routino.profile_speed[type][routino.transport];
403     if(value<10) value=2*Math.floor(value/2)+2;
404     else if(value<30) value=5*Math.floor(value/5)+5;
405     else value=10*Math.floor(value/10)+10;
406 amb 985 }
407 amb 1515 else if(value == '-')
408     {
409     value=routino.profile_speed[type][routino.transport];
410     if(value<=10) value=2*Math.ceil(value/2)-2;
411     else if(value<=30) value=5*Math.ceil(value/5)-5;
412     else value=10*Math.ceil(value/10)-10;
413     }
414     else if(value == '=')
415     value=document.forms["form"].elements["speed-" + type].value;
416 amb 569
417 amb 1515 value=Number(value);
418     if(isNaN(value)) value= 60;
419     if(value>150) value=150;
420     if(value< 0) value= 0;
421    
422     document.forms["form"].elements["speed-" + type].value=value;
423     routino.profile_speed[type][routino.transport]=value;
424    
425 amb 569 paramschanged=true;
426 amb 1486
427     updateURLs();
428 amb 569 }
429    
430    
431     //
432 amb 574 // Change of Property in the form
433     //
434    
435 amb 1035 function formSetProperty(type,value) // called from router.html (with one argument)
436 amb 574 {
437 amb 1515 if(value == '+')
438 amb 985 {
439 amb 1515 value=routino.profile_property[type][routino.transport];
440     if(value>=40 && value<60) value=2*Math.floor(value/2)+2;
441     else value=5*Math.floor(value/5)+5;
442 amb 985 }
443 amb 1515 else if(value == '-')
444     {
445     value=routino.profile_property[type][routino.transport];
446     if(value>40 && value<=60) value=2*Math.ceil(value/2)-2;
447     else value=5*Math.ceil(value/5)-5;
448     }
449     else if(value == '=')
450     value=document.forms["form"].elements["property-" + type].value;
451 amb 574
452 amb 1515 value=Number(value);
453     if(isNaN(value)) value= 50;
454     if(value>100) value=100;
455     if(value< 0) value= 0;
456    
457     document.forms["form"].elements["property-" + type].value=value;
458     routino.profile_property[type][routino.transport]=value;
459    
460 amb 574 paramschanged=true;
461 amb 1486
462     updateURLs();
463 amb 574 }
464    
465    
466     //
467 amb 622 // Change of Restriction rule in the form
468 amb 569 //
469    
470 amb 1035 function formSetRestriction(type,value) // called from router.html (with one argument)
471 amb 569 {
472 amb 1515 if(type=="oneway" || type=="turns")
473 amb 985 {
474 amb 1515 if(value === undefined)
475 amb 985 routino.profile_restrictions[type][routino.transport]=document.forms["form"].elements["restrict-" + type].checked;
476     else
477 amb 1515 document.forms["form"].elements["restrict-" + type].checked=value;
478    
479     routino.profile_restrictions[type][routino.transport]=value;
480 amb 985 }
481 amb 1515 else if(type=="weight")
482 amb 985 {
483 amb 1515 if(value == '+')
484     value=routino.profile_restrictions[type][routino.transport]+5;
485     else if(value == '-')
486     value=routino.profile_restrictions[type][routino.transport]-5;
487     else if(value == '=')
488     value=document.forms["form"].elements["restrict-" + type].value;
489 amb 569
490 amb 1515 value=Number(value);
491     if(isNaN(value)) value= 0;
492     if(value>50) value=50;
493     if(value< 0) value= 0;
494    
495     document.forms["form"].elements["restrict-" + type].value=value;
496 amb 985 routino.profile_restrictions[type][routino.transport]=value;
497     }
498 amb 1515 else /* if(type=="height" || type=="width" || type=="length") */
499     {
500     if(value == '+')
501     value=routino.profile_restrictions[type][routino.transport]+1;
502     else if(value == '-')
503     value=routino.profile_restrictions[type][routino.transport]-1;
504     else if(value == '=')
505     value=document.forms["form"].elements["restrict-" + type].value;
506 amb 985
507 amb 1515 value=Number(value);
508     if(isNaN(value)) value= 0;
509     if(value>25) value=25;
510     if(value< 0) value= 0;
511    
512     document.forms["form"].elements["restrict-" + type].value=value;
513     routino.profile_restrictions[type][routino.transport]=value;
514     }
515    
516 amb 569 paramschanged=true;
517 amb 1486
518     updateURLs();
519 amb 569 }
520    
521    
522     //
523 amb 577 // Set the feature coordinates from the form when the form changes.
524     //
525    
526 amb 1035 function formSetCoords(marker,lon,lat) // called from router.html (with one argument)
527 amb 577 {
528 amb 1005 clearSearchResult(marker);
529    
530 amb 1493 if(lon === undefined && lat === undefined)
531 amb 985 {
532 amb 1034 lon=document.forms["form"].elements["lon" + marker].value;
533     lat=document.forms["form"].elements["lat" + marker].value;
534 amb 985 }
535 amb 1034
536 amb 1493 if(lon === "" && lat === "")
537 amb 985 {
538 amb 1034 document.forms["form"].elements["lon" + marker].value="";
539     document.forms["form"].elements["lat" + marker].value="";
540 amb 985
541 amb 1034 routino.point[marker].lon="";
542 amb 1483 routino.point[marker].lat="";
543 amb 1486
544     updateURLs();
545 amb 985 }
546 amb 1034 else
547     {
548 amb 1483 var lonlat;
549    
550 amb 1493 if(lon==="")
551 amb 1034 {
552 amb 1483 lonlat=map.getCenter().clone();
553 amb 1034 lonlat.transform(epsg900913,epsg4326);
554 amb 985
555 amb 1034 lon=lonlat.lon;
556     }
557 amb 577
558 amb 1034 if(lon<-180) lon=-180;
559     if(lon>+180) lon=+180;
560 amb 577
561 amb 1493 if(lat==="")
562 amb 1034 {
563 amb 1483 lonlat=map.getCenter().clone();
564 amb 1034 lonlat.transform(epsg900913,epsg4326);
565 amb 577
566 amb 1034 lat=lonlat.lat;
567     }
568 amb 577
569 amb 1034 if(lat<-90 ) lat=-90 ;
570     if(lat>+90 ) lat=+90 ;
571 amb 577
572 amb 1483 lonlat = new OpenLayers.LonLat(lon,lat);
573 amb 1034 lonlat.transform(epsg4326,epsg900913);
574    
575     markers[marker].move(lonlat);
576    
577     markersmoved=true;
578    
579     document.forms["form"].elements["lon" + marker].value=format5f(lon);
580     document.forms["form"].elements["lat" + marker].value=format5f(lat);
581    
582     routino.point[marker].lon=lon;
583     routino.point[marker].lat=lat;
584     routino.point[marker].used=true;
585 amb 1039
586     markerCheckHome(marker);
587 amb 1034 }
588 amb 577 }
589    
590    
591     //
592 amb 1032 // Set the search field from the form when the form changes.
593 amb 1001 //
594    
595 amb 1035 function formSetSearch(marker,search) // called from event handler linked to router.html (with one argument)
596 amb 1001 {
597 amb 1005 clearSearchResult(marker);
598    
599 amb 1493 if(search === undefined)
600 amb 1001 {
601     routino.point[marker].search=document.forms["form"].elements["search" + marker].value;
602    
603     DoSearch(marker);
604     }
605     else
606     {
607     document.forms["form"].elements["search" + marker].value=search;
608    
609     routino.point[marker].search=search;
610     }
611     }
612    
613    
614     //
615 amb 577 // Format a number in printf("%.5f") format.
616     //
617    
618     function format5f(number)
619     {
620     var newnumber=Math.floor(number*100000+0.5);
621     var delta=0;
622    
623     if(newnumber>=0 && newnumber<100000) delta= 100000;
624     if(newnumber<0 && newnumber>-100000) delta=-100000;
625    
626     var string=String(newnumber+delta);
627    
628     var intpart =string.substring(0,string.length-5);
629     var fracpart=string.substring(string.length-5,string.length);
630    
631     if(delta>0) intpart="0";
632     if(delta<0) intpart="-0";
633    
634     return(intpart + "." + fracpart);
635     }
636    
637    
638     //
639     // Build a set of URL arguments
640     //
641    
642 amb 986 function buildURLArguments(lang)
643 amb 577 {
644 amb 986 var url= "transport=" + routino.transport;
645 amb 577
646     for(var marker=1;marker<=vismarkers;marker++)
647 amb 986 if(routino.point[marker].active)
648 amb 577 {
649 amb 985 url=url + ";lon" + marker + "=" + routino.point[marker].lon;
650     url=url + ";lat" + marker + "=" + routino.point[marker].lat;
651 amb 1493 if(routino.point[marker].search !== "")
652 amb 1001 url=url + ";search" + marker + "=" + encodeURIComponent(routino.point[marker].search);
653 amb 577 }
654    
655     for(var key in routino.profile_highway)
656     if(routino.profile_highway[key][routino.transport]!=routino_default.profile_highway[key][routino.transport])
657     url=url + ";highway-" + key + "=" + routino.profile_highway[key][routino.transport];
658    
659     for(var key in routino.profile_speed)
660     if(routino.profile_speed[key][routino.transport]!=routino_default.profile_speed[key][routino.transport])
661     url=url + ";speed-" + key + "=" + routino.profile_speed[key][routino.transport];
662    
663     for(var key in routino.profile_property)
664     if(routino.profile_property[key][routino.transport]!=routino_default.profile_property[key][routino.transport])
665     url=url + ";property-" + key + "=" + routino.profile_property[key][routino.transport];
666    
667     for(var key in routino.restrictions)
668     if(routino.profile_restrictions[key][routino.transport]!=routino_default.profile_restrictions[key][routino.transport])
669     url=url + ";" + key + "=" + routino.profile_restrictions[key][routino.transport];
670    
671 amb 986 if(lang && routino.language)
672 amb 577 url=url + ";language=" + routino.language;
673    
674     return(url);
675     }
676    
677    
678     //
679 amb 986 // Build a set of URL arguments for the map location
680 amb 569 //
681    
682 amb 986 function buildMapArguments()
683 amb 569 {
684 amb 1009 var lonlat = map.getCenter().clone();
685     lonlat.transform(epsg900913,epsg4326);
686 amb 569
687 amb 986 var zoom = map.getZoom() + map.minZoomLevel;
688    
689     return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lon) + ";zoom=" + zoom;
690 amb 569 }
691    
692    
693     //
694 amb 1486 // Update the URLs
695 amb 986 //
696    
697 amb 1486 function updateURLs()
698 amb 986 {
699 amb 1486 var urlargs1=buildURLArguments(true);
700     var urlargs2=buildURLArguments(false);
701     var mapargs=buildMapArguments();
702 amb 986
703 amb 1486 var links=document.getElementsByTagName("a");
704 amb 986
705 amb 1486 for(var i=0; i<links.length; i++)
706     {
707     var element=links[i];
708 amb 986
709 amb 1486 if(element.id == "permalink_url")
710     element.href=location.pathname + "?" + urlargs1 + ";" + mapargs;
711    
712     if(element.id == "visualiser_url")
713     element.href="visualiser.html" + "?" + mapargs;
714    
715     if(element.id == "edit_url")
716     element.href=mapprops.editurl + "?" + mapargs;
717    
718     if(element.id.match(/^lang_([a-zA-Z-]+)_url$/))
719     element.href="router.html" + "." + RegExp.$1 + "?" + urlargs2 + ";" + mapargs;
720     }
721 amb 986 }
722    
723    
724 amb 577 ////////////////////////////////////////////////////////////////////////////////
725     ///////////////////////////////// Map handling /////////////////////////////////
726     ////////////////////////////////////////////////////////////////////////////////
727 amb 569
728     var map;
729 amb 933 var layerMap=[], layerVectors, layerGPX;
730 amb 569 var epsg4326, epsg900913;
731 amb 1491 var routing_type;
732 amb 569
733 amb 985 //
734 amb 569 // Initialise the 'map' object
735     //
736    
737 amb 1035 function map_init() // called from router.html
738 amb 569 {
739 amb 1491 // Create the map (Map URLs and limits are in mapprops.js)
740 amb 985
741 amb 569 epsg4326=new OpenLayers.Projection("EPSG:4326");
742     epsg900913=new OpenLayers.Projection("EPSG:900913");
743    
744     map = new OpenLayers.Map ("map",
745     {
746     controls:[
747     new OpenLayers.Control.Navigation(),
748     new OpenLayers.Control.PanZoomBar(),
749     new OpenLayers.Control.ScaleLine(),
750     new OpenLayers.Control.LayerSwitcher()
751     ],
752    
753     projection: epsg900913,
754     displayProjection: epsg4326,
755    
756 amb 933 minZoomLevel: mapprops.zoomout,
757     numZoomLevels: mapprops.zoomin-mapprops.zoomout+1,
758 amb 1018 maxResolution: 156543.03390625 / Math.pow(2,mapprops.zoomout),
759 amb 569
760 amb 1013 restrictedExtent: new OpenLayers.Bounds(mapprops.westedge,mapprops.southedge,mapprops.eastedge,mapprops.northedge).transform(epsg4326,epsg900913)
761 amb 569 });
762    
763 amb 1491 // Get a URL for the tile (mostly copied from OpenLayers/Layer/XYZ.js).
764    
765     function limitedUrl(bounds)
766     {
767     var res = this.map.getResolution();
768    
769     var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
770     var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
771     var z = this.map.getZoom() + this.map.minZoomLevel;
772    
773     var limit = Math.pow(2, z);
774     x = ((x % limit) + limit) % limit;
775    
776     var xyz = {"x": x, "y": y, "z": z};
777     var url = this.url;
778    
779     if (OpenLayers.Util.isArray(url))
780     {
781     var s = "" + xyz.x + xyz.y + xyz.z;
782     url = this.selectUrl(s, url);
783     }
784    
785     return OpenLayers.String.format(url, xyz);
786     }
787    
788 amb 933 // Add map tile layers
789 amb 569
790 amb 1491 for(var l=0; l<mapprops.mapdata.length; l++)
791 amb 933 {
792 amb 1491 var urls;
793    
794     if(OpenLayers.Util.isArray(mapprops.mapdata[l].tiles.subdomains))
795     {
796     urls=[];
797    
798     for(var s=0; s<mapprops.mapdata[l].tiles.subdomains.length; s++)
799     urls.push(mapprops.mapdata[l].tiles.url.replace(/\${s}/,mapprops.mapdata[l].tiles.subdomains[s]));
800     }
801     else
802     urls=mapprops.mapdata[l].tiles.url;
803    
804 amb 933 layerMap[l] = new OpenLayers.Layer.TMS(mapprops.mapdata[l].label,
805 amb 1491 urls,
806 amb 933 {
807     getURL: limitedUrl,
808     displayOutsideMaxExtent: true,
809     buffer: 1
810     });
811     map.addLayer(layerMap[l]);
812     }
813 amb 569
814 amb 1239 // Update the attribution if the layer changes
815 amb 569
816 amb 1239 function change_attribution_event(event)
817 amb 569 {
818 amb 1491 for(var l=0; l<mapprops.mapdata.length; l++)
819     if(layerMap[l] == event.layer)
820 amb 1239 change_attribution(l);
821     }
822 amb 569
823 amb 1491 map.events.register("changelayer",layerMap,change_attribution_event);
824    
825 amb 1239 function change_attribution(l)
826     {
827     var data_url =mapprops.mapdata[l].attribution.data_url;
828     var data_text=mapprops.mapdata[l].attribution.data_text;
829     var tile_url =mapprops.mapdata[l].attribution.tile_url;
830     var tile_text=mapprops.mapdata[l].attribution.tile_text;
831 amb 569
832 amb 1239 document.getElementById("attribution_data").innerHTML="<a href=\"" + data_url + "\" target=\"data_attribution\">" + data_text + "</a>";
833     document.getElementById("attribution_tile").innerHTML="<a href=\"" + tile_url + "\" target=\"tile_attribution\">" + tile_text + "</a>";
834     }
835    
836     change_attribution(0);
837    
838 amb 569 // Define a GPX layer but don't add it yet
839    
840     layerGPX={shortest: null, quickest: null};
841    
842     gpx_style={shortest: new OpenLayers.Style({},{strokeWidth: 3, strokeColor: "#00FF00"}),
843     quickest: new OpenLayers.Style({},{strokeWidth: 3, strokeColor: "#0000FF"})};
844 amb 985
845 amb 569 // Add a vectors layer
846 amb 985
847 amb 1328 layerVectors = new OpenLayers.Layer.Vector("Markers",{displayInLayerSwitcher: false});
848 amb 569 map.addLayer(layerVectors);
849    
850     // A set of markers
851    
852 amb 574 markers={};
853 amb 569 markersmoved=false;
854     paramschanged=false;
855    
856 amb 1012 for(var marker=1;marker<=mapprops.maxmarkers;marker++)
857 amb 569 {
858 amb 987 markers[marker] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0),{},
859 amb 1483 new OpenLayers.Style({},{externalGraphic: "icons/marker-" + marker + "-red.png",
860 amb 987 fillColor: "white",
861     graphicYOffset: -25,
862     graphicWidth: 21,
863     graphicHeight: 25,
864     display: "none"}));
865 amb 569
866 amb 987 layerVectors.addFeatures([markers[marker]]);
867 amb 569 }
868    
869     // A function to drag the markers
870    
871     var drag = new OpenLayers.Control.DragFeature(layerVectors,
872     {onDrag: dragMove,
873     onComplete: dragComplete });
874     map.addControl(drag);
875     drag.activate();
876    
877     // Markers to highlight a selected point
878    
879 amb 577 for(var highlight in highlights)
880 amb 569 {
881     highlights[highlight] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0),{},
882 amb 577 new OpenLayers.Style({},{strokeColor: route_dark_colours[highlight],
883 amb 574 fillColor: "white",
884 amb 569 pointRadius: 10,
885     strokeWidth: 4,
886     fillOpacity: 0,
887     display: "none"}));
888    
889     layerVectors.addFeatures([highlights[highlight]]);
890     }
891    
892 amb 574 // A popup for routing results
893    
894 amb 577 for(var popup in popups)
895     popups[popup] = createPopup(popup);
896 amb 574
897 amb 569 // Move the map
898    
899 amb 1486 map.events.register("moveend", map, updateURLs);
900    
901 amb 1491 var lon =args["lon"];
902     var lat =args["lat"];
903     var zoom=args["zoom"];
904    
905 amb 1493 if(lon !== undefined && lat !== undefined && zoom !== undefined)
906 amb 569 {
907 amb 933 if(lon<mapprops.westedge) lon=mapprops.westedge;
908     if(lon>mapprops.eastedge) lon=mapprops.eastedge;
909    
910     if(lat<mapprops.southedge) lat=mapprops.southedge;
911     if(lat>mapprops.northedge) lat=mapprops.northedge;
912    
913     if(zoom<mapprops.zoomout) zoom=mapprops.zoomout;
914     if(zoom>mapprops.zoomin) zoom=mapprops.zoomin;
915    
916 amb 1009 var lonlat = new OpenLayers.LonLat(lon,lat);
917     lonlat.transform(epsg4326,epsg900913);
918 amb 569
919     map.moveTo(lonlat,zoom-map.minZoomLevel);
920     }
921 amb 1491 else
922     {
923     map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true));
924     map.maxResolution = map.getResolution();
925     }
926 amb 1334
927     // Unhide editing URL if variable set
928    
929 amb 1493 if(mapprops.editurl !== undefined && mapprops.editurl !== "")
930 amb 1334 {
931 amb 1483 var edit_url=document.getElementById("edit_url");
932 amb 1334
933     edit_url.style.display="";
934     edit_url.href=mapprops.editurl;
935     }
936 amb 1486
937     updateURLs();
938 amb 569 }
939    
940    
941     //
942 amb 1491 // Callback for a drag occuring.
943 amb 569 //
944    
945     function dragMove(feature,pixel)
946     {
947 amb 574 for(var marker in markers)
948 amb 569 if(feature==markers[marker])
949 amb 985 dragSetForm(marker);
950 amb 569 }
951    
952    
953     //
954 amb 1491 // Callback for completing a drag.
955 amb 569 //
956    
957     function dragComplete(feature,pixel)
958     {
959 amb 574 for(var marker in markers)
960 amb 569 if(feature==markers[marker])
961 amb 985 dragSetForm(marker);
962 amb 1486
963     updateURLs();
964 amb 569 }
965    
966    
967 amb 985 //
968     // Set the feature coordinates in the form after dragging.
969     //
970    
971     function dragSetForm(marker)
972     {
973     var lonlat = new OpenLayers.LonLat(markers[marker].geometry.x, markers[marker].geometry.y);
974 amb 1009 lonlat.transform(epsg900913,epsg4326);
975 amb 985
976     var lon=format5f(lonlat.lon);
977     var lat=format5f(lonlat.lat);
978    
979     formSetCoords(marker,lon,lat);
980     }
981    
982    
983 amb 577 ////////////////////////////////////////////////////////////////////////////////
984     /////////////////////////////// Marker handling ////////////////////////////////
985     ////////////////////////////////////////////////////////////////////////////////
986    
987    
988 amb 569 //
989 amb 574 // Toggle a marker on the map.
990 amb 569 //
991    
992 amb 1035 function markerToggleMap(marker) // called from router.html
993 amb 569 {
994 amb 1034 if(!routino.point[marker].used)
995     {
996     routino.point[marker].used=true;
997     markerCentre(marker);
998     markerCoords(marker);
999     }
1000 amb 1005
1001 amb 1032 markerAddRemoveMap(marker,!routino.point[marker].active);
1002     }
1003    
1004    
1005     //
1006     // Show or hide a marker on the map.
1007     //
1008    
1009     function markerAddRemoveMap(marker,active)
1010     {
1011     if(active)
1012     markerAddMap(marker);
1013     else
1014 amb 574 markerRemoveMap(marker);
1015     }
1016    
1017    
1018     //
1019     // Show a marker on the map.
1020     //
1021    
1022     function markerAddMap(marker)
1023     {
1024 amb 1005 clearSearchResult(marker);
1025    
1026 amb 577 markers[marker].style.display = "";
1027 amb 985 routino.point[marker].active=true;
1028 amb 1034 routino.point[marker].used=true;
1029 amb 574
1030 amb 577 updateIcon(marker);
1031 amb 574
1032     markersmoved=true;
1033 amb 1486
1034     updateURLs();
1035 amb 574 }
1036    
1037    
1038     //
1039     // Remove a marker from the map.
1040     //
1041    
1042     function markerRemoveMap(marker)
1043     {
1044 amb 1005 clearSearchResult(marker);
1045    
1046 amb 577 markers[marker].style.display = "none";
1047 amb 985 routino.point[marker].active=false;
1048 amb 574
1049 amb 577 updateIcon(marker);
1050 amb 574
1051 amb 577 markersmoved=true;
1052 amb 1486
1053     updateURLs();
1054 amb 577 }
1055 amb 574
1056 amb 577
1057     //
1058 amb 1001 // Display search string for the marker
1059     //
1060    
1061 amb 1035 function markerSearch(marker) // called from router.html
1062 amb 1001 {
1063 amb 1005 clearSearchResult(marker);
1064    
1065 amb 1011 document.getElementById("coords" + marker).style.display="none";
1066     document.getElementById("search" + marker).style.display="";
1067 amb 1001 }
1068    
1069    
1070     //
1071     // Display coordinates for the marker
1072     //
1073    
1074 amb 1035 function markerCoords(marker) // called from router.html
1075 amb 1001 {
1076 amb 1005 clearSearchResult(marker);
1077    
1078 amb 1011 document.getElementById("search" + marker).style.display="none";
1079     document.getElementById("coords" + marker).style.display="";
1080 amb 1001 }
1081    
1082    
1083     //
1084 amb 577 // Centre the marker on the map
1085     //
1086    
1087 amb 1035 function markerCentre(marker) // called from router.html
1088 amb 577 {
1089 amb 1034 if(!routino.point[marker].used)
1090     return;
1091    
1092 amb 1005 clearSearchResult(marker);
1093    
1094 amb 985 var lonlat=map.getCenter().clone();
1095 amb 1009 lonlat.transform(epsg900913,epsg4326);
1096 amb 577
1097 amb 1486 formSetCoords(marker,format5f(lonlat.lon),format5f(lonlat.lat));
1098 amb 574 }
1099    
1100    
1101     //
1102 amb 984 // Centre the map on the marker
1103     //
1104    
1105 amb 1035 function markerRecentre(marker) // called from router.html
1106 amb 984 {
1107 amb 1034 if(!routino.point[marker].used)
1108     return;
1109    
1110 amb 1005 clearSearchResult(marker);
1111    
1112 amb 1483 var lon=routino.point[marker].lon;
1113     var lat=routino.point[marker].lat;
1114 amb 984
1115 amb 1009 var lonlat = new OpenLayers.LonLat(lon,lat);
1116     lonlat.transform(epsg4326,epsg900913);
1117 amb 984
1118     map.panTo(lonlat);
1119     }
1120    
1121    
1122     //
1123 amb 574 // Clear the current marker.
1124     //
1125    
1126 amb 1035 function markerRemove(marker) // called from router.html
1127 amb 574 {
1128 amb 1005 clearSearchResult(marker);
1129    
1130 amb 1033 for(var m=marker;m<vismarkers;m++)
1131 amb 1039 markerCopy(m,m+1);
1132 amb 574
1133 amb 1033 markerRemoveForm(vismarkers--);
1134 amb 574
1135     if(vismarkers==1)
1136     markerAddAfter(1);
1137     }
1138    
1139    
1140     //
1141     // Add a marker before the current one.
1142     //
1143    
1144     function markerAddBefore(marker)
1145     {
1146 amb 1005 clearSearchResult(marker);
1147    
1148 amb 1012 if(vismarkers==mapprops.maxmarkers || marker==1)
1149 amb 574 return false;
1150    
1151 amb 1033 markerAddForm(++vismarkers);
1152 amb 574
1153 amb 1033 for(var m=vismarkers;m>marker;m--)
1154 amb 1039 markerCopy(m,m-1);
1155 amb 574
1156 amb 1033 markerClearForm(marker-1);
1157 amb 574 }
1158    
1159    
1160     //
1161     // Add a marker after the current one.
1162     //
1163    
1164 amb 1035 function markerAddAfter(marker) // called from router.html
1165 amb 574 {
1166 amb 1005 clearSearchResult(marker);
1167    
1168 amb 1012 if(vismarkers==mapprops.maxmarkers)
1169 amb 574 return false;
1170    
1171 amb 1033 markerAddForm(++vismarkers);
1172 amb 574
1173 amb 1033 for(var m=vismarkers;m>(marker+1);m--)
1174 amb 1039 markerCopy(m,m-1);
1175 amb 574
1176 amb 1033 markerClearForm(marker+1);
1177 amb 569 }
1178    
1179    
1180     //
1181 amb 577 // Set this marker as the home location.
1182     //
1183    
1184 amb 1035 function markerHome(marker) // called from router.html
1185 amb 577 {
1186 amb 1034 if(!routino.point[marker].used)
1187 amb 1036 {
1188     markerMoveHome(marker);
1189     }
1190 amb 1039 else
1191     {
1192     clearSearchResult(marker);
1193 amb 1034
1194 amb 1039 markerSetClearHome(marker,!routino.point[marker].home);
1195     }
1196 amb 577 }
1197    
1198    
1199     //
1200 amb 984 // Set this marker as the current location.
1201     //
1202    
1203 amb 1035 function markerLocate(marker) // called from router.html
1204 amb 984 {
1205 amb 1005 clearSearchResult(marker);
1206    
1207 amb 984 if(navigator.geolocation)
1208     navigator.geolocation.getCurrentPosition(
1209     function(position) {
1210 amb 1032 formSetCoords(marker,position.coords.longitude,position.coords.latitude);
1211     markerAddMap(marker);
1212 amb 984 });
1213     }
1214    
1215    
1216     //
1217 amb 577 // Update an icon to set colours and home or normal marker.
1218     //
1219    
1220     function updateIcon(marker)
1221     {
1222 amb 1036 if(routino.point[marker].home)
1223 amb 577 {
1224 amb 985 if(routino.point[marker].active)
1225 amb 1475 document.getElementById("icon" + marker).src="icons/marker-home-red.png";
1226 amb 577 else
1227 amb 1475 document.getElementById("icon" + marker).src="icons/marker-home-grey.png";
1228 amb 577
1229     markers[marker].style.externalGraphic="icons/marker-home-red.png";
1230     }
1231     else
1232     {
1233 amb 985 if(routino.point[marker].active)
1234 amb 1475 document.getElementById("icon" + marker).src="icons/marker-" + marker + "-red.png";
1235 amb 577 else
1236 amb 1475 document.getElementById("icon" + marker).src="icons/marker-" + marker + "-grey.png";
1237 amb 577
1238     markers[marker].style.externalGraphic="icons/marker-" + marker + "-red.png";
1239     }
1240    
1241     layerVectors.drawFeature(markers[marker]);
1242     }
1243    
1244    
1245     //
1246 amb 1036 // Move the marker to the home location
1247 amb 577 //
1248    
1249 amb 1036 function markerMoveHome(marker)
1250 amb 577 {
1251 amb 1493 if(homelon===null || homelat===null)
1252 amb 1036 return;
1253 amb 577
1254 amb 1036 routino.point[marker].home=true;
1255     routino.point[marker].used=true;
1256 amb 577
1257 amb 1036 formSetCoords(marker,homelon,homelat);
1258     markerAddMap(marker);
1259     }
1260    
1261    
1262     //
1263     // Set or clear the home marker icon
1264     //
1265    
1266     function markerSetClearHome(marker,home)
1267     {
1268 amb 577 var cookie;
1269     var date = new Date();
1270    
1271 amb 1036 if(home)
1272 amb 577 {
1273 amb 1036 homelat=routino.point[marker].lat;
1274     homelon=routino.point[marker].lon;
1275 amb 577
1276 amb 1036 cookie="Routino-home=lon:" + homelon + ":lat:" + homelat;
1277    
1278 amb 577 date.setUTCFullYear(date.getUTCFullYear()+5);
1279    
1280 amb 1036 routino.point[marker].home=true;
1281 amb 577 }
1282     else
1283     {
1284 amb 1036 homelat=null;
1285     homelon=null;
1286    
1287 amb 577 cookie="Routino-home=unset";
1288    
1289     date.setUTCFullYear(date.getUTCFullYear()-1);
1290    
1291 amb 1036 routino.point[marker].home=false;
1292 amb 577 }
1293    
1294     document.cookie=cookie + ";expires=" + date.toGMTString();
1295    
1296 amb 1039 updateIcon(marker);
1297    
1298 amb 1483 for(var m=1;m<=mapprops.maxmarkers;m++)
1299 amb 1039 markerCheckHome(m);
1300     }
1301 amb 1036
1302 amb 1039
1303     //
1304     // Check if a marker is the home marker
1305     //
1306    
1307     function markerCheckHome(marker)
1308     {
1309     var home=routino.point[marker].home;
1310    
1311     if(routino.point[marker].lon==homelon && routino.point[marker].lat==homelat)
1312     routino.point[marker].home=true;
1313     else
1314     routino.point[marker].home=false;
1315    
1316     if(home!=routino.point[marker].home)
1317     updateIcon(marker);
1318 amb 577 }
1319    
1320    
1321     //
1322 amb 574 // Move this marker up.
1323     //
1324    
1325 amb 1035 function markerMoveUp(marker) // called from router.html
1326 amb 574 {
1327     if(marker==1)
1328 amb 984 {
1329     for(var m=1;m<vismarkers;m++)
1330     markerSwap(m,m+1);
1331     }
1332     else
1333     markerSwap(marker,marker-1);
1334 amb 574 }
1335    
1336    
1337     //
1338     // Move this marker down.
1339     //
1340    
1341 amb 1035 function markerMoveDown(marker) // called from router.html
1342 amb 574 {
1343     if(marker==vismarkers)
1344 amb 984 {
1345     for(var m=vismarkers;m>1;m--)
1346     markerSwap(m,m-1);
1347     }
1348     else
1349     markerSwap(marker,marker+1);
1350 amb 574 }
1351    
1352    
1353     //
1354 amb 1039 // Copy a marker from one place to another.
1355 amb 1033 //
1356    
1357 amb 1039 function markerCopy(marker1,marker2)
1358 amb 1033 {
1359     for(var element in routino.point[marker2])
1360     routino.point[marker1][element]=routino.point[marker2][element];
1361    
1362     document.getElementById("search" + marker1).style.display=document.getElementById("search" + marker2).style.display;
1363    
1364     document.getElementById("coords" + marker1).style.display=document.getElementById("coords" + marker2).style.display;
1365    
1366     document.forms["form"].elements["search" + marker1].value=document.forms["form"].elements["search" + marker2].value;
1367    
1368     formSetCoords(marker1,routino.point[marker1].lon,routino.point[marker1].lat);
1369    
1370     markerAddRemoveMap(marker1,routino.point[marker1].active);
1371     }
1372    
1373    
1374     //
1375 amb 574 // Swap a pair of markers.
1376     //
1377    
1378     function markerSwap(marker1,marker2)
1379     {
1380 amb 1033 for(var element in routino.point[marker2])
1381     {
1382     var temp=routino.point[marker1][element];
1383     routino.point[marker1][element]=routino.point[marker2][element];
1384     routino.point[marker2][element]=temp;
1385     }
1386 amb 574
1387 amb 1033 var search_display=document.getElementById("search" + marker1).style.display;
1388     document.getElementById("search" + marker1).style.display=document.getElementById("search" + marker2).style.display;
1389     document.getElementById("search" + marker2).style.display=search_display;
1390 amb 574
1391 amb 1033 var coords_display=document.getElementById("coords" + marker1).style.display;
1392     document.getElementById("coords" + marker1).style.display=document.getElementById("coords" + marker2).style.display;
1393     document.getElementById("coords" + marker2).style.display=coords_display;
1394    
1395     var search_value=document.forms["form"].elements["search" + marker1].value;
1396     document.forms["form"].elements["search" + marker1].value=document.forms["form"].elements["search" + marker2].value;
1397     document.forms["form"].elements["search" + marker2].value=search_value;
1398    
1399     formSetCoords(marker1,routino.point[marker1].lon,routino.point[marker1].lat);
1400     formSetCoords(marker2,routino.point[marker2].lon,routino.point[marker2].lat);
1401    
1402     markerAddRemoveMap(marker1,routino.point[marker1].active);
1403     markerAddRemoveMap(marker2,routino.point[marker2].active);
1404 amb 574 }
1405    
1406    
1407     //
1408     // Reverse the markers.
1409     //
1410    
1411 amb 1035 function markersReverse() // called from router.html
1412 amb 574 {
1413     for(var marker=1;marker<=vismarkers/2;marker++)
1414     markerSwap(marker,vismarkers+1-marker);
1415 amb 1507
1416     markersmoved=true;
1417    
1418     updateURLs();
1419 amb 574 }
1420    
1421    
1422 amb 1033 //
1423 amb 1038 // Close the loop.
1424     //
1425    
1426     function markersLoop() // called from router.html
1427     {
1428     if(vismarkers==mapprops.maxmarkers)
1429     return false;
1430    
1431     if(routino.point[vismarkers].lon==routino.point[1].lon && routino.point[vismarkers].lat==routino.point[1].lat)
1432     return false;
1433    
1434     if(routino.point[vismarkers].used)
1435     markerAddForm(++vismarkers);
1436    
1437 amb 1039 markerCopy(vismarkers,1);
1438 amb 1507
1439     markersmoved=true;
1440    
1441     updateURLs();
1442 amb 1038 }
1443    
1444    
1445     //
1446 amb 1033 // Display the form for a marker
1447     //
1448    
1449     function markerAddForm(marker)
1450     {
1451     document.getElementById("waypoint" + marker).style.display="";
1452     }
1453    
1454    
1455     //
1456     // Hide the form for a marker
1457     //
1458    
1459     function markerRemoveForm(marker)
1460     {
1461     document.getElementById("waypoint" + marker).style.display="none";
1462    
1463     markerClearForm(marker);
1464     }
1465    
1466    
1467     //
1468     // Clear the form for a marker
1469     //
1470    
1471     function markerClearForm(marker)
1472     {
1473     markerRemoveMap(marker);
1474     markerCoords(marker);
1475    
1476     formSetCoords(marker,"","");
1477     formSetSearch(marker,"");
1478    
1479     updateIcon(marker);
1480    
1481     routino.point[marker].used=false;
1482 amb 1036 routino.point[marker].home=false;
1483 amb 1033 }
1484    
1485    
1486 amb 577 ////////////////////////////////////////////////////////////////////////////////
1487     //////////////////////////// Route results handling ////////////////////////////
1488     ////////////////////////////////////////////////////////////////////////////////
1489    
1490     var route_light_colours={shortest: "#60C060", quickest: "#6060C0"};
1491     var route_dark_colours ={shortest: "#408040", quickest: "#404080"};
1492    
1493     var highlights={shortest: null, quickest: null};
1494     var popups={shortest: null, quickest: null};
1495     var routepoints={shortest: {}, quickest: {}};
1496     var gpx_style={shortest: null, quickest: null};
1497    
1498 amb 569
1499     //
1500 amb 577 // Highlight a specific item in the route
1501 amb 569 //
1502    
1503 amb 1507 function highlight(type,line,action)
1504 amb 569 {
1505 amb 1507 if(action == "clear")
1506 amb 577 {
1507     highlights[type].style.display = "none";
1508 amb 569
1509 amb 1499 drawPopup(type,null);
1510 amb 569 }
1511 amb 1507 else if(action == "zoom")
1512     {
1513     var lonlat = new OpenLayers.LonLat(routepoints[type][line].lon,routepoints[type][line].lat);
1514     lonlat.transform(epsg4326,epsg900913);
1515    
1516     map.moveTo(lonlat,map.numZoomLevels-2);
1517     }
1518 amb 577 else
1519 amb 569 {
1520 amb 577 // Marker
1521 amb 569
1522 amb 1009 var lonlat = new OpenLayers.LonLat(routepoints[type][line].lon,routepoints[type][line].lat);
1523     lonlat.transform(epsg4326,epsg900913);
1524 amb 569
1525 amb 577 highlights[type].move(lonlat);
1526 amb 569
1527 amb 1483 if(highlights[type].style.display == "none")
1528 amb 577 highlights[type].style.display = "";
1529 amb 569
1530 amb 577 // Popup
1531 amb 569
1532 amb 1499 drawPopup(type,"<table>" + routepoints[type][line].html + "</table>");
1533 amb 577 }
1534    
1535     layerVectors.drawFeature(highlights[type]);
1536 amb 569 }
1537    
1538    
1539     //
1540 amb 1491 // Create a popup - independent of map because want it fixed on screen not fixed on map.
1541 amb 569 //
1542    
1543 amb 577 function createPopup(type)
1544 amb 569 {
1545 amb 1483 var popup=document.createElement("div");
1546 amb 569
1547 amb 577 popup.className = "popup";
1548 amb 569
1549 amb 577 popup.innerHTML = "<span></span>";
1550 amb 569
1551 amb 577 popup.style.display = "none";
1552 amb 569
1553 amb 577 popup.style.position = "fixed";
1554     popup.style.top = "-4000px";
1555     popup.style.left = "-4000px";
1556     popup.style.zIndex = "100";
1557 amb 569
1558 amb 577 popup.style.padding = "5px";
1559 amb 569
1560 amb 577 popup.style.opacity=0.85;
1561     popup.style.backgroundColor=route_light_colours[type];
1562     popup.style.border="4px solid " + route_dark_colours[type];
1563 amb 569
1564 amb 577 document.body.appendChild(popup);
1565 amb 569
1566 amb 577 return(popup);
1567 amb 569 }
1568    
1569    
1570     //
1571 amb 1491 // Draw a popup - independent of map because want it fixed on screen not fixed on map.
1572 amb 569 //
1573    
1574 amb 1499 function drawPopup(type,html)
1575 amb 569 {
1576 amb 1499 var popup=popups[type];
1577    
1578 amb 1493 if(html===null)
1579 amb 569 {
1580 amb 577 popup.style.display="none";
1581     return;
1582     }
1583 amb 574
1584 amb 577 if(popup.style.display=="none")
1585 amb 569 {
1586 amb 577 var map_div=document.getElementById("map");
1587 amb 569
1588 amb 577 popup.style.left =map_div.offsetParent.offsetLeft+map_div.offsetLeft+60 + "px";
1589     popup.style.top = map_div.offsetTop +30 + "px";
1590 amb 1499 popup.style.width =map_div.clientWidth-120 + "px";
1591 amb 574
1592 amb 577 popup.style.display="";
1593 amb 569 }
1594    
1595 amb 1507 var close="<span style='float: right; cursor: pointer;' onclick='highlight(\""+type+"\",-1,\"clear\")'>X</span>";
1596 amb 1499
1597     popup.innerHTML=close+html;
1598 amb 569 }
1599    
1600    
1601     //
1602 amb 577 // Remove a GPX trace
1603 amb 569 //
1604    
1605 amb 577 function removeGPXTrace(type)
1606 amb 569 {
1607 amb 577 map.removeLayer(layerGPX[type]);
1608     layerGPX[type].destroy();
1609     layerGPX[type]=null;
1610 amb 569
1611 amb 577 displayStatus(type,"no_info");
1612 amb 569
1613 amb 1011 document.getElementById(type + "_links").style.display = "none";
1614 amb 569
1615 amb 1011 document.getElementById(type + "_route").innerHTML = "";
1616 amb 569
1617 amb 577 hideshow_hide(type);
1618     }
1619 amb 569
1620 amb 574
1621 amb 577 ////////////////////////////////////////////////////////////////////////////////
1622     /////////////////////////////// Server handling ////////////////////////////////
1623     ////////////////////////////////////////////////////////////////////////////////
1624 amb 569
1625 amb 1491 //
1626     // Define an AJAX request object
1627     //
1628 amb 1483
1629 amb 1491 function ajaxGET(url,success,failure,state)
1630     {
1631     var ajaxRequest=new XMLHttpRequest();
1632    
1633     function ajaxGOT(options) {
1634     if(this.readyState==4)
1635     if(this.status==200)
1636     { if(typeof(options.success)=="function") options.success(this,options.state); }
1637     else
1638     { if(typeof(options.failure)=="function") options.failure(this,options.state); }
1639     }
1640    
1641     ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); };
1642     ajaxRequest.open("GET", url, true);
1643     ajaxRequest.send(null);
1644     }
1645    
1646    
1647 amb 569 //
1648     // Display data statistics
1649     //
1650    
1651 amb 1035 function displayStatistics() // called from router.html
1652 amb 569 {
1653     // Use AJAX to get the statistics
1654    
1655 amb 1491 ajaxGET("statistics.cgi", runStatisticsSuccess);
1656 amb 569 }
1657    
1658    
1659     //
1660 amb 577 // Success in running data statistics generation.
1661 amb 569 //
1662    
1663     function runStatisticsSuccess(response)
1664     {
1665 amb 1011 document.getElementById("statistics_data").innerHTML="<pre>" + response.responseText + "</pre>";
1666     document.getElementById("statistics_link").style.display="none";
1667 amb 569 }
1668    
1669    
1670     //
1671 amb 577 // Submit form - perform the routing
1672 amb 569 //
1673    
1674 amb 1035 function findRoute(type) // called from router.html
1675 amb 569 {
1676     tab_select("results");
1677    
1678 amb 1483 hideshow_hide("help_options");
1679     hideshow_hide("shortest");
1680     hideshow_hide("quickest");
1681 amb 569
1682 amb 577 displayStatus("result","running");
1683 amb 569
1684 amb 986 var url="router.cgi" + "?" + buildURLArguments(true) + ";type=" + type;
1685 amb 569
1686     // Destroy the existing layer(s)
1687    
1688 amb 1507 highlight("shortest",-1,"clear");
1689     highlight("quickest",-1,"clear");
1690    
1691 amb 569 if(markersmoved || paramschanged)
1692     {
1693 amb 1493 if(layerGPX.shortest!==null)
1694 amb 569 removeGPXTrace("shortest");
1695 amb 1493 if(layerGPX.quickest!==null)
1696 amb 569 removeGPXTrace("quickest");
1697     markersmoved=false;
1698     paramschanged=false;
1699     }
1700 amb 1493 else if(layerGPX[type]!==null)
1701 amb 569 removeGPXTrace(type);
1702    
1703     // Use AJAX to run the router
1704    
1705     routing_type=type;
1706    
1707 amb 1491 ajaxGET(url, runRouterSuccess, runRouterFailure);
1708 amb 569 }
1709    
1710    
1711     //
1712     // Success in running router.
1713     //
1714    
1715     function runRouterSuccess(response)
1716     {
1717 amb 1483 var lines=response.responseText.split("\n");
1718 amb 569
1719     var uuid=lines[0];
1720 amb 1043 var success=lines[1];
1721 amb 569
1722 amb 629 var link;
1723    
1724 amb 569 // Update the status message
1725    
1726 amb 1043 if(success=="ERROR")
1727 amb 569 {
1728 amb 577 displayStatus("result","error");
1729 amb 1483 hideshow_show("help_route");
1730 amb 629
1731     link=document.getElementById("router_log_error");
1732     link.href="results.cgi?uuid=" + uuid + ";type=router;format=log";
1733    
1734 amb 569 return;
1735     }
1736     else
1737     {
1738 amb 577 displayStatus("result","complete");
1739 amb 1483 hideshow_hide("help_route");
1740 amb 629
1741     link=document.getElementById("router_log_complete");
1742     link.href="results.cgi?uuid=" + uuid + ";type=router;format=log";
1743 amb 569 }
1744    
1745     // Update the routing result message
1746    
1747 amb 577 link=document.getElementById(routing_type + "_html");
1748     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=html";
1749 amb 1011
1750 amb 577 link=document.getElementById(routing_type + "_gpx_track");
1751     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track";
1752 amb 1011
1753 amb 577 link=document.getElementById(routing_type + "_gpx_route");
1754     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-route";
1755 amb 1011
1756 amb 577 link=document.getElementById(routing_type + "_text_all");
1757     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text-all";
1758 amb 1011
1759 amb 577 link=document.getElementById(routing_type + "_text");
1760     link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text";
1761 amb 569
1762 amb 1491 document.getElementById(routing_type + "_links").style.display = "";
1763 amb 569
1764     // Add a GPX layer
1765    
1766     var url="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track";
1767    
1768 amb 1013 layerGPX[routing_type] = new OpenLayers.Layer.Vector("GPX (" + routing_type + ")",
1769     {
1770 amb 1491 displayInLayerSwitcher: false,
1771 amb 1013 protocol: new OpenLayers.Protocol.HTTP({url: url, format: new OpenLayers.Format.GPX()}),
1772     strategies: [new OpenLayers.Strategy.Fixed()],
1773     style: gpx_style[routing_type],
1774     projection: map.displayProjection
1775     });
1776 amb 569
1777     map.addLayer(layerGPX[routing_type]);
1778    
1779     hideshow_show(routing_type);
1780    
1781     displayResult(routing_type,uuid);
1782     }
1783    
1784    
1785     //
1786     // Failure in running router.
1787     //
1788    
1789     function runRouterFailure(response)
1790     {
1791 amb 577 displayStatus("result","failed");
1792 amb 569 }
1793    
1794    
1795     //
1796 amb 577 // Display the status
1797     //
1798    
1799     function displayStatus(type,subtype,content)
1800     {
1801 amb 1011 var child=document.getElementById(type + "_status").firstChild;
1802 amb 577
1803     do
1804     {
1805 amb 1493 if(child.id !== undefined)
1806 amb 577 child.style.display="none";
1807    
1808     child=child.nextSibling;
1809     }
1810 amb 1496 while(child !== null);
1811 amb 577
1812 amb 936 var chosen_status=document.getElementById(type + "_status_" + subtype);
1813 amb 577
1814 amb 936 chosen_status.style.display="";
1815 amb 577
1816 amb 1496 if(content !== undefined)
1817 amb 936 chosen_status.innerHTML=content;
1818 amb 577 }
1819    
1820    
1821     //
1822 amb 569 // Display the route
1823     //
1824    
1825     function displayResult(type,uuid)
1826     {
1827     routing_type = type;
1828    
1829     // Add the route
1830    
1831 amb 577 var url="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=html";
1832 amb 569
1833     // Use AJAX to get the route
1834    
1835 amb 1491 ajaxGET(url, getRouteSuccess, getRouteFailure);
1836 amb 569 }
1837    
1838    
1839     //
1840     // Success in getting route.
1841     //
1842    
1843     function getRouteSuccess(response)
1844     {
1845 amb 1483 var lines=response.responseText.split("\n");
1846 amb 569
1847 amb 577 routepoints[routing_type]=[];
1848 amb 569
1849 amb 577 var points=routepoints[routing_type];
1850 amb 569
1851 amb 577 var table=0;
1852     var point=0;
1853     var total_table,total_word;
1854 amb 569
1855 amb 577 for(var line=0;line<lines.length;line++)
1856 amb 569 {
1857 amb 577 var thisline=lines[line];
1858 amb 569
1859 amb 1493 if(table===0)
1860 amb 577 {
1861 amb 1483 if(thisline.match("<table>"))
1862 amb 577 table=1;
1863     else
1864     continue;
1865     }
1866 amb 574
1867 amb 1483 if(thisline.match("</table>"))
1868 amb 577 break;
1869    
1870 amb 1483 if(thisline.match("<tr class='([a-z])'>"))
1871 amb 569 {
1872 amb 577 var rowtype=RegExp.$1;
1873 amb 569
1874 amb 1483 if(rowtype=="c")
1875 amb 577 {
1876 amb 1483 thisline.match("<td class='r'> *([-0-9.]+) *([-0-9.]+)");
1877 amb 577 points[point]={lat: Number(RegExp.$1), lon: Number(RegExp.$2), html: "", highway: "", distance: "", total: ""};
1878 amb 574
1879 amb 577 point++;
1880     }
1881 amb 1483 else if(rowtype=="n")
1882 amb 577 {
1883     points[point-1].html += thisline;
1884     }
1885 amb 1483 else if(rowtype=="s")
1886 amb 577 {
1887 amb 1483 thisline.match("<span class='h'>([^<]+)</span>");
1888 amb 577 points[point-1].highway = RegExp.$1;
1889 amb 574
1890 amb 1483 thisline.match("<span class='d'>([^<]+)</span>");
1891 amb 577 points[point-1].distance = RegExp.$1;
1892 amb 574
1893 amb 1483 thisline.match("(<span class='j'>[^<]+</span>)");
1894 amb 577 points[point-1].total = RegExp.$1;
1895    
1896 amb 1483 thisline.match("^(.*).<span class='j'>");
1897 amb 577
1898     points[point-1].html += RegExp.$1;
1899     }
1900 amb 1483 else if(rowtype=="t")
1901 amb 577 {
1902     points[point-1].html += thisline;
1903    
1904 amb 1483 thisline.match("^(.*<td class='r'>)");
1905 amb 577 total_table = RegExp.$1;
1906    
1907 amb 1483 thisline.match("<td class='l'>([^<]+)<");
1908 amb 577 total_word = RegExp.$1;
1909    
1910 amb 1483 thisline.match("<span class='j'>([^<]+)</span>");
1911 amb 577 points[point-1].total = RegExp.$1;
1912     }
1913 amb 569 }
1914     }
1915    
1916 amb 935 displayStatus(routing_type,"info",points[point-1].total.bold());
1917    
1918 amb 1507 var result="<table onmouseout='highlight(\"" + routing_type + "\",-1,\"clear\")'>";
1919 amb 577
1920     for(var p=0;p<point-1;p++)
1921     {
1922     points[p].html += total_table + points[p].total;
1923    
1924 amb 1507 result=result + "<tr onmouseover='highlight(\"" + routing_type + "\"," + p + ",\"show\")'>" +
1925     "<td onclick='highlight(\"" + routing_type + "\"," + p + ",\"zoom\")'" +
1926     " class='distance' title='" + points[p].distance + "'>#" + (p+1) +
1927 amb 577 "<td class='highway'>" + points[p].highway;
1928     }
1929    
1930 amb 1507 result=result + "<tr onmouseover='highlight(\"" + routing_type + "\"," + p + ",\"show\")'>" +
1931     "<td onclick='highlight(\"" + routing_type + "\"," + p + ",\"zoom\")'" +
1932     " class='distance'>#" + (p+1) +
1933     "<td class='highway'>" + total_word + " " + points[p].total;
1934 amb 577
1935 amb 569 result=result + "</table>";
1936    
1937 amb 1011 document.getElementById(routing_type + "_route").innerHTML=result;
1938 amb 569 }
1939    
1940    
1941     //
1942     // Failure in getting route.
1943     //
1944    
1945     function getRouteFailure(response)
1946     {
1947 amb 1011 document.getElementById(routing_type + "_route").innerHTML = "";
1948 amb 569 }
1949 amb 1001
1950    
1951     //
1952     // Perform a search
1953     //
1954    
1955     function DoSearch(marker)
1956     {
1957     // Use AJAX to get the search result
1958    
1959     var search=routino.point[marker].search;
1960    
1961 amb 1491 var mapbounds=map.getExtent().clone();
1962     mapbounds.transform(epsg900913,epsg4326);
1963 amb 1001
1964 amb 1487 var url="search.cgi";
1965 amb 1008
1966 amb 1487 url=url + "?marker=" + marker;
1967     url=url + ";lonmin=" + format5f(mapbounds.left);
1968     url=url + ";latmin=" + format5f(mapbounds.bottom);
1969     url=url + ";lonmax=" + format5f(mapbounds.right);
1970     url=url + ";latmax=" + format5f(mapbounds.top);
1971     url=url + ";search=" + encodeURIComponent(search);
1972    
1973 amb 1493 ajaxGET(url,runSearchSuccess);
1974 amb 1001 }
1975    
1976    
1977 amb 1005 var searchresults=[];
1978    
1979 amb 1001 //
1980     // Success in running search.
1981     //
1982    
1983     function runSearchSuccess(response)
1984     {
1985 amb 1483 var lines=response.responseText.split("\n");
1986 amb 1001
1987     var marker=lines[0];
1988     var cpuinfo=lines[1]; // not used
1989 amb 1483 var message=lines[2];
1990 amb 1001
1991 amb 1493 if(message !== "")
1992 amb 1005 {
1993     alert(message);
1994     return;
1995     }
1996 amb 1001
1997 amb 1005 searchresults[marker]=[];
1998    
1999     for(var line=3;line<lines.length;line++)
2000     {
2001     var thisline=lines[line];
2002    
2003 amb 1493 if(thisline==="")
2004 amb 1005 break;
2005    
2006 amb 1483 thisline.match("([-.0-9]+) ([-.0-9]+) (.*)");
2007 amb 1005
2008     searchresults[marker][searchresults[marker].length]={lat: Number(RegExp.$1), lon: Number(RegExp.$2), name: RegExp.$3};
2009     }
2010    
2011     if(searchresults[marker].length==1)
2012     {
2013     formSetSearch(marker,searchresults[marker][0].name);
2014 amb 1032 formSetCoords(marker,searchresults[marker][0].lon,searchresults[marker][0].lat);
2015     markerAddMap(marker);
2016 amb 1005 }
2017     else
2018     {
2019     var results=document.getElementById("searchresults" + marker);
2020    
2021     var innerHTML="<td colspan=\"3\">";
2022    
2023     for(var n=0;n<searchresults[marker].length;n++)
2024     {
2025     if(n>0)
2026     innerHTML+="<br>";
2027    
2028     innerHTML+="<a href=\"#\" onclick=\"choseSearchResult(" + marker + "," + n + ")\">" +
2029     searchresults[marker][n].name +
2030     "</a>";
2031     }
2032    
2033     results.innerHTML=innerHTML;
2034    
2035     results.style.display="";
2036     }
2037 amb 1001 }
2038 amb 1005
2039    
2040     //
2041     // Display search results.
2042     //
2043    
2044     function choseSearchResult(marker,n)
2045     {
2046     if(n>=0)
2047     {
2048     formSetSearch(marker,searchresults[marker][n].name);
2049 amb 1032 formSetCoords(marker,searchresults[marker][n].lon,searchresults[marker][n].lat);
2050     markerAddMap(marker);
2051 amb 1005 }
2052     }
2053    
2054    
2055     //
2056     // Clear search results.
2057     //
2058    
2059     function clearSearchResult(marker)
2060     {
2061 amb 1011 document.getElementById("searchresults" + marker).style.display="none";
2062 amb 1005 }