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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 635 - (show annotations) (download) (as text)
Fri Feb 11 18:43:15 2011 UTC (14 years, 1 month ago) by amb
File MIME type: application/javascript
File size: 36306 byte(s)
Move the Javascript and Perl profiles into separate files.

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