1 <html> 2 <head> 3 <title>DSTAR.SU • Maps</title> 4 <meta name="copyright" content="Copyright © 2012 Artem Prilutskiy"/> 5 <meta name="viewport" content="width=device-width, user-scalable=no"/> 6
6<script type="text/javascript" src="Metrica.js"></script>
6 7
7<script type="text/javascript" src="OpenLayers/2.12/OpenLayers.js"></script>
7 8
8<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
8 9
9<script type="text/javascript" src="Libraries/jquery-2.0.3.min.js"></script>
9 10
10<script type="text/javascript" src="Libraries/date.format.js"></script>
10 11
11<script type="text/javascript" src="Libraries/mosquitto-1.1.min.js"></script>
11 12
12<script type="text/javascript" src="UserInterface/SteelSeries-Canvas/tween-min.js"></script>
12 13
13<script type="text/javascript" src="UserInterface/SteelSeries-Canvas/steelseries-min.js"></script>
13 14
14<script type="text/javascript" src="UserInterface/iscroll/dist/iscroll-min.js"></script>
14 15
15<script type="text/javascript" src="OpenLayerTools.js"></script>
15 16
16<script type="text/javascript" src="BrowserTools.js"></script>
16 17
17<script type="text/javascript" src="PushUpdater.js"></script>
17 18
18<script type="text/javascript" src="RepeaterLayer.js"></script>
18 19
19<script type="text/javascript" src="CoverageLayer.js"></script>
19 20
20<script type="text/javascript" src="StationLayer.js"></script>
20 21
21<script type="text/javascript" src="TrackLayer.js"></script>
21 22
22<script type="text/javascript" src="LocatorLayer.js"></script>
22 23
23<script type="text/javascript" src="StationTools.js"></script>
23 24
24<script type="text/javascript" src="MeasureTools.js"></script>
24 25
25<script type="text/javascript" src="StationDetails.js"></script>
25 26
26<script type="text/javascript" src="Data/agents.php?callback=setAgentMapping"></script>
26 27 <style type="text/css" media="only screen and (-webkit-min-device-pixel-ratio: 2) and (max-device-width: 1136px)"> 28 body 29 { 30 zoom: 50%; 31 } 32 </style> 33 <style type="text/css"> 34 body 35 { 36 font-family: Arial, Tahoma, Veranda, Hevelica; 37 font-size: 10pt; 38 } 39 .olControlNoSelect 40 { 41 font-size: 8pt !important; 42 } 43 .olFramedCloudPopupContent 44 { 45 font-size: 9pt; 46 } 47 .olPopupCloseBox 48 { 49 right: 8px !important; 50 background-image: url('Data/buttons/close.png') !important; 51 } 52 .mapPane 53 { 54 position: relative; 55 width: 100%; 56 height: 100%; 57 z-index: 1; 58 } 59 .controlPane 60 { 61 position: absolute; 62 top: 22px; 63 left: 54px; 64 z-index: 2; 65 padding: 6px 6px 6px 6px; 66 border-radius: 6px; 67 background-color: rgba(255, 255, 255, 0.6); 68 } 69 .clusterData a 70 { 71 font-size: 9pt; 72 white-space: pre; 73 } 74 .clusterData img 75 { 76 text-align: center; 77 vertical-align: middle; 78 } 79 .stationImage 80 { 81 position: relative; 82 bottom: 10px; 83 left: 232px; 84 width: 21px; 85 height: 21px; 86 margin-left: -21px; 87 margin-bottom: -21px; 88 vertical-align: text-top; 89 } 90 input 91 { 92 border: 1px solid #abadb3; 93 padding: 1px; 94 vertical-align: middle; 95 background-color: rgba(255, 255, 255, 0.6); 96 } 97 p 98 { 99 margin-top: 2px; 100 margin-bottom: 8px; 101 } 102 .success, 103 .error 104 { 105 background-repeat: no-repeat; 106 background-position: right center; 107 } 108 .success 109 { 110 background-image: url('Data/buttons/success.png'); 111 } 112 .error 113 { 114 background-image: url('Data/buttons/error.png'); 115 } 116 #home, 117 #reset, 118 #track, 119 #locate, 120 #toggle 121 { 122 background-repeat: no-repeat; 123 background-position: center center; 124 height: 22px; 125 width: 22px; 126 } 127 #home 128 { 129 background-image: url('Data/buttons/home.png'); 130 } 131 #reset 132 { 133 background-image: url('Data/buttons/cursor.png'); 134 } 135 #track 136 { 137 background-image: url('Data/buttons/pin.png'); 138 } 139 #locate 140 { 141 background-image: url('Data/buttons/search.png'); 142 } 143 #toggle 144 { 145 background-image: url('Data/buttons/ruler.png'); 146 } 147 .pushed 148 { 149 border-width: 2px; 150 border-color: black; 151 } 152 .text 153 { 154 display: inline-block; 155 position: relative; 156 vertical-align: middle; 157 } 158 #measure 159 { 160 display: inline-block; 161 position: relative; 162 text-align: center; 163 vertical-align: middle; 164 width: 96px; 165 } 166 </style> 167 </head> 168 <body> 169 <div class="mapPane" id="map"></div> 170 <div class="controlPane"> 171 <input id="home" type="button" onclick="goHome();"/> 172 <span class="text"> Call:</span> 173 <input id="call" type="text" size="14" maxlength="10" style="text-transform: uppercase;" onfocus="handleFocus();" onkeydown="return handleKeyDown(event);" onkeyup="handleKeyUp(event);"/> 174 <input id="locate" type="button" onclick="showCall();"/> 175 <select id="interval"> 176 <option value="900">15 minutes</option> 177 <option value="1800">30 minutes</option> 178 <option value="3600">1 hour</option> 179 <option value="10800">3 hours</option> 180 <option value="21600">6 hours</option> 181 <option value="43200">12 hour</option> 182 <option value="86400">24 hour</option> 183 <option value="172800">2 days</option> 184 <option value="259200">3 days</option> 185 <option value="345600">4 days</option> 186 <option value="432000">5 days</option> 187 <option value="518400">6 days</option> 188 <option value="604800">7 days</option> 189 </select> 190 <input id="track" type="button" onclick="showTrack();"/> 191 <div id="measure">-</div> 192 <input id="toggle" type="button" onclick="toggleControl();"/> 193 <input id="reset" type="button" onclick="resetControl();"/> 194 </div> 195
195<script defer="defer" type="text/javascript"> 196 197 // Bing Maps API Key 198 199 var key = 'AreSBTndXwzXCXV7iIDC-kmk-0rMc80Z-XMLLpiQshc0gtOBz5IptDR-A3CFmukk'; 200 201 // Pre-OpenLayers options 202 203 var link = new String(document.location); 204 205 // OpenLayers map initialization 206 207 var projection1 = new OpenLayers.Projection('EPSG:4326'); 208 var projection2 = new OpenLayers.Projection('EPSG:900913'); 209 210 var coordinates = new OpenLayers.LonLat(37.37, 55.34).transform(projection1, projection2); 211 212 var map = new OpenLayers.Map({ 213 projection: projection2, 214 displayProjection: projection1, 215 div: 'map', 216 layers: 217 [ 218 new OpenLayers.Layer.OSM(), 219 new OpenLayers.Layer.Google('Google Map', { sphericalMercator: true, type: google.maps.MapTypeId.ROADMAP }), 220 new OpenLayers.Layer.Google('Google Physical Map', { sphericalMercator: true, type: google.maps.MapTypeId.TERRAIN }), 221 new OpenLayers.Layer.Google('Google Satellite Map', { sphericalMercator: true, type: google.maps.MapTypeId.SATELLITE }), 222 new OpenLayers.Layer.Google('Google Hybrid Map', { sphericalMercator: true, type: google.maps.MapTypeId.HYBRID }), 223 new OpenLayers.Layer.Bing({ name: 'Bing Road Map', key: key, type: 'Road' }), 224 new OpenLayers.Layer.Bing({ name: 'Bing Aerial Map', key: key, type: 'Aerial' }), 225 new OpenLayers.Layer.Bing({ name: 'Bing Hybrid Map', key: key, type: 'AerialWithLabels' }), 226 createLocatorLayer('Locator Grid'), 227 createCoverageLayer('APRS Stations Coverage'), 228 createRepeaterLayer('D-STAR Nodes (dstar.su)', { mark: 1 }), 229 createRepeaterLayer('D-STAR Nodes (ircddb.net)', { mark: 2 }), 230 createStationLayer('DMR Stations', { interval: 43200, path: 'DMR*' }), 231 createStationLayer('D-STAR Stations', { interval: 43200, path: 'DSTAR*' }), 232 createStationLayer('APRS Stations', { interval: 10800 }), 233 new OpenLayers.Layer.WMS('D-STAR Propagation', 'https://cloud.dstar.su/tilecache/tilecache.fcgi', 234 { layers: 'splat', transparent: true }, { isBaseLayer: false, opacity: 0.55, visibility: false }), 235 new OpenLayers.Layer.XYZ('Pressure (OWM)', 'https://${s}.tile.openweathermap.org/map/pressure_cntr/${z}/${x}/${y}.png', 236 { numZoomLevels: 19, isBaseLayer: false, opacity: 0.4, sphericalMercator: true, visibility: false }), 237 new OpenLayers.Layer.XYZ('Precipitation (OWM)', 'https://${s}.tile.openweathermap.org/map/precipitation/${z}/${x}/${y}.png', 238 { numZoomLevels: 19, isBaseLayer: false, opacity: 0.6, sphericalMercator: true, visibility: false }), 239 new OpenLayers.Layer.XYZ('Clouds (OWM)', 'https://${s}.tile.openweathermap.org/map/clouds/${z}/${x}/${y}.png', 240 { numZoomLevels: 19, isBaseLayer: false, opacity: 0.7, sphericalMercator: true, visibility: false }) 241 ], 242 controls: 243 [ 244 new OpenLayers.Control.Attribution(), 245 new OpenLayers.Control.Navigation({ dragPanOptions: { enableKinetic: true } }), 246 new OpenLayers.Control.Zoom(), 247 new OpenLayers.Control.Permalink({ anchor: true }) 248 ], 249 eventListeners: 250 { 251 changelayer: handleLayerChange 252 }, 253 center: coordinates, 254 zoom: 3 255 }); 256 257 var control = new OpenLayers.Control.LayerSwitcher({ roundedCorner: true }); 258 map.addControl(control); 259 control.maximizeControl(); 260 261 // Experimental code with Google's Traffic Layer 262 263 var layers = map.getLayersByName('Google Map'); 264 if (layers.length > 0) 265 { 266 var layer = new google.maps.TrafficLayer(); 267 layer.setMap(layers[0].mapObject); 268 } 269 270 // Measure tool 271 272 var control1 = createMeasureControl( 273 function(event) 274 { 275 $('#measure').html(event.measure.toFixed(3) + ' ' + event.units); 276 } 277 ); 278 map.addControl(control1); 279 280 // Popups with call details 281 282 function removePopup(feature) 283 { 284 if (feature.popup != null) 285 { 286 map.removePopup(feature.popup); 287 feature.destroyPopup(); 288 feature.popup = null; 289 } 290 } 291 292 function closePopup(event) 293 { 294 var name = $(event.target).attr('id').match(/^(.+)_close$/)[1]; 295 296 var element = $('.olFramedCloudPopupContent > :first', event.target.parent); 297 $.removeData(element); 298
299 eachFeatureWithAttribute(map, 'name', name, removePopup); 300 301 for (var index = 0; index < map.popups.length; index ++) 302 { 303 var popup = map.popups[index]; 304 if (popup.id == name) 305 { 306 popup.destroy(); 307 break; 308 } 309 } 310 } 311 312 function attachPopup(feature) 313 { 314 for (var index = 0; index < map.popups.length; index ++) 315 { 316 var popup = map.popups[index]; 317 if (popup.id == feature.attributes['name']) 318 { 319 feature.popup = popup; 320 popup.lonlat = feature.geometry.getBounds().getCenterLonLat(); 321 var element = $(':first', popup.contentDiv); 322 queryStationDetails(popup.id, element); 323 popup.updatePosition(); 324 } 325 } 326 } 327 328 function createPopup(name, feature) 329 { 330 if (feature.popup == null) 331 { 332 var popup = new OpenLayers.Popup.FramedCloud( 333 name, 334 feature.geometry.getBounds().getCenterLonLat(), 335 new OpenLayers.Size(256, 136), 336 '', 337 null, 338 true, 339 closePopup 340 ); 341 popup.autoSize = false; 342 feature.popup = popup; 343 map.addPopup(popup); 344 345 var element = document.createElement('div'); 346 popup.contentDiv.appendChild(element); 347 348 if (feature.cluster != undefined) 349 { 350 $(element).html( 351 '<b>Stations in cluster:</b><br/>' + 352 getStationClusterData(feature.cluster, togglePopup) 353 ); 354 activateWebKitScroll(element); 355 return; 356 } 357 if (name.length < 16) 358 { 359 queryStationDetails(name, element); 360 return; 361 } 362 if (name.length == 24) 363 { 364 queryPositionDetails(name, element); 365 return; 366 } 367 } 368 } 369 370 function togglePopup(event) 371 { 372 var name = $(event.target).text(); 373 eachFeatureWithAttribute( 374 map, 375 'name', 376 name, 377 function(feature) 378 { 379 createPopup(name, feature); 380 var element = $('#call'); 381 element.removeClass('success error'); 382 element.val(name); 383 } 384 ); 385 } 386 387 function handleNewFeatures(event) 388 { 389 for (var index = 0; index < event.features.length; index ++) 390 { 391 var feature = event.features[index]; 392 attachPopup(feature); 393 } 394 } 395 396 function handleSelectFeature(feature) 397 { 398 var name = feature.attributes['name']; 399 if (name != undefined) 400 { 401 createPopup(name, feature); 402 if (name.length < 16) 403 { 404 var element = $('#call'); 405 element.removeClass('success error'); 406 element.val(name); 407 } 408 } 409 if (feature.cluster != undefined) 410 { 411 var date = new Date(); 412 var name = date.getTime(); 413 createPopup(name, feature); 414 } 415 } 416 417 var layers = map.getLayersByName(/Stations$/); 418 for (var index = 0; index < layers.length; index ++) 419 { 420 var layer = layers[index]; 421 layer.events.register('featuresadded', layer, handleNewFeatures); 422 } 423 424 var control2 = new OpenLayers.Control.SelectFeature(layers, 425 { onSelect: handleSelectFeature, geometryTypes: [ 'OpenLayers.Geometry.Point' ] }); 426 map.addControl(control2); 427 control2.toggle = true; 428 429 // Control switcher 430 431 function goHome() 432 { 433 if (confirm('Are you shure you want to leave this page?')) 434 window.top.location = '/'; 435 } 436 437 function toggleControl() 438 { 439 var element = $('#toggle'); 440 var pushed = element.hasClass('pushed'); 441 if (pushed) 442 { 443 control1.deactivate(); 444 control2.activate(); 445 } 446 else 447 { 448 $('#measure').html('-'); 449 control2.deactivate(); 450 control1.activate(); 451 } 452 element.toggleClass('pushed', !pushed); 453 } 454 455 function resetControl() 456 { 457 element.toggleClass('pushed', false); 458 $('#measure').html('-'); 459 control1.deactivate(); 460 control2.activate(); 461 } 462 463 control2.activate(); 464 465 // Track layer and call locate functionality 466 467 var colors = [ 'blue', 'green', 'red', 'black', 'purple' ]; 468 469 function addTrackLayer(call) 470 { 471 var name = 'Station Track (' + call + ')'; 472 var layers = map.getLayersByName(name); 473 for (var index = 0; index < layers.length; index ++) 474 { 475 var layer = layers[index]; 476 map.removeLayer(layer); 477 layer.destroy(); 478 } 479 var interval = $('#interval').val(); 480 var color = colors[Math.floor(Math.random() * colors.length)]; 481 var layer = createTrackLayer(name, call, interval, color); 482 map.addLayer(layer); 483 var layers = map.getLayersByName(/(Stations$|^Station Track)/); 484 control2.setLayer(layers); 485 } 486 487 function showCallStatus(valid) 488 { 489 var name = valid ? 'success' : 'error'; 490 $('#call').toggleClass(name); 491 } 492 493 function showTrack() 494 { 495 var call = $('#call').val(); 496 queryStationPosition(call, 497 function(data) 498 {
499 var valid = (data['position'] != undefined); 500 showCallStatus(valid); 501 if (valid) 502 addTrackLayer(call); 503 } 504 ); 505 } 506 507 function showCall() 508 { 509 var call = $('#call').val(); 510 queryStationPosition(call, 511 function(data) 512 { 513 var valid = (data['position'] != undefined); 514 showCallStatus(valid); 515 if (valid) 516 locatePosition(data, map); 517 } 518 ); 519 } 520 521 function handleLayerChange(event) 522 { 523 var expression = /^Station Track/; 524 if ((event.property == 'visibility') && 525 expression.test(event.layer.name)) 526 map.removeLayer(event.layer); 527 } 528 529 function handleFocus() 530 { 531 $('#call').removeClass('success error'); 532 } 533 534 function handleKeyDown(event) 535 { 536 var character = String.fromCharCode(event.keyCode); 537 var expression = /[\-a-zA-Z0-9\r\x08\x7f\xad\xbd]/; 538 return expression.test(character); 539 } 540 541 function handleKeyUp(event) 542 { 543 if (event.keyCode == 13) 544 { 545 showCall(); 546 return; 547 } 548 event.target.value = event.target.value.toUpperCase(); 549 } 550 551 // Locate position on the map at the start 552 553 var expression = /(layers|call|lat|log)=/; 554 if ((navigator.geolocation != undefined) && 555 !expression.test(link)) 556 { 557 navigator.geolocation.getCurrentPosition( 558 function(location) 559 { 560 var position = location.coords; 561 var coordinates = new OpenLayers.LonLat(position.longitude, position.latitude).transform( 562 new OpenLayers.Projection('EPSG:4326'), map.projection); 563 map.setCenter(coordinates, 10, false, false); 564 } 565 ); 566 } 567 568 var expression = /call=([\w]{4,7}(?:-[\w]{1,2})?)/; 569 if (expression.test(link)) 570 { 571 var call = link.match(expression)[1]; 572 $('#call').val(call); 573 locateStation(call, map); 574 } 575 576 // Validate browser application 577 578 if (navigator.appName == 'Microsoft Internet Explorer') 579 alert( 580 'This page is not compatible with Internet Explorer!\n' + 581 'We strongly recomend you to use other modern\n' + 582 'browsers like Chrome, FireFox, Opera or Safari.' 583 ); 584 585 </script>
585 586 </body> 587</html>
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.