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