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 // '© <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: © 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}×tamp={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.