Routino SVN Repository Browser

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

ViewVC logotype

Contents of /trunk/web/www/routino/router.leaflet.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1493 - (show annotations) (download) (as text)
Sun Jan 26 15:13:36 2014 UTC (11 years, 2 months ago) by amb
File MIME type: application/javascript
File size: 44948 byte(s)
Run jshint again and update some more in the JavaScript.

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