Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html><head>
- <!-- based on https://jsfiddle.net/xrz53a7k/show/ https://jsfiddle.net/xrz53a7k/ https://vts-geospatial.org/tutorials/gpx-viewer.html -->
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- <title></title>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- <meta name="robots" content="noindex, nofollow">
- <meta name="googlebot" content="noindex, nofollow">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <script type="text/javascript" src="/js/lib/dummy.js"></script>
- <link rel="stylesheet" type="text/css" href="/css/result-light.css">
- <link rel="stylesheet" type="text/css" href="https://cdn.melown.com/libs/vtsjs/browser/v2/vts-browser.min.css">
- <script type="text/javascript" src="https://cdn.melown.com/libs/vtsjs/browser/v2/vts-browser.min.js"></script>
- <style id="compiled-css" type="text/css">
- .pointer-div2 {
- position: absolute;
- left: 0px;
- top: 0px;
- width: 2px;
- height : 120px;
- display: none;
- background-color: rgba(255,0,0,0.5);
- z-index: 1;
- }
- .distance-div {
- font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
- position: absolute;
- left: 0px;
- top: 0px;
- display: none;
- padding: 5px;
- background: #ffde59;
- border: 2px solid #000000;
- border-radius: 4px;
- pointer-events: none;
- font-size: 12px;
- font-weight: bold;
- z-index: 2;
- }
- .distance-div:after, .distance-div:before {
- top: 100%;
- left: 50%;
- border: solid transparent;
- content: " ";
- height: 0;
- width: 0;
- position: absolute;
- pointer-events: none;
- }
- .distance-div:after {
- border-color: rgba(255, 222, 89, 0);
- border-top-color: #ffde59;
- border-width: 7px;
- margin-left: -7px;
- }
- .distance-div:before {
- border-color: rgba(0, 0, 0, 0);
- border-top-color: #000000;
- border-width: 10px;
- margin-left: -10px;
- }
- .profile-div {
- font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
- position: absolute;
- left: 10px;
- right: 10px;
- bottom: 10px;
- height: 122px;
- background-color: rgba(255,255,255,0.47);
- padding: 10px 20px;
- border-radius: 5px;
- }
- .profile-canvas-holder {
- position: absolute;
- left: 2px;
- top: 2px;
- right: 2px;
- bottom: 2px;
- background-color: rgba(255,255,255,0.60);
- }
- .profile-canvas {
- position: absolute;
- left: 0px;
- top: 0px;
- width: 100%;
- height: 100%;
- }
- /* EOS */
- </style>
- <script id="insert"></script>
- <script>
- const customConsole = (w) => {
- const pushToConsole = (payload, type) => {
- w.parent.postMessage({
- console: {
- payload: payload,
- type: type
- }
- }, "*")
- }
- w.onerror = (message, url, line, column) => {
- // the line needs to correspond with the editor panel
- // unfortunately this number needs to be altered every time this view is changed
- line = line - 70
- if (line < 0){
- pushToConsole(message, "error")
- } else {
- pushToConsole(`[${line}:${column}] ${message}`, "error")
- }
- }
- let console = (function(systemConsole){
- return {
- log: function(){
- let args = Array.from(arguments)
- pushToConsole(args, "log")
- systemConsole.log.apply(this, args)
- },
- info: function(){
- let args = Array.from(arguments)
- pushToConsole(args, "info")
- systemConsole.info.apply(this, args)
- },
- warn: function(){
- let args = Array.from(arguments)
- pushToConsole(args, "warn")
- systemConsole.warn.apply(this, args)
- },
- error: function(){
- let args = Array.from(arguments)
- pushToConsole(args, "error")
- systemConsole.error.apply(this, args)
- },
- system: function(){
- let args = Array.from(arguments)
- pushToConsole(args, "system")
- }
- }
- }(window.console))
- window.console = console
- console.system("Running fiddle")
- }
- if (window.parent){
- customConsole(window)
- }
- </script>
- </head>
- <body>
- <div id="map-div" style="width:100%; height:100%;">
- <div class="vts-browser"><div style="display: block;"><div id="vts-map" class="vts-map"> <canvas width="821" height="244" style="display: block;"></canvas></div></div><div style="display: block;"><div id="vts-compass" style="bottom: 170px;"><div id="vts-compass-frame"><img id="vts-compass-compass" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGMAAABjCAYAAACPO76VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODRDNjZFNDJCQjNCMTFFM0IyN0ZCQTZFQTAwNzEzNDUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODRDNjZFNDNCQjNCMTFFM0IyN0ZCQTZFQTAwNzEzNDUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4NEM2NkU0MEJCM0IxMUUzQjI3RkJBNkVBMDA3MTM0NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4NEM2NkU0MUJCM0IxMUUzQjI3RkJBNkVBMDA3MTM0NSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pgg3VBcAAAzUSURBVHja7F1bbBTX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" style="transform: rotateX(21deg) rotateZ(-45deg);"></div><div id="vts-compass-frame2"><img id="vts-compass-compass2" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGMAAABjCAYAAACPO76VAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABG9JREFUeNrtnM9LFGEcxkeEPCQVmbkh7EXoEgW6noIQzQwKoQ5Lkgh7SA8iddlCQfAQFApdghAxooJCsEMe9JAEek8i81YQCIEYQvgHZM9L37Fpmpl9Z3d+rs8DDw7unuaz3+ddX+d9DIOiKIqiKIqiKIqiKIqiKIqiKIqiKMpTQ0NDyqNwTq7/MRUNAKsfwL2EER+MLHxBru/BA4QR3zR0wY/lWmmEMKKHcVh+tsEv5PoGPE4Y0cP4LD9b4AW57oC/whvwB3gZfgN3886FG1EmjAZ41WEa6uAm+DTcyLsXPAz11fWkDUYtvAVPwHfgAnwdbmVMhQtjDj4jN3gNPiTXF+E8fAsuwvfhQScIuVwuMusK762H69IGYwY+LwDew+3wcZkOQ2fhThoMvK8TnkrjZEzCV+RGF2XhXoE/wuvwJ7jGK5aSAkOm4Qm8DTemEcYYfNNtCnTWiCTAkGn4Bu/B+bSuGcPwF3gJfg1Pww/l661uLMQGwzINe+L5tH+1PSpbIOdkG0TtRWWSDsM2Dco/UhlPQSpqGA7TsJfqeEorDLjHNg3pj6cUwjgCzzpAYDxFDENNw6YLCOU+Uggfhtc0mH5LAuHDKDUNyjtwhgTCg6EzDab7effDg6EzDYynkGH4mQbGU4gw/EwD4ykkGMfgZz4hMJ5CgHEV/l4GCMZTgDDUNDwvAwLjKeD1odxp2I8nP/92JQx3P6oAwn48EUYw64N5U3+VG09+H0ggDOc1woymn/Bl2WH1A2KhnKdDCON/WxfrgvzurA8gCmAzYVQOwxpPi7bXdIEUyn1uijDc46nZ4T2lgCxW8hAbYfz1U69PtwYQN4AE4BNGT6lPtwaQQqWPdxLGn93XzVKfbgff1QVI6cOY1Ywnt+2RkgApPRh+48m+PaJA9Ab1FPpBhuEnnpw2Cxd1I40qDUM3npymoRDG+YyDCsMaT0thTANh6MGwxtMunA1jGghDD4Y1ngY1pkH9T+JUFMfIDhoMazy9g2s8pmHHug1OGMHCcIunBvilwzRkoj5geZBgOMXTNXgrjGkgDHcYl2zxdAJ+FeY0EIYziHrLQRUVT7ejmAbCcIZhPbq1G9U06MIo97RuGkF0ejy50Z9LwDlwuekZOSB6QQ6MZuUAaVXGU+TT4BNGixydnpaj1EtytHq4GuPJPEPXF/HBSkcYOmUCUjowVo3xNK8OM8YBwgNGjdRqrEvNxorUbhTldVXHMVlN8aSmIR8XBDsMjymolSKadimmMaSoZqZa4mnePNqbMBiDUr1UlCqmvFQzGVLVtCbXqsJpLu3xtG1vHYgThMMUtEopWUFKyiaktKzWVmamys1G0xxPU04H3RMAo1Fq+Zqkps8OaFVq/aww0vt3hleDWQJgdEth5bIUWG5IoWWHvL5gNgJZYVABy2PRHpfKV0MqYNts1bC8eRHCGJEyZEPKkbvYwRsfjAGpCTdkGyRLAPHB6JUCfU5DAmDkpJ+XN4miKIqiKIqiKIqiKIqiKIqiKIpKpn4DKrVAiBFUfdUAAAAASUVORK5CYII=" style="transform: rotateX(21deg) rotateZ(-45deg);"></div><div id="vts-compass-frame3"><img id="vts-compass-compass3" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGMAAABjCAYAAACPO76VAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABG9JREFUeNrtnM9LFGEcxkeEPCQVmbkh7EXoEgW6noIQzQwKoQ5Lkgh7SA8iddlCQfAQFApdghAxooJCsEMe9JAEek8i81YQCIEYQvgHZM9L37Fpmpl9Z3d+rs8DDw7unuaz3+ddX+d9DIOiKIqiKIqiKIqiKIqiKIqiKIqiKMpTQ0NDyqNwTq7/MRUNAKsfwL2EER+MLHxBru/BA4QR3zR0wY/lWmmEMKKHcVh+tsEv5PoGPE4Y0cP4LD9b4AW57oC/whvwB3gZfgN3886FG1EmjAZ41WEa6uAm+DTcyLsXPAz11fWkDUYtvAVPwHfgAnwdbmVMhQtjDj4jN3gNPiTXF+E8fAsuwvfhQScIuVwuMusK762H69IGYwY+LwDew+3wcZkOQ2fhThoMvK8TnkrjZEzCV+RGF2XhXoE/wuvwJ7jGK5aSAkOm4Qm8DTemEcYYfNNtCnTWiCTAkGn4Bu/B+bSuGcPwF3gJfg1Pww/l661uLMQGwzINe+L5tH+1PSpbIOdkG0TtRWWSDsM2Dco/UhlPQSpqGA7TsJfqeEorDLjHNg3pj6cUwjgCzzpAYDxFDENNw6YLCOU+Uggfhtc0mH5LAuHDKDUNyjtwhgTCg6EzDab7effDg6EzDYynkGH4mQbGU4gw/EwD4ykkGMfgZz4hMJ5CgHEV/l4GCMZTgDDUNDwvAwLjKeD1odxp2I8nP/92JQx3P6oAwn48EUYw64N5U3+VG09+H0ggDOc1woymn/Bl2WH1A2KhnKdDCON/WxfrgvzurA8gCmAzYVQOwxpPi7bXdIEUyn1uijDc46nZ4T2lgCxW8hAbYfz1U69PtwYQN4AE4BNGT6lPtwaQQqWPdxLGn93XzVKfbgff1QVI6cOY1Ywnt+2RkgApPRh+48m+PaJA9Ab1FPpBhuEnnpw2Cxd1I40qDUM3npymoRDG+YyDCsMaT0thTANh6MGwxtMunA1jGghDD4Y1ngY1pkH9T+JUFMfIDhoMazy9g2s8pmHHug1OGMHCcIunBvilwzRkoj5geZBgOMXTNXgrjGkgDHcYl2zxdAJ+FeY0EIYziHrLQRUVT7ejmAbCcIZhPbq1G9U06MIo97RuGkF0ejy50Z9LwDlwuekZOSB6QQ6MZuUAaVXGU+TT4BNGixydnpaj1EtytHq4GuPJPEPXF/HBSkcYOmUCUjowVo3xNK8OM8YBwgNGjdRqrEvNxorUbhTldVXHMVlN8aSmIR8XBDsMjymolSKadimmMaSoZqZa4mnePNqbMBiDUr1UlCqmvFQzGVLVtCbXqsJpLu3xtG1vHYgThMMUtEopWUFKyiaktKzWVmamys1G0xxPU04H3RMAo1Fq+Zqkps8OaFVq/aww0vt3hleDWQJgdEth5bIUWG5IoWWHvL5gNgJZYVABy2PRHpfKV0MqYNts1bC8eRHCGJEyZEPKkbvYwRsfjAGpCTdkGyRLAPHB6JUCfU5DAmDkpJ+XN4miKIqiKIqiKIqiKIqiKIqiKIpKpn4DKrVAiBFUfdUAAAAASUVORK5CYII=" style="transform: rotateX(21deg) rotateZ(-45deg);"></div> </div></div><div style="display: block;"><div id="vts-credits" class="vts-credits" style="bottom: 134px;"><div class="vts-credits-supercell"><div class="vts-credits-cell">Imagery: ©2005-16 Jonathan de Ferranti</div><div class="vts-credits-cell-button" id="vts-credits-imagery-more">and others</div><div class="vts-credits-separator"></div></div><div class="vts-credits-supercell"><div class="vts-credits-cell">Map Data: <a href="https://www.openstreetmap.org/about/" target="blank"> © OpenStreetMap contributors</a></div><div class="vts-credits-cell-button" id="vts-credits-mapdata-more">and others</div><div class="vts-credits-separator"></div></div><div class="vts-credits-supercell"><div class="vts-credits-cell">Powered by <a class="vts-logo" href="https://www.melown.com/products/vts/" target="blank">VTS 3D Geospatial Software Stack</a></div><div class="vts-credits-separator"></div></div></div></div><div style="display: none;"><img id="vts-fullscreen" class="vts-fullscreen" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAwUlEQVRo3u2YwRWDIBBEIc+SLMKmckpTFkFPePKQQ57DsitR/z/D6KgMDikBAMCTycKYxai9Bul8MYkic+NFS7BOs4FUa/1IrzTn9xk6O6+rrwEMjGayTlS/UXWeujbcDKgpEZRObgYOc1oYt7CIMXCFFLKmTrS+aqAEP8iSAGBYI1s776FLv7eReaWHWd/cyLz3Bas+vxIYGNXIhBTxOhcKNdCaHvPfGPjVYb3OhVjEGLhrI/Pewc9uZDQvAABwZQMKFi+DmFdLbgAAAABJRU5ErkJggg=="></div><div style="display: block;"><div id="vts-zoom" class="vts-zoom"><div id="vts-zoom-plus" class="vts-zoom-plus" style="bottom: 140px;"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAASUlEQVRIx+2Tyw0AIAhDq0d2KsMzFFddQBO9+En6rqR5kFBAiBVINpJtJ1NPLCbJe5IyG7j78IMyEwBgZsNcRJQrl6gnkgjxIx12Cg3wDaLBUAAAAABJRU5ErkJggg=="></div><div id="vts-zoom-minus" class="vts-zoom-minus" style="bottom: 140px;"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAALUlEQVRIx2NgGAWjYBSMAqoCRlwSdnZ2/8kx8NChQxhmMo2G8ygYBaNgFGAHAElYBARpOBYqAAAAAElFTkSuQmCC"></div> </div></div><div style="display: block;"><div id="vts-space" class="vts-space" style="bottom: 140px;"><img id="vts-space-2d" class="vts-space-button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAABqElEQVRIx+2UsWoUURSGv3Nn1sIiaKMBSbD0AdRBdmbdB7DMA0gaSSVRbFRYiGAaUWJhEAQVEey10yacO/gAwqZNSKWwhShs4ew9NtewTDI6sRCE/at7h8P/nfnvuRdmmum/lkxvut1u5pwbAOfNrAMMzWy9LMt3v2qKorCaRwC+A9vApqq+bITkeX4Z+CAiab3IzJa9988bIPXaR977G9Pf3NT6joikZvYmSZL5JElOAPcBRORu3UxVRVVlNBodCyEsmtkAMBFZjQ3va79rETluZl+rqrrpvf8c41t3zt0GFpo6Hw6HP4A9YK0oinlgRUSuAVsHIKqaH8hSJIsR7LQ54KqqNtI0XTGzS01xURuCBeBZhD1pAzGz3Vh/+o+QXq93zjnnReSsmb1W1Y0jTm3yW0ie5xdDCB5YNLMX4/H4KmAtzc/EP/py6MHH8bwAvAfmgDXv/eAo7Xc6nSsxro+HQrIsO2Vmb0VkDrilqg9aert+v39yMpksAfciZLPpMj4UkdUmJ1WVNpcReKyq15viWvrLp8mAb8CnEMLTsixfzV7rmf6dfgKmzKAWE7bqxgAAAABJRU5ErkJggg==" style="display: block;"><img id="vts-space-3d" class="vts-space-button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAB8klEQVRIx+1Uv4sTQRT+3mRygyDInYXFabaxsRNOIiG7mEPQxsJCLQVF8AeiaCNWigrWiniCVfA/0Eo4ONnZ4P4FURAL9yyCEMQfRMzs7LOZk2HZxNgIQr7qzbw373t838wAc8zxX4P8RbvdPimEuMLM+4loAcAmM3eTJLkHgAEgiiIu9SgAfAfwBsCa1rpbJqltBWEYXhBCdAE0HEENwBIRrQZBQFmWvQKAIAhuVwyqAOwGcLzRaOzIsuylXyB+VxKdc+FTY8yyMWZbURSn3N7l8nRaa9Ja03A4XCiKosHMtwAwEV0Lw/BQJYnW+oAxZu9oNLqUpulASrmdiPa49GCS3v1+3/R6vc0kSe4AeOIGPu/XSH+Rpul7J906ER0GAGYeADgzi8F5nj+QUl5k5tZEEk+6fV6sfO+mgZk/uDO7KuUqYcUYswTgGYBFAPf/8tbW/kiitR6kafqZma+7CVdmbL7s6j9VyhVF0QtmbuV5fnDLm/F4rJRSICKehaFerx9zcr2uJGHmn0S0U0r5uNlsnlVKWQCPXG5jSm/R6XQWrbUnANx1JGuTjL/JzEeJ6IhS6qNH/kUIcaPc2X/51lo/9TCO441KT5IkeWetXQWwDuAHgG/M/BxAK47jt9MuFYCvAHpFUZzWWl+d/9Zz/Dv8ApJPyD0fWCwOAAAAAElFTkSuQmCC" style="display: none;"> </div></div><div style="display: block;"><div class="vts-search"><div class="vts-search-input"><input type="text" id="vts-search-input" autocomplete="off" spellcheck="false" placeholder="Search location..."></div><div id="vts-search-list" class="vts-search-list" style="display: none;"></div></div></div><div style="display: none;"><div id="vts-link" class="vts-link" style="left: 115px;"><div id="vts-link-button" class="vts-link-button"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAABrUlEQVRIx+2VMWtUQRSFz5nZjVrpD9gNVhpLQbZZ5vWaIoUECayNRSpbo9UiJI1pBRs7DVjYGBC1ntm3yHaiwgYsZP+EmMe7x8K3YJEH+xYLwT3NcGe483HvnJkBVvovxWWSsiy7BeAxgGuSpmY2zPP8/V+DhBAekDysQgPgAMDMbo5Gow9n5bgmgF6vd47kAYBC0t0Y45qkPQAguV+X1wgymUx+ShqUZZmllI4AlEVRPJckkht1ea1FNu/3+1ve+31JV0h+dc49mq+12+0dkpQ0XfpMQgh7JJ9U4SmANf3WZUnXvfevAbQBbMYY3zVu1x+Awsx2YoznzewOgKcke3OApId1AADwCwIGJG90u12f5/nx+vr6Jefc0RyQUjpsfE9CCJsk3wIoyrLcljRttVrznv8AcAEAFgHUtovksNrkXp7nx+Px+ETSbQBfKrN8NrOtRQC17pK0QbJMKb2az5nZd+fc/ZRSBKAm1q+r5ASADyHsVuPAe/+R5JtlnqEzIWY2rGDPsiw7JfmysulB0ypq3TWbzb51Op0JyaskLwL4BGA3xvhi9aes9G/pF4AdwlhUZ8RfAAAAAElFTkSuQmCC"></div><div id="vts-link-text-holder" class="vts-link-text-holder" style="display: none;"><div class="vts-link-text"><textarea id="vts-link-text-input" rows="4" cols="50" wrap="hard"></textarea></div></div> </div></div><div style="display: none;"><a target="_blank" href="https://github.com/Melown/vts-browser-js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/52760788cde945287fbb584134c4cbc2bc36f904/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f77686974655f6666666666662e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png"></a></div><div style="display: none;"><div id="vts-measure" class="vts-measure" style="left: 115px;"><img id="vts-measure-button" class="vts-measure-button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpkNjI1MjFjMi1mYzE5LTcyNDUtOTI5My1kNTU3MmE5N2E1MjgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODJGRUI2NzE2NzkwMTFFN0EzRUZFNzQ1NEFCMkVFQUQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODJGRUI2NzA2NzkwMTFFN0EzRUZFNzQ1NEFCMkVFQUQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRBMjkwN0JENjc4QzExRTc5QTQwRjk4NjQzOEI4RDczIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjRBMjkwN0JFNjc4QzExRTc5QTQwRjk4NjQzOEI4RDczIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k3ySjQAAAdJJREFUeNrclk0oBGEYgHemjZOLm8tSyt9BqT2I1O7JSdSSkpsDxZGLi5MTjn5K4SDh4OfiaPfkIDebOPiPUqKUiLKet96pzzT7MztxMPX0le+b95n3Z2ZZmUwm9NuXHfqLK1smsVhsED5hKkhswc4mYJmHVxgNIvIslyE4hnLYDSqycwiaoCGVSnUFFdk5BH2wKHtBRbYKqlVwbQhGoNU5GETkZHKpggjMqaBFhaGgIltv/mKphRuQss1oZkPuG4oRWTLHlmU5fSlhOYNKSEK7xIUugj+6hmSHpROm2RvL9Q7arqf80IykdDEdgll4IWi/Bm+ECT8Z2R7l+DBKV6N/PoRnEbBuwIKf0nm+8S7RGuzDLaxLMuw/5OuR+bn60ROPt9/pUUQnUEa6A56SyeSWeTYejzs9GkC8ZIpySjxEy1APbdCM6MAlGmeZdIahYIlLVAU9kIA7KZFxrJrA5+bU8RBjBf+eGD26gk0oI4AItiU4dMOqHh+GTylbQT3JU7oj2IMLmNBJrIATKIUoD5L2LfEQJbRPvXAP0iPZj5J92vNl9Fk6mSCZsBV4dwuyflb8XJrRqX6C3iDsFhSdiXOzZlSnwxD2yuBHJv/iX6JvAQYAPSICqA82OnoAAAAASUVORK5CYII=" style="display: block;"><img id="vts-measure-button2" class="vts-measure-button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2Nzg3NzczMzY3OEMxMUU3QjU2QUUxNTNCNzc4MzVBQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2Nzg3NzczNDY3OEMxMUU3QjU2QUUxNTNCNzc4MzVBQiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjY3ODc3NzMxNjc4QzExRTdCNTZBRTE1M0I3NzgzNUFCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY3ODc3NzMyNjc4QzExRTdCNTZBRTE1M0I3NzgzNUFCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+owD8TQAAAepJREFUeNrcls8rBGEYx993lIMfxR4kF/+AKMqBg7K1ajelLEWK025tKOTnjVykuAklNgcHuzmQg4MiTtz4Aza3TeGActDr+45nZt41s7tmBwdbn2l35933M9/3eead5UII9tsvjf3FK2uSiGgBKdDtZW6JllXA2DG4A3teRM7LZQl2QRuY9irScghGQRXb5KteRVoOQSMY0895FGkk8JHgSBH0gllzpAeRkeSRBAEwQIIZUJMxukARly3GOZdpivA5DnpAM2iQ5zFx3KE55DIugT6cT+a7PTTlKt9xHAT74AzU6vWJiEVQ4iWR9uXHhkgu3QhYB/JK3zBZE6WoBkE3Ivt9YolOQBd9uwJedQFjC+A8XyJ1J3G+4zNFV+CCmmMejINnY8sQG0wVzZnFlnW2Fd55ezGaIUAtPgzqwAsmv8mYMCLW8DaqdyY1g73w+RMFQRh0glse1RtDHRvDcdJp6XInsScKU3u3gnukSfCoOcoH0YPa3jif/P7zxEqUoPqUkWBZ398YqwdTNHqLdu+YuyTONToEl+AaTIAhUE61qwTtuJC0e4klkssQAn7QTy3+BA5AhRQgfdoovHvJp6iYli5EdTqlBKZA7a7CJFaiHdABUqBUFfyMxBJt06PBrwpskn/xl+hDgAEAH0j0b9rsgVUAAAAASUVORK5CYII=" style="display: none;"><div id="vts-measure-text-holder" class="vts-measure-text-holder" style="display: none;"><div class="vts-measure-text-holder2"><div class="vts-measure-text"><textarea id="vts-measure-text-input" rows="10" cols="67" wrap="hard"></textarea></div><div class="vts-measure-tools"><div id="vts-measure-position" class="vts-measure-tools-button">Position</div><div id="vts-measure-length" class="vts-measure-tools-button">Length</div><div id="vts-measure-track" class="vts-measure-tools-button">Track Length</div><div id="vts-measure-area" class="vts-measure-tools-button">Area</div><div id="vts-measure-volume" class="vts-measure-tools-button">Volume</div><div id="vts-measure-clear" class="vts-measure-tools-button">Clear Log</div><div id="vts-measure-metric" class="vts-measure-tools-button">Units: Meters</div></div></div></div><div id="vts-measure-info" class="vts-measure-info"></div><div id="vts-measure-buttons" class="vts-measure-compute"><div id="vts-measure-undo" class="vts-measure-tools-button">Undo</div><div id="vts-measure-compute" class="vts-measure-tools-button">Compute</div></div> </div></div><div style="display: none;"><div id="vts-measure" class="vts-measure" style="left: 115px;"><img id="vts-measure-button" class="vts-measure-button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpkNjI1MjFjMi1mYzE5LTcyNDUtOTI5My1kNTU3MmE5N2E1MjgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODJGRUI2NzE2NzkwMTFFN0EzRUZFNzQ1NEFCMkVFQUQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODJGRUI2NzA2NzkwMTFFN0EzRUZFNzQ1NEFCMkVFQUQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRBMjkwN0JENjc4QzExRTc5QTQwRjk4NjQzOEI4RDczIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjRBMjkwN0JFNjc4QzExRTc5QTQwRjk4NjQzOEI4RDczIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k3ySjQAAAdJJREFUeNrclk0oBGEYgHemjZOLm8tSyt9BqT2I1O7JSdSSkpsDxZGLi5MTjn5K4SDh4OfiaPfkIDebOPiPUqKUiLKet96pzzT7MztxMPX0le+b95n3Z2ZZmUwm9NuXHfqLK1smsVhsED5hKkhswc4mYJmHVxgNIvIslyE4hnLYDSqycwiaoCGVSnUFFdk5BH2wKHtBRbYKqlVwbQhGoNU5GETkZHKpggjMqaBFhaGgIltv/mKphRuQss1oZkPuG4oRWTLHlmU5fSlhOYNKSEK7xIUugj+6hmSHpROm2RvL9Q7arqf80IykdDEdgll4IWi/Bm+ECT8Z2R7l+DBKV6N/PoRnEbBuwIKf0nm+8S7RGuzDLaxLMuw/5OuR+bn60ROPt9/pUUQnUEa6A56SyeSWeTYejzs9GkC8ZIpySjxEy1APbdCM6MAlGmeZdIahYIlLVAU9kIA7KZFxrJrA5+bU8RBjBf+eGD26gk0oI4AItiU4dMOqHh+GTylbQT3JU7oj2IMLmNBJrIATKIUoD5L2LfEQJbRPvXAP0iPZj5J92vNl9Fk6mSCZsBV4dwuyflb8XJrRqX6C3iDsFhSdiXOzZlSnwxD2yuBHJv/iX6JvAQYAPSICqA82OnoAAAAASUVORK5CYII=" style="display: block;"><img id="vts-measure-button2" class="vts-measure-button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2Nzg3NzczMzY3OEMxMUU3QjU2QUUxNTNCNzc4MzVBQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2Nzg3NzczNDY3OEMxMUU3QjU2QUUxNTNCNzc4MzVBQiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjY3ODc3NzMxNjc4QzExRTdCNTZBRTE1M0I3NzgzNUFCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY3ODc3NzMyNjc4QzExRTdCNTZBRTE1M0I3NzgzNUFCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+owD8TQAAAepJREFUeNrcls8rBGEYx993lIMfxR4kF/+AKMqBg7K1ajelLEWK025tKOTnjVykuAklNgcHuzmQg4MiTtz4Aza3TeGActDr+45nZt41s7tmBwdbn2l35933M9/3eead5UII9tsvjf3FK2uSiGgBKdDtZW6JllXA2DG4A3teRM7LZQl2QRuY9irScghGQRXb5KteRVoOQSMY0895FGkk8JHgSBH0gllzpAeRkeSRBAEwQIIZUJMxukARly3GOZdpivA5DnpAM2iQ5zFx3KE55DIugT6cT+a7PTTlKt9xHAT74AzU6vWJiEVQ4iWR9uXHhkgu3QhYB/JK3zBZE6WoBkE3Ivt9YolOQBd9uwJedQFjC+A8XyJ1J3G+4zNFV+CCmmMejINnY8sQG0wVzZnFlnW2Fd55ezGaIUAtPgzqwAsmv8mYMCLW8DaqdyY1g73w+RMFQRh0glse1RtDHRvDcdJp6XInsScKU3u3gnukSfCoOcoH0YPa3jif/P7zxEqUoPqUkWBZ398YqwdTNHqLdu+YuyTONToEl+AaTIAhUE61qwTtuJC0e4klkssQAn7QTy3+BA5AhRQgfdoovHvJp6iYli5EdTqlBKZA7a7CJFaiHdABUqBUFfyMxBJt06PBrwpskn/xl+hDgAEAH0j0b9rsgVUAAAAASUVORK5CYII=" style="display: none;"><div id="vts-measure-text-holder" class="vts-measure-text-holder" style="display: none;"><div class="vts-measure-text-holder2"><div class="vts-measure-text"><textarea id="vts-measure-text-input" rows="6" cols="50" wrap="hard"></textarea></div><div class="vts-measure-tools"><div id="vts-measure-clear" class="vts-measure-tools-button">Clear</div></div></div></div><div id="vts-measure-info" class="vts-measure-info"></div> </div></div><div style="display: none;"><div class="vts-layers" <="" div=""></div></div><div style="display: block;"><div class="vts-fallback"><div class="vts-fallback-text"><p>VTS Browser needs <a href="http://get.webgl.org/">WebGL</a> capable web browser.</p></div> </div></div><div style="display: none;"><div class="vts-popup-background" id="vts-popup-background"><div id="vts-popup" <="" div=""></div></div></div><div style="display: none;"><div id="vts-loading" class="vts-loading"><div class="vts-loading-progress"><div id="vts-loading-dot1" class="vts-loading-dot" style="opacity: 0.1248;"></div><div id="vts-loading-dot2" class="vts-loading-dot" style="opacity: 0.637381;"></div><div id="vts-loading-dot3" class="vts-loading-dot" style="opacity: 0.789372;"></div><div id="vts-loading-dot4" class="vts-loading-dot" style="opacity: 0.455468;"></div><div id="vts-loading-dot5" class="vts-loading-dot" style="opacity: -0.0890522;"></div></div> </div></div><div style="display: block;"><div id="distance-div" class="distance-div"></div><div id="height-div" class="distance-div"></div><div id="height-div2" class="pointer-div2"></div></div><div style="display: block;"><div id="profile-div" class="profile-div"><div id="profile-canvas-holder" class="profile-canvas-holder"><canvas id="profile-canvas" class="profile-canvas" width="797" height="118"></canvas></div></div></div></div></div>
- <!-- TODO: Missing CoffeeScript 2 -->
- <script type="text/javascript">//<![CDATA[
- var browser, renderer, map;
- var geodata, lineGeometry = null;
- var demoTexture = null;
- var usedMouseCoords = [0,0];
- var linePoint, lineSegment = 0;
- var distancePointer, heightPointer, heightPointer2;
- var trackHeights = [], trackLengths = [];
- var trackMinHeight, trackMaxHeight;
- var canvas, canvasCtx;
- var pathLength = 0, pathDistance = 0;
- (function startDemo() {
- // create map in the html div with id 'map-div'
- // parameter 'map' sets path to the map which will be displayed
- // you can create your own map on melown.com
- // position parameter is described in documentation
- // https://github.com/Melown/vts-browser-js/wiki/VTS-Browser-Map-API#position
- // view parameter is described in documentation
- // https://github.com/Melown/vts-browser-js/wiki/VTS-Browser-Map-API#definition-of-view
- browser = vts.browser('map-div', {
- map: 'https://cdn.melown.com/mario/store/melown2015/map-config/melown/VTS-Tutorial-Map-4/mapConfig.json',
- position : [ 'obj', 23.3,42.6, 'float', 0.00, 0.00, -180.00, 0.00, 21255.06, 55.00 ]
- });
- //check whether browser is supported
- if (!browser) {
- console.log('Your web browser does not support WebGL');
- return;
- }
- //move map controls little bit higher
- browser.ui.getControl('credits').getElement('vts-credits').setStyle('bottom', '134px');
- browser.ui.getControl('space').getElement('vts-space').setStyle('bottom', '140px');
- browser.ui.getControl('zoom').getElement('vts-zoom-plus').setStyle('bottom', '140px');
- browser.ui.getControl('zoom').getElement('vts-zoom-minus').setStyle('bottom', '140px');
- browser.ui.getControl('compass').getElement('vts-compass').setStyle('bottom', '170px');
- // create ui control with info pointers
- var infoPointers = browser.ui.addControl('info-pointers',
- '<div id="distance-div" class="distance-div">' +
- '</div>' +
- '<div id="height-div" class="distance-div">' +
- '</div>' +
- '<div id="height-div2" class="pointer-div2">' +
- '</div>');
- distancePointer = infoPointers.getElement('distance-div');
- heightPointer = infoPointers.getElement('height-div');
- heightPointer2 = infoPointers.getElement('height-div2');
- // create panel with path profile
- var profilePanel = browser.ui.addControl('profile-panel',
- '<div id="profile-div" class="profile-div">' +
- '<div id="profile-canvas-holder" class="profile-canvas-holder">' +
- '<canvas id="profile-canvas" class="profile-canvas">' +
- '</canvas>' +
- '</div>' +
- '</div>');
- renderer = browser.renderer;
- //add mouse events to map element
- var mapElement = browser.ui.getMapElement();
- mapElement.on('mousemove', onMouseMove);
- mapElement.on('mouseleave', onMouseLeave);
- mapElement.on('dragover', onDragover);
- mapElement.on('drop', onDrop);
- mapElement.on('resize', onResize, window);
- //add mouse events to canvas element
- canvas = profilePanel.getElement('profile-canvas');
- canvas.on('mousemove', onCanvasHover);
- canvas.on('dragover', onDragover);
- canvas.on('drop', onDrop);
- canvasCtx = canvas.getElement().getContext("2d");
- drawCanvasMessage('Drop GPX file here')
- //callback once is map config loaded
- browser.on('map-loaded', onMapLoaded);
- //callback when path hovered
- browser.on('geo-feature-hover', onFeatureHover);
- loadTexture();
- })();
- function loadTexture() {
- //load icon used for displaying path point
- var demoImage = vts.utils.loadImage(
- 'http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png',
- (function(){
- demoTexture = renderer.createTexture({ source: demoImage });
- }));
- }
- //add render slot for dynamic rendering
- function onMapLoaded() {
- map = browser.map;
- map.addRenderSlot('custom-render', onCustomRender, true);
- map.moveRenderSlotAfter('after-map-render', 'custom-render');
- }
- // prevent default browser behaviour for droping files
- function onDragover(event) {
- var e = event.event;
- e.stopPropagation();
- e.preventDefault();
- e.dataTransfer.dropEffect = 'copy';
- };
- //load droped file
- function onDrop(event) {
- if (!map) {
- return;
- }
- // prevent default browser behaviour for droping files
- var e = event.event;
- e.stopPropagation();
- e.preventDefault();
- var files = e.dataTransfer.files; // Array of all files
- for (var i = 0, li = files.length; i < li; i++) {
- var reader = new FileReader();
- reader.onloadend = function (event) {
- var parser = new DOMParser();
- var data = parser.parseFromString(event.target.result, 'text/xml');
- loadGPX(data);
- };
- //remove old layyer and hide pointers
- map.removeFreeLayer('gpx-geodata');
- distancePointer.setStyle("display", "none");
- heightPointer.setStyle("display", "none");
- heightPointer2.setStyle("display", "none");
- lineGeometry = null;
- drawCanvasMessage('Loading ...')
- reader.readAsText(files[i], 'text/plain');
- }
- }
- function getElementChildValue(element, name) {
- var child = element.getElementsByTagName(name)[0];
- if (child) {
- if(child.childNodes[0]) {
- return child.childNodes[0].nodeValue;
- }
- }
- return null;
- };
- function loadGPX(data) {
- var gpx = data.getElementsByTagName('gpx')[0];
- if (!gpx) {
- return;
- }
- var coords, heightMode, i, li, j, lj, points, name, properties;
- //crete geodaata
- geodata = map.createGeodata();
- //process way points
- var wayPoints = gpx.getElementsByTagName('wpt');
- if (wayPoints.length) {
- //create new group
- //all waypoints will be stored in this group
- geodata.addGroup('waypoints');
- for (i = 0, li = wayPoints.length; i < li; i++) {
- var wayPoint = wayPoints[i];
- coords = [wayPoint.getAttribute('lon'), wayPoint.getAttribute('lat'), 0];
- properties = {};
- name = getElementChildValue(wayPoint, 'name');
- if (name !== null) {
- properties.name = name;
- }
- var elevation = getElementChildValue(wayPoint, 'ele');
- if (elevation !== null) {
- heightMode = 'fix';
- coords[2] = parseFloat(elevation);
- } else {
- heightMode = 'float';
- }
- geodata.addPoint(coords, heightMode, properties);
- }
- }
- //process routes
- var routes = gpx.getElementsByTagName('rte');
- if (routes.length) {
- //create new group
- //all routes will be stored in this group
- geodata.addGroup('routes');
- for (i = 0, li = routes.length; i < li; i++) {
- var route = routes[i];
- var routePoints = route.getElementsByTagName('rtept');
- points = new Array(routePoints.length);
- //add route points with their names
- for (j = 0, lj = routePoints.length; j < lj; j++) {
- var routePoint = routePoints[j];
- coords = [routePoint.getAttribute('lon'), routePoint.getAttribute('lat'), 0];
- properties = {};
- name = getElementChildValue(routePoint, 'name');
- if (name !== null) {
- properties.name = name;
- }
- var elevation = getElementChildValue(routePoint, 'ele');
- if (elevation !== null) {
- heightMode = 'fix';
- coords[2] = parseFloat(elevation);
- } else {
- heightMode = 'float';
- }
- geodata.addPoint(coords, heightMode, properties);
- points[j] = coords;
- }
- // add route line
- if (routePoints.length) {
- properties = {};
- var name = getElementChildValue(route, 'name');
- if (name !== null) {
- properties.name = name;
- }
- geodata.addLineString(points, heightMode, properties, 'some-path');
- }
- }
- }
- //process tracks
- var tracks = gpx.getElementsByTagName('trk');
- if (tracks.length) {
- //create new group
- //all waypoints will be stored in this group
- geodata.addGroup('tracks');
- for (i = 0, li = tracks.length; i < li; i++) {
- var track = tracks[i];
- var trackSegments = track.getElementsByTagName('trkseg');
- // get total trak points
- var totalPoints = 0, trackPoints, index = 0;
- for (j = 0, lj = trackSegments.length; j < lj; j++) {
- trackPoints = trackSegments[j].getElementsByTagName('trkpt');
- totalPoints += trackPoints.length;
- }
- points = new Array(totalPoints);
- for (j = 0, lj = trackSegments.length; j < lj; j++) {
- trackPoints = trackSegments[j].getElementsByTagName('trkpt');
- //add track points with their names
- for (var k = 0, lk = trackPoints.length; k < lk; k++) {
- var trackPoint = trackPoints[k];
- coords = [trackPoint.getAttribute('lon'), trackPoint.getAttribute('lat'), 0];
- properties = {};
- name = getElementChildValue(trackPoint, 'name');
- if (name !== null) {
- properties.name = name;
- }
- var elevation = getElementChildValue(trackPoint, 'ele');
- if (elevation !== null) {
- heightMode = 'fix';
- coords[2] = parseFloat(elevation);
- } else {
- heightMode = 'float';
- }
- geodata.addPoint(coords, heightMode, properties);
- points[index] = coords;
- index++;
- }
- }
- //add track line
- if (points.length) {
- properties = {};
- var name = getElementChildValue(track, 'name');
- if (name !== null) {
- properties.name = name;
- }
- geodata.addLineString(points, heightMode, properties, 'some-path');
- }
- }
- }
- drawCanvasMessage('Processing heights ...')
- // geodata.processHeights('heightmap-by-precision', 62, onHeightProcessed);
- geodata.processHeights('node-by-precision', 62, onHeightProcessed);
- };
- //when are heights converted then we can create free layer
- // and dispaly that layer on the map
- function onHeightProcessed() {
- //extrack gemteru with id == 'some-path'
- lineGeometry = geodata.extractGeometry('some-path');
- //center map postion to track gemetery
- centerPositonToGeometry(lineGeometry);
- //draw track profile
- drawPathProfile(lineGeometry);
- //style used for displaying geodata
- var style = {
- 'constants': {
- '@icon-marker': ['icons', 6, 8, 18, 18]
- },
- 'bitmaps': {
- 'icons': 'http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png'
- },
- "layers" : {
- "track-line" : {
- "filter" : ["==", "#type", "line"],
- "line": true,
- "line-width" : 4,
- "line-color": [255,0,255,255],
- "zbuffer-offset" : [-5,0,0],
- "z-index" : -1
- },
- "track-shadow" : {
- "filter" : ["==", "#type", "line"],
- "line": true,
- "line-width" : 20,
- "line-color": [0,0,0,120],
- "zbuffer-offset" : [-5,0,0],
- "hover-event" : true,
- "advanced-hit" : true
- },
- "way-points" : {
- "filter" : ["all", ["==", "#type", "point"], ["==", "#group", "waypoints"]],
- "point": true,
- "point-radius" : 20,
- "point-color": [0,255,255,255],
- "zbuffer-offset" : [-5,0,0]
- },
- }
- };
- //meke free layres
- var freeLayer = geodata.makeFreeLayer(style);
- //add free layer to the map
- map.addFreeLayer('gpxgeodata', freeLayer);
- //add free layer to the list of free layers
- //which will be rendered on the map
- var view = map.getView();
- view.freeLayers.gpxgeodata = {};
- map.setView(view);
- }
- // move map position to the center of gemetru and adjust
- // view extent to size of geometry
- function centerPositonToGeometry(geometry) {
- if (!geometry.getElements()) {
- return;
- }
- //get detailed info about map reference frame
- var refFrame = map.getReferenceFrame();
- var navigationSrsId = refFrame.navigationSrs;
- var navigationSrs = map.getSrsInfo(navigationSrsId);
- var physicalSrsId = refFrame.physicalSrs;
- var physicalSrs = map.getSrsInfo(physicalSrsId);
- var i, li, midPoint = [0,0,0], line, vec3 = vts.vec3;
- //find center of gemetry
- for (i = 0, li = geometry.getElements() + 1; i < li; i++) {
- if (i == (li - 1)) { //last line point
- line = geometry.getElement(i-1);
- coords = line[1];
- } else {
- line = geometry.getElement(i);
- coords = line[0];
- }
- midPoint[0] += coords[0];
- midPoint[1] += coords[1];
- midPoint[2] += coords[2];
- };
- midPoint[0] /= li;
- midPoint[1] /= li;
- midPoint[2] /= li;
- // construct line which goes through the center of geometry
- // and mesure most distant point from this line
- var cameraPosition = midPoint;
- var cameraVector = [-cameraPosition[0], -cameraPosition[1], -cameraPosition[2]];
- vec3.normalize(cameraVector);
- var viewExtent = 500;
- for (i = 0, li = geometry.getElements() + 1; i < li; i++) {
- if (i == (li - 1)) { //last line point
- line = geometry.getElement(i - 1);
- coords = line[1];
- } else {
- line = geometry.getElement(i);
- coords = line[0];
- }
- //get line point distance
- var ab = cameraVector;
- var av = [coords[0] - cameraPosition[0], coords[1] - cameraPosition[1], coords[2] - cameraPosition[2]];
- var b = [cameraPosition[0] + cameraVector[0], cameraPosition[1] + cameraVector[1], cameraPosition[2] + cameraVector[2]];
- var bv = [coords[0] - b[0], coords[1] - b[1], coords[2] - b[2]];
- var af = [0,0,0];
- vec3.cross(ab, av, af);
- var d = (vec3.length(bv) / vec3.length(ab)) * 2;
- if (d > viewExtent) {
- viewExtent = d;
- }
- }
- //limit view extent according to planet radius
- if (viewExtent > navigationSrs.a*1.4) {
- viewExtent = navigationSrs.a*1.4;
- }
- //convert coods from physical to nav
- var navCoords = vts.proj4(physicalSrs.srsDef, navigationSrs.srsDef, midPoint);
- navCoords[2] = 0;
- //set new map positon
- var pos = map.getPosition();
- pos.setCoords(navCoords);
- pos.setOrientation([0, -70, 0]);
- pos.setViewExtent(viewExtent);
- map.setPosition(pos);
- }
- //set heigth profile pointer accoring to current track position
- function setProfilePointer(p) {
- var rect = canvas.getRect();
- var x = (pathDistance / pathLength) * rect.width;
- var rect2 = heightPointer.getRect();
- p = map.convertCoordsFromPhysToPublic(p);
- heightPointer.setStyle('display', 'block');
- heightPointer.setStyle('left', (rect.left + x -(rect2.width*0.5)) + 'px');
- heightPointer.setStyle('top', (rect.top) + 'px');
- heightPointer.setHtml((p[2]).toFixed(2) + " m");
- heightPointer2.setStyle('display', 'block');
- heightPointer2.setStyle('left', (rect.left + x - 1) + 'px');
- heightPointer2.setStyle('top', (rect.top) + 'px');
- }
- //redraw track profile when browser window is resized
- function onResize() {
- refereshCanvasDimensions();
- drawPathProfile(lineGeometry);
- }
- //sets canvas size accoding to HTML element size
- function refereshCanvasDimensions() {
- var rect = canvas.getRect();
- var canvasElement = canvas.getElement();
- if (canvasElement.width != rect.width) {
- canvasElement.width = rect.width;
- }
- if (canvasElement.height != rect.height) {
- canvasElement.height = rect.height;
- }
- return [rect.width, rect.height];
- }
- //display status message in the canvas
- function drawCanvasMessage(message) {
- var dim = refereshCanvasDimensions();
- canvasCtx.clearRect(0, 0, dim[0], dim[1]);
- canvasCtx.font="30px Arial, 'Helvetica Neue', Helvetica, sans-serif";
- canvasCtx.fillStyle = "rgba(0,0,0,1)";
- canvasCtx.fillText(message, dim[0]*0.5 - canvasCtx.measureText(message).width*0.5, 70);
- }
- //process track geometry and display track profile
- function drawPathProfile(geometry) {
- if (!geometry) {
- return;
- }
- var totalElements = geometry.getElements();
- if (!totalElements) {
- return;
- }
- pathLength = geometry.getPathLength();
- trackHeights = new Array(totalElements);
- trackLengths = new Array(totalElements);
- trackMinHeight = Number.POSITIVE_INFINITY;
- trackMaxHeight = Number.NEGATIVE_INFINITY;
- var totalLength = 0;
- //get track point heights and length between track points
- for (var i = 0, li = totalElements; i < li; i++) {
- var l = geometry.getElement(i);
- var p = map.convertCoordsFromPhysToPublic(l[0]);
- trackHeights[i] = p[2];
- totalLength += vts.vec3.length([l[1][0] - l[0][0], l[1][1] - l[0][1], l[1][2] - l[0][2]]);
- trackLengths[i] = totalLength;
- if (p[2] > trackMaxHeight) {
- trackMaxHeight = p[2];
- }
- if (p[2] < trackMinHeight) {
- trackMinHeight = p[2];
- }
- }
- //draw track profile
- var dim = refereshCanvasDimensions();
- var lx = dim[0], ly = dim[1];
- canvasCtx.clearRect(0,0,lx,ly);
- canvasCtx.beginPath();
- canvasCtx.moveTo(-1,ly-1);
- if (trackMaxHeight == trackMinHeight) {
- canvasCtx.lineTo(lx,ly);
- } else {
- canvasCtx.lineTo(-1, (ly - 2) - ((trackHeights[0] - trackMinHeight) / (trackMaxHeight - trackMinHeight)) * (ly-30) );
- for (var i = 0, li = trackHeights.length; i < li; i++) {
- canvasCtx.lineTo((trackLengths[i]/pathLength)*lx, (ly - 2) - ((trackHeights[i] - trackMinHeight) / (trackMaxHeight - trackMinHeight)) * (ly-30) );
- }
- }
- canvasCtx.lineTo(lx,ly-1);
- canvasCtx.lineTo(0,ly-1);
- // Create gradient
- var grd = canvasCtx.createLinearGradient(0,0,0,ly);
- grd.addColorStop(0,"rgba(252,186,136,0.3)");
- grd.addColorStop(1,"rgba(94,45,18,0.3)");
- // Fill profile with gradient
- canvasCtx.fillStyle = grd;
- canvasCtx.fill();
- //draw profile outline
- canvasCtx.strokeStyle = "rgba(50,50,50,0.7)";
- canvasCtx.stroke();
- }
- function onMouseMove(event) {
- if (map) {
- var coords = event.getMouseCoords();
- usedMouseCoords = coords;
- //set map to hover cusor over provided coordinates permanently
- map.hover(coords[0], coords[1], true);
- }
- }
- function onMouseLeave(event) {
- if (map) {
- var coords = event.getMouseCoords();
- //stop cursor hovering
- map.hover(coords[0], coords[1], false);
- }
- };
- function onFeatureHover(event) {
- lineSegment = event.element;
- if (lineGeometry) {
- //get distance of cursor on the line segment
- var res = lineGeometry.getRelationToCanvasPoint(lineSegment, usedMouseCoords[0], usedMouseCoords[1]);
- //get path length to line segment and length of the segment itself
- var lineSegmentInfo = lineGeometry.getPathLengthToElement(lineSegment);
- //compute path distance to point where cursor is hovering over the track
- pathDistance = lineSegmentInfo.lengthToElement + (lineSegmentInfo.elementLengh * vts.math.clamp(res.distance, 0, 1));
- //get point coodinates
- linePoint = lineGeometry.getPathPoint(pathDistance);
- //refresh pointer in height profile
- setProfilePointer(linePoint);
- //force redraw map (we have to redraw track point)
- map.redraw();
- }
- }
- function onCanvasHover(event) {
- if (map && lineGeometry) {
- var coords = event.getMouseCoords();
- usedMouseCoords = coords;
- //compute new path distance from cursor position in canvas
- var rect = canvas.getRect();
- pathDistance = ((coords[0] - rect.left) / canvas.getElement().width) * pathLength;
- //get point coodinates
- linePoint = lineGeometry.getPathPoint(pathDistance);
- //refresh pointer in height profile
- setProfilePointer(linePoint);
- //force redraw map (we have to redraw track point)
- map.redraw();
- }
- }
- function onCustomRender() {
- if (demoTexture && lineGeometry && linePoint) { //check whether texture is loaded
- //get canvas postion of the track point
- var p = map.convertCoordsFromPhysToCanvas(linePoint);
- //display distance pointer in the track point coordiantes
- var rect = distancePointer.getRect();
- distancePointer.setStyle("display", "block");
- distancePointer.setStyle("left", (p[0]-(rect.width*0.5)) + "px");
- distancePointer.setStyle("top", (p[1]-50) + "px");
- distancePointer.setHtml((pathDistance*0.001).toFixed(2) + " Km");
- //draw point image at the last line point
- renderer.drawImage({
- rect : [p[0]-12*1.5, p[1]-12*1.5, 24*1.5, 24*1.5],
- texture : demoTexture,
- color : [255,0,255,255],
- depth : p[2],
- depthTest : false,
- blend : true
- });
- }
- }
- //]]></script>
- <script>
- // tell the embed parent frame the height of the content
- if (window.parent && window.parent.parent){
- window.parent.parent.postMessage(["resultsFrame", {
- height: document.body.getBoundingClientRect().height,
- slug: "xrz53a7k"
- }], "*")
- }
- // always overwrite window.name, in case users try to set it manually
- window.name = "result"
- </script>
- <script>
- let allLines = []
- window.addEventListener("message", (message) => {
- if (message.data.console){
- let insert = document.querySelector("#insert")
- allLines.push(message.data.console.payload)
- insert.innerHTML = allLines.join(";\r")
- let result = eval.call(null, message.data.console.payload)
- if (result !== undefined){
- console.log(result)
- }
- }
- })
- </script>
- </body></html>
- <script>
- browser.on("map-loaded", function() {
- var gpxElement = document.getElementById("gpsdata");
- if (gpxElement) {
- loadGPX(new DOMParser().parseFromString(gpxElement.innerHTML, "text/xml"));
- }
- });
- </script>
Add Comment
Please, Sign In to add comment