Функция отправки карты с точкой местонаходжения объекта (maps.yandex API)

Вопросы и информация о скриптах для ioBroker
Antworten
Haba
starter
Beiträge: 56
Registriert: 29.03.2016, 13:07

Функция отправки карты с точкой местонаходжения объекта (maps.yandex API)

Beitrag von Haba » 05.10.2017, 08:31

Использую такой вариант определения местонахождения телефона (Andriod)

1. ставим программу, которая будет в фоне отправлять текущие координаты с заданной периодичностью.
Например tasker или как я использую Automagic Premium.
Spoiler: Show hidden text
Bild
т.е. get запросом каждые 5 минут отправляем на IoBroker координкаты телефона на драйвер Simple API (должен быть запущен и настроен) в объект location.roman, который создали скриптом (см. ниже).

2. Отправляем в телеграмм ссылку на картинку с координатами заданного объекта через драйвер JS
3. Вторым сообщением отправляем определенный адрес местонахождения объекта и дату последнего обновления координат.
Используется бесплатный API maps

переменная tag это объект с координатами вида "25.22498,25.21571"

Code: Alles auswählen

createState('location.roman');

function GPSsendMap(tag) {
    var location = tag.val.split(',');
    sendTo('telegram', {
        user: user,
        text : "https://static-maps.yandex.ru/1.x/?size=450,450&z=16&z=13&l=map&pt="+ location[1] + "," + location[0] +",flag"
    });
    
    geocode(location[1] + "," + location[0], 
        function(addr) {
            sendTo('telegram.0', {
                    user : user,
                    text: "Адрес: " + addr + "\nОбновлено " + formatDate (tag.ts, "JJJJ.MM.TT SS:mm:ss"), 
                });
        }, function (error) {
            log (error);
        });
}

function geocode(coordinates, okCallback, errorCallback) {
    var addr = "Адрес не найден!";
    request ('https://geocode-maps.yandex.ru/1.x/?format=json&results=1&geocode=' + coordinates, function (error, response, body) {
    // Получаем ответ
        if (!error && response.statusCode === 200) {
            // Парсим данные
            var obj = JSON.parse(body);
            addr = getKeyArray(obj,"AddressLine");
            return okCallback(addr);
        } else {
            return errorCallback(error);
        }
    });
}

function getKeyArray(obj, keyName) {
    var result = [];
    for (var attr in obj) {
        if (obj[attr] && typeof obj[attr] === 'object') {
            result = result.concat(getKeyArray(obj[attr], keyName));
        }
        if (attr === keyName) {
            result.push(obj[attr]);
        }
    }
    return result;
}
Функции можно вызывать например по нажатию кнопки или любому другому событию
Dateianhänge
gps2.jpg
gps.jpg
Zuletzt geändert von Haba am 23.03.2018, 16:05, insgesamt 3-mal geändert.

Haba
starter
Beiträge: 56
Registriert: 29.03.2016, 13:07

Re: Функция отправки карты с точкой местонаходжения объекта (maps.yandex API)

Beitrag von Haba » 15.12.2017, 11:12

Продолжение темы в сторону контроля локаций.

Ниже пример для трех человек. Каждому задается имя, индивидуальные зоны контроля на вход/выход, радиусы зон и т.п.
вставляем скрипт:
Spoiler: Show hidden text

Code: Alles auswählen

createState('location.user1');
createState('location.user2');
createState('location.user3');

var radius = 0.0014;
/*
71,24035723	км	=	1	град
1	км	        =	0,014036987	град
0,1	км	        =	0,001403699	град
0,05 км	        =	0,000701849	град
*/

// массив текущих локаций
var currentLocations = {
    "user1" : "",
    "user2"  : "",
    "user3"  : ""
};

// массив локаций для сравнения с текущими координатами
var locations = {
    "user1" : {
        name : "Марфуша",                                    // имя человека
        text : ["вошла в локацию ","вышла из локации "],    // действие событие
        location : [  // локации: имя, координаты центра. Дополнительно можно задать другой радиус и действия/события для определенной локации
            {name : "Дом", coord : "45.225003,39.215152"},
            {name : "Бассейн", coord : "45.235450,39.218855"},
            {name : "Школа", coord : "45.22203,39.22134"}
        ]
    },
    "user2" : {
        name : "Маша",
        text : ["вошла в локацию ","вышла из локации "],
        location : [
            {name : "Дом", coord : "45.225003,39.215152"},
            {name : "Работа", coord : "45.22203,39.22134"}
        ]
    },
    "user3" : {
        name : "Иван",
        text : ["вошел в локацию ","вышел из локации "],
        location : [
            {name : "Дому", coord : "45.225003,39.215152", radius : 0.014036987*5, text : ["подъезжает к ",""]}, // контроль зоны с радиусом 5 км и только на въезд
            {name : "Дом", coord : "45.225003,39.215152"},
            {name : "Работа", coord : "45.04984,38.97755"}
        ]
    }
};

on({id: /^javascript\.0\.location\./, change: 'any'}, function (gps) {
    //log (gps.id);
    var name = gps.id.substr(22); // парсим имя
    //log(name);
    var txt = "";
    var current;
    //log("Текущее положение: " + currentLocations[name]);
    for (var i = 0; i < locations[name].location.length; ++i) {
        //log( "Локация: " + locations[name].location[i].name + " Координаты: " + locations[name].location[i].coord);
        var rad = radius;
        if (locations[name].location[i].radius !== undefined) rad = locations[name].location[i].radius; // присваиваем альтернативный радиус, если есть
        current = locationRegion(getState("javascript.0.location." + name), locations[name].location[i].coord, rad);
        var locName = locations[name].location[i].name;
        var action = locations[name].text[0];
        if (typeof (locations[name].location[i].text) !== 'undefined')
            action = locations[name].location[i].text[0]; // присваиваем альтернативное действие, если есть
        if (current && (currentLocations[name] !== locName)) {
            if (action !== "")
                txt = locations[name].name + " " + action + locName;
            currentLocations[name] = locName;
        }
        action = locations[name].text[1];
        if (typeof (locations[name].location[i].text) !== 'undefined')
            action = locations[name].location[i].text[1]; // присваиваем альтернативное действие, если есть
        if (!current && (currentLocations[name] === locations[name].location[i].name)) {
            if (action !== "")
                txt = locations[name].name + " " + action + locName;
            currentLocations[name] = "";
        }
        //log ("txt: " + txt);
    }
    if (txt !=="") sendTelegram(txt);
});

//определяем нахожение точки в заданной локации с радиусом
function locationRegion(coordinate, location, radius) {
    var h;
    var result = false; // точка в локации: true - да, false - нет
    var coord = coordinate.val.split(',');
    var loc = location.split(',');
    h = Math.sqrt(Math.pow((parseFloat(coord[1])-parseFloat(loc[1])),2) 
        + Math.pow((parseFloat(coord[0])-parseFloat(loc[0])),2));
    //log("Гипотенуза равна = " + h);
    if (h > radius) {
        log("Точка не принадлежит кругу.\n");
        result = false;
    }
    else {
        log("Точка принадлежит кругу.\n");
        result = true;
    }
    return result;
}
результат примерно такой:
Dateianhänge
1.PNG
1.PNG (34.47 KiB) 598 mal betrachtet

Antworten