Routino SVN Repository Browser

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

ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2008 - (show annotations) (download) (as text)
Sun Sep 1 14:49:11 2019 UTC (5 years, 6 months ago) by amb
File MIME type: application/javascript
File size: 15678 byte(s)
Merge from trunk (renaming of openlayers to openlayers2).

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