PageSourceSearch

https://baustellen.saarland/js/map.js?1

js baustellen.saarland collected 2026-10-07 15:54:53 UTC 12,768 bytes, 464 lines download raw bytes

1let mymap;
2
3const QuadKeyTileLayer = L.TileLayer.extend({
4  // tslint:disable-next-line: object-literal-shorthand
5  getTileUrl: function (tilePoint) {
6    return L.Util.template(this._url, {
7      q: this._quadKey(tilePoint.x, tilePoint.y, this._getZoomForUrl()),
8      z: this._getZoomForUrl(),
9      t: new Date().getTime(),
10    });
11  },
12  _quadKey: (x, y, z) => {
13    const quadKey = [];
14    for (let i = z; i > 0; i--) {
15      let digit = 0;
16      // tslint:disable-next-line: no-bitwise
17      const mask = 1 << (i - 1);
18      // tslint:disable-next-line: no-bitwise
19      if ((x & mask) !== 0) {
20        digit++;
21      }
22      // tslint:disable-next-line: no-bitwise
23      if ((y & mask) !== 0) {
24        digit++;
25        digit++;
26      }
27      quadKey.push(digit);
28    }
29    const qk = quadKey.join('');
30    return qk;
31  },
32});
33
34const darkblue = '#0B5196';
35const lightgreen = '#C6DF29';
36// const red = "#DA2F36"
37const red = '#952025';
38const lightblue = '#00AECA';
39const grey = '#636363';
40const orange = '#FFB300';
41
42const bounds = [
43  [48.501357283942795, 5.259324429806133], // Southwest coordinates kleiner machen
44  [49.75726310648551, 8.550780383665505], // Northeast coordinates größer machen
45];
46
47function init() {
48  mymap = L.map('map', {
49    center: [49.4, 6.96],
50    zoom: 10,
51    zoomControl: true,
52    minZoom: 8,
53    maxZoom: 16,
54    maxBoundsViscosity: 1,
55  });
56	
57  //const osm_grey = 'http://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png';
58  //const background = L.tileLayer(osm_grey, {
59  //  attribution:
60  //    '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
61  //}); 
62  const osm_grey = 'https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web_light_grau/default/WEBMERCATOR/{z}/{y}/{x}.png';
63  const background = L.tileLayer(osm_grey, {
64    attribution: 'Kartendarstellung und Präsentationsgraphiken: &copy; Bundesamt für Kartographie und Geodäsie'
65  });
66
67  background.addTo(mymap);
68  mymap.zoomControl.setPosition('bottomright');
69  //$('.icon.verkehrslage').click();
70  addBaustellenLayer();
71}
72
73function createClusterIcon(cluster, color, className) {
74  let iconSize, iconAnchor, popupAnchor, textnumber;
75  let children = cluster.getChildCount();
76  if (children > 999) {
77    iconSize = [80, 90];
78    iconAnchor = [40, 90];
79    popupAnchor = [0, -90];
80    textnumber = '1000';
81  } else if (children > 99) {
82    iconSize = [60, 70];
83    iconAnchor = [30, 70];
84    popupAnchor = [0, -70];
85    textnumber = '100';
86  } else if (children > 9) {
87    iconSize = [50, 60];
88    iconAnchor = [25, 60];
89    popupAnchor = [0, -60];
90    textnumber = '10';
91  } else {
92    iconSize = [40, 50];
93    iconAnchor = [20, 50];
94    popupAnchor = [0, -50];
95    textnumber = '';
96  }
97  return new L.divIcon({
98    html:
99      '<div class="clusternumber' +
100      textnumber +
101      '" style="background-color:' +
102      color +
103      '">' +
104      children +
105      '</div>',
106    iconSize: iconSize,
107    iconAnchor: iconAnchor,
108    popupAnchor: popupAnchor,
109    className: className,
110  });
111}
112/*
113listenansicht = {
114    [target:string] =  string[]
115}
116*/
117const listenansicht = {};
118function populateListenansicht(target, feature) {
119  const props = feature.properties;
120
121  const desc = props['description'],
122    road = props['roadname'],
123    id = props['recordid'],
124    start = props['starttime'],
125    end = props['endtime'],
126    event = props['event'],
127    roadarr = road.split(' ');
128  let color;
129  if (
130    roadarr.length > 1 &&
131    roadarr[1] &&
132    roadarr[1] !== 'Straße' &&
133    roadarr[1] !== 'Weg'
134  ) {
135    color = roadarr[0] === 'A' ? 'blue' : 'yellow';
136  } else {
137    color = 'white';
138  }
139
140  if (!listenansicht[target] || listenansicht[target].indexOf(road) === -1) {
141    if (!listenansicht[target]) {
142      listenansicht[target] = [road];
143    } else {
144      listenansicht[target].push(road);
145    }
146    if (
147      roadarr.length > 1 &&
148      roadarr[1] &&
149      roadarr[1] !== 'Straße' &&
150      roadarr[1] !== 'Weg'
151    ) {
152      const box =
153        '<div id="' +
154        id +
155        '" class="small-box listen ' +
156        color +
157        '" data="' +
158        target +
159        '" data-road="' +
160        road +
161        '">' +
162        road +
163        '</div>';
164      $('#boxenNumbers[data=' + target + ']').append(box);
165    } else {
166      const box =
167        '<div id="' +
168        id +
169        '" class="small-box listen ' +
170        color +
171        '" data="' +
172        target +
173        '" data-road="' +
174        road +
175        '">' +
176        road +
177        '</div>';
178      $('#boxenStreets[data=' + target + ']').append(box);
179    }
180  }
181  const imgSrc =
182    target === 'baustelle'
183      ? 'img/svg_bunt/baustellen.svg'
184      : 'img/verkehrsmeldungen.svg';
185  let meldungen = '';
186  meldungen +=
187    '<div class="meldung" onclick="zoomToGeometry(\'' +
188    target +
189    "'," +
190    JSON.stringify(feature.geometry.coordinates) +
191    ')" data-road="' +
192    road +
193    '" data="' +
194    target +
195    '"><div class="list-view-item" id="listenview">';
196  meldungen += '<div class="left-col"><img src="' + imgSrc + '"></div>';
197  meldungen += '<div class="right-col"><div class="headline-wrapper">';
198  meldungen +=
199    '<div class="small-box ' + color + '" style="margin:0" >' + road + '</div>';
200  meldungen += '<h3>' + event + '</h3></div>';
201  meldungen += '<div class="information">';
202  meldungen += '<span class="text">' + desc + '</span>';
203  meldungen += '<span class="time">Start: ' + convertTime(start) + '</span>';
204  meldungen +=
205    '<span class="time" style="margin:0;">Ende: ' +
206    convertTime(end) +
207    '</span></div >';
208  meldungen += '<span class="clear"></span></div ></div >';
209  meldungen += '<hr style="background-color: #636363;">';
210
211  $('#meldungsmenu[data=' + target + ']').append(meldungen);
212}
213
214function zoomToGeometry(target, geometry) {
215  if (target === 'baustelle') {
216    addBaustellenLayer();
217  } else if (target === 'verkehrswarndienst') {
218    addVerkehrsmeldungenLayer();
219  }
220  let bounds = new L.latLngBounds();
221  for (let i = 0; i < geometry[0].length; i++) {
222    const coord = geometry[0][i];
223    bounds.extend(new L.latLng(coord[1], coord[0]));
224  }
225  mymap.fitBounds(bounds.pad(0.2));
226}
227
228// .window impressum && datenschutz scrollable
229$(document).on(
230  {
231    mouseenter: function () {
232      mymap.scrollWheelZoom.disable();
233      mymap.dragging.disable();
234    },
235    mouseleave: function () {
236      mymap.scrollWheelZoom.enable();
237      mymap.dragging.enable();
238    },
239  },
240  '.window',
241);
242
243//+++++++++++++++++++
244//Layer + Icons
245//+++++++++++++++++++
246
247//Icon Optionen
248let myIcon = L.Icon.extend({
249  options: {
250    iconSize: [38, 51],
251    iconAnchor: [19, 51],
252    popupAnchor: [0, -51],
253  },
254});
255
256// +++++++++++++++++++++++++++
257// Dynamische Verkehrsdaten
258// +++++++++++++++++++++++++++
259
260//Verkehrsmeldungen
261let tm2color = red;
262let tm2 = L.markerClusterGroup({
263  showCoverageOnHover: false,
264  iconCreateFunction: function (cluster) {
265    return createClusterIcon(cluster, tm2color, 'tm2');
266  },
267});
268
269//Verkehrsmeldungslinien
270let tm2style = {
271  color: tm2color,
272  weight: 6,
273  opacity: 1,
274};
275
276function convertTime(time) {
277  const date = new Date(time);
278  const day = date.getDate().toString().padStart(2, '0');
279  const month = (date.getMonth() + 1).toString().padStart(2, '0');
280  const year = date.getFullYear().toString().padStart(4, '0');
281
282  const hour = date.getHours().toString().padStart(2, '0');
283  const minute = date.getMinutes().toString().padStart(2, '0');
284  //   let newtime = time.split('T');
285  //   let date = newtime[0];
286  //   let clock = newtime[1];
287  //   let datearr = date.split('-');
288  //   let string = datearr[2] + '.' + datearr[1] + '.' + datearr[0] + ' ' + clock;
289  //   return string;
290  return day + '.' + month + '.' + year + ' ' + hour + ':' + minute;
291}
292
293function genericPopup(feature) {
294  let string = '';
295  props = feature.properties;
296  if (
297    props.event &&
298    props.event !== 'undefined' &&
299    props.event !== '' &&
300    props.event !== 'Baustelle'
301  ) {
302    string += props.event + '<br>';
303  }
304  if (
305    props.roadname &&
306    props.roadname !== '' &&
307    props.roadname !== 'unbekannt'
308  ) {
309    string += props.roadname + '<br>';
310  }
311  if (props.starttime && props.starttime !== '') {
312    string += 'Von: ' + convertTime(props.starttime) + '<br>';
313  }
314  if (props.endtime && props.endtime !== '') {
315    string += 'Bis: ' + convertTime(props.endtime) + '<br>';
316  }
317  if (props.description && props.description !== '') {
318    string += props.description + '<br>';
319  }
320  return string;
321}
322
323let tm2line = L.geoJSON.ajax(
324  'data/verkehrsmeldungen/traffic_messages_line_geojson.geojson?' +
325    new Date().getTime(),
326  {
327    style: tm2style,
328    onEachFeature: function (feature, layer) {
329      populateListenansicht('verkehrswarndienst', feature);
330      layer.bindPopup(genericPopup(feature));
331    },
332  },
333);
334
335tm2line.on('data:loaded', function () {
336  tm2.addLayer(tm2line);
337});
338
339//Verkehrsmeldungsmarker
340let tmmarker = L.geoJSON.ajax(
341  'data/verkehrsmeldungen/traffic_messages_point_geojson.geojson?' +
342    new Date().getTime(),
343  {
344    pointToLayer: function (feature, latlng) {
345      return L.marker(latlng, {
346        icon: new myIcon({
347          iconUrl: 'img/svg_marker/marker_verkehrsmeldungen.svg?1',
348        }),
349      });
350    },
351    onEachFeature: function (feature, layer) {
352      layer.bindPopup(genericPopup(feature));
353    },
354  },
355);
356
357tmmarker.on('data:loaded', function () {
358  tm2.addLayer(tmmarker);
359});
360
361$(document).on('click', 'div.icon.verkehrsmeldungen', function () {
362  !$(this).hasClass('active')
363    ? addVerkehrsmeldungenLayer()
364    : removeVerkehrsmeldungenLayer();
365});
366
367function addVerkehrsmeldungenLayer() {
368  mymap.addLayer(tm2);
369}
370function removeVerkehrsmeldungenLayer() {
371  mymap.removeLayer(tm2);
372}
373
374// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
375// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
376// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
377
378//Baustellen
379let baucolor = red;
380
381//Baustellenlinien
382let bau2style = {
383  color: baucolor,
384  weight: 6,
385  opacity: 1,
386};
387
388const baustellenRegex = new RegExp('<a.*Details</a>');
389let bau2line = L.geoJSON.ajax(
390  'data/baustellen/roadworks_line_geojson.geojson?' + new Date().getTime(),
391  {
392    style: bau2style,
393    filter: function (feature) {
394      return !baustellenRegex.test(feature.properties.description);
395    },
396    onEachFeature: function (feature, layer) {
397      populateListenansicht('baustelle', feature);
398      layer.bindPopup(genericPopup(feature));
399    },
400  },
401);
402
403//Baustellenmeldungsmarker
404let baumarker = L.geoJSON.ajax(
405  'data/baustellen/roadworks_point_geojson.geojson?' + new Date().getTime(),
406  {
407    filter: function (feature) {
408      return !baustellenRegex.test(feature.properties.description);
409    },
410    pointToLayer: function (feature, latlng) {
411      return L.marker(latlng, {
412        icon: new myIcon({ iconUrl: 'img/svg_marker/marker_baustellen.svg?1' }),
413      });
414    },
415    onEachFeature: function (feature, layer) {
416      layer.bindPopup(genericPopup(feature));
417    },
418  },
419);
420
421$(document).on('click', 'div.icon.baustellen', function () {
422  !$(this).hasClass('active') ? addBaustellenLayer() : removeBaustellenLayer();
423});
424
425function addBaustellenLayer() {
426  mymap.addLayer(bau2line);
427  mymap.addLayer(baumarker);
428}
429function removeBaustellenLayer() {
430  mymap.removeLayer(bau2line);
431  mymap.removeLayer(baumarker);
432}
433
434// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
435// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
436// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
437
438/*
439+++++++++++++++++++++++++++
440LOS Layer
441+++++++++++++++++++++++++++
442*/
443const los = new QuadKeyTileLayer(
444  'https://mobilitaet.saarland/api/verkehr?quadkey={q}&zoom={z}&timestamp={t}',
445  {
446    attribution: 'Inrix',
447  },
448);
449
450$(document).on('click', 'div.icon.verkehrslage', function () {
451  !$(this).hasClass('active') ? addVerkehrslage() : removeVerkehrslage();
452});
453
454function addVerkehrslage() {
455  mymap.addLayer(los);
456}
457
458function removeVerkehrslage() {
459  mymap.removeLayer(los);
460}
461
462$(document).on('click', '#close', function () {
463  removeVerkehrslage();
464});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.