Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/web/www/routino/visualiser.js
Parent Directory
|
Revision Log
Revision 572 -
(hide annotations)
(download)
(as text)
Wed Dec 29 09:58:20 2010 UTC (14 years, 3 months ago) by amb
File MIME type: application/javascript
File size: 15785 byte(s)
Wed Dec 29 09:58:20 2010 UTC (14 years, 3 months ago) by amb
File MIME type: application/javascript
File size: 15785 byte(s)
Added the uncontrolled (not auto-generated) files from routino-1.2.
1 | amb | 569 | // |
2 | // Routino data visualiser web page Javascript | ||
3 | // | ||
4 | // Part of the Routino routing software. | ||
5 | // | ||
6 | // This file Copyright 2008,2009 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: true, | ||
29 | super: true, | ||
30 | oneway: true, | ||
31 | speed: true, | ||
32 | weight: true, | ||
33 | height: true, | ||
34 | width: true, | ||
35 | length: true | ||
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 configuration | ||
76 | // | ||
77 | |||
78 | var map; | ||
79 | amb | 572 | var layerMapOSM, layerVectors, layerBoxes; |
80 | amb | 569 | var epsg4326, epsg900913; |
81 | |||
82 | var box; | ||
83 | |||
84 | |||
85 | // | ||
86 | // Initialise the 'map' object | ||
87 | // | ||
88 | |||
89 | function map_init(lat,lon,zoom) | ||
90 | { | ||
91 | var data; | ||
92 | |||
93 | for(data in data_types) | ||
94 | hideshow_hide(data); | ||
95 | |||
96 | // | ||
97 | // Create the map | ||
98 | // | ||
99 | |||
100 | epsg4326=new OpenLayers.Projection("EPSG:4326"); | ||
101 | epsg900913=new OpenLayers.Projection("EPSG:900913"); | ||
102 | |||
103 | // UK coordinate range: West -11.0, South 49.5, East 2.0, North 61.0 | ||
104 | |||
105 | // EDIT THIS to change the visible map boundary. | ||
106 | var mapbounds=new OpenLayers.Bounds(-11.0,49.5,2.0,61.0).transform(epsg4326,epsg900913); | ||
107 | |||
108 | map = new OpenLayers.Map ("map", | ||
109 | { | ||
110 | controls:[ | ||
111 | new OpenLayers.Control.Navigation(), | ||
112 | new OpenLayers.Control.PanZoomBar(), | ||
113 | new OpenLayers.Control.ScaleLine(), | ||
114 | new OpenLayers.Control.LayerSwitcher() | ||
115 | ], | ||
116 | |||
117 | projection: epsg900913, | ||
118 | displayProjection: epsg4326, | ||
119 | |||
120 | // EDIT THIS to set the minimum zoom level | ||
121 | minZoomLevel: 4, | ||
122 | |||
123 | // EDIT THIS to set the number of zoom levels | ||
124 | numZoomLevels: 12, // zoom levels 4-15 inclusive | ||
125 | |||
126 | // EDIT THIS if you change the minimum zoom level above | ||
127 | maxResolution: 156543.0339 / Math.pow(2,4), // Math.pow(2,minZoomLevel) | ||
128 | |||
129 | maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34), | ||
130 | |||
131 | restrictedExtent: mapbounds, | ||
132 | |||
133 | units: "m" | ||
134 | }); | ||
135 | |||
136 | map.events.register("moveend", map, mapMoved); | ||
137 | |||
138 | amb | 572 | // Add a map tile layer (OpenStreetMap tiles, direct access) |
139 | amb | 569 | |
140 | amb | 572 | layerMapOSM = new OpenLayers.Layer.TMS("Original OSM map", |
141 | amb | 569 | "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 | amb | 572 | map.addLayer(layerMapOSM); |
150 | amb | 569 | |
151 | // Get a URL for the tile; limited to mapbounds. | ||
152 | |||
153 | function limitedUrl(bounds) | ||
154 | { | ||
155 | var z = map.getZoom() + map.minZoomLevel; | ||
156 | |||
157 | if (z>7 && (bounds.right < mapbounds.left || | ||
158 | bounds.left > mapbounds.right || | ||
159 | bounds.top < mapbounds.bottom || | ||
160 | bounds.bottom > mapbounds.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 | var colour; | ||
182 | for(colour in junction_colours) | ||
183 | junction_styles[colour]=new OpenLayers.Style({},{stroke: false, pointRadius: 2,fillColor: junction_colours[colour]}); | ||
184 | |||
185 | super_node_style =new OpenLayers.Style({},{stroke: false, pointRadius: 3,fillColor : "#FF0000"}); | ||
186 | super_segment_style=new OpenLayers.Style({},{fill: false , strokeWidth: 2,strokeColor: "#FF0000"}); | ||
187 | |||
188 | // Add a boxes layer | ||
189 | |||
190 | amb | 572 | layerBoxes = new OpenLayers.Layer.Boxes("Boundary"); |
191 | amb | 569 | map.addLayer(layerBoxes); |
192 | |||
193 | box=null; | ||
194 | |||
195 | amb | 572 | // Set the map centre to the limited range specified |
196 | |||
197 | map.setCenter(mapbounds.getCenterLonLat(), map.getZoomForExtent(mapbounds,true)); | ||
198 | map.maxResolution = map.getResolution(); | ||
199 | |||
200 | amb | 569 | // Move the map |
201 | |||
202 | if(lon != 'lon' && lat != 'lat' && zoom != 'zoom') | ||
203 | { | ||
204 | var lonlat = new OpenLayers.LonLat(lon,lat).transform(epsg4326,map.getProjectionObject()); | ||
205 | |||
206 | map.moveTo(lonlat,zoom-map.minZoomLevel); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | |||
211 | // | ||
212 | // Map has moved | ||
213 | // | ||
214 | |||
215 | function mapMoved() | ||
216 | { | ||
217 | var centre = map.getCenter().clone(); | ||
218 | |||
219 | var lonlat = centre.transform(map.getProjectionObject(),epsg4326); | ||
220 | |||
221 | var zoom = this.getZoom() + map.minZoomLevel; | ||
222 | |||
223 | var router_url=document.getElementById("router_url"); | ||
224 | var link_url =document.getElementById("link_url"); | ||
225 | var edit_url =document.getElementById("edit_url"); | ||
226 | |||
227 | var args="lat=" + lonlat.lat + ";lon=" + lonlat.lon + ";zoom=" + zoom; | ||
228 | |||
229 | router_url.href="customrouter.cgi?" + args; | ||
230 | link_url.href="customvisualiser.cgi?" + args; | ||
231 | edit_url.href="http://www.openstreetmap.org/edit?" + args; | ||
232 | } | ||
233 | |||
234 | |||
235 | // | ||
236 | // Display data statistics | ||
237 | // | ||
238 | |||
239 | function displayStatistics() | ||
240 | { | ||
241 | // Use AJAX to get the statistics | ||
242 | |||
243 | OpenLayers.loadURL("statistics.cgi",null,null,runStatisticsSuccess); | ||
244 | } | ||
245 | |||
246 | |||
247 | // | ||
248 | // Success in running router. | ||
249 | // | ||
250 | |||
251 | function runStatisticsSuccess(response) | ||
252 | { | ||
253 | var statistics_data=document.getElementById("statistics_data"); | ||
254 | var statistics_link=document.getElementById("statistics_link"); | ||
255 | |||
256 | statistics_data.innerHTML="<pre>" + response.responseText + "</pre>"; | ||
257 | |||
258 | statistics_link.style.display="none"; | ||
259 | } | ||
260 | |||
261 | |||
262 | // | ||
263 | // Get the requested data | ||
264 | // | ||
265 | |||
266 | function displayData(datatype) | ||
267 | { | ||
268 | var data; | ||
269 | |||
270 | for(data in data_types) | ||
271 | hideshow_hide(data); | ||
272 | |||
273 | if(datatype != "") | ||
274 | hideshow_show(datatype); | ||
275 | |||
276 | // Delete the old data | ||
277 | |||
278 | layerVectors.destroyFeatures(); | ||
279 | |||
280 | if(box != null) | ||
281 | layerBoxes.removeMarker(box); | ||
282 | box=null; | ||
283 | |||
284 | // Print the status | ||
285 | |||
286 | var div_status=document.getElementById("result_status"); | ||
287 | div_status.innerHTML = "No data displayed"; | ||
288 | |||
289 | // Return if just here to clear the data | ||
290 | |||
291 | if(datatype == "") | ||
292 | return; | ||
293 | |||
294 | // Get the new data | ||
295 | |||
296 | var mapbounds=map.getExtent().clone(); | ||
297 | mapbounds.transform(epsg900913,epsg4326); | ||
298 | |||
299 | var url="visualiser.cgi"; | ||
300 | |||
301 | url=url + "?lonmin=" + mapbounds.left; | ||
302 | url=url + ";latmin=" + mapbounds.bottom; | ||
303 | url=url + ";lonmax=" + mapbounds.right; | ||
304 | url=url + ";latmax=" + mapbounds.top; | ||
305 | url=url + ";data=" + datatype; | ||
306 | |||
307 | // Print the status | ||
308 | |||
309 | div_status.innerHTML = "Fetching " + datatype + " data ..."; | ||
310 | |||
311 | // Use AJAX to get the data | ||
312 | |||
313 | switch(datatype) | ||
314 | { | ||
315 | case 'junctions': | ||
316 | OpenLayers.loadURL(url,null,null,runJunctionsSuccess,runFailure); | ||
317 | break; | ||
318 | case 'super': | ||
319 | OpenLayers.loadURL(url,null,null,runSuperSuccess,runFailure); | ||
320 | break; | ||
321 | case 'oneway': | ||
322 | OpenLayers.loadURL(url,null,null,runOnewaySuccess,runFailure); | ||
323 | break; | ||
324 | case 'speed': | ||
325 | case 'weight': | ||
326 | case 'height': | ||
327 | case 'width': | ||
328 | case 'length': | ||
329 | OpenLayers.loadURL(url,null,null,runLimitSuccess,runFailure); | ||
330 | break; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | |||
335 | // | ||
336 | // Success in getting the junctions. | ||
337 | // | ||
338 | |||
339 | function runJunctionsSuccess(response) | ||
340 | { | ||
341 | var lines=response.responseText.split('\n'); | ||
342 | |||
343 | var div_status=document.getElementById("result_status"); | ||
344 | div_status.innerHTML = "Processing " + (lines.length-2) + " junctions ..."; | ||
345 | |||
346 | var features=[]; | ||
347 | |||
348 | for(line in lines) | ||
349 | { | ||
350 | amb | 572 | var words=lines[line].split(' '); |
351 | amb | 569 | |
352 | if(line == 0) | ||
353 | { | ||
354 | var lat1=words[0]; | ||
355 | var lon1=words[1]; | ||
356 | var lat2=words[2]; | ||
357 | var lon2=words[3]; | ||
358 | |||
359 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); | ||
360 | |||
361 | box = new OpenLayers.Marker.Box(bounds); | ||
362 | |||
363 | layerBoxes.addMarker(box); | ||
364 | } | ||
365 | else if(words[0] != "") | ||
366 | { | ||
367 | var lat=words[0]; | ||
368 | var lon=words[1]; | ||
369 | var count=words[2]; | ||
370 | |||
371 | var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913); | ||
372 | |||
373 | var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat); | ||
374 | |||
375 | features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[count])); | ||
376 | |||
377 | } | ||
378 | } | ||
379 | |||
380 | layerVectors.addFeatures(features); | ||
381 | |||
382 | div_status.innerHTML = "Processed " + (lines.length-2) + " junctions"; | ||
383 | } | ||
384 | |||
385 | |||
386 | // | ||
387 | // Success in getting the super-node and super-segments | ||
388 | // | ||
389 | |||
390 | function runSuperSuccess(response) | ||
391 | { | ||
392 | var lines=response.responseText.split('\n'); | ||
393 | |||
394 | var div_status=document.getElementById("result_status"); | ||
395 | div_status.innerHTML = "Processing " + (lines.length-2) + " super-nodes/segments ..."; | ||
396 | |||
397 | var features=[]; | ||
398 | |||
399 | var nodepoint; | ||
400 | |||
401 | for(line in lines) | ||
402 | { | ||
403 | amb | 572 | var words=lines[line].split(' '); |
404 | amb | 569 | |
405 | if(line == 0) | ||
406 | { | ||
407 | var lat1=words[0]; | ||
408 | var lon1=words[1]; | ||
409 | var lat2=words[2]; | ||
410 | var lon2=words[3]; | ||
411 | |||
412 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); | ||
413 | |||
414 | box = new OpenLayers.Marker.Box(bounds); | ||
415 | |||
416 | layerBoxes.addMarker(box); | ||
417 | } | ||
418 | else if(words[0] != "") | ||
419 | { | ||
420 | var lat=words[0]; | ||
421 | var lon=words[1]; | ||
422 | var type=words[2]; | ||
423 | |||
424 | var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913); | ||
425 | |||
426 | var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat); | ||
427 | |||
428 | if(type == "n") | ||
429 | { | ||
430 | nodepoint=point; | ||
431 | |||
432 | features.push(new OpenLayers.Feature.Vector(point,{},super_node_style)); | ||
433 | } | ||
434 | else | ||
435 | { | ||
436 | var line = new OpenLayers.Geometry.LineString([nodepoint,point]); | ||
437 | |||
438 | features.push(new OpenLayers.Feature.Vector(line,{},super_segment_style)); | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | |||
443 | layerVectors.addFeatures(features); | ||
444 | |||
445 | div_status.innerHTML = "Processed " + (lines.length-2) + " super-nodes/segments"; | ||
446 | } | ||
447 | |||
448 | |||
449 | // | ||
450 | // Success in getting the oneway data | ||
451 | // | ||
452 | |||
453 | function runOnewaySuccess(response) | ||
454 | { | ||
455 | var lines=response.responseText.split('\n'); | ||
456 | |||
457 | var div_status=document.getElementById("result_status"); | ||
458 | div_status.innerHTML = "Processing " + (lines.length-2) + " oneway segments ..."; | ||
459 | |||
460 | var features=[]; | ||
461 | |||
462 | for(line in lines) | ||
463 | { | ||
464 | amb | 572 | var words=lines[line].split(' '); |
465 | amb | 569 | |
466 | if(line == 0) | ||
467 | { | ||
468 | var lat1=words[0]; | ||
469 | var lon1=words[1]; | ||
470 | var lat2=words[2]; | ||
471 | var lon2=words[3]; | ||
472 | |||
473 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); | ||
474 | |||
475 | box = new OpenLayers.Marker.Box(bounds); | ||
476 | |||
477 | layerBoxes.addMarker(box); | ||
478 | } | ||
479 | else if(words[0] != "") | ||
480 | { | ||
481 | var lat1=words[0]; | ||
482 | var lon1=words[1]; | ||
483 | var lat2=words[2]; | ||
484 | var lon2=words[3]; | ||
485 | |||
486 | var lonlat1= new OpenLayers.LonLat(lon1,lat1).transform(epsg4326,epsg900913); | ||
487 | var lonlat2= new OpenLayers.LonLat(lon2,lat2).transform(epsg4326,epsg900913); | ||
488 | |||
489 | //var point1 = new OpenLayers.Geometry.Point(lonlat1.lon,lonlat1.lat); | ||
490 | var point2 = new OpenLayers.Geometry.Point(lonlat2.lon,lonlat2.lat); | ||
491 | |||
492 | var dlat = lonlat2.lat-lonlat1.lat; | ||
493 | var dlon = lonlat2.lon-lonlat1.lon; | ||
494 | var dist = Math.sqrt(dlat*dlat+dlon*dlon)/10; | ||
495 | var ang = Math.atan2(dlat,dlon); | ||
496 | |||
497 | var point3 = new OpenLayers.Geometry.Point(lonlat1.lon+dlat/dist,lonlat1.lat-dlon/dist); | ||
498 | var point4 = new OpenLayers.Geometry.Point(lonlat1.lon-dlat/dist,lonlat1.lat+dlon/dist); | ||
499 | |||
500 | var line = new OpenLayers.Geometry.LineString([point2,point3,point4,point2]); | ||
501 | |||
502 | var r=Math.round(7.5+7.9*Math.cos(ang)); | ||
503 | var g=Math.round(7.5+7.9*Math.cos(ang+2.0943951)); | ||
504 | var b=Math.round(7.5+7.9*Math.cos(ang-2.0943951)); | ||
505 | var colour = "#" + hex[r] + hex[g] + hex[b]; | ||
506 | |||
507 | var style=new OpenLayers.Style({},{strokeWidth: 2,strokeColor: colour}); | ||
508 | |||
509 | features.push(new OpenLayers.Feature.Vector(line,{},style)); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | layerVectors.addFeatures(features); | ||
514 | |||
515 | div_status.innerHTML = "Processed " + (lines.length-2) + " oneway segments"; | ||
516 | } | ||
517 | |||
518 | |||
519 | // | ||
520 | // Success in getting the speed/weight/height/width/length limits | ||
521 | // | ||
522 | |||
523 | function runLimitSuccess(response) | ||
524 | { | ||
525 | var lines=response.responseText.split('\n'); | ||
526 | |||
527 | var div_status=document.getElementById("result_status"); | ||
528 | div_status.innerHTML = "Processing " + (lines.length-2) + " limits ..."; | ||
529 | |||
530 | var features=[]; | ||
531 | |||
532 | var nodelonlat; | ||
533 | |||
534 | for(line in lines) | ||
535 | { | ||
536 | amb | 572 | var words=lines[line].split(' '); |
537 | amb | 569 | |
538 | if(line == 0) | ||
539 | { | ||
540 | var lat1=words[0]; | ||
541 | var lon1=words[1]; | ||
542 | var lat2=words[2]; | ||
543 | var lon2=words[3]; | ||
544 | |||
545 | var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject()); | ||
546 | |||
547 | box = new OpenLayers.Marker.Box(bounds); | ||
548 | |||
549 | layerBoxes.addMarker(box); | ||
550 | } | ||
551 | else if(words[0] != "") | ||
552 | { | ||
553 | var lat=words[0]; | ||
554 | var lon=words[1]; | ||
555 | var number=words[2]; | ||
556 | |||
557 | var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913); | ||
558 | |||
559 | if(number == undefined) | ||
560 | { | ||
561 | var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat); | ||
562 | |||
563 | nodelonlat=lonlat; | ||
564 | |||
565 | features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[1])); | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | var dlat = lonlat.lat-nodelonlat.lat; | ||
570 | var dlon = lonlat.lon-nodelonlat.lon; | ||
571 | var dist = Math.sqrt(dlat*dlat+dlon*dlon)/60; | ||
572 | |||
573 | var point = new OpenLayers.Geometry.Point(nodelonlat.lon+dlon/dist,nodelonlat.lat+dlat/dist); | ||
574 | |||
575 | features.push(new OpenLayers.Feature.Vector(point,{}, | ||
576 | new OpenLayers.Style({},{externalGraphic: 'icons/limit-' + number + '.png', | ||
577 | graphicYOffset: -9, | ||
578 | graphicWidth: 19, | ||
579 | graphicHeight: 19}))); | ||
580 | } | ||
581 | } | ||
582 | } | ||
583 | |||
584 | layerVectors.addFeatures(features); | ||
585 | |||
586 | div_status.innerHTML = "Processed " + (lines.length-2) + " limits"; | ||
587 | } | ||
588 | |||
589 | |||
590 | // | ||
591 | // Failure in getting data. | ||
592 | // | ||
593 | |||
594 | function runFailure(response) | ||
595 | { | ||
596 | var div_status=document.getElementById("result_status"); | ||
597 | div_status.innerHTML = "Failed to get visualiser data!"; | ||
598 | |||
599 | window.alert("Failed to get visualiser data!\n" + response.statusText); | ||
600 | } |