Клуб Народной карты

Скрипт-букмарклет для создания шаблонов (клонирования) объектов

Никита Юшков
13 августа, 11:41

Скрипт добавляет в панель «Недавно созданные» объект, который Вы собираетесь клонировать, со всеми заполненными пользовательскими атрибутами и привязками (по желанию). Тип объекта неважен, скрипт работает для всех доступных пользователю типов объектов.

ID объекта содержится в адресе страницы при открытой его карточке в редакторе:

Имейте в виду, что у дорог в разделе привязок содержатся также идущие по этому участку нитки. Поэтому с копированием дорог будьте предельно осторожны! Если при сохранении созданного через шаблон объекта появляется надпись «Недостаточно прав для выполнения операции», значит, либо Вы пытаетесь создать служебный объект (например, страну), либо объект содержит в разделе привязок служебный и/или заблокированный объект. В последнем случае при отключении галочки «Копировать привязку (и)» проблема должна исчезнуть.

Код букмарклета (last update 22:38 23.08.18):

javascript:
var categories = {"rd_el":["rd_el:fc","rd_el:fow","rd_el:oneway","rd_el:struct_type","rd_el:f_zlev","rd_el:t_zlev","rd_el:access_id","rd_el:back_bus","rd_el:paved","rd_el:srv_uc","rd_el:speed_limit","rd_el:toll","rd_el:poor_condition"],"rd":["rd_nm","rd:rd_type"],"ad":["ad:town","ad_nm","ad:capital","ad:population","ad:level_kind","ad:municipality","ad:informal"],"ad_fc":[],"ad_el":[],"ad_cnt":[],"addr":["addr_nm"],"transport_railway":["transport_railway:ft_type_id","transport_railway_nm"],"transport_railway_station":["transport_railway_nm","transport_railway_station:ft_type_id","transport_railway_station:url","transport_railway_station:email","transport_railway_station:phone","transport_railway_station:addr_info","transport_railway_station:open_hours"],"transport_railway_el":["transport_railway_el:f_zlev","transport_railway_el:t_zlev"],"transport_railway_jc":[],"transport_metro_line":["transport_metro_line:ft_type_id","transport_metro_nm"],"transport_metro_station":["transport_metro_nm"],"transport_metro_el":["transport_metro_el:f_zlev","transport_metro_el:t_zlev"],"transport_metro_jc":[],"transport_metro_exit":["transport_metro_nm"],"hydro":["hydro:ft_type_id","hydro_nm"],"hydro_fc":[],"vegetation":["vegetation:ft_type_id","vegetation_nm"],"vegetation_fc":[],"relief":["relief:ft_type_id","relief_nm"],"relief_fc":[],"transport_tram_route":["transport_nm"],"transport_waterway_route":["transport_waterway_route_nm"],"urban_fc":[],"urban_roadnet":[],"urban_roadnet_fc":[],"bld":["bld:ft_type_id","bld:height","bld:cond"],"rd_jc":["cat:bound_jc"],"hydro_ln":["hydro_ln:ft_type_id","hydro_nm"],"hydro_point":["hydro_point:ft_type_id","hydro_nm"],"relief_point":["relief_point:ft_type_id","relief_nm"],"urban_roadnet_areal":["urban_roadnet_areal:ft_type_id","urban_roadnet_nm"],"urban_areal":["urban_areal:ft_type_id"],"transport_airport":["transport_airport_nm","transport_airport:ft_type_id","transport_airport:url","transport_airport:email","transport_airport:phone","transport_airport:addr_info","transport_airport:open_hours"],"transport_waterway_stop":["transport_waterway_nm","transport_waterway_stop:ft_type_id","transport_waterway_stop:url","transport_waterway_stop:email","transport_waterway_stop:phone","transport_waterway_stop:addr_info","transport_waterway_stop:open_hours"],"transport_terminal":["transport_terminal_nm","transport_terminal:url","transport_terminal:email","transport_terminal:phone","transport_terminal:addr_info","transport_terminal:open_hours"],"transport_airport_terminal":["transport_airport_nm"],"transport_helicopter":["transport_airport_nm"],"transport_stop":["transport_stop_nm"],"ad_jc":[],"relief_el":[],"relief_jc":[],"vegetation_el":[],"vegetation_jc":[],"hydro_fc_el":[],"hydro_fc_jc":[],"urban_el":[],"urban_jc":[],"urban_roadnet_el":[],"urban_roadnet_jc":[],"transport_tram_el":["transport_tram_el:f_zlev","transport_tram_el:t_zlev"],"transport_tram_jc":[],"transport_waterway_el":[],"transport_waterway_jc":[],"hydro_ln_el":[],"hydro_ln_jc":[],"urban_roadnet_parking_lot":["urban_roadnet_parking_lot:count","urban_roadnet_parking_lot:residental","urban_roadnet_parking_lot:toll","urban_roadnet_parking_lot:bld"],"poi_medicine":["poi_nm","poi_medicine:ft_type_id","poi_medicine:url","poi_medicine:email","poi_medicine:phone","poi_medicine:addr_info","poi_medicine:open_hours","poi:business_id","poi:business_rubric_id","poi_medicine:open_type"],"poi_edu":["poi_nm","poi_edu:ft_type_id","poi_edu:url","poi_edu:email","poi_edu:phone","poi_edu:addr_info","poi_edu:open_hours","poi:business_id","poi:business_rubric_id","poi_edu:open_type"],"poi_finance":["poi_nm","poi_finance:ft_type_id","poi_finance:url","poi_finance:email","poi_finance:phone","poi_finance:addr_info","poi_finance:open_hours","poi:business_id","poi:business_rubric_id","poi_finance:open_type"],"poi_shopping":["poi_nm","poi_shopping:ft_type_id","poi_shopping:url","poi_shopping:email","poi_shopping:phone","poi_shopping:addr_info","poi_shopping:open_hours","poi:business_id","poi:business_rubric_id","poi_shopping:open_type"],"poi_goverment":["poi_nm","poi_goverment:ft_type_id","poi_goverment:url","poi_goverment:email","poi_goverment:phone","poi_goverment:addr_info","poi_goverment:open_hours","poi:business_id","poi:business_rubric_id","poi_goverment:open_type"],"poi_religion":["poi_nm","poi_religion:ft_type_id","poi_religion:url","poi_religion:email","poi_religion:phone","poi_religion:addr_info","poi_religion:open_hours","poi:business_id","poi:business_rubric_id","poi_religion:open_type"],"poi_food":["poi_nm","poi_food:ft_type_id","poi_food:url","poi_food:email","poi_food:phone","poi_food:addr_info","poi_food:open_hours","poi:business_id","poi:business_rubric_id","poi_food:open_type"],"poi_auto":["poi_nm","poi_auto:ft_type_id","poi_auto:url","poi_auto:email","poi_auto:phone","poi_auto:addr_info","poi_auto:open_hours","poi:business_id","poi:business_rubric_id","poi_auto:open_type"],"poi_sport":["poi_nm","poi_sport:ft_type_id","poi_sport:url","poi_sport:email","poi_sport:phone","poi_sport:addr_info","poi_sport:open_hours","poi:business_id","poi:business_rubric_id","poi_sport:open_type"],"poi_leisure":["poi_nm","poi_leisure:ft_type_id","poi_leisure:url","poi_leisure:email","poi_leisure:phone","poi_leisure:addr_info","poi_leisure:open_hours","poi:business_id","poi:business_rubric_id","poi_leisure:open_type"],"poi_urban":["poi_nm","poi_urban:ft_type_id","poi_urban:url","poi_urban:email","poi_urban:phone","poi_urban:addr_info","poi_urban:open_hours","poi:business_id","poi:business_rubric_id","poi_urban:open_type"],"poi_service":["poi_nm","poi_service:ft_type_id","poi_service:url","poi_service:email","poi_service:phone","poi_service:addr_info","poi_service:open_hours","poi:business_id","poi:business_rubric_id","poi_service:open_type"],"cond":["cond:cond_type","cond:cond_dt","cond:access_id"],"cond_cam":["cond_cam:cond_type","cond:cond_dt"],"transport_railway_platform":["transport_railway_platform_nm"],"cond_traffic_light":[],"transport_thread_stop":["transport_thread_stop:travel_time","transport_thread_stop:wait_time","transport_thread_stop:no_embarkation","transport_thread_stop:no_disembarkation"],"urban_roadnet_fence_el":[],"urban_roadnet_fence_jc":[],"poi_entrance":["poi_nm"],"transport_bus_route":["transport_nm","transport_bus_route:ft_type_id"],"urban_roadnet_parking_lot_linear":["urban_roadnet_parking_lot_linear:ft_type_id"],"vegetation_cnt":[],"transport_tram_thread":["transport_thread:freq_dt","transport_thread:type"],"transport_bus_thread":["transport_thread:freq_dt","transport_thread:type"],"transport_waterway_thread":["transport_thread:freq_dt","transport_thread:type"],"urban":[],"feed_region":[],"zipcode":[],"bld_complex":[]};

function loadScripts( src, callback ) {
    var script = document.createElement("SCRIPT"),
        head = document.getElementsByTagName( "head" )[ 0 ],
        error = false;
    script.id = "jQ";
    script.type = "text/javascript";
    script.onload = script.onreadystatechange = function( e ){
        if ( ( !this.readyState || this.readyState == "loaded" || this.readyState == "complete" ) ) {
            if ( !error ) {
                removeListeners();
                callback( true );
            } else {
                callback( false );
            }
        }
    };
    script.onerror = function() {
        error = true;
        removeListeners();
        callback( false );
    }; 
    function errorHandle( msg, url, line ) {
        if ( url == src ) {
            error = true;
            removeListeners();
            callback( false );
        }
        return false;
    }
    function removeListeners() {
        script.onreadystatechange = script.onload = script.onerror = null;
 
        if ( window.removeEventListener ) {
            window.removeEventListener('error', errorHandle, false );
        } else {
            window.detachEvent("onerror", errorHandle );
        }
    }
    if ( window.addEventListener ) {
        window.addEventListener('error', errorHandle, false );
    } else {
        window.attachEvent("onerror", errorHandle );
    }
    script.src = src;
    head.appendChild( script );
}

function f1(){$.ajax({
    url : "https://n.maps.yandex.ru/api/batch",
    type : "POST",
    data : {
        "branch" :  0,
        "methods" : null,
        "token" : JSON.parse(localStorage.getItem('nk:token')),
        "lang" : "ru",
        "csrf_token" : null},
    success : function(data){tok = data.meta.csrfToken; f=0; f2();},
    error : function(){f+=1; if(f<5){
        if(f<5){if(confirm('Не удалось выполнить запрос № 1. Осталось попыток: '+(5-f)+'. Попробовать снова?'))f1();}}
        else{alert('Не удалось выполнить запрос. Попробуйте позже.');}}
});}
function f2(){$.ajax({
    url : "https://n.maps.yandex.ru/api/batch",
    type : "POST",
    data : {
        "branch" :  0,
        "methods" : JSON.stringify(method),
        "token" : JSON.parse(localStorage.getItem('nk:token')),
        "lang" : "ru",
        "csrf_token" : tok},
    success : function(data){
        if(!((data.data[0].data === undefined) || (data.data[0].data === null))){
        var j = JSON.parse(localStorage.getItem('nk:app-settings'));
        var a = [{"templateId":"bld","template":{"categoryId":"rd","attrs":{},masters:{}}}];
        a[0].template.categoryId = data.data[0].data.data.geoObject.categoryId;
        if(!(categories[a[0].template.categoryId] === undefined)){for(var i = 0; i < categories[a[0].template.categoryId].length; i++){
            a[0].template.attrs[categories[a[0].template.categoryId][i]] = data.data[0].data.data.geoObject.attrs[categories[a[0].template.categoryId][i]];
        }
        if(m)a[0].template.masters = data.data[0].data.data.geoObject.masters;
        j.lastUsedGeoObjectTemplates = a;
        if(confirm("Страница будет перезагружена. Несохранённые данные будут потеряны. Продолжить?")){
        localStorage.setItem('nk:app-settings', JSON.stringify(j));
        location.reload();}}else{alert('Клонирование служебных объектов запрещено');}}else{alert('Ошибка: '+data.data[0].error.type);};
    },
    error : function(){f+=1; if(f<5){
        if(f<5){if(confirm('Не удалось выполнить запрос № 2. Осталось попыток: '+(5-f)+'. Попробовать снова?'))f2();}}
        else{alert('Не удалось выполнить запрос. Попробуйте позже.');}}
});}

function ex(){document.getElementById('okno').parentNode.removeChild(document.getElementById('okno'));}
function go(){
    var vid = parseInt(document.getElementById('inp1').value);
    if(!((vid < 1) || (vid === undefined) || (vid === null) || isNaN(vid))){
    id = vid;
    method[0].params.id = id;
    m = document.getElementById('inp2').checked;
    document.getElementById('okno').parentNode.removeChild(document.getElementById('okno'));
    var jQ = document.getElementById('jQ');
    if (jQ === null){loadScripts('https://yastatic.net/jquery/3.1.1/jquery.min.js', function(status){if (status) { f1()};});
                    }else f1();
    }else{alert('ID некорректен'); document.getElementById('exit').onclick = ex; document.getElementById('go').onclick = go; document.getElementById('inp1').onkeypress=function(e){
    if(e.keyCode==13){
        go();
    }
};
    document.getElementById('inp2').onkeypress=function(e){
    if(e.keyCode==13){
        go();
    }
};}}

var tok;
var f = 0;
var m = 1;
var sk = document.getElementById('sk');
var id = 0;
var method = [{"method":"editor/getGeoObject","params":{"id":null}}];
if (sk === null){document.getElementsByTagName('body')[0].insertAdjacentHTML('beforeEnd','<style id="sk">a.button10 {display: inline-block; color: black; font-size: 110%; text-decoration: none; user-select: none; padding: .25em .5em; outline: none; border: 1px solid rgb(250,172,17); border-radius: 7px; background: rgb(255,212,3) linear-gradient(rgb(255,212,3), rgb(248,157,23)); box-shadow: inset 0 -2px 1px rgba(0,0,0,0), inset 0 1px 2px rgba(0,0,0,0), inset 0 0 0 60px rgba(255,255,0,0); transition: box-shadow .2s, border-color .2s;} a.button10:hover { box-shadow: inset 0 -1px 1px rgba(0,0,0,0), inset 0 1px 2px rgba(0,0,0,0), inset 0 0 0 60px rgba(255,255,0,.5);} a.button10:active { padding: calc(.25em + 1px) .5em calc(.25em - 1px); border-color: rgba(177,159,0,1); box-shadow: inset 0 -1px 1px rgba(0,0,0,.1), inset 0 1px 2px rgba(0,0,0,.3), inset 0 0 0 60px rgba(255,255,0,.45);}</style>');}

document.getElementsByTagName('body')[0].insertAdjacentHTML('beforeEnd','<div id="okno" style="position: fixed; z-index: 99999; right: 600px; top: 424px;  background: #fff"><form><fieldset><legend>Создание шаблона</legend><table><tr><td>ID объекта:</td><td><input type="text" autocomplete="off" size="7" id="inp1"></td></tr></table><p><input type="checkbox" id="inp2" checked>Копировать привязку(и)</p><table><tr><td><a class="button10" id="exit">Выйти</a></td><td><a class="button10" id="go">Создать шаблон</a></td></tr></table></fieldset></form></div>');

document.getElementById('exit').onclick = ex; 
document.getElementById('go').onclick = go;
document.getElementById('inp1').onkeypress=function(e){
    if(e.keyCode==13){
        go();
    }
};
document.getElementById('inp2').onkeypress=function(e){
    if(e.keyCode==13){
        go();
    }
};

Установка стандартно через диспетчер закладок браузера (в Яндекс.Браузере и Google Chrome можно открыть комбинацией клавиш Ctrl + Shift + O).