Клуб API Карт

Пользовательские элементы управления

Пост в архиве.

На карту нужно добавить элементы управления, такие, как на примере API 1.x: https://yandex.github.io/mapsapi-examples-old/html/reversegeocoderinformation.html.

Как сделать чтобы активным был только один элемент? Так,например, при нажатии "Информация" деактивировалась, напрмер, стандартная кнопка "Линейка", но, при этом, чтобы еще оставались независимые кнопки.

15 комментариев
Есть пример собственного контрола в 2.1
https://tech.yandex.ru/maps/jsbox/2.1/custom_control


dimik,
Как создать контрол, я знаю. Я не знаю, как связать контролы. В 2.0 это было возможно и просто.
Я делал так:


// новый класс infoButton - кнопка режима отображения координат на карте
function infoButton(params,options){
infoButton.superclass.constructor.call(this,params,options);
}


....


    // инициализация класса infoButton
ymaps.util.augment(infoButton,ymaps.control.Button,{
onAddToMap:function(){
infoButton.superclass.onAddToMap.apply(this,arguments);
this.events.add('select',this._onSelect,this);
this.events.add('deselect',this._onDeselect,this);
},
onRemoveFromMap:function(){
var m=this.getMap();
if(this.cursor){this.cursor.remove();}
if(m.balloon.isOpen()){m.balloon.close();};
m.events.remove('click',this._onMapClick,this);
this.events.remove('select',this._onSelect,this);
this.events.remove('deselect',this._onDeselect,this);
infoButton.superclass.onRemoveFromMap.apply(this,arguments);
},
_onSelect:function(e){
var m=e.get('target').getMap();
this.cursor=m.cursors.push('help');
m.events.add('click',this._onMapClick,this);
},
_onDeselect:function(e){
var m=e.get('target').getMap();
if(this.cursor){this.cursor.remove();}
if(m.balloon.isOpen()){m.balloon.close();};
m.events.remove('click',this._onMapClick,this);
},
_onMapClick:function(e){
if(!this.stopEvents){ // не будут обрабатываться все последующте запросы на геокодирование, пока не отрабатается текущий
this.stopEvents=true;
var coords=e.get('coords');
var m=this.getMap();
e.stopPropagation(); // останов распространения события
var b=m.balloon.open(coords,{content:'поиск...'},{closeButton:true});
ymaps.geocode(coords,{
results: 1
}).then(function(res){
var geoResult=res.geoObjects.get(0);
if(geoResult){
b.setData({content:"<b>"+geoResult.properties.get('name')+"</b><div>"+geoResult.properties.get('description')+"</div>"});
m.doClick('openBalloon',coords[0],coords[1]);
}
},function(err){b.setData({content:"<b>Нет данных по объекту</div>"})});
this.stopEvents=false;
}
}


Далее, при инициализации карты theMap:
...
 theMap.mapTools=new ymaps.control.MapTools({items:["default",new infoButton({
data:{
image:'моя картинки.jpg',
title:'Информация об объекте'
}
},{
selectOnClick:true,
parent:this
})]})
.....


И все. Моя infoButton автоматом попадала в связку с "рукой" и "линейкой".


Теперь же, не могу найти как.
otsygankov165,
В 2.1 нет радиогруппы. Я написал свою для инструмента определения координат. 


https://github.com/dimik/ymaps/blob/gh-pages/examples/2.1/location-tool/src/control/radioGroup/RadioGroup.js
dimik,
Так я тоже делал.... Точнее, именно так сейчас у меня и сделано. Только коллекция вместо радиогруппы. А где универсальность? А где гибкость для последующего использования? Будет новый заказ, придется поднимать свои исходники и убывать время, чтобы вспомнить, что же я хотел сказать таким кодом. 
otsygankov165,
Гибкость и универсальность в использовании модульной системы. 
dimik,
Да итак целый фреймворм написал с недостающим функционалом. Надо сказать, 2.1 значительно проигрывает по сравнению с 2.0. Много полезного убито.

dimik,
Сразу, в догонку еще вопрос. По поводу инициализации карты.
В 2.0 я создавал карту со своими координатами в центре по ip следующим образом:
var theMap;

ymaps.ready(function(){
theMap=new ymaps.Map("map",{
center:[ymaps.geolocation.latitude,ymaps.geolocation.longitude], // Определение координат по ip
zoom:10,
behaviors:['default','scrollZoom']
});
}
Теперь приходится вот так:
var theMap;

ymaps.ready(function(){
ymaps.geolocation.get().then(function(result){
// Пытаемся рассчитать видимую область для текущего положения пользователя
createMap(result.geoObjects.get(0).geometry.getCoordinates());
},function(e){
// Если местоположение невозможно получить, то просто создаем карту.
createMap([55.751574,37.573856]);
}),

function createMap(coord){theMap=new ymaps.Map('map',{
center:coord,
zoom:10,
behaviors:['default','scrollZoom'],
controls:['zoomControl','geolocationControl','trafficControl','typeSelector','rulerControl','searchControl']
},{
searchControlNoPlacemark:true, //не добавлять метку при выборе результат поиска
searchControlProvider:'yandex#map',
searchControlSize:'large'
}
);

}
Это правильно? Асинхронный вызов в асинхронном? Тогда становится проблематичным отлавливать момент завершения формирования карты.
otsygankov165,


1. Используйте промисы, все станет сильно проще и без вложенных вызовов.
2. Надо отключать автогеокодирование при геолокации, тогда он 100% будет находить
dimik,
1. Придется
2. Если на стороне клиента, то мои проекты отличны от веб-проектов

otsygankov165,
там есть опция autoReverseGeocode: false 
https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/geolocation-docpage/#get-param-options.autoReverseGeocode



АПИ можно использовать только в мобильных приложениях и на сайтах, – все остальное – нарушает Условия Использования
dimik,
Это проблемы заказчика
dimik,
А за первый пункт преогромнейшее спасибо!
dimik,
в вашем примере http://dimik.github.io/ymaps/examples/2.1/location-tool/ линейка тоже живет своей жизнью.
otsygankov165,
Она не входит в радиогруппу, только кнопки сверху
dimik,
спасибо, я уже "расковырял" исходники... Чтобы добавить "Линейку" в Вашу группу, можно использовать control.RulerControl?