Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/web/www/routino/visualiser.leaflet.js
Parent Directory
|
Revision Log
Revision 2067 -
(hide annotations)
(download)
(as text)
Thu Aug 13 18:26:27 2020 UTC (4 years, 7 months ago) by amb
File MIME type: application/javascript
File size: 28592 byte(s)
Thu Aug 13 18:26:27 2020 UTC (4 years, 7 months ago) by amb
File MIME type: application/javascript
File size: 28592 byte(s)
Allow multiple map libraries to be used with the web pages and select between them with a URL argument.
1 | amb | 1491 | // |
2 | // Routino data visualiser web page Javascript | ||
3 | // | ||
4 | // Part of the Routino routing software. | ||
5 | // | ||
6 | amb | 2040 | // This file Copyright 2008-2014, 2019, 2020 Andrew M. Bishop |
7 | amb | 1491 | // |
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 | // | ||
24 | // Data types | ||
25 | // | ||
26 | |||
27 | var data_types=[ | ||
28 | "junctions", | ||
29 | "super", | ||
30 | amb | 1560 | "waytype", |
31 | amb | 1491 | "highway", |
32 | "transport", | ||
33 | "barrier", | ||
34 | "turns", | ||
35 | "speed", | ||
36 | "weight", | ||
37 | "height", | ||
38 | "width", | ||
39 | "length", | ||
40 | "property", | ||
41 | "errorlogs" | ||
42 | ]; | ||
43 | |||
44 | |||
45 | //////////////////////////////////////////////////////////////////////////////// | ||
46 | /////////////////////////////// Initialisation ///////////////////////////////// | ||
47 | //////////////////////////////////////////////////////////////////////////////// | ||
48 | |||
49 | // Process the URL query string and extract the arguments | ||
50 | |||
51 | var legal={"^lon" : "^[-0-9.]+$", | ||
52 | "^lat" : "^[-0-9.]+$", | ||
53 | "^zoom" : "^[0-9]+$"}; | ||
54 | |||
55 | var args={}; | ||
56 | |||
57 | if(location.search.length>1) | ||
58 | { | ||
59 | var query,queries; | ||
60 | |||
61 | query=location.search.replace(/^\?/,""); | ||
62 | query=query.replace(/;/g,"&"); | ||
63 | queries=query.split("&"); | ||
64 | |||
65 | for(var i=0;i<queries.length;i++) | ||
66 | { | ||
67 | queries[i].match(/^([^=]+)(=(.*))?$/); | ||
68 | |||
69 | var k=RegExp.$1; | ||
70 | var v=decodeURIComponent(RegExp.$3); | ||
71 | |||
72 | for(var l in legal) | ||
73 | { | ||
74 | if(k.match(RegExp(l)) && v.match(RegExp(legal[l]))) | ||
75 | args[k]=v; | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | |||
81 | //////////////////////////////////////////////////////////////////////////////// | ||
82 | ///////////////////////////////// Map handling ///////////////////////////////// | ||
83 | //////////////////////////////////////////////////////////////////////////////// | ||
84 | |||
85 | var map; | ||
86 | var layerMap=[], layerHighlights, layerVectors, layerBoxes; | ||
87 | var box; | ||
88 | |||
89 | // | ||
90 | // Initialise the 'map' object | ||
91 | // | ||
92 | |||
93 | function map_init() // called from visualiser.html | ||
94 | { | ||
95 | // Create the map (Map URLs and limits are in mapprops.js) | ||
96 | |||
97 | map = L.map("map", | ||
98 | { | ||
99 | attributionControl: false, | ||
100 | zoomControl: false, | ||
101 | |||
102 | minZoom: mapprops.zoomout, | ||
103 | maxZoom: mapprops.zoomin, | ||
104 | |||
105 | maxBounds: L.latLngBounds(L.latLng(mapprops.southedge,mapprops.westedge),L.latLng(mapprops.northedge,mapprops.eastedge)) | ||
106 | }); | ||
107 | |||
108 | // Add map tile layers | ||
109 | |||
110 | var baselayers={}; | ||
111 | |||
112 | for(var l=0; l<mapprops.mapdata.length; l++) | ||
113 | { | ||
114 | var urls=mapprops.mapdata[l].tiles.url.replace(/\${/g,"{"); | ||
115 | |||
116 | if(mapprops.mapdata[l].tiles.subdomains===undefined) | ||
117 | layerMap[l] = L.tileLayer(urls); | ||
118 | else | ||
119 | layerMap[l] = L.tileLayer(urls, {subdomains: mapprops.mapdata[l].tiles.subdomains}); | ||
120 | |||
121 | baselayers[mapprops.mapdata[l].label]=layerMap[l]; | ||
122 | |||
123 | if(l===0) | ||
124 | map.addLayer(layerMap[l]); | ||
125 | } | ||
126 | |||
127 | // Add the controls | ||
128 | |||
129 | map.addControl(L.control.zoom()); | ||
130 | map.addControl(L.control.scale()); | ||
131 | map.addControl(L.control.layers(baselayers)); | ||
132 | |||
133 | // Update the attribution if the layer changes | ||
134 | |||
135 | function change_attribution_event(event) | ||
136 | { | ||
137 | for(var l=0; l<mapprops.mapdata.length; l++) | ||
138 | if(layerMap[l] == event.layer) | ||
139 | change_attribution(l); | ||
140 | } | ||
141 | |||
142 | map.on("baselayerchange",change_attribution_event); | ||
143 | |||
144 | function change_attribution(l) | ||
145 | { | ||
146 | var data_url =mapprops.mapdata[l].attribution.data_url; | ||
147 | var data_text=mapprops.mapdata[l].attribution.data_text; | ||
148 | var tile_url =mapprops.mapdata[l].attribution.tile_url; | ||
149 | var tile_text=mapprops.mapdata[l].attribution.tile_text; | ||
150 | |||
151 | document.getElementById("attribution_data").innerHTML="<a href=\"" + data_url + "\" target=\"data_attribution\">" + data_text + "</a>"; | ||
152 | document.getElementById("attribution_tile").innerHTML="<a href=\"" + tile_url + "\" target=\"tile_attribution\">" + tile_text + "</a>"; | ||
153 | } | ||
154 | |||
155 | change_attribution(0); | ||
156 | |||
157 | // Add two vectors layers (one for highlights that display behind the vectors) | ||
158 | |||
159 | layerVectors = L.layerGroup(); | ||
160 | map.addLayer(layerVectors); | ||
161 | |||
162 | layerHighlights = L.layerGroup(); | ||
163 | map.addLayer(layerHighlights); | ||
164 | |||
165 | // Handle popup | ||
166 | |||
167 | createPopup(); | ||
168 | |||
169 | // Add a boxes layer | ||
170 | |||
171 | layerBoxes = L.rectangle(map.options.maxBounds,{stroke: false, color: "#f00", weight: 1, opacity: 1.0, | ||
172 | fill: false}); | ||
173 | |||
174 | map.addLayer(layerBoxes); | ||
175 | |||
176 | box=false; | ||
177 | |||
178 | // Move the map | ||
179 | |||
180 | map.on("moveend", updateURLs); | ||
181 | |||
182 | var lon =args["lon"]; | ||
183 | var lat =args["lat"]; | ||
184 | var zoom=args["zoom"]; | ||
185 | |||
186 | amb | 1493 | if(lon !== undefined && lat !== undefined && zoom !== undefined) |
187 | amb | 1491 | { |
188 | if(lon<mapprops.westedge) lon=mapprops.westedge; | ||
189 | if(lon>mapprops.eastedge) lon=mapprops.eastedge; | ||
190 | |||
191 | if(lat<mapprops.southedge) lat=mapprops.southedge; | ||
192 | if(lat>mapprops.northedge) lat=mapprops.northedge; | ||
193 | |||
194 | if(zoom<mapprops.zoomout) zoom=mapprops.zoomout; | ||
195 | if(zoom>mapprops.zoomin) zoom=mapprops.zoomin; | ||
196 | |||
197 | amb | 2040 | map.setView(L.latLng(Number(lat),Number(lon)),zoom); |
198 | amb | 1491 | } |
199 | else | ||
200 | map.fitBounds(map.options.maxBounds); | ||
201 | |||
202 | // Unhide editing URL if variable set | ||
203 | |||
204 | amb | 1493 | if(mapprops.editurl !== undefined && mapprops.editurl !== "") |
205 | amb | 1491 | { |
206 | var edit_url=document.getElementById("edit_url"); | ||
207 | |||
208 | edit_url.style.display=""; | ||
209 | edit_url.href=mapprops.editurl; | ||
210 | } | ||
211 | |||
212 | updateURLs(); | ||
213 | } | ||
214 | |||
215 | |||
216 | // | ||
217 | // Format a number in printf("%.5f") format. | ||
218 | // | ||
219 | |||
220 | function format5f(number) | ||
221 | { | ||
222 | var newnumber=Math.floor(number*100000+0.5); | ||
223 | var delta=0; | ||
224 | |||
225 | if(newnumber>=0 && newnumber<100000) delta= 100000; | ||
226 | if(newnumber<0 && newnumber>-100000) delta=-100000; | ||
227 | |||
228 | var string=String(newnumber+delta); | ||
229 | |||
230 | var intpart =string.substring(0,string.length-5); | ||
231 | var fracpart=string.substring(string.length-5,string.length); | ||
232 | |||
233 | if(delta>0) intpart="0"; | ||
234 | if(delta<0) intpart="-0"; | ||
235 | |||
236 | return(intpart + "." + fracpart); | ||
237 | } | ||
238 | |||
239 | |||
240 | // | ||
241 | // Build a set of URL arguments for the map location | ||
242 | // | ||
243 | |||
244 | function buildMapArguments() | ||
245 | { | ||
246 | var lonlat = map.getCenter(); | ||
247 | |||
248 | var zoom = map.getZoom(); | ||
249 | |||
250 | return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lng) + ";zoom=" + zoom; | ||
251 | } | ||
252 | |||
253 | |||
254 | // | ||
255 | // Update the URLs | ||
256 | // | ||
257 | |||
258 | function updateURLs() | ||
259 | { | ||
260 | var mapargs=buildMapArguments(); | ||
261 | amb | 2067 | var libargs=";library=" + mapprops.library; |
262 | amb | 1491 | |
263 | amb | 2067 | if(!mapprops.libraries) |
264 | libargs=""; | ||
265 | |||
266 | amb | 1491 | var links=document.getElementsByTagName("a"); |
267 | |||
268 | for(var i=0; i<links.length; i++) | ||
269 | { | ||
270 | var element=links[i]; | ||
271 | |||
272 | if(element.id == "permalink_url") | ||
273 | amb | 2067 | element.href=location.pathname + "?" + mapargs + libargs; |
274 | amb | 1491 | |
275 | if(element.id == "router_url") | ||
276 | amb | 2052 | if(location.pathname.match(/visualiser\.html\.([a-zA-Z-]+)$/)) |
277 | amb | 2067 | element.href="router.html" + "." + RegExp.$1 + "?" + mapargs + libargs; |
278 | amb | 2052 | else |
279 | amb | 2067 | element.href="router.html" + "?" + mapargs + libargs; |
280 | amb | 1491 | |
281 | if(element.id == "edit_url") | ||
282 | element.href=mapprops.editurl + "?" + mapargs; | ||
283 | |||
284 | if(element.id.match(/^lang_([a-zA-Z-]+)_url$/)) | ||
285 | amb | 2067 | element.href="visualiser.html" + "." + RegExp.$1 + "?" + mapargs + libargs; |
286 | amb | 1491 | } |
287 | } | ||
288 | |||
289 | |||
290 | //////////////////////////////////////////////////////////////////////////////// | ||
291 | ///////////////////////// Popup and selection handling ///////////////////////// | ||
292 | //////////////////////////////////////////////////////////////////////////////// | ||
293 | |||
294 | var popup=null; | ||
295 | |||
296 | // | ||
297 | // Create a popup - independent of map because want it fixed on screen not fixed on map. | ||
298 | // | ||
299 | |||
300 | function createPopup() | ||
301 | { | ||
302 | popup=document.createElement("div"); | ||
303 | |||
304 | popup.className = "popup"; | ||
305 | |||
306 | popup.innerHTML = "<span></span>"; | ||
307 | |||
308 | popup.style.display = "none"; | ||
309 | |||
310 | popup.style.position = "fixed"; | ||
311 | popup.style.top = "-4000px"; | ||
312 | popup.style.left = "-4000px"; | ||
313 | popup.style.zIndex = "100"; | ||
314 | |||
315 | popup.style.padding = "5px"; | ||
316 | |||
317 | popup.style.opacity=0.85; | ||
318 | popup.style.backgroundColor="#C0C0C0"; | ||
319 | popup.style.border="4px solid #404040"; | ||
320 | |||
321 | document.body.appendChild(popup); | ||
322 | } | ||
323 | |||
324 | |||
325 | // | ||
326 | // Draw a popup - independent of map because want it fixed on screen not fixed on map. | ||
327 | // | ||
328 | |||
329 | function drawPopup(html) | ||
330 | { | ||
331 | amb | 1493 | if(html===null) |
332 | amb | 1491 | { |
333 | popup.style.display="none"; | ||
334 | return; | ||
335 | } | ||
336 | |||
337 | if(popup.style.display=="none") | ||
338 | { | ||
339 | var map_div=document.getElementById("map"); | ||
340 | |||
341 | popup.style.left =map_div.offsetParent.offsetLeft+map_div.offsetLeft+60 + "px"; | ||
342 | popup.style.top = map_div.offsetTop +30 + "px"; | ||
343 | amb | 1499 | popup.style.width =map_div.clientWidth-120 + "px"; |
344 | amb | 1491 | |
345 | popup.style.display=""; | ||
346 | } | ||
347 | |||
348 | amb | 1499 | var close="<span style='float: right; cursor: pointer;' onclick='drawPopup(null)'>X</span>"; |
349 | |||
350 | popup.innerHTML=close+html; | ||
351 | amb | 1491 | } |
352 | |||
353 | |||
354 | // | ||
355 | // Select a circleMarker feature | ||
356 | // | ||
357 | |||
358 | function selectCircleMarkerFeature(feature,dump,event) | ||
359 | { | ||
360 | if(dump) | ||
361 | ajaxGET("visualiser.cgi?dump=" + dump, runDumpSuccess); | ||
362 | |||
363 | layerHighlights.clearLayers(); | ||
364 | |||
365 | var highlight = L.circleMarker(feature.getLatLng(),{radius: 2*feature.getRadius(), fill: true, fillColor: "#F0F000", fillOpacity: 1.0, | ||
366 | stroke: false}); | ||
367 | |||
368 | layerHighlights.addLayer(highlight); | ||
369 | |||
370 | highlight.bringToBack(); | ||
371 | } | ||
372 | |||
373 | |||
374 | // | ||
375 | // Select a Polyline feature | ||
376 | // | ||
377 | |||
378 | function selectPolylineFeature(feature,dump,event) | ||
379 | { | ||
380 | if(dump) | ||
381 | ajaxGET("visualiser.cgi?dump=" + dump, runDumpSuccess); | ||
382 | |||
383 | layerHighlights.clearLayers(); | ||
384 | |||
385 | var highlight = L.polyline(feature.getLatLngs(),{weight: 8, stroke: true, color: "#F0F000", opacity: 1.0, | ||
386 | fill: false}); | ||
387 | |||
388 | layerHighlights.addLayer(highlight); | ||
389 | |||
390 | highlight.bringToBack(); | ||
391 | } | ||
392 | |||
393 | |||
394 | // | ||
395 | // Select a Polygon feature | ||
396 | // | ||
397 | |||
398 | function selectPolygonFeature(feature,dump,event) | ||
399 | { | ||
400 | if(dump) | ||
401 | ajaxGET("visualiser.cgi?dump=" + dump, runDumpSuccess); | ||
402 | |||
403 | layerHighlights.clearLayers(); | ||
404 | |||
405 | var highlight = L.polygon(feature.getLatLngs(),{weight: 8, stroke: true, color: "#F0F000", opacity: 1.0, | ||
406 | fill: false}); | ||
407 | |||
408 | layerHighlights.addLayer(highlight); | ||
409 | |||
410 | highlight.bringToBack(); | ||
411 | } | ||
412 | |||
413 | |||
414 | // | ||
415 | // Un-select a feature | ||
416 | // | ||
417 | |||
418 | function unselectFeature(feature) | ||
419 | { | ||
420 | layerHighlights.clearLayers(); | ||
421 | |||
422 | drawPopup(null); | ||
423 | } | ||
424 | |||
425 | |||
426 | // | ||
427 | // Display the dump data | ||
428 | // | ||
429 | |||
430 | function runDumpSuccess(response) | ||
431 | { | ||
432 | var string=response.responseText; | ||
433 | |||
434 | amb | 2041 | if(mapprops.browseurl !== undefined && mapprops.browseurl !== "") |
435 | amb | 1491 | { |
436 | var types=["node", "way", "relation"]; | ||
437 | var Types=["Node", "Way", "Relation"]; | ||
438 | |||
439 | for(var t in types) | ||
440 | { | ||
441 | var Type=Types[t]; | ||
442 | var type=types[t]; | ||
443 | |||
444 | var regexp=RegExp(Type + " [0-9]+"); | ||
445 | |||
446 | var match; | ||
447 | |||
448 | amb | 1493 | while((match=string.match(regexp)) !== null) |
449 | amb | 1491 | { |
450 | match=String(match); | ||
451 | |||
452 | var id=match.slice(1+type.length,match.length); | ||
453 | |||
454 | string=string.replace(regexp,Type + " <a href='" + mapprops.browseurl + "/" + type + "/" + id + "' target='" + type + id + "'>" + id + "</a>"); | ||
455 | } | ||
456 | } | ||
457 | } | ||
458 | |||
459 | drawPopup(string.split("\n").join("<br>")); | ||
460 | } | ||
461 | |||
462 | |||
463 | //////////////////////////////////////////////////////////////////////////////// | ||
464 | /////////////////////////////// Server handling //////////////////////////////// | ||
465 | //////////////////////////////////////////////////////////////////////////////// | ||
466 | |||
467 | // | ||
468 | // Define an AJAX request object | ||
469 | // | ||
470 | |||
471 | function ajaxGET(url,success,failure,state) | ||
472 | { | ||
473 | var ajaxRequest=new XMLHttpRequest(); | ||
474 | |||
475 | function ajaxGOT(options) { | ||
476 | if(this.readyState==4) | ||
477 | if(this.status==200) | ||
478 | { if(typeof(options.success)=="function") options.success(this,options.state); } | ||
479 | else | ||
480 | { if(typeof(options.failure)=="function") options.failure(this,options.state); } | ||
481 | } | ||
482 | |||
483 | ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); }; | ||
484 | ajaxRequest.open("GET", url, true); | ||
485 | ajaxRequest.send(null); | ||
486 | } | ||
487 | |||
488 | |||
489 | // | ||
490 | // Display the status | ||
491 | // | ||
492 | |||
493 | function displayStatus(type,subtype,content) | ||
494 | { | ||
495 | var child=document.getElementById("result_status").firstChild; | ||
496 | |||
497 | do | ||
498 | { | ||
499 | amb | 1493 | if(child.id !== undefined) |
500 | amb | 1491 | child.style.display="none"; |
501 | |||
502 | child=child.nextSibling; | ||
503 | } | ||
504 | amb | 1496 | while(child !== null); |
505 | amb | 1491 | |
506 | var chosen_status=document.getElementById("result_status_" + type); | ||
507 | |||
508 | chosen_status.style.display=""; | ||
509 | |||
510 | amb | 1496 | if(subtype !== undefined) |
511 | amb | 1491 | { |
512 | var format_status=document.getElementById("result_status_" + subtype).innerHTML; | ||
513 | |||
514 | chosen_status.innerHTML=format_status.replace("#",String(content)); | ||
515 | } | ||
516 | } | ||
517 | |||
518 | |||
519 | // | ||
520 | // Display data statistics | ||
521 | // | ||
522 | |||
523 | function displayStatistics() | ||
524 | { | ||
525 | // Use AJAX to get the statistics | ||
526 | |||
527 | ajaxGET("statistics.cgi", runStatisticsSuccess); | ||
528 | } | ||
529 | |||
530 | |||
531 | // | ||
532 | // Success in running data statistics generation. | ||
533 | // | ||
534 | |||
535 | function runStatisticsSuccess(response) | ||
536 | { | ||
537 | document.getElementById("statistics_data").innerHTML="<pre>" + response.responseText + "</pre>"; | ||
538 | document.getElementById("statistics_link").style.display="none"; | ||
539 | } | ||
540 | |||
541 | |||
542 | // | ||
543 | // Get the requested data | ||
544 | // | ||
545 | |||
546 | function displayData(datatype) // called from visualiser.html | ||
547 | { | ||
548 | for(var data in data_types) | ||
549 | hideshow_hide(data_types[data]); | ||
550 | |||
551 | amb | 1493 | if(datatype !== "") |
552 | amb | 1491 | hideshow_show(datatype); |
553 | |||
554 | // Delete the old data | ||
555 | |||
556 | unselectFeature(); | ||
557 | |||
558 | layerVectors.clearLayers(); | ||
559 | layerHighlights.clearLayers(); | ||
560 | |||
561 | layerBoxes.setStyle({stroke:false}); | ||
562 | box=false; | ||
563 | |||
564 | // Print the status | ||
565 | |||
566 | displayStatus("no_data"); | ||
567 | |||
568 | // Return if just here to clear the data | ||
569 | |||
570 | amb | 1493 | if(datatype === "") |
571 | amb | 1491 | return; |
572 | |||
573 | // Get the new data | ||
574 | |||
575 | var mapbounds=map.getBounds(); | ||
576 | |||
577 | var url="visualiser.cgi"; | ||
578 | |||
579 | url=url + "?lonmin=" + format5f(mapbounds.getWest()); | ||
580 | url=url + ";latmin=" + format5f(mapbounds.getSouth()); | ||
581 | url=url + ";lonmax=" + format5f(mapbounds.getEast()); | ||
582 | url=url + ";latmax=" + format5f(mapbounds.getNorth()); | ||
583 | url=url + ";data=" + datatype; | ||
584 | |||
585 | // Use AJAX to get the data | ||
586 | |||
587 | switch(datatype) | ||
588 | { | ||
589 | case "junctions": | ||
590 | ajaxGET(url, runJunctionsSuccess, runFailure); | ||
591 | break; | ||
592 | case "super": | ||
593 | ajaxGET(url, runSuperSuccess, runFailure); | ||
594 | break; | ||
595 | amb | 1560 | case "waytype": |
596 | var waytype; | ||
597 | var waytypes=document.forms["waytypes"].elements["waytype"]; | ||
598 | for(var h in waytypes) | ||
599 | if(waytypes[h].checked) | ||
600 | waytype=waytypes[h].value; | ||
601 | url+="-" + waytype; | ||
602 | ajaxGET(url, runWaytypeSuccess, runFailure); | ||
603 | amb | 1491 | break; |
604 | case "highway": | ||
605 | var highway; | ||
606 | var highways=document.forms["highways"].elements["highway"]; | ||
607 | for(var h in highways) | ||
608 | if(highways[h].checked) | ||
609 | highway=highways[h].value; | ||
610 | url+="-" + highway; | ||
611 | ajaxGET(url, runHighwaySuccess, runFailure); | ||
612 | break; | ||
613 | case "transport": | ||
614 | var transport; | ||
615 | var transports=document.forms["transports"].elements["transport"]; | ||
616 | for(var t in transports) | ||
617 | if(transports[t].checked) | ||
618 | transport=transports[t].value; | ||
619 | url+="-" + transport; | ||
620 | ajaxGET(url, runTransportSuccess, runFailure); | ||
621 | break; | ||
622 | case "barrier": | ||
623 | var transport; | ||
624 | var transports=document.forms["barriers"].elements["barrier"]; | ||
625 | for(var t in transports) | ||
626 | if(transports[t].checked) | ||
627 | transport=transports[t].value; | ||
628 | url+="-" + transport; | ||
629 | ajaxGET(url, runBarrierSuccess, runFailure); | ||
630 | break; | ||
631 | case "turns": | ||
632 | ajaxGET(url, runTurnsSuccess, runFailure); | ||
633 | break; | ||
634 | case "speed": | ||
635 | case "weight": | ||
636 | case "height": | ||
637 | case "width": | ||
638 | case "length": | ||
639 | ajaxGET(url, runLimitSuccess, runFailure); | ||
640 | break; | ||
641 | case "property": | ||
642 | var property; | ||
643 | var properties=document.forms["properties"].elements["property"]; | ||
644 | for(var p in properties) | ||
645 | if(properties[p].checked) | ||
646 | property=properties[p].value; | ||
647 | url+="-" + property; | ||
648 | ajaxGET(url, runPropertySuccess, runFailure); | ||
649 | break; | ||
650 | case "errorlogs": | ||
651 | ajaxGET(url, runErrorlogSuccess, runFailure); | ||
652 | break; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | |||
657 | // | ||
658 | amb | 2006 | // Add a bounding box |
659 | // | ||
660 | |||
661 | function addBox(words) | ||
662 | { | ||
663 | amb | 2040 | var lat1=Number(words[0]); |
664 | var lon1=Number(words[1]); | ||
665 | var lat2=Number(words[2]); | ||
666 | var lon2=Number(words[3]); | ||
667 | amb | 2006 | |
668 | var bounds = L.latLngBounds(L.latLng(lat1,lon1),L.latLng(lat2,lon2)); | ||
669 | |||
670 | layerBoxes.setBounds(bounds); | ||
671 | |||
672 | layerBoxes.setStyle({stroke: true}); | ||
673 | box=true; | ||
674 | } | ||
675 | |||
676 | |||
677 | // | ||
678 | amb | 1491 | // Success in getting the junctions. |
679 | // | ||
680 | |||
681 | function runJunctionsSuccess(response) | ||
682 | { | ||
683 | var lines=response.responseText.split("\n"); | ||
684 | |||
685 | var junction_colours={ | ||
686 | 0: "#FFFFFF", | ||
687 | 1: "#FF0000", | ||
688 | 2: "#FFFF00", | ||
689 | 3: "#00FF00", | ||
690 | 4: "#8B4513", | ||
691 | 5: "#00BFFF", | ||
692 | 6: "#FF69B4", | ||
693 | 7: "#000000", | ||
694 | 8: "#000000", | ||
695 | 9: "#000000" | ||
696 | }; | ||
697 | |||
698 | for(var line=0;line<lines.length;line++) | ||
699 | { | ||
700 | var words=lines[line].split(" "); | ||
701 | |||
702 | amb | 1493 | if(line === 0) |
703 | amb | 2006 | addBox(words); |
704 | amb | 1493 | else if(words[0] !== "") |
705 | amb | 1491 | { |
706 | var dump=words[0]; | ||
707 | amb | 2040 | var lat=Number(words[1]); |
708 | var lon=Number(words[2]); | ||
709 | amb | 1491 | var count=words[3]; |
710 | |||
711 | var lonlat = L.latLng(lat,lon); | ||
712 | |||
713 | var feature = L.circleMarker(lonlat,{radius: 2, fill: true, fillColor: junction_colours[count], fillOpacity: 1.0, | ||
714 | stroke: false}); | ||
715 | |||
716 | feature.on("click", (function(f,d) { return function(evt) { selectCircleMarkerFeature(f,d,evt); }; }(feature,dump))); | ||
717 | |||
718 | layerVectors.addLayer(feature); | ||
719 | } | ||
720 | } | ||
721 | |||
722 | displayStatus("data","junctions",lines.length-2); | ||
723 | } | ||
724 | |||
725 | |||
726 | // | ||
727 | // Success in getting the super-node and super-segments | ||
728 | // | ||
729 | |||
730 | function runSuperSuccess(response) | ||
731 | { | ||
732 | var lines=response.responseText.split("\n"); | ||
733 | |||
734 | var nodelonlat; | ||
735 | |||
736 | for(var line=0;line<lines.length;line++) | ||
737 | { | ||
738 | var words=lines[line].split(" "); | ||
739 | |||
740 | amb | 1493 | if(line === 0) |
741 | amb | 2006 | addBox(words); |
742 | amb | 1493 | else if(words[0] !== "") |
743 | amb | 1491 | { |
744 | var dump=words[0]; | ||
745 | amb | 2040 | var lat=Number(words[1]); |
746 | var lon=Number(words[2]); | ||
747 | amb | 1491 | |
748 | var lonlat = L.latLng(lat,lon); | ||
749 | |||
750 | if(dump.charAt(0) == "n") | ||
751 | { | ||
752 | nodelonlat=lonlat; | ||
753 | |||
754 | var feature = L.circleMarker(lonlat,{radius: 4, fill: true, fillColor: "#FF0000", fillOpacity: 1.0, | ||
755 | stroke: false}); | ||
756 | |||
757 | feature.on("click", (function(f,d) { return function(evt) { selectCircleMarkerFeature(f,d,evt); }; }(feature,dump))); | ||
758 | |||
759 | layerVectors.addLayer(feature); | ||
760 | } | ||
761 | else | ||
762 | { | ||
763 | var feature = L.polyline([nodelonlat,lonlat],{weight: 2, stroke: true, color: "#FF0000", opacity: 1.0, | ||
764 | fill: false}); | ||
765 | |||
766 | feature.on("click", (function(f,d) { return function(evt) { selectPolylineFeature(f,d,evt); }; }(feature,dump))); | ||
767 | |||
768 | layerVectors.addLayer(feature); | ||
769 | } | ||
770 | } | ||
771 | } | ||
772 | |||
773 | displayStatus("data","super",lines.length-2); | ||
774 | } | ||
775 | |||
776 | |||
777 | // | ||
778 | amb | 1560 | // Success in getting the waytype data |
779 | amb | 1491 | // |
780 | |||
781 | amb | 1560 | function runWaytypeSuccess(response) |
782 | amb | 1491 | { |
783 | var hex={0: "00", 1: "11", 2: "22", 3: "33", 4: "44", 5: "55", 6: "66", 7: "77", | ||
784 | 8: "88", 9: "99", 10: "AA", 11: "BB", 12: "CC", 13: "DD", 14: "EE", 15: "FF"}; | ||
785 | |||
786 | var lines=response.responseText.split("\n"); | ||
787 | |||
788 | for(var line=0;line<lines.length;line++) | ||
789 | { | ||
790 | var words=lines[line].split(" "); | ||
791 | |||
792 | amb | 1493 | if(line === 0) |
793 | amb | 2006 | addBox(words); |
794 | amb | 1493 | else if(words[0] !== "") |
795 | amb | 1491 | { |
796 | var dump=words[0]; | ||
797 | amb | 2040 | var lat1=Number(words[1]); |
798 | var lon1=Number(words[2]); | ||
799 | var lat2=Number(words[3]); | ||
800 | var lon2=Number(words[4]); | ||
801 | amb | 1491 | |
802 | var lonlat1 = L.latLng(lat1,lon1); | ||
803 | var lonlat2 = L.latLng(lat2,lon2); | ||
804 | |||
805 | var point1 = map.options.crs.latLngToPoint(lonlat1,15); | ||
806 | var point2 = map.options.crs.latLngToPoint(lonlat2,15); | ||
807 | |||
808 | var dy = point2.y-point1.y; | ||
809 | var dx = point2.x-point1.x; | ||
810 | var dist = Math.sqrt(dx*dx+dy*dy)/2; | ||
811 | var ang = Math.atan2(-dy,dx); | ||
812 | |||
813 | var point3 = L.point(point1.x-dy/dist,point1.y+dx/dist); | ||
814 | var point4 = L.point(point1.x+dy/dist,point1.y-dx/dist); | ||
815 | |||
816 | var lonlat3 = map.options.crs.pointToLatLng(point3,15); | ||
817 | var lonlat4 = map.options.crs.pointToLatLng(point4,15); | ||
818 | |||
819 | var r=Math.round(7.5+7.9*Math.cos(ang)); | ||
820 | var g=Math.round(7.5+7.9*Math.cos(ang+2.0943951)); | ||
821 | var b=Math.round(7.5+7.9*Math.cos(ang-2.0943951)); | ||
822 | var colour = "#" + hex[r] + hex[g] + hex[b]; | ||
823 | |||
824 | var feature = L.polygon([lonlat2,lonlat3,lonlat4],{weight: 2, stroke: true, color: colour, opacity: 1.0, | ||
825 | fill: false}); | ||
826 | |||
827 | feature.on("click", (function(f,d) { return function(evt) { selectPolygonFeature(f,d,evt); }; }(feature,dump))); | ||
828 | |||
829 | layerVectors.addLayer(feature); | ||
830 | } | ||
831 | } | ||
832 | |||
833 | amb | 1560 | displayStatus("data","waytype",lines.length-2); |
834 | amb | 1491 | } |
835 | |||
836 | |||
837 | // | ||
838 | // Success in getting the highway data | ||
839 | // | ||
840 | |||
841 | function runHighwaySuccess(response) | ||
842 | { | ||
843 | var lines=response.responseText.split("\n"); | ||
844 | |||
845 | for(var line=0;line<lines.length;line++) | ||
846 | { | ||
847 | var words=lines[line].split(" "); | ||
848 | |||
849 | amb | 1493 | if(line === 0) |
850 | amb | 2006 | addBox(words); |
851 | amb | 1493 | else if(words[0] !== "") |
852 | amb | 1491 | { |
853 | var dump=words[0]; | ||
854 | amb | 2040 | var lat1=Number(words[1]); |
855 | var lon1=Number(words[2]); | ||
856 | var lat2=Number(words[3]); | ||
857 | var lon2=Number(words[4]); | ||
858 | amb | 1491 | |
859 | var lonlat1 = L.latLng(lat1,lon1); | ||
860 | var lonlat2 = L.latLng(lat2,lon2); | ||
861 | |||
862 | var feature = L.polyline([lonlat1,lonlat2],{weight: 2, stroke: true, color: "#FF0000", opacity: 1.0, | ||
863 | fill: false}); | ||
864 | |||
865 | feature.on("click", (function(f,d) { return function(evt) { selectPolylineFeature(f,d,evt); }; }(feature,dump))); | ||
866 | |||
867 | layerVectors.addLayer(feature); | ||
868 | } | ||
869 | } | ||
870 | |||
871 | displayStatus("data","highway",lines.length-2); | ||
872 | } | ||
873 | |||
874 | |||
875 | // | ||
876 | // Success in getting the transport data | ||
877 | // | ||
878 | |||
879 | function runTransportSuccess(response) | ||
880 | { | ||
881 | var lines=response.responseText.split("\n"); | ||
882 | |||
883 | for(var line=0;line<lines.length;line++) | ||
884 | { | ||
885 | var words=lines[line].split(" "); | ||
886 | |||
887 | amb | 1493 | if(line === 0) |
888 | amb | 2006 | addBox(words); |
889 | amb | 1493 | else if(words[0] !== "") |
890 | amb | 1491 | { |
891 | var dump=words[0]; | ||
892 | amb | 2040 | var lat1=Number(words[1]); |
893 | var lon1=Number(words[2]); | ||
894 | var lat2=Number(words[3]); | ||
895 | var lon2=Number(words[4]); | ||
896 | amb | 1491 | |
897 | var lonlat1 = L.latLng(lat1,lon1); | ||
898 | var lonlat2 = L.latLng(lat2,lon2); | ||
899 | |||
900 | var feature = L.polyline([lonlat1,lonlat2],{weight: 2, stroke: true, color: "#FF0000", opacity: 1.0, | ||
901 | fill: false}); | ||
902 | |||
903 | feature.on("click", (function(f,d) { return function(evt) { selectPolylineFeature(f,d,evt); }; }(feature,dump))); | ||
904 | |||
905 | layerVectors.addLayer(feature); | ||
906 | } | ||
907 | } | ||
908 | |||
909 | displayStatus("data","transport",lines.length-2); | ||
910 | } | ||
911 | |||
912 | |||
913 | // | ||
914 | // Success in getting the barrier data | ||
915 | // | ||
916 | |||
917 | function runBarrierSuccess(response) | ||
918 | { | ||
919 | var lines=response.responseText.split("\n"); | ||
920 | |||
921 | for(var line=0;line<lines.length;line++) | ||
922 | { | ||
923 | var words=lines[line].split(" "); | ||
924 | |||
925 | amb | 1493 | if(line === 0) |
926 | amb | 2006 | addBox(words); |
927 | amb | 1493 | else if(words[0] !== "") |
928 | amb | 1491 | { |
929 | var dump=words[0]; | ||
930 | amb | 2040 | var lat=Number(words[1]); |
931 | var lon=Number(words[2]); | ||
932 | amb | 1491 | |
933 | var lonlat = L.latLng(lat,lon); | ||
934 | |||
935 | var feature = L.circleMarker(lonlat,{radius: 2, fill: true, fillColor: "#FF0000", fillOpacity: 1.0, | ||
936 | stroke: false}); | ||
937 | |||
938 | feature.on("click", (function(f,d) { return function(evt) { selectCircleMarkerFeature(f,d,evt); }; }(feature,dump))); | ||
939 | |||
940 | layerVectors.addLayer(feature); | ||
941 | } | ||
942 | } | ||
943 | |||
944 | displayStatus("data","barrier",lines.length-2); | ||
945 | } | ||
946 | |||
947 | |||
948 | // | ||
949 | // Success in getting the turn restrictions data | ||
950 | // | ||
951 | |||
952 | function runTurnsSuccess(response) | ||
953 | { | ||
954 | var lines=response.responseText.split("\n"); | ||
955 | |||
956 | for(var line=0;line<lines.length;line++) | ||
957 | { | ||
958 | var words=lines[line].split(" "); | ||
959 | |||
960 | amb | 1493 | if(line === 0) |
961 | amb | 2006 | addBox(words); |
962 | amb | 1493 | else if(words[0] !== "") |
963 | amb | 1491 | { |
964 | var dump=words[0]; | ||
965 | amb | 2040 | var lat1=Number(words[1]); |
966 | var lon1=Number(words[2]); | ||
967 | var lat2=Number(words[3]); | ||
968 | var lon2=Number(words[4]); | ||
969 | var lat3=Number(words[5]); | ||
970 | var lon3=Number(words[6]); | ||
971 | amb | 1491 | |
972 | var lonlat1 = L.latLng(lat1,lon1); | ||
973 | var lonlat2 = L.latLng(lat2,lon2); | ||
974 | var lonlat3 = L.latLng(lat3,lon3); | ||
975 | |||
976 | var feature = L.polygon([lonlat1,lonlat2,lonlat3],{weight: 2, stroke: true, color: "#FF0000", opacity: 1.0, | ||
977 | fill: false}); | ||
978 | |||
979 | feature.on("click", (function(f,d) { return function(evt) { selectPolygonFeature(f,d,evt); }; }(feature,dump))); | ||
980 | |||
981 | layerVectors.addLayer(feature); | ||
982 | } | ||
983 | } | ||
984 | |||
985 | displayStatus("data","turns",lines.length-2); | ||
986 | } | ||
987 | |||
988 | |||
989 | // | ||
990 | // Success in getting the speed/weight/height/width/length limits | ||
991 | // | ||
992 | |||
993 | function runLimitSuccess(response) | ||
994 | { | ||
995 | var lines=response.responseText.split("\n"); | ||
996 | |||
997 | var nodelonlat; | ||
998 | |||
999 | for(var line=0;line<lines.length;line++) | ||
1000 | { | ||
1001 | var words=lines[line].split(" "); | ||
1002 | |||
1003 | amb | 1493 | if(line === 0) |
1004 | amb | 2006 | addBox(words); |
1005 | amb | 1493 | else if(words[0] !== "") |
1006 | amb | 1491 | { |
1007 | var dump=words[0]; | ||
1008 | amb | 2040 | var lat=Number(words[1]); |
1009 | var lon=Number(words[2]); | ||
1010 | amb | 1491 | var number=words[3]; |
1011 | |||
1012 | var lonlat = L.latLng(lat,lon); | ||
1013 | |||
1014 | amb | 1493 | if(number === undefined) |
1015 | amb | 1491 | { |
1016 | nodelonlat=lonlat; | ||
1017 | |||
1018 | var feature = L.circleMarker(lonlat,{radius: 3, fill: true, fillColor: "#FF0000", fillOpacity: 1.0, | ||
1019 | stroke: false}); | ||
1020 | |||
1021 | feature.on("click", (function(f,d) { return function(evt) { selectCircleMarkerFeature(f,d,evt); }; }(feature,dump))); | ||
1022 | |||
1023 | layerVectors.addLayer(feature); | ||
1024 | } | ||
1025 | else | ||
1026 | { | ||
1027 | var lonlat = L.latLng(lat,lon); | ||
1028 | |||
1029 | var feature = L.polyline([nodelonlat,lonlat],{weight: 2, stroke: true, color: "#FF0000", opacity: 1.0, | ||
1030 | fill: false}); | ||
1031 | |||
1032 | feature.on("click", (function(f,d) { return function(evt) { selectPolylineFeature(f,d,evt); }; }(feature,dump))); | ||
1033 | |||
1034 | layerVectors.addLayer(feature); | ||
1035 | |||
1036 | var point1 = map.options.crs.latLngToPoint(nodelonlat,15); | ||
1037 | var point2 = map.options.crs.latLngToPoint(lonlat ,15); | ||
1038 | |||
1039 | var dy = point2.y-point1.y; | ||
1040 | var dx = point2.x-point1.x; | ||
1041 | var dist = Math.sqrt(dx*dx+dy*dy)/24; | ||
1042 | |||
1043 | var point = L.point(point1.x+dx/dist,point1.y+dy/dist); | ||
1044 | |||
1045 | feature=L.marker(map.options.crs.pointToLatLng(point,15), {clickable: false, | ||
1046 | icon: L.icon({iconUrl: "icons/limit-" + number + ".png", | ||
1047 | iconSize: L.point(19,19), | ||
1048 | iconAnchor: L.point(9,10)})}); | ||
1049 | |||
1050 | layerVectors.addLayer(feature); | ||
1051 | } | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | displayStatus("data","limit",lines.length-2); | ||
1056 | } | ||
1057 | |||
1058 | |||
1059 | // | ||
1060 | // Success in getting the property data | ||
1061 | // | ||
1062 | |||
1063 | function runPropertySuccess(response) | ||
1064 | { | ||
1065 | var lines=response.responseText.split("\n"); | ||
1066 | |||
1067 | for(var line=0;line<lines.length;line++) | ||
1068 | { | ||
1069 | var words=lines[line].split(" "); | ||
1070 | |||
1071 | amb | 1493 | if(line === 0) |
1072 | amb | 2006 | addBox(words); |
1073 | amb | 1493 | else if(words[0] !== "") |
1074 | amb | 1491 | { |
1075 | var dump=words[0]; | ||
1076 | amb | 2040 | var lat1=Number(words[1]); |
1077 | var lon1=Number(words[2]); | ||
1078 | var lat2=Number(words[3]); | ||
1079 | var lon2=Number(words[4]); | ||
1080 | amb | 1491 | |
1081 | var lonlat1 = L.latLng(lat1,lon1); | ||
1082 | var lonlat2 = L.latLng(lat2,lon2); | ||
1083 | |||
1084 | var feature = L.polyline([lonlat1,lonlat2],{weight: 2, stroke: true, color: "#FF0000", opacity: 1.0, | ||
1085 | fill: false}); | ||
1086 | |||
1087 | feature.on("click", (function(f,d) { return function(evt) { selectPolylineFeature(f,d,evt); }; }(feature,dump))); | ||
1088 | |||
1089 | layerVectors.addLayer(feature); | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | displayStatus("data","property",lines.length-2); | ||
1094 | } | ||
1095 | |||
1096 | |||
1097 | // | ||
1098 | // Success in getting the error log data | ||
1099 | // | ||
1100 | |||
1101 | function runErrorlogSuccess(response) | ||
1102 | { | ||
1103 | var lines=response.responseText.split("\n"); | ||
1104 | |||
1105 | for(var line=0;line<lines.length;line++) | ||
1106 | { | ||
1107 | var words=lines[line].split(" "); | ||
1108 | |||
1109 | amb | 1493 | if(line === 0) |
1110 | amb | 2006 | addBox(words); |
1111 | amb | 1493 | else if(words[0] !== "") |
1112 | amb | 1491 | { |
1113 | var dump=words[0]; | ||
1114 | amb | 2040 | var lat=Number(words[1]); |
1115 | var lon=Number(words[2]); | ||
1116 | amb | 1491 | |
1117 | var lonlat = L.latLng(lat,lon); | ||
1118 | |||
1119 | var feature = L.circleMarker(lonlat,{radius: 3, fill: true, fillColor: "#FF0000", fillOpacity: 1.0, | ||
1120 | stroke: false}); | ||
1121 | |||
1122 | feature.on("click", (function(f,d) { return function(evt) { selectCircleMarkerFeature(f,d,evt); }; }(feature,dump))); | ||
1123 | |||
1124 | layerVectors.addLayer(feature); | ||
1125 | } | ||
1126 | } | ||
1127 | |||
1128 | displayStatus("data","errorlogs",lines.length-2); | ||
1129 | } | ||
1130 | |||
1131 | |||
1132 | // | ||
1133 | // Failure in getting data. | ||
1134 | // | ||
1135 | |||
1136 | function runFailure(response) | ||
1137 | { | ||
1138 | displayStatus("failed"); | ||
1139 | } |