script.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. var widths = [12, 13, 13, 13, 13, 13, 13, 13];
  2. var opas = [0.8, 0.6, 0.5, 0.5, 0.4];
  3. var mwidths = [1, 1, 1, 1.5, 2, 3, 5, 6, 6, 4, 3, 2];
  4. var backend = "";
  5. var openGr = -1;
  6. var openSt = -1;
  7. function marker(stat, z) {
  8. if (stat.g.length == 1) {
  9. if (z > 15) {
  10. return L.circle(
  11. stat.g[0], {
  12. color: 'black',
  13. fillColor: stat.e ? 'red' : stat.s ? '#0000c3' : '#78f378',
  14. radius: mwidths[23 - z],
  15. fillOpacity: 1,
  16. weight: z > 17 ? 1.5 : 1,
  17. id: stat.i
  18. }
  19. );
  20. } else {
  21. return L.polyline(
  22. [stat.g[0], stat.g[0]], {
  23. color: stat.e ? 'red' : stat.s ? '#0000c3' : '#78f378',
  24. fillColor: stat.e ? 'red' : stat.s ? '#0000c3' : '#78f378',
  25. weight: widths[15 - z],
  26. opacity: opas[15 - z],
  27. id: stat.i
  28. }
  29. );
  30. }
  31. } else {
  32. return L.polygon(
  33. stat.g, {
  34. color: z > 15 ? 'black': (stat.e ? 'red' : stat.s ? '#0000c3' : '#78f378'),
  35. fillColor: stat.e ? 'red' : stat.s ? '#0000c3' : '#78f378',
  36. smoothFactor: 0,
  37. fillOpacity: 0.75,
  38. weight: z > 17 ? 1.5 : 1,
  39. id: stat.i
  40. }
  41. );
  42. }
  43. }
  44. function poly(group, z) {
  45. var col = group.e ? 'red' : group.s ? '#0000c3' : '#85f385';
  46. var style = {
  47. color: col,
  48. fillColor: col,
  49. smoothFactor: 0.4,
  50. fillOpacity: 0.2,
  51. id: group.i
  52. };
  53. if (group.n) {
  54. style.color = "#0000c3";
  55. style.fillColor = "#0000c3";
  56. }
  57. if (z < 16) {
  58. style.weight = 11;
  59. style.opacity = 0.5;
  60. style.fillOpacity = 0.5;
  61. }
  62. return L.polygon(group.g, style)
  63. }
  64. function sugArr(sug, z) {
  65. return L.polyline(sug.a, {
  66. id: sug.i,
  67. color: '#0000c3',
  68. smoothFactor: 0.1,
  69. weight: 4,
  70. opacity: 0.5
  71. });
  72. }
  73. function renderStat(stat) {
  74. openSt = stat.id;
  75. nodeHl(stat.id);
  76. var attrrows = {};
  77. var ll = {
  78. lat: stat.lat,
  79. lon: stat.lon
  80. };
  81. var way = stat.osmid < 0;
  82. var osmid = Math.abs(stat.osmid);
  83. var ident = way ? "Way" : "Node";
  84. var content = document.createElement('div');
  85. content.setAttribute("id", "nav")
  86. var suggD = document.createElement('div');
  87. suggD.setAttribute("id", "sugg")
  88. content.innerHTML = ident + " <a target='_blank' href='https://www.openstreetmap.org/"+ident.toLowerCase()+"/" + osmid + "'>" + osmid + "</a>";
  89. if (stat.attrs.name) {
  90. content.innerHTML += " (<b>\"" + stat.attrs.name + "\"</b>)";
  91. }
  92. content.innerHTML += "<a class='editbut' target='_blank' href='https://www.openstreetmap.org/edit?" + ident.toLowerCase() + "=" + osmid +"'>&#9998;</a>";
  93. var attrTbl = document.createElement('table');
  94. attrTbl.setAttribute("id", "attr-tbl")
  95. content.appendChild(attrTbl);
  96. content.appendChild(suggD);
  97. var tbody = document.createElement('tbody');
  98. attrTbl.appendChild(tbody);
  99. for (var key in stat.attrs) {
  100. var row = document.createElement('tr');
  101. var col1 = document.createElement('td');
  102. var col2 = document.createElement('td');
  103. col2.className = "err-wrap";
  104. tbody.appendChild(row);
  105. row.appendChild(col1);
  106. row.appendChild(col2);
  107. col1.innerHTML = "<a href=\"https://wiki.openstreetmap.org/wiki/Key:" + key + "\" target=\"_blank\"><tt>" + key + "</tt></a>";
  108. for (var i = 0; i < stat.attrs[key].length; i++) col2.innerHTML += "<span class='attrval'>" + stat.attrs[key][i] + "</span>" + "<br>";
  109. attrrows[key] = row;
  110. }
  111. for (var i = 0; i < stat.attrerrs.length; i++) {
  112. var err = stat.attrerrs[i];
  113. var row = attrrows[err.attr[0]];
  114. row.className = "err-" + Math.round(err.conf * 10);
  115. var info = document.createElement('div');
  116. if (err.other_grp) {
  117. // the mismatch was with a group name
  118. if (err.other_osmid > 1) {
  119. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> in relation <a onmouseover='groupHl( " + err.other_grp + ")' onmouseout='groupUnHl( " + err.other_grp + ")' target=\"_blank\" href=\"https://www.openstreetmap.org/relation/" + Math.abs(err.other_osmid) + "\">" + Math.abs(err.other_osmid) + "</a>";
  120. } else {
  121. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> in relation <span onmouseover='groupHl( " + err.other_grp + ")' onmouseout='groupUnHl( " + err.other_grp + ")'>" + Math.abs(err.other_osmid) + "</span>";
  122. }
  123. } else {
  124. // the mismatch was with another station
  125. if (err.other_osmid != stat.osmid) {
  126. var ident = err.other_osmid < 0 ? "way" : "node";
  127. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> in " + ident + " <a onmouseover='nodeHl( " + err.other + ")' onmouseout='nodeUnHl( " + err.other + ")' target=\"_blank\" href=\"https://www.openstreetmap.org/"+ident+"/" + Math.abs(err.other_osmid) + "\">" + Math.abs(err.other_osmid) + "</a>";
  128. } else {
  129. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> = '" + err.other_attr[1] + "'";
  130. }
  131. }
  132. info.className = 'attr-err-info';
  133. row.childNodes[1].appendChild(info);
  134. }
  135. var suggList = document.createElement('ul');
  136. if (stat.su.length) {
  137. var a = document.createElement('span');
  138. a.className = "sugtit";
  139. a.innerHTML = "Suggestions";
  140. suggD.appendChild(a);
  141. }
  142. suggD.appendChild(suggList);
  143. for (var i = 0; i < stat.su.length; i++) {
  144. var sugg = stat.su[i];
  145. var suggDiv = document.createElement('li');
  146. if (sugg.type == 1) {
  147. suggDiv.innerHTML = "Move into a <span class='grouplink' onmouseover='groupHl( " + sugg.target_gid + ")' onmouseout='groupUnHl( " + sugg.target_gid + ")'>new relation</span> <tt>public_transport=stop_area</tt>.";
  148. } else if (sugg.type == 2) {
  149. suggDiv.innerHTML = "Move into relation <a onmouseover='groupHl( " + sugg.target_gid + ")' onmouseout='groupUnHl( " + sugg.target_gid + ")' href=\"https://www.openstreetmap.org/relation/" + sugg.target_osm_rel_id + "\" target=\"_blank\">" + sugg.target_osm_rel_id + "</a>.";
  150. } else if (sugg.type == 3) {
  151. suggDiv.innerHTML = "Move from relation <a onmouseover='groupHl( " + sugg.orig_gid + ")' onmouseout='groupUnHl( " + sugg.orig_gid + ")' href=\"https://www.openstreetmap.org/relation/" + sugg.orig_osm_rel_id + "\" target=\"_blank\">" + sugg.orig_osm_rel_id + "</a> into a <span class='grouplink' onmouseover='groupHl( " + sugg.target_gid + ")' onmouseout='groupUnHl( " + sugg.target_gid + ")'>new relation</span> <tt>public_transport=stop_area</tt>.";
  152. } else if (sugg.type == 4) {
  153. suggDiv.innerHTML = "Move from relation <a onmouseover='groupHl( " + sugg.orig_gid + ")' onmouseout='groupUnHl( " + sugg.orig_gid + ")' href=\"https://www.openstreetmap.org/relation/" + sugg.orig_osm_rel_id + "\" target=\"_blank\">" + sugg.orig_osm_rel_id + "</a> into relation <a onmouseover='groupHl( " + sugg.target_gid + ")' onmouseout='groupUnHl( " + sugg.target_gid + ")' href=\"https://www.openstreetmap.org/relation/" + sugg.target_osm_rel_id + "\" target=\"_blank\">" + sugg.target_osm_rel_id + "</a>.";
  154. } else if (sugg.type == 5) {
  155. suggDiv.innerHTML = "Move out of relation <a onmouseover='groupHl( " + sugg.orig_gid + ")' onmouseout='groupUnHl( " + sugg.orig_gid + ")' href=\"https://www.openstreetmap.org/relation/" + sugg.orig_osm_rel_id + "\" target=\"_blank\">" + sugg.orig_osm_rel_id + "</a>";
  156. } else if (sugg.type == 6) {
  157. suggDiv.innerHTML = "Fix attribute <tt>" + sugg.attr + "</tt>.";
  158. } else if (sugg.type == 7) {
  159. suggDiv.innerHTML = "Consider adding a <tt><a target='_blank' href='https://wiki.openstreetmap.org/wiki/Key:name'>name</a></tt> attribute.";
  160. } else if (sugg.type == 8) {
  161. suggDiv.innerHTML = "Attribute <tt>" + sugg.attr + "</tt> seems to be a track number. Use <tt>ref</tt> for this and set <tt>" + sugg.attr + "</tt> to the station name.";
  162. }
  163. suggList.appendChild(suggDiv);
  164. }
  165. if (map.getZoom() < 18) {
  166. map.setView(ll, 18, {
  167. animate: true
  168. });
  169. }
  170. L.popup({
  171. opacity: 0.8
  172. })
  173. .setLatLng(ll)
  174. .setContent(content)
  175. .openOn(map)
  176. .on('remove', function() {openSt = -1; nodeUnHl(stat.id);;});
  177. }
  178. function openStat(id) {
  179. window.xmlhttp = new XMLHttpRequest();
  180. window.xmlhttp.onreadystatechange = function() {
  181. if (this.readyState == 4 && this.status == 200 && this == window.xmlhttp) {
  182. var content = JSON.parse(this.responseText);
  183. renderStat(content);
  184. }
  185. };
  186. window.xmlhttp.open("GET", backend + "/stat?id=" + id, true);
  187. window.xmlhttp.send();
  188. }
  189. function renderGroup(grp, ll) {
  190. openGr = grp.id;
  191. var attrrows = {};
  192. groupHl(grp.id);
  193. var content = document.createElement('div');
  194. content.setAttribute("id", "nav");
  195. var newMembers = document.createElement('div');
  196. newMembers.setAttribute("id", "group-stations-new")
  197. newMembers.innerHTML = "<span class='newmemberstit'>New Members</span>";
  198. var oldMembers = document.createElement('div');
  199. oldMembers.setAttribute("id", "group-stations-old")
  200. oldMembers.innerHTML = "<span class='oldmemberstit'>Existing Members</span>";
  201. if (grp.osmid == 1) {
  202. content.innerHTML = "<span class='grouplink'>New relation</span> <tt>public_transport=stop_area</tt>";
  203. } else {
  204. content.innerHTML = "OSM relation <a target='_blank' href='https://www.openstreetmap.org/relation/" + grp.osmid + "'>" + grp.osmid + "</a>";
  205. if (grp.attrs.name) {
  206. content.innerHTML += " (<b>\"" + grp.attrs.name + "\"</b>)";
  207. }
  208. content.innerHTML += "<a class='editbut' target='_blank' href='https://www.openstreetmap.org/edit?relation=" + grp.osmid +"'>&#9998;</a>";
  209. }
  210. var attrTbl = document.createElement('table');
  211. attrTbl.setAttribute("id", "attr-tbl")
  212. content.appendChild(attrTbl);
  213. var tbody = document.createElement('tbody');
  214. attrTbl.appendChild(tbody);
  215. var suggD = document.createElement('div');
  216. suggD.setAttribute("id", "sugg")
  217. for (var key in grp.attrs) {
  218. var row = document.createElement('tr');
  219. var col1 = document.createElement('td');
  220. var col2 = document.createElement('td');
  221. col2.className = "err-wrap";
  222. tbody.appendChild(row);
  223. row.appendChild(col1);
  224. row.appendChild(col2);
  225. col1.innerHTML = "<a href=\"https://wiki.openstreetmap.org/wiki/Key:" + key + "\" target=\"_blank\"><tt>" + key + "</tt></a>";
  226. for (var i = 0; i < grp.attrs[key].length; i++) col2.innerHTML += "<span class='attrval'>" + grp.attrs[key][i] + "</span>" + "<br>";
  227. attrrows[key] = row;
  228. }
  229. for (var i = 0; i < grp.attrerrs.length; i++) {
  230. var err = grp.attrerrs[i];
  231. var row = attrrows[err.attr[0]];
  232. row.className = "err-" + Math.round(err.conf * 10);
  233. var info = document.createElement('div');
  234. if (err.other_grp) {
  235. // the mismatch was with a group name
  236. if (err.other_osmid != grp.osmid) {
  237. if (err.other_osmid > 1) {
  238. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> in relation <a onmouseover='groupHl( " + err.other_grp + ")' onmouseout='groupUnHl( " + err.other_grp + ")' target=\"_blank\" href=\"https://www.openstreetmap.org/relation/" + Math.abs(err.other_osmid) + "\">" + Math.abs(err.other_osmid) + "</a>";
  239. } else {
  240. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> in relation <span onmouseover='groupHl( " + err.other_grp + ")' onmouseout='groupUnHl( " + err.other_grp + ")'>" + Math.abs(err.other_osmid) + "</span>";
  241. }
  242. } else {
  243. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> = '" + err.other_attr[1] + "'";
  244. }
  245. } else {
  246. // the mismatch was with another station
  247. var ident = err.other_osmid < 0 ? "way" : "node";
  248. info.innerHTML = "Does not match <tt>" + err.other_attr[0] + "</tt> in " + ident + " <a onmouseover='nodeHl( " + err.other + ")' onmouseout='nodeUnHl( " + err.other + ")' target=\"_blank\" href=\"https://www.openstreetmap.org/"+ident+"/" + Math.abs(err.other_osmid) + "\">" + Math.abs(err.other_osmid) + "</a>";
  249. }
  250. info.className = 'attr-err-info';
  251. row.childNodes[1].appendChild(info);
  252. }
  253. content.appendChild(newMembers);
  254. if (grp.osmid != 1) content.appendChild(oldMembers);
  255. for (var key in grp.stations) {
  256. var stat = grp.stations[key];
  257. var row = document.createElement('div');
  258. var ident = stat.osmid < 0 ? "Way" : "Node";
  259. row.innerHTML = ident + " <a onmouseover='nodeHl( " + stat.id + ")' onmouseout='nodeUnHl( " + stat.id + ")' target='_blank' href='https://www.openstreetmap.org/" + ident.toLowerCase() + "/" + Math.abs(stat.osmid) + "'>" + Math.abs(stat.osmid) + "</a>";
  260. if (stat.attrs.name) {
  261. row.innerHTML += " (<b>\"" + stat.attrs.name + "\"</b>)";
  262. }
  263. row.style.backgroundColor = stat.e ? '#f58d8d' : stat.s ? '#b6b6e4' : '#c0f7c0';
  264. if (grp.osmid == 1 || stat.orig_group != grp.id) newMembers.appendChild(row);
  265. else {
  266. oldMembers.appendChild(row);
  267. if (stat.group != grp.id) {
  268. row.className = "del-stat";
  269. }
  270. }
  271. }
  272. var suggList = document.createElement('ul');
  273. if (grp.su.length) {
  274. var a = document.createElement('span');
  275. a.className = "sugtit";
  276. a.innerHTML = "Suggestions";
  277. suggD.appendChild(a);
  278. }
  279. suggD.appendChild(suggList);
  280. for (var i = 0; i < grp.su.length; i++) {
  281. var sugg = grp.su[i];
  282. var suggDiv = document.createElement('li');
  283. if (sugg.type == 6) {
  284. suggDiv.innerHTML = "Fix attribute <tt>" + sugg.attr + "</tt>.";
  285. } else if (sugg.type == 7) {
  286. suggDiv.innerHTML = "Consider adding a <tt><a target='_blank' href='https://wiki.openstreetmap.org/wiki/Key:name'>name</a></tt> attribute.";
  287. } else if (sugg.type == 8) {
  288. suggDiv.innerHTML = "Attribute <tt>" + sugg.attr + "</tt> seems to be a track number. Use <tt>ref</tt> for this and set <tt>" + sugg.attr + "</tt> to the station name.";
  289. }
  290. suggList.appendChild(suggDiv);
  291. }
  292. content.appendChild(suggD);
  293. if (map.getZoom() < 18) {
  294. map.setView(ll, 18, {
  295. animate: true
  296. });
  297. }
  298. L.popup({
  299. opacity: 0.8
  300. })
  301. .setLatLng(ll)
  302. .setContent(content)
  303. .openOn(map)
  304. .on('remove', function() {openGr = -1; groupUnHl(grp.id)});
  305. }
  306. function openGroup(id, ll) {
  307. window.xmlhttp = new XMLHttpRequest();
  308. window.xmlhttp.onreadystatechange = function() {
  309. if (this.readyState == 4 && this.status == 200 && this == window.xmlhttp) {
  310. var content = JSON.parse(this.responseText);
  311. renderGroup(content, ll);
  312. }
  313. };
  314. window.xmlhttp.open("GET", backend + "/group?id=" + id, true);
  315. window.xmlhttp.send();
  316. }
  317. function groupHl(id) {
  318. if (!document.groupIdx[id]) return;
  319. document.groupIdx[id].setStyle({
  320. 'weight': 6,
  321. 'color': "#eecc00"
  322. });
  323. }
  324. function groupUnHl(id) {
  325. if (!document.groupIdx[id]) return;
  326. document.groupIdx[id].setStyle({
  327. 'weight': 3,
  328. 'color': document.groupIdx[id].options["fillColor"]
  329. });
  330. }
  331. function nodeHl(id) {
  332. if (!document.nodeIdx[id]) return;
  333. if (map.getZoom() > 15) {
  334. document.nodeIdx[id].setStyle({
  335. 'weight': 5,
  336. 'color': "#eecc00"
  337. });
  338. } else {
  339. document.nodeIdx[id].setStyle({
  340. 'color': "#eecc00"
  341. });
  342. }
  343. }
  344. function nodeUnHl(id) {
  345. if (!document.nodeIdx[id]) return;
  346. if (map.getZoom() > 15) {
  347. document.nodeIdx[id].setStyle({
  348. 'weight': 1,
  349. 'color': "black"
  350. });
  351. } else {
  352. document.nodeIdx[id].setStyle({
  353. 'color': document.nodeIdx[id].options["fillColor"]
  354. });
  355. }
  356. }
  357. var map = L.map('map', {
  358. renderer: L.canvas(),
  359. attributionControl: false,
  360. }).setView([47.9965, 7.8469], 13);
  361. map.addControl(L.control.attribution({
  362. position: 'bottomright',
  363. prefix: '&copy; <a href="http://ad.cs.uni-freiburg.de">University of Freiburg, Chair of Algorithms and Data Structures</a>'
  364. }));
  365. L.tileLayer('http://{s}.tile.stamen.com/toner-lite/{z}/{x}/{y}.png', {
  366. maxZoom: 20,
  367. attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
  368. opacity: 0.8
  369. }).addTo(map);
  370. var layer = L.featureGroup().addTo(map);
  371. var labelLayer = L.featureGroup().addTo(map);
  372. map.on("moveend", function() {
  373. render();
  374. });
  375. function render() {
  376. window.xmlhttp = new XMLHttpRequest();
  377. if (map.getZoom() < 11) {
  378. window.xmlhttp.onreadystatechange = function() {
  379. if (this.readyState == 4 && this.status == 200 && this == window.xmlhttp) {
  380. var content = JSON.parse(this.responseText);
  381. layer.clearLayers();
  382. labelLayer.clearLayers();
  383. var blur = 22 - map.getZoom();
  384. var rad = 25 - map.getZoom();
  385. layer.addLayer(L.heatLayer(content.ok, {
  386. max: 500,
  387. gradient: {
  388. 0: '#cbf7cb',
  389. 0.5: '#78f378',
  390. 1: '#29c329'
  391. },
  392. minOpacity: 0.65,
  393. blur: blur,
  394. radius: rad
  395. }));
  396. layer.addLayer(L.heatLayer(content.sugg, {
  397. max: 500,
  398. gradient: {
  399. 0: '#7f7fbd',
  400. 0.5: '#4444b3',
  401. 1: '#0606c1'
  402. },
  403. minOpacity: 0.65,
  404. blur: blur - 3,
  405. radius: Math.min(12, rad - 3)
  406. }));
  407. layer.addLayer(L.heatLayer(content.err, {
  408. max: 500,
  409. gradient: {
  410. 0: '#f39191',
  411. 0.5: '#ff5656',
  412. 1: '#ff0000'
  413. },
  414. minOpacity: 0.75,
  415. blur: blur - 3,
  416. radius: Math.min(10, rad - 3),
  417. maxZoom: 15
  418. }));
  419. }
  420. };
  421. window.xmlhttp.open("GET", backend + "/heatmap?z=" + map.getZoom() + "&bbox=" + [map.getBounds().getSouthWest().lat, map.getBounds().getSouthWest().lng, map.getBounds().getNorthEast().lat, map.getBounds().getNorthEast().lng].join(","), true);
  422. window.xmlhttp.send();
  423. } else {
  424. window.xmlhttp.onreadystatechange = function() {
  425. if (this.readyState == 4 && this.status == 200 && this == window.xmlhttp) {
  426. var content = JSON.parse(this.responseText);
  427. layer.clearLayers();
  428. labelLayer.clearLayers();
  429. document.groupIdx = {};
  430. document.nodeIdx = {};
  431. var stations = [];
  432. var labels = [];
  433. for (var i = 0; i < content.stats.length; i++) {
  434. stat = content.stats[i];
  435. var ndMarker = marker(stat, map.getZoom());
  436. stations.push(ndMarker);
  437. document.nodeIdx[stat.i] = ndMarker;
  438. }
  439. var groups = [];
  440. for (var i = 0; i < content.groups.length; i++) {
  441. group = content.groups[i];
  442. var groupPoly = poly(group, map.getZoom());
  443. groups.push(groupPoly);
  444. document.groupIdx[group.i] = groupPoly;
  445. }
  446. var suggs = [];
  447. for (var i = 0; i < content.su.length; i++) {
  448. sugg = content.su[i];
  449. var a = sugArr(sugg, map.getZoom());
  450. suggs.push(a);
  451. }
  452. if (map.getZoom() > 13) {
  453. layer.addLayer(L.featureGroup(groups).on('click', function(a) {
  454. openGroup(a.layer.options.id, a.layer.getBounds().getCenter());
  455. }));
  456. }
  457. if (map.getZoom() > 15) {
  458. labelLayer.addLayer(L.featureGroup(labels));
  459. layer.addLayer(L.featureGroup(suggs).on('click', function(a) {
  460. openStat(a.layer.options.id);
  461. }));
  462. }
  463. layer.addLayer(L.featureGroup(stations).on('click', function(a) {
  464. openStat(a.layer.options.id);
  465. }));
  466. groupHl(openGr);
  467. nodeHl(openSt);
  468. }
  469. };
  470. window.xmlhttp.open("GET", backend + "/map?z=" + map.getZoom() + "&bbox=" + [map.getBounds().getSouthWest().lat, map.getBounds().getSouthWest().lng, map.getBounds().getNorthEast().lat, map.getBounds().getNorthEast().lng].join(","), true);
  471. window.xmlhttp.send();
  472. }
  473. }
  474. render();