Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /branches/destination-access/extras/find-fixme/web/www/fixme.openlayers2.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2085 - (hide annotations) (download) (as text)
Sat Nov 21 16:10:04 2020 UTC (4 years, 3 months ago) by amb
File MIME type: application/javascript
File size: 15696 byte(s)
Merge from trunk [update leaflet and openlayers versions].

1 amb 1367 //
2     // Routino (extras) fixme web page Javascript
3     //
4     // Part of the Routino routing software.
5     //
6 amb 2044 // This file Copyright 2008-2014, 2019, 2020 Andrew M. Bishop
7 amb 1367 //
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     /////////////////////////////// Initialisation /////////////////////////////////
25     ////////////////////////////////////////////////////////////////////////////////
26    
27     // Process the URL query string and extract the arguments
28    
29     var legal={"^lon" : "^[-0-9.]+$",
30     "^lat" : "^[-0-9.]+$",
31 amb 2085 "^zoom" : "^[-0-9.]+$"};
32 amb 1367
33     var args={};
34    
35     if(location.search.length>1)
36     {
37     var query,queries;
38    
39     query=location.search.replace(/^\?/,"");
40 amb 1483 query=query.replace(/;/g,"&");
41     queries=query.split("&");
42 amb 1367
43     for(var i=0;i<queries.length;i++)
44     {
45     queries[i].match(/^([^=]+)(=(.*))?$/);
46    
47 amb 1483 var k=RegExp.$1;
48 amb 1484 var v=decodeURIComponent(RegExp.$3);
49 amb 1367
50     for(var l in legal)
51     {
52     if(k.match(RegExp(l)) && v.match(RegExp(legal[l])))
53     args[k]=v;
54     }
55     }
56     }
57    
58    
59     ////////////////////////////////////////////////////////////////////////////////
60     ///////////////////////////////// Map handling /////////////////////////////////
61     ////////////////////////////////////////////////////////////////////////////////
62    
63     var map;
64 amb 2081 var layerMap=[], layerHighlights, layerVectors;
65     var vectorData=[];
66 amb 1367 var epsg4326, epsg900913;
67     var select;
68    
69 amb 1491 //
70 amb 1367 // Initialise the 'map' object
71     //
72    
73     function map_init() // called from fixme.html
74     {
75 amb 1491 // Create the map (Map URLs and limits are in mapprops.js)
76 amb 1367
77     epsg4326=new OpenLayers.Projection("EPSG:4326");
78     epsg900913=new OpenLayers.Projection("EPSG:900913");
79    
80     map = new OpenLayers.Map ("map",
81     {
82     controls:[
83     new OpenLayers.Control.Navigation(),
84     new OpenLayers.Control.PanZoomBar(),
85     new OpenLayers.Control.ScaleLine(),
86     new OpenLayers.Control.LayerSwitcher()
87     ],
88    
89     projection: epsg900913,
90     displayProjection: epsg4326,
91    
92     minZoomLevel: mapprops.zoomout,
93     numZoomLevels: mapprops.zoomin-mapprops.zoomout+1,
94     maxResolution: 156543.03390625 / Math.pow(2,mapprops.zoomout),
95    
96     restrictedExtent: new OpenLayers.Bounds(mapprops.westedge,mapprops.southedge,mapprops.eastedge,mapprops.northedge).transform(epsg4326,epsg900913)
97     });
98    
99 amb 1491 // Get a URL for the tile (mostly copied from OpenLayers/Layer/XYZ.js).
100    
101     function limitedUrl(bounds)
102     {
103     var res = this.map.getResolution();
104    
105     var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
106     var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
107     var z = this.map.getZoom() + this.map.minZoomLevel;
108    
109     var limit = Math.pow(2, z);
110     x = ((x % limit) + limit) % limit;
111    
112     var xyz = {"x": x, "y": y, "z": z};
113     var url = this.url;
114    
115     if (OpenLayers.Util.isArray(url))
116     {
117     var s = "" + xyz.x + xyz.y + xyz.z;
118     url = this.selectUrl(s, url);
119     }
120    
121     return OpenLayers.String.format(url, xyz);
122     }
123    
124 amb 1367 // Add map tile layers
125    
126 amb 1491 for(var l=0; l<mapprops.mapdata.length; l++)
127 amb 1367 {
128 amb 1491 var urls;
129    
130     if(OpenLayers.Util.isArray(mapprops.mapdata[l].tiles.subdomains))
131     {
132     urls=[];
133    
134     for(var s=0; s<mapprops.mapdata[l].tiles.subdomains.length; s++)
135     urls.push(mapprops.mapdata[l].tiles.url.replace(/\${s}/,mapprops.mapdata[l].tiles.subdomains[s]));
136     }
137     else
138     urls=mapprops.mapdata[l].tiles.url;
139    
140 amb 1367 layerMap[l] = new OpenLayers.Layer.TMS(mapprops.mapdata[l].label,
141 amb 1491 urls,
142 amb 1367 {
143     getURL: limitedUrl,
144     displayOutsideMaxExtent: true,
145     buffer: 1
146     });
147     map.addLayer(layerMap[l]);
148     }
149    
150     // Update the attribution if the layer changes
151    
152     function change_attribution_event(event)
153     {
154 amb 1491 for(var l=0; l<mapprops.mapdata.length; l++)
155     if(layerMap[l] == event.layer)
156 amb 1367 change_attribution(l);
157     }
158    
159 amb 1491 map.events.register("changelayer",layerMap,change_attribution_event);
160    
161 amb 1367 function change_attribution(l)
162     {
163     var data_url =mapprops.mapdata[l].attribution.data_url;
164     var data_text=mapprops.mapdata[l].attribution.data_text;
165     var tile_url =mapprops.mapdata[l].attribution.tile_url;
166     var tile_text=mapprops.mapdata[l].attribution.tile_text;
167    
168     document.getElementById("attribution_data").innerHTML="<a href=\"" + data_url + "\" target=\"data_attribution\">" + data_text + "</a>";
169     document.getElementById("attribution_tile").innerHTML="<a href=\"" + tile_url + "\" target=\"tile_attribution\">" + tile_text + "</a>";
170     }
171    
172     change_attribution(0);
173    
174 amb 1491 // Add two vectors layers (one for highlights that display behind the vectors)
175 amb 1367
176     layerHighlights = new OpenLayers.Layer.Vector("Highlights",{displayInLayerSwitcher: false});
177     map.addLayer(layerHighlights);
178    
179     layerVectors = new OpenLayers.Layer.Vector("Markers",{displayInLayerSwitcher: false});
180     map.addLayer(layerVectors);
181    
182     // Handle feature selection and popup
183    
184     select = new OpenLayers.Control.SelectFeature(layerVectors,
185     {onSelect: selectFeature, onUnselect: unselectFeature});
186    
187     map.addControl(select);
188     select.activate();
189    
190     createPopup();
191    
192     // Move the map
193    
194 amb 2081 map.events.register("moveend", map, (function() { displayMoreData();}));
195 amb 1486
196 amb 1491 var lon =args["lon"];
197     var lat =args["lat"];
198     var zoom=args["zoom"];
199    
200 amb 1493 if(lon !== undefined && lat !== undefined && zoom !== undefined)
201 amb 1367 {
202 amb 2085 lat = Number(lat);
203     lon = Number(lon);
204     zoom = Number.parseInt(Number(zoom)+0.5);
205    
206 amb 1367 if(lon<mapprops.westedge) lon=mapprops.westedge;
207     if(lon>mapprops.eastedge) lon=mapprops.eastedge;
208    
209     if(lat<mapprops.southedge) lat=mapprops.southedge;
210     if(lat>mapprops.northedge) lat=mapprops.northedge;
211    
212     if(zoom<mapprops.zoomout) zoom=mapprops.zoomout;
213     if(zoom>mapprops.zoomin) zoom=mapprops.zoomin;
214    
215 amb 2085 var lonlat = new OpenLayers.LonLat(lon,lat);
216 amb 1367 lonlat.transform(epsg4326,epsg900913);
217    
218     map.moveTo(lonlat,zoom-map.minZoomLevel);
219     }
220 amb 1491 else
221     {
222 amb 2070 map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,false));
223 amb 1491 map.maxResolution = map.getResolution();
224     }
225 amb 1367
226     // Unhide editing URL if variable set
227    
228 amb 1493 if(mapprops.editurl !== undefined && mapprops.editurl !== "")
229 amb 1367 {
230 amb 1483 var edit_url=document.getElementById("edit_url");
231 amb 1367
232     edit_url.style.display="";
233     edit_url.href=mapprops.editurl;
234     }
235 amb 1486
236 amb 2070 updateURLs(false);
237 amb 1367 }
238    
239    
240     //
241     // Format a number in printf("%.5f") format.
242     //
243    
244     function format5f(number)
245     {
246     var newnumber=Math.floor(number*100000+0.5);
247     var delta=0;
248    
249     if(newnumber>=0 && newnumber<100000) delta= 100000;
250     if(newnumber<0 && newnumber>-100000) delta=-100000;
251    
252     var string=String(newnumber+delta);
253    
254     var intpart =string.substring(0,string.length-5);
255     var fracpart=string.substring(string.length-5,string.length);
256    
257     if(delta>0) intpart="0";
258     if(delta<0) intpart="-0";
259    
260     return(intpart + "." + fracpart);
261     }
262    
263    
264     //
265     // Build a set of URL arguments for the map location
266     //
267    
268     function buildMapArguments()
269     {
270     var lonlat = map.getCenter().clone();
271     lonlat.transform(epsg900913,epsg4326);
272    
273     var zoom = map.getZoom() + map.minZoomLevel;
274    
275     return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lon) + ";zoom=" + zoom;
276     }
277    
278    
279     //
280 amb 1486 // Update the URLs
281 amb 1367 //
282    
283 amb 2070 function updateURLs(addhistory)
284 amb 1367 {
285 amb 1486 var mapargs=buildMapArguments();
286 amb 2070 var libargs=";library=" + mapprops.library;
287 amb 1367
288 amb 2070 if(!mapprops.libraries)
289     libargs="";
290    
291 amb 1486 var links=document.getElementsByTagName("a");
292    
293     for(var i=0; i<links.length; i++)
294     {
295     var element=links[i];
296 amb 1491
297 amb 1486 if(element.id == "permalink_url")
298 amb 2070 element.href=location.pathname + "?" + mapargs + libargs;
299 amb 1486
300     if(element.id == "edit_url")
301     element.href=mapprops.editurl + "?" + mapargs;
302     }
303 amb 2070
304     if(addhistory)
305     history.replaceState(null, null, location.pathname + "?" + mapargs + libargs);
306 amb 1367 }
307    
308    
309     ////////////////////////////////////////////////////////////////////////////////
310     ///////////////////////// Popup and selection handling /////////////////////////
311     ////////////////////////////////////////////////////////////////////////////////
312    
313     var popup=null;
314    
315     //
316 amb 1491 // Create a popup - independent of map because want it fixed on screen not fixed on map.
317 amb 1367 //
318    
319     function createPopup()
320     {
321 amb 1483 popup=document.createElement("div");
322 amb 1367
323     popup.className = "popup";
324    
325     popup.innerHTML = "<span></span>";
326    
327     popup.style.display = "none";
328    
329     popup.style.position = "fixed";
330     popup.style.top = "-4000px";
331     popup.style.left = "-4000px";
332     popup.style.zIndex = "100";
333    
334     popup.style.padding = "5px";
335    
336     popup.style.opacity=0.85;
337     popup.style.backgroundColor="#C0C0C0";
338     popup.style.border="4px solid #404040";
339    
340     document.body.appendChild(popup);
341     }
342    
343    
344     //
345 amb 1491 // Draw a popup - independent of map because want it fixed on screen not fixed on map.
346 amb 1367 //
347    
348     function drawPopup(html)
349     {
350 amb 1493 if(html===null)
351 amb 1367 {
352     popup.style.display="none";
353     return;
354     }
355    
356     if(popup.style.display=="none")
357     {
358     var map_div=document.getElementById("map");
359    
360     popup.style.left =map_div.offsetParent.offsetLeft+map_div.offsetLeft+60 + "px";
361     popup.style.top = map_div.offsetTop +30 + "px";
362 amb 1499 popup.style.width =map_div.clientWidth-120 + "px";
363 amb 1367
364     popup.style.display="";
365     }
366    
367 amb 1499 var close="<span style='float: right; cursor: pointer;' onclick='drawPopup(null)'>X</span>";
368    
369     popup.innerHTML=close+html;
370 amb 1367 }
371    
372    
373     //
374     // Select a feature
375     //
376    
377     function selectFeature(feature)
378     {
379     if(feature.attributes.dump)
380 amb 1491 ajaxGET("fixme.cgi?dump=" + feature.attributes.dump, runDumpSuccess);
381 amb 1367
382     layerHighlights.destroyFeatures();
383    
384 amb 1483 var highlight_style = new OpenLayers.Style({},{strokeColor: "#F0F000",strokeWidth: 8,
385     fillColor: "#F0F000",pointRadius: 4});
386 amb 1367
387 amb 1483 var highlight = new OpenLayers.Feature.Vector(feature.geometry.clone(),{},highlight_style);
388 amb 1367
389     layerHighlights.addFeatures([highlight]);
390     }
391    
392    
393     //
394     // Un-select a feature
395     //
396    
397     function unselectFeature(feature)
398     {
399     layerHighlights.destroyFeatures();
400    
401     drawPopup(null);
402     }
403    
404    
405     //
406     // Display the dump data
407     //
408    
409     function runDumpSuccess(response)
410     {
411 amb 1394 var string=response.responseText;
412    
413 amb 2044 if(mapprops.browseurl !== undefined && mapprops.browseurl !== "")
414 amb 1394 {
415     var types=["node", "way", "relation"];
416    
417     for(var t in types)
418     {
419     var type=types[t];
420    
421 amb 1994 var regexp=RegExp(type + " id=&#39;([0-9]+)&#39;");
422 amb 1394
423     var match=string.match(regexp);
424    
425 amb 1493 if(match !== null)
426 amb 1394 {
427 amb 1994 var id=match[1];
428 amb 1394
429 amb 1506 string=string.replace(regexp,type + " id=&#39;<a href='" + mapprops.browseurl + "/" + type + "/" + id + "' target='" + type + id + "'>" + id + "</a>&#39;");
430 amb 1394 }
431     }
432     }
433    
434     drawPopup(string.split("&gt;&lt;").join("&gt;<br>&lt;").split("<br>&lt;tag").join("<br>&nbsp;&nbsp;&lt;tag"));
435 amb 1367 }
436    
437    
438     ////////////////////////////////////////////////////////////////////////////////
439     /////////////////////////////// Server handling ////////////////////////////////
440     ////////////////////////////////////////////////////////////////////////////////
441    
442     //
443 amb 1491 // Define an AJAX request object
444     //
445    
446     function ajaxGET(url,success,failure,state)
447     {
448     var ajaxRequest=new XMLHttpRequest();
449    
450     function ajaxGOT(options) {
451     if(this.readyState==4)
452     if(this.status==200)
453     { if(typeof(options.success)=="function") options.success(this,options.state); }
454     else
455     { if(typeof(options.failure)=="function") options.failure(this,options.state); }
456     }
457    
458     ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); };
459     ajaxRequest.open("GET", url, true);
460     ajaxRequest.send(null);
461     }
462    
463    
464     //
465 amb 1367 // Display the status
466     //
467    
468     function displayStatus(type,subtype,content)
469     {
470     var child=document.getElementById("result_status").firstChild;
471    
472     do
473     {
474 amb 1493 if(child.id !== undefined)
475 amb 1367 child.style.display="none";
476    
477     child=child.nextSibling;
478     }
479 amb 1496 while(child !== null);
480 amb 1367
481     var chosen_status=document.getElementById("result_status_" + type);
482    
483     chosen_status.style.display="";
484    
485 amb 1496 if(subtype !== undefined)
486 amb 1367 {
487     var format_status=document.getElementById("result_status_" + subtype).innerHTML;
488    
489 amb 1483 chosen_status.innerHTML=format_status.replace("#",String(content));
490 amb 1367 }
491     }
492    
493    
494     //
495 amb 1393 // Display data statistics
496     //
497    
498     function displayStatistics()
499     {
500     // Use AJAX to get the statistics
501    
502 amb 1491 ajaxGET("fixme.cgi?statistics=yes", runStatisticsSuccess);
503 amb 1393 }
504    
505    
506     //
507     // Success in running data statistics generation.
508     //
509    
510     function runStatisticsSuccess(response)
511     {
512     document.getElementById("statistics_data").innerHTML="<pre>" + response.responseText + "</pre>";
513     document.getElementById("statistics_link").style.display="none";
514     }
515    
516    
517     //
518 amb 1367 // Get the requested data
519     //
520    
521     function displayData(datatype) // called from fixme.html
522     {
523     // Delete the old data
524    
525 amb 2081 vectorData=[];
526    
527 amb 1367 unselectFeature();
528    
529     select.deactivate();
530    
531     layerVectors.destroyFeatures();
532    
533     // Print the status
534    
535     displayStatus("no_data");
536    
537     // Return if just here to clear the data
538    
539 amb 1493 if(datatype === "")
540 amb 1367 return;
541    
542 amb 2081 displayMoreData();
543     }
544    
545    
546     function displayMoreData()
547     {
548 amb 1367 // Get the new data
549    
550     var mapbounds=map.getExtent().clone();
551     mapbounds.transform(epsg900913,epsg4326);
552    
553     var url="fixme.cgi";
554    
555 amb 1487 url=url + "?lonmin=" + format5f(mapbounds.left);
556     url=url + ";latmin=" + format5f(mapbounds.bottom);
557     url=url + ";lonmax=" + format5f(mapbounds.right);
558     url=url + ";latmax=" + format5f(mapbounds.top);
559 amb 2081 url=url + ";data=fixmes";
560 amb 1367
561     // Use AJAX to get the data
562    
563 amb 1491 ajaxGET(url, runFixmeSuccess, runFailure);
564 amb 1367
565 amb 2081 updateURLs(true);
566 amb 2009 }
567    
568    
569     //
570 amb 1367 // Success in getting the error log data
571     //
572    
573     function runFixmeSuccess(response)
574     {
575 amb 1483 var lines=response.responseText.split("\n");
576 amb 1367
577     var style = new OpenLayers.Style({},{stroke: false,
578     pointRadius: 3,fillColor: "#FF0000",
579     cursor: "pointer"});
580    
581     var features=[];
582    
583     for(var line=0;line<lines.length;line++)
584     {
585 amb 1483 var words=lines[line].split(" ");
586 amb 1367
587 amb 1493 if(line === 0)
588 amb 2081 continue;
589 amb 1493 else if(words[0] !== "")
590 amb 1367 {
591     var dump=words[0];
592 amb 2081
593     if(vectorData[dump])
594     continue;
595     else
596     vectorData[dump]=1;
597    
598 amb 2044 var lat=Number(words[1]);
599     var lon=Number(words[2]);
600 amb 1367
601     var lonlat = new OpenLayers.LonLat(lon,lat).transform(epsg4326,epsg900913);
602    
603     var point = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);
604    
605     features.push(new OpenLayers.Feature.Vector(point,{dump: dump},style));
606     }
607     }
608    
609     select.activate();
610    
611     layerVectors.addFeatures(features);
612    
613 amb 2081 displayStatus("data","fixme",Object.keys(vectorData).length);
614 amb 1367 }
615    
616    
617     //
618     // Failure in getting data.
619     //
620    
621     function runFailure(response)
622     {
623     displayStatus("failed");
624     }