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 1496 - (hide annotations) (download) (as text)
Sun Jan 26 16:33:12 2014 UTC (11 years, 1 month ago) by amb
File MIME type: application/javascript
File size: 49071 byte(s)
Fix bugs in displayStatus() function after jshint tidy-up.

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