Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/web/www/routino/visualiser.js
Parent Directory
|
Revision Log
Revision 577 -
(show annotations)
(download)
(as text)
Wed Dec 29 10:25:14 2010 UTC (14 years, 2 months ago) by amb
File MIME type: application/javascript
File size: 17058 byte(s)
Wed Dec 29 10:25:14 2010 UTC (14 years, 2 months ago) by amb
File MIME type: application/javascript
File size: 17058 byte(s)
Added the uncontrolled (not auto-generated) files from routino-1.4.
1 | // |
2 | // Routino data visualiser web page Javascript |
3 | // |
4 | // Part of the Routino routing software. |
5 | // |
6 | // This file Copyright 2008-2010 Andrew M. Bishop |
7 | // |
8 | // This program is free software: you can redistribute it and/or modify |
9 | // it under the terms of the GNU Affero General Public License as published by |
10 | // the Free Software Foundation, either version 3 of the License, or |
11 | // (at your option) any later version. |
12 | // |
13 | // This program is distributed in the hope that it will be useful, |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | // GNU Affero General Public License for more details. |
17 | // |
18 | // You should have received a copy of the GNU Affero General Public License |
19 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | // |
21 | |
22 | |
23 | // |
24 | // Data types |
25 | // |
26 | |
27 | var data_types=[ |
28 | "junctions", |
29 | "super", |
30 | "oneway", |
31 | "speed", |
32 | "weight", |
33 | "height", |
34 | "width", |
35 | "length" |
36 | ]; |
37 | |
38 | |
39 | // |
40 | // Junction styles |
41 | // |
42 | |
43 | var junction_colours={ |
44 | 0: "#FFFFFF", |
45 | 1: "#FF0000", |
46 | 2: "#FFFF00", |
47 | 3: "#00FF00", |
48 | 4: "#8B4513", |
49 | 5: "#00BFFF", |
50 | 6: "#FF69B4", |
51 | 7: "#000000", |
52 | 8: "#000000", |
53 | 9: "#000000" |
54 | }; |
55 | |
56 | var junction_styles={}; |
57 | |
58 | |
59 | // |
60 | // Super styles |
61 | // |
62 | |
63 | var super_node_style,super_segment_style; |
64 | |
65 | |
66 | // |
67 | // Oneway styles |
68 | // |
69 | |
70 | var hex={0: "00", 1: "11", 2: "22", 3: "33", 4: "44", 5: "55", 6: "66", 7: "77", |
71 | 8: "88", 9: "99", 10: "AA", 11: "BB", 12: "CC", 13: "DD", 14: "EE", 15: "FF"}; |
72 | |
73 | |
74 | //////////////////////////////////////////////////////////////////////////////// |
75 | ///////////////////////////////// Map handling ///////////////////////////////// |
76 | //////////////////////////////////////////////////////////////////////////////// |
77 | |
78 | var map; |
79 | var layerMapOSM, layerVectors, layerBoxes; |
80 | var epsg4326, epsg900913; |
81 | var map_args; |
82 | |
83 | var box; |
84 | |
85 | // |
86 | // Initialise the 'map' object |
87 | // |
88 | |
89 | function map_init(lat,lon,zoom) |
90 | { |
91 | // Default configuration: |
92 | // UK coordinate range |
93 | // West -11.0, South 49.5, East 2.0, North 61.0 |
94 | // Zoom level 4 to 15 |
95 | |
96 | // EDIT THIS below to change the visible map limits |
97 | |
98 | var westedge = -11.0; // Minimum longitude (degrees) |
99 | var eastedge = 2.0; // Maximum longitude (degrees) |
100 | var southedge = 49.5; // Minimum latitude (degrees) |
101 | var northedge = 61.0; // Maximum latitude (degrees) |
102 | var zoomout = 4; // Minimum zoom |
103 | var zoomin = 15; // Maximum zoom |
104 | |
105 | // EDIT THIS above to change the visible map limits |
106 | |
107 | // |
108 | // Create the map |
109 | // |
110 | |
111 | epsg4326=new OpenLayers.Projection("EPSG:4326"); |
112 | epsg900913=new OpenLayers.Projection("EPSG:900913"); |
113 | |
114 | map = new OpenLayers.Map ("map", |
115 | { |
116 | controls:[ |
117 | new OpenLayers.Control.Navigation(), |
118 | new OpenLayers.Control.PanZoomBar(), |
119 | new OpenLayers.Control.ScaleLine(), |
120 | new OpenLayers.Control.LayerSwitcher() |
121 | ], |
122 | |
123 | projection: epsg900913, |
124 | displayProjection: epsg4326, |
125 | |
126 | minZoomLevel: zoomout, |
127 | numZoomLevels: zoomin-zoomout+1, |
128 | maxResolution: 156543.0339 / Math.pow(2,zoomout), |
129 | |
130 | maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34), |
131 | restrictedExtent: new OpenLayers.Bounds(westedge,southedge,eastedge,northedge).transform(epsg4326,epsg900913), |
132 | |
133 | units: "m" |
134 | }); |
135 | |
136 | map.events.register("moveend", map, mapMoved); |
137 | |
138 | // Add a map tile layer (OpenStreetMap tiles, direct access) |
139 | |
140 | layerMapOSM = new OpenLayers.Layer.TMS("Original OSM map", |
141 | "http://tile.openstreetmap.org/", |
142 | { |
143 | emptyUrl: "http://openstreetmap.org/openlayers/img/404.png", |
144 | type: 'png', |
145 | getURL: limitedUrl, |
146 | displayOutsideMaxExtent: true, |
147 | buffer: 1 |
148 | }); |
149 | map.addLayer(layerMapOSM); |
150 | |
151 | // Get a URL for the tile; limited to map restricted extent. |
152 | |
153 | function limitedUrl(bounds) |
154 | { |
155 | var z = map.getZoom() + map.minZoomLevel; |
156 | |
157 | if (z>=7 && (bounds.right < map.restrictedExtent.left || |
158 | bounds.left > map.restrictedExtent.right || |
159 | bounds.top < map.restrictedExtent.bottom || |
160 | bounds.bottom > map.restrictedExtent.top)) |
161 | return this.emptyUrl; |
162 | |
163 | var res = map.getResolution(); |
164 | var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h)); |
165 | var limit = Math.pow(2, z); |
166 | |
167 | if (y < 0 || y >= limit) |
168 | return this.emptyUrl; |
169 | |
170 | var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w)); |
171 | |
172 | x = ((x % limit) + limit) % limit; |
173 | return this.url + z + "/" + x + "/" + y + "." + this.type; |
174 | } |
175 | |
176 | // Add a vectors layer |
177 | |
178 | layerVectors = new OpenLayers.Layer.Vector("Markers"); |
179 | map.addLayer(layerVectors); |
180 | |
181 | for(var colour in junction_colours) |
182 | junction_styles[colour]=new OpenLayers.Style({},{stroke: false, pointRadius: 2,fillColor: junction_colours[colour]}); |
183 | |
184 | super_node_style =new OpenLayers.Style({},{stroke: false, pointRadius: 3,fillColor : "#FF0000"}); |
185 | super_segment_style=new OpenLayers.Style({},{fill: false , strokeWidth: 2,strokeColor: "#FF0000"}); |
186 | |
187 | // Add a boxes layer |
188 | |
189 | layerBoxes = new OpenLayers.Layer.Boxes("Boundary"); |
190 | map.addLayer(layerBoxes); |
191 | |
192 | box=null; |
193 | |
194 | // Set the map centre to the limited range specified |
195 | |
196 | map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true)); |
197 | map.maxResolution = map.getResolution(); |
198 | |
199 | // Move the map |
200 | |
201 | if(lon != 'lon' && lat != 'lat' && zoom != 'zoom') |
202 | { |
203 | var lonlat = new OpenLayers.LonLat(lon,lat).transform(epsg4326,map.getProjectionObject()); |
204 | |
205 | map.moveTo(lonlat,zoom-map.minZoomLevel); |
206 | } |
207 | } |
208 | |
209 | |
210 | // |
211 | // Map has moved |
212 | // |
213 | |
214 | function mapMoved() |
215 | { |
216 | var centre = map.getCenter().clone(); |
217 | |
218 | var lonlat = centre.transform(map.getProjectionObject(),epsg4326); |
219 | |
220 | var zoom = this.getZoom() + map.minZoomLevel; |
221 | |
222 | map_args="lat=" + lonlat.lat + ";lon=" + lonlat.lon + ";zoom=" + zoom; |
223 | |
224 | updateCustomURL(); |
225 | } |
226 | |
227 | |
228 | // |
229 | // Update custom URL |
230 | // |
231 | |
232 | function updateCustomURL() |
233 | { |
234 | var router_url=document.getElementById("router_url"); |
235 | var link_url =document.getElementById("link_url"); |
236 | var edit_url =document.getElementById("edit_url"); |
237 | |
238 | router_url.href="customrouter.cgi?" + map_args; |
239 | link_url.href="customvisualiser.cgi?" + map_args; |
240 | edit_url.href="http://www.openstreetmap.org/edit?" + map_args; |
241 | } |
242 | |
243 | |
244 | //////////////////////////////////////////////////////////////////////////////// |
245 | /////////////////////////////// Server handling //////////////////////////////// |
246 | //////////////////////////////////////////////////////////////////////////////// |
247 | |
248 | // |
249 | // Display data statistics |
250 | // |
251 | |
252 | function displayStatistics() |
253 | { |
254 | // Use AJAX to get the statistics |
255 | |
256 | OpenLayers.loadURL("statistics.cgi",null,null,runStatisticsSuccess); |
257 | } |
258 | |
259 | |
260 | // |
261 | // Success in running data statistics generation. |
262 | // |
263 | |
264 | function runStatisticsSuccess(response) |
265 | { |
266 | var statistics_data=document.getElementById("statistics_data"); |
267 | var statistics_link=document.getElementById("statistics_link"); |
268 | |
269 | statistics_data.innerHTML="<pre>" + response.responseText + "</pre>"; |
270 | |
271 | statistics_link.style.display="none"; |
272 | } |
273 | |
274 | |
275 | // |
276 | // Get the requested data |
277 | // |
278 | |
279 | function displayData(datatype) |
280 | { |
281 | for(var data in data_types) |
282 | hideshow_hide(data_types[data]); |
283 | |
284 | if(datatype != "") |
285 | hideshow_show(datatype); |
286 | |
287 | // Delete the old data |
288 | |
289 | layerVectors.destroyFeatures(); |
290 | |
291 | if(box != null) |
292 | layerBoxes.removeMarker(box); |
293 | box=null; |
294 | |
295 | // Print the status |
296 | |
297 | var div_status=document.getElementById("result_status"); |
298 | div_status.innerHTML = "No data displayed"; |
299 | |
300 | // Return if just here to clear the data |
301 | |
302 | if(datatype == "") |
303 | return; |
304 | |
305 | // Get the new data |
306 | |
307 | var mapbounds=map.getExtent().clone(); |
308 | mapbounds.transform(epsg900913,epsg4326); |
309 | |
310 | var url="visualiser.cgi"; |
311 | |
312 | url=url + "?lonmin=" + mapbounds.left; |
313 | url=url + ";latmin=" + mapbounds.bottom; |
314 | url=url + ";lonmax=" + mapbounds.right; |
315 | url=url + ";latmax=" + mapbounds.top; |
316 | url=url + ";data=" + datatype; |
317 | |
318 | // Print the status |
319 | |
320 | div_status.innerHTML = "Fetching " + datatype + " data ..."; |
321 | |
322 | // Use AJAX to get the data |
323 | |
324 | switch(datatype) |
325 | { |
326 | case 'junctions': |
327 | OpenLayers.loadURL(url,null,null,runJunctionsSuccess,runFailure); |
328 | break; |
329 | case 'super': |
330 | OpenLayers.loadURL(url,null,null,runSuperSuccess,runFailure); |
331 | break; |
332 | case 'oneway': |
333 | OpenLayers.loadURL(url,null,null,runOnewaySuccess,runFailure); |
334 | break; |
335 | case 'speed': |
336 | case 'weight': |
337 | case 'height': |
338 | case 'width': |
339 | case 'length': |
340 | OpenLayers.loadURL(url,null,null,runLimitSuccess,runFailure); |
341 | break; |
342 | } |
343 | } |
344 | |
345 | |
346 | // |
347 | // Success in getting the junctions. |
348 | // |
349 | |
350 | function runJunctionsSuccess(response) |
351 | { |
352 | var lines=response.responseText.split('\n'); |
353 | |
354 | // This won't update the browser window |
355 | // var div_status=document.getElementById("result_status"); |
356 | // div_status.innerHTML = "Processing " + (lines.length-2) + " junctions ..."; |
357 | |
358 | var features=[]; |
359 | |
360 | for(var line=0;line<lines.length;line++) |
361 | { |
362 | var words=lines[line].split(' '); |
363 | |
364 | if(line == 0) |
365 | { |
366 | var lat1=words[0]; |
367 | var lon1=words[1]; |
368 | var lat2=words[2]; |
369 | var lon2=words[3]; |
370 | |
371 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); |
372 | |
373 | box = new OpenLayers.Marker.Box(bounds); |
374 | |
375 | layerBoxes.addMarker(box); |
376 | } |
377 | else if(words[0] != "") |
378 | { |
379 | var lat=words[0]; |
380 | var lon=words[1]; |
381 | var count=words[2]; |
382 | |
383 | var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913); |
384 | |
385 | var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat); |
386 | |
387 | features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[count])); |
388 | } |
389 | } |
390 | |
391 | layerVectors.addFeatures(features); |
392 | |
393 | var div_status=document.getElementById("result_status"); |
394 | div_status.innerHTML = "Processed " + (lines.length-2) + " junctions"; |
395 | } |
396 | |
397 | |
398 | // |
399 | // Success in getting the super-node and super-segments |
400 | // |
401 | |
402 | function runSuperSuccess(response) |
403 | { |
404 | var lines=response.responseText.split('\n'); |
405 | |
406 | // This won't update the browser window |
407 | // var div_status=document.getElementById("result_status"); |
408 | // div_status.innerHTML = "Processing " + (lines.length-2) + " super-nodes/segments ..."; |
409 | |
410 | var features=[]; |
411 | |
412 | var nodepoint; |
413 | |
414 | for(var line=0;line<lines.length;line++) |
415 | { |
416 | var words=lines[line].split(' '); |
417 | |
418 | if(line == 0) |
419 | { |
420 | var lat1=words[0]; |
421 | var lon1=words[1]; |
422 | var lat2=words[2]; |
423 | var lon2=words[3]; |
424 | |
425 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); |
426 | |
427 | box = new OpenLayers.Marker.Box(bounds); |
428 | |
429 | layerBoxes.addMarker(box); |
430 | } |
431 | else if(words[0] != "") |
432 | { |
433 | var lat=words[0]; |
434 | var lon=words[1]; |
435 | var type=words[2]; |
436 | |
437 | var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913); |
438 | |
439 | var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat); |
440 | |
441 | if(type == "n") |
442 | { |
443 | nodepoint=point; |
444 | |
445 | features.push(new OpenLayers.Feature.Vector(point,{},super_node_style)); |
446 | } |
447 | else |
448 | { |
449 | var segment = new OpenLayers.Geometry.LineString([nodepoint,point]); |
450 | |
451 | features.push(new OpenLayers.Feature.Vector(segment,{},super_segment_style)); |
452 | } |
453 | } |
454 | } |
455 | |
456 | layerVectors.addFeatures(features); |
457 | |
458 | var div_status=document.getElementById("result_status"); |
459 | div_status.innerHTML = "Processed " + (lines.length-2) + " super-nodes/segments"; |
460 | } |
461 | |
462 | |
463 | // |
464 | // Success in getting the oneway data |
465 | // |
466 | |
467 | function runOnewaySuccess(response) |
468 | { |
469 | var lines=response.responseText.split('\n'); |
470 | |
471 | // This won't update the browser window |
472 | // var div_status=document.getElementById("result_status"); |
473 | // div_status.innerHTML = "Processing " + (lines.length-2) + " oneway segments ..."; |
474 | |
475 | var features=[]; |
476 | |
477 | for(var line=0;line<lines.length;line++) |
478 | { |
479 | var words=lines[line].split(' '); |
480 | |
481 | if(line == 0) |
482 | { |
483 | var lat1=words[0]; |
484 | var lon1=words[1]; |
485 | var lat2=words[2]; |
486 | var lon2=words[3]; |
487 | |
488 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); |
489 | |
490 | box = new OpenLayers.Marker.Box(bounds); |
491 | |
492 | layerBoxes.addMarker(box); |
493 | } |
494 | else if(words[0] != "") |
495 | { |
496 | var lat1=words[0]; |
497 | var lon1=words[1]; |
498 | var lat2=words[2]; |
499 | var lon2=words[3]; |
500 | |
501 | var lonlat1= new OpenLayers.LonLat(lon1,lat1).transform(epsg4326,epsg900913); |
502 | var lonlat2= new OpenLayers.LonLat(lon2,lat2).transform(epsg4326,epsg900913); |
503 | |
504 | //var point1 = new OpenLayers.Geometry.Point(lonlat1.lon,lonlat1.lat); |
505 | var point2 = new OpenLayers.Geometry.Point(lonlat2.lon,lonlat2.lat); |
506 | |
507 | var dlat = lonlat2.lat-lonlat1.lat; |
508 | var dlon = lonlat2.lon-lonlat1.lon; |
509 | var dist = Math.sqrt(dlat*dlat+dlon*dlon)/10; |
510 | var ang = Math.atan2(dlat,dlon); |
511 | |
512 | var point3 = new OpenLayers.Geometry.Point(lonlat1.lon+dlat/dist,lonlat1.lat-dlon/dist); |
513 | var point4 = new OpenLayers.Geometry.Point(lonlat1.lon-dlat/dist,lonlat1.lat+dlon/dist); |
514 | |
515 | var segment = new OpenLayers.Geometry.LineString([point2,point3,point4,point2]); |
516 | |
517 | var r=Math.round(7.5+7.9*Math.cos(ang)); |
518 | var g=Math.round(7.5+7.9*Math.cos(ang+2.0943951)); |
519 | var b=Math.round(7.5+7.9*Math.cos(ang-2.0943951)); |
520 | var colour = "#" + hex[r] + hex[g] + hex[b]; |
521 | |
522 | var style=new OpenLayers.Style({},{strokeWidth: 2,strokeColor: colour}); |
523 | |
524 | features.push(new OpenLayers.Feature.Vector(segment,{},style)); |
525 | } |
526 | } |
527 | |
528 | layerVectors.addFeatures(features); |
529 | |
530 | var div_status=document.getElementById("result_status"); |
531 | div_status.innerHTML = "Processed " + (lines.length-2) + " oneway segments"; |
532 | } |
533 | |
534 | |
535 | // |
536 | // Success in getting the speed/weight/height/width/length limits |
537 | // |
538 | |
539 | function runLimitSuccess(response) |
540 | { |
541 | var lines=response.responseText.split('\n'); |
542 | |
543 | // This won't update the browser window |
544 | // var div_status=document.getElementById("result_status"); |
545 | // div_status.innerHTML = "Processing " + (lines.length-2) + " limits ..."; |
546 | |
547 | var features=[]; |
548 | |
549 | var nodelonlat; |
550 | |
551 | for(var line=0;line<lines.length;line++) |
552 | { |
553 | var words=lines[line].split(' '); |
554 | |
555 | if(line == 0) |
556 | { |
557 | var lat1=words[0]; |
558 | var lon1=words[1]; |
559 | var lat2=words[2]; |
560 | var lon2=words[3]; |
561 | |
562 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); |
563 | |
564 | box = new OpenLayers.Marker.Box(bounds); |
565 | |
566 | layerBoxes.addMarker(box); |
567 | } |
568 | else if(words[0] != "") |
569 | { |
570 | var lat=words[0]; |
571 | var lon=words[1]; |
572 | var number=words[2]; |
573 | |
574 | var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913); |
575 | |
576 | if(number == undefined) |
577 | { |
578 | var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat); |
579 | |
580 | nodelonlat=lonlat; |
581 | |
582 | features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[1])); |
583 | } |
584 | else |
585 | { |
586 | var dlat = lonlat.lat-nodelonlat.lat; |
587 | var dlon = lonlat.lon-nodelonlat.lon; |
588 | var dist = Math.sqrt(dlat*dlat+dlon*dlon)/60; |
589 | |
590 | var point = new OpenLayers.Geometry.Point(nodelonlat.lon+dlon/dist,nodelonlat.lat+dlat/dist); |
591 | |
592 | features.push(new OpenLayers.Feature.Vector(point,{}, |
593 | new OpenLayers.Style({},{externalGraphic: 'icons/limit-' + number + '.png', |
594 | graphicYOffset: -9, |
595 | graphicWidth: 19, |
596 | graphicHeight: 19}))); |
597 | } |
598 | } |
599 | } |
600 | |
601 | layerVectors.addFeatures(features); |
602 | |
603 | var div_status=document.getElementById("result_status"); |
604 | div_status.innerHTML = "Processed " + (lines.length-2) + " limits"; |
605 | } |
606 | |
607 | |
608 | // |
609 | // Failure in getting data. |
610 | // |
611 | |
612 | function runFailure(response) |
613 | { |
614 | var div_status=document.getElementById("result_status"); |
615 | div_status.innerHTML = "Failed to get visualiser data!"; |
616 | |
617 | window.alert("Failed to get visualiser data!\n" + response.statusText); |
618 | } |