<commit_before>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        console.log('positionCurrent.hng ',positionCurrent.hng,positionCurrent);
        console.log( (360 - phase | 0) + "°");

        /*
        if(worldAdjustRotation==null != worldAdjustRotation !=0)
        {
            worldAdjustRotation = positionCurrent.hng;
            $('#pointers').attr('rotation','0 '+positionCurrent.hng+' 0');
            alert('Ajuste: '+parseInt(positionCurrent.hng));
        }
        */

        var ajusteRot = 90 - positionCurrent.hng;
        $('.orientation').html('
ajuster Rot: '+ajusteRot+'
')

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);
    /*
    window.addEventListener("deviceorientation", function(event)
    {

        var xValue      = Math.round(event.gamma);
        var yValue      = Math.round(event.beta);
        var rotation    = Math.round(event.alpha);

        //$('#cameraControl').attr('rotation' , '0 '+yValue+' 0');

        $('.orientation').html('xValue :'+xValue + '
yValue :'+yValue+ '
rotation :'+rotation)

    }, true)
    */

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 100000;
MAP_HEIGHT          = 100000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    //ajuste inical mundo, mandar el norte arriba
    $('#pointers').attr('rotation','0 -90 0');

    //ajuste por la posicion inicial del teléfono con respecto al norte
    $('#pointers').attr('rotation','0 146 0');

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            //console.log('startPos ', startPos);
            //console.log('camera '  , $('#camera').attr('position'));

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            //console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 5000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }
            //console.log(difCoordenads)

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

            console.log('X:', startPos.coords.latitude, stores[s].lat , difCoordenads.x , stores[s].info.title);
            console.log(' ');

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            //box.setAttribute("position"	, difCoordenads.x+' 0.5 0');
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var cylinder	= document.createElement('a-cylinder');
        cylinder.setAttribute("position"    , '-10 0 0');
        cylinder.setAttribute("radius"	    , "0.5");
        cylinder.setAttribute("height"      , "1.5");
        cylinder.setAttribute("color"       , "#ff0000");

        scene.appendChild(cylinder);

    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<commit_msg>coordendas<commit_after>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        console.log('positionCurrent.hng ',positionCurrent.hng,positionCurrent);
        console.log( (360 - phase | 0) + "°");

        /*
        if(worldAdjustRotation==null != worldAdjustRotation !=0)
        {
            worldAdjustRotation = positionCurrent.hng;
            $('#pointers').attr('rotation','0 '+positionCurrent.hng+' 0');
            alert('Ajuste: '+parseInt(positionCurrent.hng));
        }
        */

        var ajusteRot = 90 - positionCurrent.hng;
        $('.orientation').html('
ajuster Rot: '+ajusteRot+'
')

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);
    /*
    window.addEventListener("deviceorientation", function(event)
    {

        var xValue      = Math.round(event.gamma);
        var yValue      = Math.round(event.beta);
        var rotation    = Math.round(event.alpha);

        //$('#cameraControl').attr('rotation' , '0 '+yValue+' 0');

        $('.orientation').html('xValue :'+xValue + '
yValue :'+yValue+ '
rotation :'+rotation)

    }, true)
    */

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 100000;
MAP_HEIGHT          = 100000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    //ajuste inical mundo, mandar el norte arriba
    $('#pointers').attr('rotation','0 -90 0');

    //ajuste por la posicion inicial del teléfono con respecto al norte
    $('#pointers').attr('rotation','0 146 0');

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            //console.log('startPos ', startPos);
            //console.log('camera '  , $('#camera').attr('position'));

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            //console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 5000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }
            //console.log(difCoordenads)

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

            console.log('X:', startPos.coords.latitude, stores[s].lat , difCoordenads.x , stores[s].info.title);
            console.log(' ');

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            //box.setAttribute("position"	, difCoordenads.x+' 0.5 0');
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var norte	= document.createElement('a-entity');
        norte.setAttribute("position"   , '-10 0 0');
        norte.setAttribute("text"       , 'width:10; color:black; value:Norte; align:center;');
        norte.setAttribute("look-at"	, "[camera]");
        scene.appendChild(norte);

        var sur	= document.createElement('a-entity');
        sur.setAttribute("position"     , '10 0 0');
        sur.setAttribute("text"         , 'width:10; color:black; value:Sur; align:center;');
        sur.setAttribute("look-at"	    , "[camera]");
        scene.appendChild(sur);

        var este	= document.createElement('a-entity');
        este.setAttribute("position"     , '0 0 -10');
        este.setAttribute("text"         , 'width:10; color:black; value:Este; align:center;');
        este.setAttribute("look-at"	    , "[camera]");
        scene.appendChild(este);

        var oeste	= document.createElement('a-entity');
        oeste.setAttribute("position"     , '0 0 10');
        oeste.setAttribute("text"         , 'width:10; color:black; value:Oeste; align:center;');
        oeste.setAttribute("look-at"	  , "[camera]");
        scene.appendChild(oeste);

    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<|endoftext|>


<commit_before>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var ajusteRot = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function adjustRotationScene()
{

    if(ajusteRot == null && positionCurrent.hng != null && positionCurrent.hng != 0)
    {
        console.log('adjustRotationScene');
        console.log('ajusteRot '+ajusteRot);
        console.log('positionCurrent ',positionCurrent);

        ajusteRot = 90 - positionCurrent.hng;
        $('.orientation').html('
AJUSTE ROT: '+ajusteRot+'
')

        console.log('Ajuste rotación: '+ajusteRot);
    }
}

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        //console.log('positionCurrent.hng ',positionCurrent.hng);
        //console.log( (360 - phase | 0) + "°");

        if(ajusteRot == null && positionCurrent.hng != null && positionCurrent.hng != 0)
        {
            setTimeout(function()
            {
                console.log('timeout');
                adjustRotationScene();
            },1000)
        }

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 100000;
MAP_HEIGHT          = 100000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    //ajuste inical mundo, mandar el norte arriba
    $('#pointers').attr('rotation','0 -90 0');

    //ajuste por la posicion inicial del teléfono con respecto al norte, prueba
   // $('#pointers').attr('rotation','0 146 0');

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            //console.log('startPos ', startPos);
            //console.log('camera '  , $('#camera').attr('position'));

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            //console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 5000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }
            //console.log(difCoordenads)

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

           // console.log('X:', startPos.coords.latitude, stores[s].lat , difCoordenads.x , stores[s].info.title);
            //console.log(' ');

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            //box.setAttribute("position"	, difCoordenads.x+' 0.5 0');
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            //console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var norte	= document.createElement('a-entity');
        norte.setAttribute("position"   , '-10 0 0');
        norte.setAttribute("text"       , 'width:10; color:black; value:Norte; align:center;');
        norte.setAttribute("look-at"	, "[camera]");
        scene.appendChild(norte);

        var sur	= document.createElement('a-entity');
        sur.setAttribute("position"     , '10 0 0');
        sur.setAttribute("text"         , 'width:10; color:black; value:Sur; align:center;');
        sur.setAttribute("look-at"	    , "[camera]");
        scene.appendChild(sur);

        var este	= document.createElement('a-entity');
        este.setAttribute("position"     , '0 0 -10');
        este.setAttribute("text"         , 'width:10; color:black; value:Este; align:center;');
        este.setAttribute("look-at"	    , "[camera]");
        scene.appendChild(este);

        var oeste	= document.createElement('a-entity');
        oeste.setAttribute("position"     , '0 0 10');
        oeste.setAttribute("text"         , 'width:10; color:black; value:Oeste; align:center;');
        oeste.setAttribute("look-at"	  , "[camera]");
        scene.appendChild(oeste);

    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<commit_msg>hng negativo<commit_after>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var ajusteRot = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function adjustRotationScene()
{

    if(ajusteRot == null && positionCurrent.hng != null && positionCurrent.hng != 0)
    {
        console.log('adjustRotationScene hng negativo');
        console.log('ajusteRot '+ajusteRot);
        console.log('positionCurrent ',positionCurrent);

        ajusteRot = 90 - (positionCurrent.hng * -1);
        $('.orientation').html('
AJUSTE ROT: '+ajusteRot+'
')

        console.log('Ajuste rotación: '+ajusteRot);
    }
}

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        //console.log('positionCurrent.hng ',positionCurrent.hng);
        //console.log( (360 - phase | 0) + "°");

        if(ajusteRot == null && positionCurrent.hng != null && positionCurrent.hng != 0)
        {
            setTimeout(function()
            {
                console.log('timeout');
                adjustRotationScene();
            },1000)
        }

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 100000;
MAP_HEIGHT          = 100000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    //ajuste inical mundo, mandar el norte arriba
    $('#pointers').attr('rotation','0 -90 0');

    //ajuste por la posicion inicial del teléfono con respecto al norte, prueba
   // $('#pointers').attr('rotation','0 146 0');

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            //console.log('startPos ', startPos);
            //console.log('camera '  , $('#camera').attr('position'));

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            //console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 5000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }
            //console.log(difCoordenads)

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

           // console.log('X:', startPos.coords.latitude, stores[s].lat , difCoordenads.x , stores[s].info.title);
            //console.log(' ');

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            //box.setAttribute("position"	, difCoordenads.x+' 0.5 0');
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            //console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var norte	= document.createElement('a-entity');
        norte.setAttribute("position"   , '-10 0 0');
        norte.setAttribute("text"       , 'width:10; color:black; value:Norte; align:center;');
        norte.setAttribute("look-at"	, "[camera]");
        scene.appendChild(norte);

        var sur	= document.createElement('a-entity');
        sur.setAttribute("position"     , '10 0 0');
        sur.setAttribute("text"         , 'width:10; color:black; value:Sur; align:center;');
        sur.setAttribute("look-at"	    , "[camera]");
        scene.appendChild(sur);

        var este	= document.createElement('a-entity');
        este.setAttribute("position"     , '0 0 -10');
        este.setAttribute("text"         , 'width:10; color:black; value:Este; align:center;');
        este.setAttribute("look-at"	    , "[camera]");
        scene.appendChild(este);

        var oeste	= document.createElement('a-entity');
        oeste.setAttribute("position"     , '0 0 10');
        oeste.setAttribute("text"         , 'width:10; color:black; value:Oeste; align:center;');
        oeste.setAttribute("look-at"	  , "[camera]");
        scene.appendChild(oeste);

    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<|endoftext|>


<commit_before>'use strict'

module.exports = [
  {
    user: 'U02AFEUJT',
    username: 'michal.brasna',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U02U8LR8C',
    username: 'jan.pavlovsky',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk', 'bad-flash-bar']
  },
  {
    user: 'UAQUTU63Z',
    username: 'alina',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U4Y0SMG5P',
    username: 'jakub.loffelmann',
    services: ['tankovna', 'lokal-hamburk', 'globus', 'bad-flash-bar']
  },
  {
    user: 'U02AG6ZJW',
    username: 'ottokovarik',
    services: ['tankovna', 'lokal-hamburk', 'globus', 'bad-flash-bar']
  },
  {
    user: 'U02DFEYFU',
    username: 'radim',
    services: ['tankovna', 'lokal-hamburk', 'u-zabranskych']
  },
  {
    user: 'U02APJAFH',
    username: 'tomas.pokorny',
    services: ['tankovna', 'lokal-hamburk']
  },
  {
    user: 'U02AAGWQL',
    username: 'radek.carda',
    services: ['peters', 'globus', 'meat-market', 'lokal-hamburk']
  },
  {
    user: 'U02UQK6DW',
    username: 'zdenek.cejka',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'globus']
  },
  {
    user: 'U02A8R785',
    username: 'mafo',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U02G1DFK5',
    username: 'martin.kadlec',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U02AAEFEE',
    username: 'tomasbauer',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U1N3KSXV5',
    username: 'snajby',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: 'U02AKQ3N6',
    username: 'milan',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U0CGN045Q',
    username: 'vaclavhosticka',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: 'U3YKTP9B3',
    username: 'ango',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: 'U4SRV3LUQ',
    username: 'ondram',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: 'U1X00FEPQ',
    username: 'jenism',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk']
  },
  {
    user: 'U02A9M0QB',
    username: 'petrkrejcik',
    services: ['tankovna', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  },
  {
    user: 'U02A54QBN',
    username: 'adamsobotka',
    services: ['tankovna', 'lokal-hamburk', 'meat-market', 'globus']
  },
  {
    user: 'U0FK93EE6',
    username: 'jakubsimecek',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: 'U8MCDASJX',
    username: 'renata.vostra',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  },
  {
    user: 'U48C6B9GW',
    username: 'martin.triska',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  },
  {
    user: 'U92CL53TP',
    username: 'martin.hrabovsky',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  }
]
<commit_msg>Martin Triska is not hungry<commit_after>'use strict'

module.exports = [
  {
    user: 'U02AFEUJT',
    username: 'michal.brasna',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U02U8LR8C',
    username: 'jan.pavlovsky',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk', 'bad-flash-bar']
  },
  {
    user: 'UAQUTU63Z',
    username: 'alina',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U4Y0SMG5P',
    username: 'jakub.loffelmann',
    services: ['tankovna', 'lokal-hamburk', 'globus', 'bad-flash-bar']
  },
  {
    user: 'U02AG6ZJW',
    username: 'ottokovarik',
    services: ['tankovna', 'lokal-hamburk', 'globus', 'bad-flash-bar']
  },
  {
    user: 'U02DFEYFU',
    username: 'radim',
    services: ['tankovna', 'lokal-hamburk', 'u-zabranskych']
  },
  {
    user: 'U02APJAFH',
    username: 'tomas.pokorny',
    services: ['tankovna', 'lokal-hamburk']
  },
  {
    user: 'U02AAGWQL',
    username: 'radek.carda',
    services: ['peters', 'globus', 'meat-market', 'lokal-hamburk']
  },
  {
    user: 'U02UQK6DW',
    username: 'zdenek.cejka',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'globus']
  },
  {
    user: 'U02A8R785',
    username: 'mafo',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U02G1DFK5',
    username: 'martin.kadlec',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U02AAEFEE',
    username: 'tomasbauer',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U1N3KSXV5',
    username: 'snajby',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: 'U02AKQ3N6',
    username: 'milan',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'lokal-hamburk', 'globus']
  },
  {
    user: 'U0CGN045Q',
    username: 'vaclavhosticka',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: 'U3YKTP9B3',
    username: 'ango',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: 'U4SRV3LUQ',
    username: 'ondram',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: 'U1X00FEPQ',
    username: 'jenism',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk']
  },
  {
    user: 'U02A9M0QB',
    username: 'petrkrejcik',
    services: ['tankovna', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  },
  {
    user: 'U02A54QBN',
    username: 'adamsobotka',
    services: ['tankovna', 'lokal-hamburk', 'meat-market', 'globus']
  },
  {
    user: 'U0FK93EE6',
    username: 'jakubsimecek',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: 'U8MCDASJX',
    username: 'renata.vostra',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  },
  {
    user: 'U92CL53TP',
    username: 'martin.hrabovsky',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  }
]
<|endoftext|>


<commit_before>module.exports = function(grunt) {

	var _               = grunt.util._;
	var requireJsConfig = require('./src/js/config.js');

	var BANNER_TEMPLATE_STRING = '/*! <%= pkg.name %> - v<%= pkg.version %> - '
		+ '<%= grunt.template.today("yyyy-mm-dd") %> */\n';

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		clean: {
			dist: ['dist']
		},
		copy: {
			require: {
				src: 'bower_components/requirejs/require.js',
				dest: 'dist/js/require.js'
			},
			audio: {
				expand: true, // required when using cwd
				cwd: '../circuit-construction-kit/src/audio/',
				src: '**',
				dest: 'dist/audio/'
			},
			fonts: {
				expand: true,
				filter: 'isFile',
				flatten: true,
				src: ['../circuit-construction-kit/node_modules/font-awesome/fonts/**'],
				dest: 'dist/node_modules/font-awesome/fonts/'
			},
			common: {
				src: [
					'../common/**/*.{eot,svg,ttf,woff,otf}',
					'../common/img/**/*.{png,jpg,jpeg,gif}',
					'!../common/**/docs/**/*'
				],
				dest: 'dist/common/'
			},
			circuit_construction_kit: {
				src: [
					'../circuit-construction-kit/src/img/**/*.{png,jpg,jpeg,gif}'
				],
				dest: 'dist/circuit-construction-kit/src/'
			},
			screenshot: {
				src: 'src/screenshot.png',
				dest: 'dist/screenshot.png'
			}
		},
		rename: {
			optimized: {
				src: 'src/optimized.js',
				dest: 'dist/js/optimized.js'
			}
		},
		connect: {
			dist: {
				options: {
					port: '8090',
					base: 'dist'
				}
			}
		},
		requirejs: {
			compile: {
				options: _.merge(requireJsConfig, {
					baseUrl: 'src/js',
					findNestedDependencies: true,
					optimize: 'uglify2',
					name: 'main',
					out: 'src/optimized.js',

					less: {
						modifyVars: {
							//'fa-font-path': '"../node_modules/font-awesome/fonts/"',
							'assets': '"../../circuit-construction-kit/src/js/assets"'
						}
					}

					// Doing it this way doesn't work:
					// mainConfigFile: 'src/js/config.js'
				})
			}
		},
		uglify: {
			options: {
				banner: BANNER_TEMPLATE_STRING
			},
			dist: {
				files: {
					'dist/scripts/require.js': ['dist/scripts/require.js']
				}
			}
		},
		targethtml: {
			dist: {
				files: {
					'dist/index.html': 'src/index.html'
				}
			}
		},
		watch: {
			styles: {
				files: ['src/less/**/*.less'], // files to watch
				tasks: ['less:development'],
				options: {
					nospawn: true
				}
			}
		},
		jshint: {
			options: {
				globals: {
					require: true,
					define: true
				},

				// Enforcing Options
				forin: true,
				immed: true,
				latedef: true,
				laxbreak: true,
				laxcomma: true,
				noarg: true,
				noempty: true,
				nonbsp: true,
				nonew: true,
				quotmark: 'single',
				undef: true,
				unused: 'vars',
				strict: true,
				trailing: true,
				//maxlen: 120,
				maxcomplexity: 10,

				// Relaxing Options
				camelcase: false,
				curly: false,
				eqeqeq: false,
				newcap: false,
				plusplus: false,
				asi: false,
				boss: false,
				debug: false,
				eqnull: false,
				evil: false,
				expr: false,
				funcscope: false,
				globalstrict: false,
				iterator: false,
				lastsemic: false,
				loopfunc: false,
				multistr: false,
				proto: false,
				scripturl: false,
				smarttabs: false,
				shadow: false,
				sub: false,
				supernew: false,
				validthis: false,

				// Environments
				browser: true,
				devel: false
			},
			source: [
				'src/**/*.js',
				'!src/js/lib/**/*.js',
				'!test/**/*.js'
			],
			test: [
				'test/**/*.js'
			]
		},
		mocha: {
			// Test all files ending in .html anywhere inside the test directory.
			browser: ['test/index.html'],
			options: {
				reporter: 'Spec',
				run: false,
				log: false,
				timeout: 15000
			}
		},
		build_tests: {
			options: {
				template: 'test/index.template.html',
				runner: 'test/index.html',
				files: 'test/**/*.js'
			}
		}
	});

	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

	grunt.registerTask('build_tests', function(){
		var options = this.options();

		// Get all the files and prepend the '../' relative path
		var tests = grunt.file.expand(options.files).map(function(file){
			grunt.log.write('../' + file);
			return '../' + file;
		});

		// Build the template, replacing {{ test }} with the list of test files
		var template = grunt.file.read(options.template).replace('{{ tests }}', JSON.stringify(tests));

		// Write template to tests directory and run tests
		grunt.file.write(options.runner, template);
	});

	grunt.registerTask('default', [
		'watch'
	]);

	grunt.registerTask('dist', [
		'clean:dist',
		'requirejs:compile',
		'copy',
		'rename:optimized',
		'targethtml'
	]);

	grunt.registerTask('test', [
		'jshint:source',
		'build_tests',
		'mocha'
	]);

	grunt.registerTask('lint', ['jshint']);

};
<commit_msg>The dist version was still trying to get its images from the circuit-construction-kit project instead of the dc-only dist folder. I also found out that it's not getting the fonts from the right place, but I haven't fixed that yet.<commit_after>module.exports = function(grunt) {

	var _               = grunt.util._;
	var requireJsConfig = require('./src/js/config.js');

	var BANNER_TEMPLATE_STRING = '/*! <%= pkg.name %> - v<%= pkg.version %> - '
		+ '<%= grunt.template.today("yyyy-mm-dd") %> */\n';

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		clean: {
			dist: ['dist']
		},
		copy: {
			require: {
				src: 'bower_components/requirejs/require.js',
				dest: 'dist/js/require.js'
			},
			audio: {
				expand: true, // required when using cwd
				cwd: '../circuit-construction-kit/src/audio/',
				src: '**',
				dest: 'dist/audio/'
			},
			fonts: {
				expand: true,
				filter: 'isFile',
				flatten: true,
				src: ['../circuit-construction-kit/node_modules/font-awesome/fonts/**'],
				dest: 'dist/node_modules/font-awesome/fonts/'
			},
			common: {
				src: [
					'../common/**/*.{eot,svg,ttf,woff,otf}',
					'../common/img/**/*.{png,jpg,jpeg,gif}',
					'!../common/**/docs/**/*'
				],
				dest: 'dist/common/'
			},
			circuit_construction_kit: {
				expand: true, // required when using cwd
				cwd: '../circuit-construction-kit/src/img/',
				src: '**',
				dest: 'dist/img/'
			},
			screenshot: {
				src: 'src/screenshot.png',
				dest: 'dist/screenshot.png'
			}
		},
		rename: {
			optimized: {
				src: 'src/optimized.js',
				dest: 'dist/js/optimized.js'
			}
		},
		connect: {
			dist: {
				options: {
					port: '8090',
					base: 'dist'
				}
			}
		},
		requirejs: {
			compile: {
				options: _.merge(requireJsConfig, {
					baseUrl: 'src/js',
					findNestedDependencies: true,
					optimize: 'uglify2',
					name: 'main',
					out: 'src/optimized.js',

					paths: {
						assets: '../../../circuit-construction-kit/src/js/assets'
					},

					less: {
						modifyVars: {
							//'fa-font-path': '"../node_modules/font-awesome/fonts/"'
						}
					}

					// Doing it this way doesn't work:
					// mainConfigFile: 'src/js/config.js'
				})
			}
		},
		uglify: {
			options: {
				banner: BANNER_TEMPLATE_STRING
			},
			dist: {
				files: {
					'dist/scripts/require.js': ['dist/scripts/require.js']
				}
			}
		},
		targethtml: {
			dist: {
				files: {
					'dist/index.html': 'src/index.html'
				}
			}
		},
		watch: {
			styles: {
				files: ['src/less/**/*.less'], // files to watch
				tasks: ['less:development'],
				options: {
					nospawn: true
				}
			}
		},
		jshint: {
			options: {
				globals: {
					require: true,
					define: true
				},

				// Enforcing Options
				forin: true,
				immed: true,
				latedef: true,
				laxbreak: true,
				laxcomma: true,
				noarg: true,
				noempty: true,
				nonbsp: true,
				nonew: true,
				quotmark: 'single',
				undef: true,
				unused: 'vars',
				strict: true,
				trailing: true,
				//maxlen: 120,
				maxcomplexity: 10,

				// Relaxing Options
				camelcase: false,
				curly: false,
				eqeqeq: false,
				newcap: false,
				plusplus: false,
				asi: false,
				boss: false,
				debug: false,
				eqnull: false,
				evil: false,
				expr: false,
				funcscope: false,
				globalstrict: false,
				iterator: false,
				lastsemic: false,
				loopfunc: false,
				multistr: false,
				proto: false,
				scripturl: false,
				smarttabs: false,
				shadow: false,
				sub: false,
				supernew: false,
				validthis: false,

				// Environments
				browser: true,
				devel: false
			},
			source: [
				'src/**/*.js',
				'!src/js/lib/**/*.js',
				'!test/**/*.js'
			],
			test: [
				'test/**/*.js'
			]
		},
		mocha: {
			// Test all files ending in .html anywhere inside the test directory.
			browser: ['test/index.html'],
			options: {
				reporter: 'Spec',
				run: false,
				log: false,
				timeout: 15000
			}
		},
		build_tests: {
			options: {
				template: 'test/index.template.html',
				runner: 'test/index.html',
				files: 'test/**/*.js'
			}
		}
	});

	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

	grunt.registerTask('build_tests', function(){
		var options = this.options();

		// Get all the files and prepend the '../' relative path
		var tests = grunt.file.expand(options.files).map(function(file){
			grunt.log.write('../' + file);
			return '../' + file;
		});

		// Build the template, replacing {{ test }} with the list of test files
		var template = grunt.file.read(options.template).replace('{{ tests }}', JSON.stringify(tests));

		// Write template to tests directory and run tests
		grunt.file.write(options.runner, template);
	});

	grunt.registerTask('default', [
		'watch'
	]);

	grunt.registerTask('dist', [
		'clean:dist',
		'requirejs:compile',
		'copy',
		'rename:optimized',
		'targethtml'
	]);

	grunt.registerTask('test', [
		'jshint:source',
		'build_tests',
		'mocha'
	]);

	grunt.registerTask('lint', ['jshint']);

};
<|endoftext|>


<commit_before>defineSuite([
        'Core/loadImageFromTypedArray',
        'Core/Resource',
        'ThirdParty/when'
    ], function(
        loadImageFromTypedArray,
        Resource,
        when) {
    'use strict';

    it('can load an image', function() {
        return Resource.fetchArrayBuffer('./Data/Images/Blue10x10.png').then(function(arrayBuffer) {
            var options = {
                uint8Array: new Uint8Array(arrayBuffer),
                format: 'image/png'
            };

            return loadImageFromTypedArray(options).then(function(image) {
                expect(image.width).toEqual(10);
                expect(image.height).toEqual(10);
            });
        });
    });

    it('flips image only when flipY is true', function() {
        var options = {
            uint8Array: new Uint8Array([67, 101, 115, 105, 117, 109]), // This is an invalid PNG.
            format: 'image/png',
            flipY: true
        };
        spyOn(window, 'createImageBitmap').and.returnValue(when.resolve({}));
        var blob = new Blob([options.uint8Array], {
            type : options.format
        });

        return Resource.supportsImageBitmapOptions()
            .then(function(result) {
                if (!result) {
                    return;
                }

                return loadImageFromTypedArray(options)
                    .then(function() {
                        expect(window.createImageBitmap).toHaveBeenCalledWith(blob, {
                            imageOrientation: 'flipY',
                            premultiplyAlpha: 'none'
                        });

                         window.createImageBitmap.calls.reset();
                         options.flipY = false;
                         return loadImageFromTypedArray(options);
                    })
                    .then(function() {
                        expect(window.createImageBitmap).toHaveBeenCalledWith(blob, {
                            imageOrientation: 'none',
                            premultiplyAlpha: 'none'
                        });
                    });
            });
    });

    it('can load an image when ImageBitmap is not supported', function() {
        spyOn(Resource, 'supportsImageBitmapOptions').and.returnValue(when.resolve(false));
        spyOn(window, 'createImageBitmap').and.callThrough();
        return Resource.fetchArrayBuffer('./Data/Images/Blue10x10.png').then(function(arrayBuffer) {
            var options = {
                uint8Array: new Uint8Array(arrayBuffer),
                format: 'image/png'
            };

            return loadImageFromTypedArray(options).then(function(image) {
                expect(image.width).toEqual(10);
                expect(image.height).toEqual(10);
                expect(window.createImageBitmap).not.toHaveBeenCalled();
            });
        });
    });

    it('can not load an invalid image', function() {
        var options = {
            uint8Array: new Uint8Array([67, 101, 115, 105, 117, 109]), // This is an invalid PNG.
            format: 'image/png'
        };
        return loadImageFromTypedArray(options).then(function(image) {
            fail('should not be called');
        }).otherwise(function() {
        });
    });

    it('Throws without array', function() {
        expect(function() {
            loadImageFromTypedArray({});
        }).toThrowDeveloperError();
    });

    it('Throws without format', function() {
        expect(function() {
            loadImageFromTypedArray({
                uint8Array: new Uint8Array()
            });
        }).toThrowDeveloperError();
    });
});
<commit_msg>Fix ImageBitmap spec on Edge<commit_after>defineSuite([
        'Core/loadImageFromTypedArray',
        'Core/Resource',
        'ThirdParty/when'
    ], function(
        loadImageFromTypedArray,
        Resource,
        when) {
    'use strict';

    var supportsImageBitmapOptions;

    beforeAll(function() {
        return Resource.supportsImageBitmapOptions()
            .then(function(result) {
                supportsImageBitmapOptions = result;
            });
    });

    it('can load an image', function() {
        return Resource.fetchArrayBuffer('./Data/Images/Blue10x10.png').then(function(arrayBuffer) {
            var options = {
                uint8Array: new Uint8Array(arrayBuffer),
                format: 'image/png'
            };

            return loadImageFromTypedArray(options).then(function(image) {
                expect(image.width).toEqual(10);
                expect(image.height).toEqual(10);
            });
        });
    });

    it('flips image only when flipY is true', function() {
        if (!supportsImageBitmapOptions) {
            return;
        }

        var options = {
            uint8Array: new Uint8Array([67, 101, 115, 105, 117, 109]), // This is an invalid PNG.
            format: 'image/png',
            flipY: true
        };
        spyOn(window, 'createImageBitmap').and.returnValue(when.resolve({}));
        var blob = new Blob([options.uint8Array], {
            type : options.format
        });

        return Resource.supportsImageBitmapOptions()
            .then(function(result) {
                if (!result) {
                    return;
                }

                return loadImageFromTypedArray(options)
                    .then(function() {
                        expect(window.createImageBitmap).toHaveBeenCalledWith(blob, {
                            imageOrientation: 'flipY',
                            premultiplyAlpha: 'none'
                        });

                         window.createImageBitmap.calls.reset();
                         options.flipY = false;
                         return loadImageFromTypedArray(options);
                    })
                    .then(function() {
                        expect(window.createImageBitmap).toHaveBeenCalledWith(blob, {
                            imageOrientation: 'none',
                            premultiplyAlpha: 'none'
                        });
                    });
            });
    });

    it('can load an image when ImageBitmap is not supported', function() {
        if (!supportsImageBitmapOptions) {
            return;
        }

        spyOn(Resource, 'supportsImageBitmapOptions').and.returnValue(when.resolve(false));
        spyOn(window, 'createImageBitmap').and.callThrough();
        return Resource.fetchArrayBuffer('./Data/Images/Blue10x10.png').then(function(arrayBuffer) {
            var options = {
                uint8Array: new Uint8Array(arrayBuffer),
                format: 'image/png'
            };

            return loadImageFromTypedArray(options).then(function(image) {
                expect(image.width).toEqual(10);
                expect(image.height).toEqual(10);
                expect(window.createImageBitmap).not.toHaveBeenCalled();
            });
        });
    });

    it('can not load an invalid image', function() {
        var options = {
            uint8Array: new Uint8Array([67, 101, 115, 105, 117, 109]), // This is an invalid PNG.
            format: 'image/png'
        };
        return loadImageFromTypedArray(options).then(function(image) {
            fail('should not be called');
        }).otherwise(function() {
        });
    });

    it('Throws without array', function() {
        expect(function() {
            loadImageFromTypedArray({});
        }).toThrowDeveloperError();
    });

    it('Throws without format', function() {
        expect(function() {
            loadImageFromTypedArray({
                uint8Array: new Uint8Array()
            });
        }).toThrowDeveloperError();
    });
});
<|endoftext|>


<commit_before>/**
 * @copyright  2011 geOps
 * @license    https://github.com/geops/ole/blob/master/license.txt
 * @link       https://github.com/geops/ole
 */

/**
 * Class: OpenLayers.Editor.Control.SnappingSettings
 * ...
 *
 * Inherits from:
 *  - <OpenLayers.Control.Button>
 */
OpenLayers.Editor.Control.SnappingSettings = OpenLayers.Class(OpenLayers.Control.Button, {

    title: OpenLayers.i18n('oleSnappingSettings'),

    layer: null,

    snapping: new OpenLayers.Control.Snapping(),

    tolerance: 10,

    /**
     * @var {Array.<String>} Identifiers of checkboxes to enable snapping for individual layers
     */
    snappingLayers: null,

    /**
     * Layer that displays guide lines and snapping points
     * @var OpenLayers.Editor.Layer.Snapping
     */
    snappingGuideLayer: null,

    layerListDiv: null,

    toleranceInput: null,

    initialize: function(layer, options) {
        this.snappingLayers = [];
        this.layer = layer;

        OpenLayers.Control.Button.prototype.initialize.apply(this, [options]);

        this.trigger = OpenLayers.Function.bind(this.openSnappingDialog, this);

        this.events.register("deactivate", this, this.onDeactivate);

        this.title = OpenLayers.i18n('oleSnappingSettings');
    },

    onDeactivate: function() {
        if(this.snapping.active) {
            this.activate();
        }
    },

    openSnappingDialog: function() {

        var content, toleranceHeader, layerHeader;

        this.activate();

        this.layerListDiv = document.createElement('div');

        content = document.createElement('div');

        toleranceHeader = document.createElement('h4');
        toleranceHeader.innerHTML = OpenLayers.i18n('oleSnappingSettingsTolerance');
        content.appendChild(toleranceHeader);

        this.toleranceInput = document.createElement('input');
        this.toleranceInput.type = 'text';
        this.toleranceInput.size = 4;
        this.toleranceInput.value = this.tolerance;
        content.appendChild(this.toleranceInput);

        layerHeader = document.createElement('h4');
        layerHeader.innerHTML = OpenLayers.i18n('oleSnappingSettingsLayer');
        content.appendChild(layerHeader);

        content.appendChild(this.layerListDiv);

        this.map.editor.dialog.show({
            content: content,
            title: OpenLayers.i18n('oleSnappingSettings'),
            close: OpenLayers.Function.bind(this.changeSnapping, this)
        });

        this.redraw();
    },

    redraw: function() {

        var layer, element, content;

        this.layerListDiv.innerHTML = '';

        for (var i = 0; i <  this.map.layers.length; i++) {

            layer = this.map.layers[i];

            if(!(layer instanceof OpenLayers.Layer.Vector.RootContainer) &&
                 layer instanceof OpenLayers.Layer.Vector &&
                 !(layer instanceof OpenLayers.Editor.Layer.Snapping) &&
                 layer.name.search(/OpenLayers.Handler.+/) == -1) {

                content = document.createElement('div');

                element = document.createElement('input');
                element.type = 'checkbox';
                element.name = 'snappingLayer';
                element.id = 'Snapping.'+layer.id;
                element.value = 'true';
                if(this.snappingLayers.indexOf('Snapping.'+layer.id) >= 0) {
                    element.checked = 'checked';
                    element.defaultChecked = 'selected'; // IE7 hack
                }
                content.appendChild(element);
                OpenLayers.Event.observe(element, 'click',
                    OpenLayers.Function.bind(this.addSnappingLayer, this));

                element = document.createElement('label');
                element.setAttribute('for', 'Snapping.'+layer.id);
                element.innerHTML = layer.name;
                content.appendChild(element);

                this.layerListDiv.appendChild(content);
            }
        }
    },

    addSnappingLayer: function(event) {
        if(this.snappingLayers.indexOf(event.currentTarget.id) >= 0) {
            this.snappingLayers.splice(this.snappingLayers.indexOf(event.currentTarget.id), 1);
        } else {
            this.snappingLayers.push(event.currentTarget.id);
        }
        this.redraw();
    },

    changeSnapping: function() {

        this.tolerance = parseInt(this.toleranceInput.value);

        if(this.snappingLayers.length > 0) {

            this.snapping.deactivate();
            var targets = [];
            for (var i = 0; i <  this.snappingLayers.length; i++) {
                targets.push({
                    layer:this.map.getLayersBy('id',this.snappingLayers[i].substr(9))[0],
                    tolerance: this.tolerance
                });
            }
            this.snapping = new OpenLayers.Control.Snapping({
                layer: this.layer,
                targets: targets
            });
            for (var i = 0; i <  targets.length; i++) {
                // moveTo call is to trigger loading of layer contents
                targets[i].layer.moveTo(this.map.getExtent(), false, false);
            }
            this.snapping.activate();
        } else {
            if (this.snapping.active) {
                this.snapping.deactivate();
                this.snapping.targets = null;
            }
        }
        if (!this.snapping.active) this.deactivate();
    },

    setMap: function(map){
        OpenLayers.Control.Button.prototype.setMap.apply(this, arguments);

        if(this.snappingGuideLayer===null){
            this.snappingGuideLayer = this.createSnappingGuideLayer();
        }
    },

    /**
     * Adds a layer for guidelines to the map
     * @return {OpenLayers.Editor.Layer.Snapping}
     */
    createSnappingGuideLayer: function(){
        var snappingGuideLayer = new OpenLayers.Editor.Layer.Snapping(OpenLayers.i18n('Snapping Layer'), {
            visibility: false
        });
        this.map.addLayer(snappingGuideLayer);

        return snappingGuideLayer;
    },

    CLASS_NAME: "OpenLayers.Editor.Control.SnappingSettings"
});<commit_msg>Avoid IE's buggy event handling when choosing layers for snapping<commit_after>/**
 * @copyright  2011 geOps
 * @license    https://github.com/geops/ole/blob/master/license.txt
 * @link       https://github.com/geops/ole
 */

/**
 * Class: OpenLayers.Editor.Control.SnappingSettings
 * ...
 *
 * Inherits from:
 *  - <OpenLayers.Control.Button>
 */
OpenLayers.Editor.Control.SnappingSettings = OpenLayers.Class(OpenLayers.Control.Button, {

    title: OpenLayers.i18n('oleSnappingSettings'),

    layer: null,

    snapping: new OpenLayers.Control.Snapping(),

    tolerance: 10,

    /**
     * @var {Array.<String>} Identifiers of checkboxes to enable snapping for individual layers
     */
    snappingLayers: null,

    /**
     * Layer that displays guide lines and snapping points
     * @var OpenLayers.Editor.Layer.Snapping
     */
    snappingGuideLayer: null,

    layerListDiv: null,

    toleranceInput: null,

    initialize: function(layer, options) {
        this.snappingLayers = [];
        this.layer = layer;

        OpenLayers.Control.Button.prototype.initialize.apply(this, [options]);

        this.trigger = OpenLayers.Function.bind(this.openSnappingDialog, this);

        this.events.register("deactivate", this, this.onDeactivate);

        this.title = OpenLayers.i18n('oleSnappingSettings');
    },

    onDeactivate: function() {
        if(this.snapping.active) {
            this.activate();
        }
    },

    openSnappingDialog: function() {

        var content, toleranceHeader, layerHeader;

        this.activate();

        this.layerListDiv = document.createElement('div');

        content = document.createElement('div');

        toleranceHeader = document.createElement('h4');
        toleranceHeader.innerHTML = OpenLayers.i18n('oleSnappingSettingsTolerance');
        content.appendChild(toleranceHeader);

        this.toleranceInput = document.createElement('input');
        this.toleranceInput.type = 'text';
        this.toleranceInput.size = 4;
        this.toleranceInput.value = this.tolerance;
        content.appendChild(this.toleranceInput);

        layerHeader = document.createElement('h4');
        layerHeader.innerHTML = OpenLayers.i18n('oleSnappingSettingsLayer');
        content.appendChild(layerHeader);

        content.appendChild(this.layerListDiv);

        this.map.editor.dialog.show({
            content: content,
            title: OpenLayers.i18n('oleSnappingSettings'),
            close: OpenLayers.Function.bind(this.changeSnapping, this)
        });

        this.redraw();
    },

    redraw: function() {

        var layer, element, content;

        this.layerListDiv.innerHTML = '';

        for (var i = 0; i <  this.map.layers.length; i++) {

            layer = this.map.layers[i];

            if(!(layer instanceof OpenLayers.Layer.Vector.RootContainer) &&
                 layer instanceof OpenLayers.Layer.Vector &&
                 !(layer instanceof OpenLayers.Editor.Layer.Snapping) &&
                 layer.name.search(/OpenLayers.Handler.+/) == -1) {

                content = document.createElement('div');

                element = document.createElement('input');
                element.type = 'checkbox';
                element.name = 'snappingLayer';
                element.id = 'Snapping.'+layer.id;
                element.value = 'true';
                if(this.snappingLayers.indexOf(layer) >= 0) {
                    element.checked = 'checked';
                    element.defaultChecked = 'selected'; // IE7 hack
                }
                content.appendChild(element);
                OpenLayers.Event.observe(element, 'click',
                    OpenLayers.Function.bind(this.setLayerSnapping, this, layer, element.checked));

                element = document.createElement('label');
                element.setAttribute('for', 'Snapping.'+layer.id);
                element.innerHTML = layer.name;
                OpenLayers.Event.observe(element, 'click', OpenLayers.Function.bind(function(event) {
                    // Allow to check checkbox by clicking its label even when drawing tools are active
                    OpenLayers.Event.stop(event, true);
                }, this));
                content.appendChild(element);

                this.layerListDiv.appendChild(content);
            }
        }
    },

    /**
     * Enables or disables a layer for snapping
     * @param {OpenLayers.Layer} layer
     * @param {Boolean} snappingEnabled Set TRUE to enable snapping to this layer's objects
     */
    setLayerSnapping: function(layer, snappingEnabled) {
        if(snappingEnabled) {
            this.snappingLayers.splice(this.snappingLayers.indexOf(layer), 1);
        } else {
            this.snappingLayers.push(layer);
        }
        this.redraw();
    },

    changeSnapping: function() {

        this.tolerance = parseInt(this.toleranceInput.value);

        if(this.snappingLayers.length > 0) {

            this.snapping.deactivate();
            var targets = [];
            for (var i = 0; i <  this.snappingLayers.length; i++) {
                targets.push({
                    layer: this.snappingLayers[i],
                    tolerance: this.tolerance
                });
            }
            this.snapping = new OpenLayers.Control.Snapping({
                layer: this.layer,
                targets: targets
            });
            for (var i = 0; i <  targets.length; i++) {
                // moveTo call is to trigger loading of layer contents
                targets[i].layer.moveTo(this.map.getExtent(), false, false);
            }
            this.snapping.activate();
        } else {
            if (this.snapping.active) {
                this.snapping.deactivate();
                this.snapping.targets = null;
            }
        }
        if (!this.snapping.active) this.deactivate();
    },

    setMap: function(map){
        OpenLayers.Control.Button.prototype.setMap.apply(this, arguments);

        if(this.snappingGuideLayer===null){
            this.snappingGuideLayer = this.createSnappingGuideLayer();
        }
    },

    /**
     * Adds a layer for guidelines to the map
     * @return {OpenLayers.Editor.Layer.Snapping}
     */
    createSnappingGuideLayer: function(){
        var snappingGuideLayer = new OpenLayers.Editor.Layer.Snapping(OpenLayers.i18n('Snapping Layer'), {
            visibility: false
        });
        this.map.addLayer(snappingGuideLayer);

        return snappingGuideLayer;
    },

    CLASS_NAME: "OpenLayers.Editor.Control.SnappingSettings"
});<|endoftext|>