2 // Routino data visualiser web page Javascript
4 // Part of the Routino routing software.
6 // This file Copyright 2008-2010 Andrew M. Bishop
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.
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.
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/>.
43 var junction_colours={
56 var junction_styles={};
63 var super_node_style,super_segment_style;
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"};
74 ////////////////////////////////////////////////////////////////////////////////
75 ///////////////////////////////// Map handling /////////////////////////////////
76 ////////////////////////////////////////////////////////////////////////////////
79 var layerMapOSM, layerVectors, layerBoxes;
80 var epsg4326, epsg900913;
86 // Initialise the 'map' object
89 function map_init(lat,lon,zoom)
91 // Default configuration:
92 // UK coordinate range
93 // West -11.0, South 49.5, East 2.0, North 61.0
96 // EDIT THIS below to change the visible map limits
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
105 // EDIT THIS above to change the visible map limits
111 epsg4326=new OpenLayers.Projection("EPSG:4326");
112 epsg900913=new OpenLayers.Projection("EPSG:900913");
114 map = new OpenLayers.Map ("map",
117 new OpenLayers.Control.Navigation(),
118 new OpenLayers.Control.PanZoomBar(),
119 new OpenLayers.Control.ScaleLine(),
120 new OpenLayers.Control.LayerSwitcher()
123 projection: epsg900913,
124 displayProjection: epsg4326,
126 minZoomLevel: zoomout,
127 numZoomLevels: zoomin-zoomout+1,
128 maxResolution: 156543.0339 / Math.pow(2,zoomout),
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),
136 map.events.register("moveend", map, mapMoved);
138 // Add a map tile layer (OpenStreetMap tiles, direct access)
140 layerMapOSM = new OpenLayers.Layer.TMS("Original OSM map",
141 "http://tile.openstreetmap.org/",
143 emptyUrl: "http://openstreetmap.org/openlayers/img/404.png",
146 displayOutsideMaxExtent: true,
149 map.addLayer(layerMapOSM);
151 // Get a URL for the tile; limited to map restricted extent.
153 function limitedUrl(bounds)
155 var z = map.getZoom() + map.minZoomLevel;
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;
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);
167 if (y < 0 || y >= limit)
168 return this.emptyUrl;
170 var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
172 x = ((x % limit) + limit) % limit;
173 return this.url + z + "/" + x + "/" + y + "." + this.type;
176 // Add a vectors layer
178 layerVectors = new OpenLayers.Layer.Vector("Markers");
179 map.addLayer(layerVectors);
181 for(var colour in junction_colours)
182 junction_styles[colour]=new OpenLayers.Style({},{stroke: false, pointRadius: 2,fillColor: junction_colours[colour]});
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"});
189 layerBoxes = new OpenLayers.Layer.Boxes("Boundary");
190 map.addLayer(layerBoxes);
194 // Set the map centre to the limited range specified
196 map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true));
197 map.maxResolution = map.getResolution();
201 if(lon != 'lon' && lat != 'lat' && zoom != 'zoom')
203 var lonlat = new OpenLayers.LonLat(lon,lat).transform(epsg4326,map.getProjectionObject());
205 map.moveTo(lonlat,zoom-map.minZoomLevel);
216 var centre = map.getCenter().clone();
218 var lonlat = centre.transform(map.getProjectionObject(),epsg4326);
220 var zoom = this.getZoom() + map.minZoomLevel;
222 map_args="lat=" + lonlat.lat + ";lon=" + lonlat.lon + ";zoom=" + zoom;
232 function updateCustomURL()
234 var router_url=document.getElementById("router_url");
235 var link_url =document.getElementById("link_url");
236 var edit_url =document.getElementById("edit_url");
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;
244 ////////////////////////////////////////////////////////////////////////////////
245 /////////////////////////////// Server handling ////////////////////////////////
246 ////////////////////////////////////////////////////////////////////////////////
249 // Display data statistics
252 function displayStatistics()
254 // Use AJAX to get the statistics
256 OpenLayers.loadURL("statistics.cgi",null,null,runStatisticsSuccess);
261 // Success in running data statistics generation.
264 function runStatisticsSuccess(response)
266 var statistics_data=document.getElementById("statistics_data");
267 var statistics_link=document.getElementById("statistics_link");
269 statistics_data.innerHTML="<pre>" + response.responseText + "</pre>";
271 statistics_link.style.display="none";
276 // Get the requested data
279 function displayData(datatype)
281 for(var data in data_types)
282 hideshow_hide(data_types[data]);
285 hideshow_show(datatype);
287 // Delete the old data
289 layerVectors.destroyFeatures();
292 layerBoxes.removeMarker(box);
297 var div_status=document.getElementById("result_status");
298 div_status.innerHTML = "No data displayed";
300 // Return if just here to clear the data
307 var mapbounds=map.getExtent().clone();
308 mapbounds.transform(epsg900913,epsg4326);
310 var url="visualiser.cgi";
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;
320 div_status.innerHTML = "Fetching " + datatype + " data ...";
322 // Use AJAX to get the data
327 OpenLayers.loadURL(url,null,null,runJunctionsSuccess,runFailure);
330 OpenLayers.loadURL(url,null,null,runSuperSuccess,runFailure);
333 OpenLayers.loadURL(url,null,null,runOnewaySuccess,runFailure);
340 OpenLayers.loadURL(url,null,null,runLimitSuccess,runFailure);
347 // Success in getting the junctions.
350 function runJunctionsSuccess(response)
352 var lines=response.responseText.split('\n');
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 ...";
360 for(var line=0;line<lines.length;line++)
362 var words=lines[line].split(' ');
371 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
373 box = new OpenLayers.Marker.Box(bounds);
375 layerBoxes.addMarker(box);
377 else if(words[0] != "")
383 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
385 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
387 features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[count]));
391 layerVectors.addFeatures(features);
393 var div_status=document.getElementById("result_status");
394 div_status.innerHTML = "Processed " + (lines.length-2) + " junctions";
399 // Success in getting the super-node and super-segments
402 function runSuperSuccess(response)
404 var lines=response.responseText.split('\n');
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 ...";
414 for(var line=0;line<lines.length;line++)
416 var words=lines[line].split(' ');
425 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
427 box = new OpenLayers.Marker.Box(bounds);
429 layerBoxes.addMarker(box);
431 else if(words[0] != "")
437 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
439 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
445 features.push(new OpenLayers.Feature.Vector(point,{},super_node_style));
449 var segment = new OpenLayers.Geometry.LineString([nodepoint,point]);
451 features.push(new OpenLayers.Feature.Vector(segment,{},super_segment_style));
456 layerVectors.addFeatures(features);
458 var div_status=document.getElementById("result_status");
459 div_status.innerHTML = "Processed " + (lines.length-2) + " super-nodes/segments";
464 // Success in getting the oneway data
467 function runOnewaySuccess(response)
469 var lines=response.responseText.split('\n');
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 ...";
477 for(var line=0;line<lines.length;line++)
479 var words=lines[line].split(' ');
488 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
490 box = new OpenLayers.Marker.Box(bounds);
492 layerBoxes.addMarker(box);
494 else if(words[0] != "")
501 var lonlat1= new OpenLayers.LonLat(lon1,lat1).transform(epsg4326,epsg900913);
502 var lonlat2= new OpenLayers.LonLat(lon2,lat2).transform(epsg4326,epsg900913);
504 //var point1 = new OpenLayers.Geometry.Point(lonlat1.lon,lonlat1.lat);
505 var point2 = new OpenLayers.Geometry.Point(lonlat2.lon,lonlat2.lat);
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);
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);
515 var segment = new OpenLayers.Geometry.LineString([point2,point3,point4,point2]);
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];
522 var style=new OpenLayers.Style({},{strokeWidth: 2,strokeColor: colour});
524 features.push(new OpenLayers.Feature.Vector(segment,{},style));
528 layerVectors.addFeatures(features);
530 var div_status=document.getElementById("result_status");
531 div_status.innerHTML = "Processed " + (lines.length-2) + " oneway segments";
536 // Success in getting the speed/weight/height/width/length limits
539 function runLimitSuccess(response)
541 var lines=response.responseText.split('\n');
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 ...";
551 for(var line=0;line<lines.length;line++)
553 var words=lines[line].split(' ');
562 var bounds = new OpenLayers.Bounds(lon1,lat1,lon2,lat2).transform(epsg4326,map.getProjectionObject());
564 box = new OpenLayers.Marker.Box(bounds);
566 layerBoxes.addMarker(box);
568 else if(words[0] != "")
574 var lonlat= new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
576 if(number == undefined)
578 var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
582 features.push(new OpenLayers.Feature.Vector(point,{},junction_styles[1]));
586 var dlat = lonlat.lat-nodelonlat.lat;
587 var dlon = lonlat.lon-nodelonlat.lon;
588 var dist = Math.sqrt(dlat*dlat+dlon*dlon)/60;
590 var point = new OpenLayers.Geometry.Point(nodelonlat.lon+dlon/dist,nodelonlat.lat+dlat/dist);
592 features.push(new OpenLayers.Feature.Vector(point,{},
593 new OpenLayers.Style({},{externalGraphic: 'icons/limit-' + number + '.png',
596 graphicHeight: 19})));
601 layerVectors.addFeatures(features);
603 var div_status=document.getElementById("result_status");
604 div_status.innerHTML = "Processed " + (lines.length-2) + " limits";
609 // Failure in getting data.
612 function runFailure(response)
614 var div_status=document.getElementById("result_status");
615 div_status.innerHTML = "Failed to get visualiser data!";
617 window.alert("Failed to get visualiser data!\n" + response.statusText);