Клуб API Карт

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

otsygankov165
1 мая 2016, 08:26

На карту нужно добавить элементы управления, такие, как на примере 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?