Страницы

Поиск по вопросам

Показаны сообщения с ярлыком yandex-maps-api. Показать все сообщения
Показаны сообщения с ярлыком yandex-maps-api. Показать все сообщения

четверг, 9 апреля 2020 г.

Как запретить масштабирование Яндекс.Карты при скролле только на мобильных устройствах?

#javascript #html #jquery #yandex_maps_api #мобильная_разработка

                    
Cкажем вот эта карта — Яндекс.Карты multiRoute.

Как запретить масштабирование карты на малых разрешениях (начиная с планшета), а
на стандартных разрешениях оставить? Чтобы при скролле пальцем не нужно было проматывать
всю карту для спуска вниз, но при этом можно было увеличивать/уменьшать масштаб с помощью +/-.

Вообще, решил так


function init() {
  var myMap = new ymaps.Map('map', {
    center: [55.76, 37.64],
    zoom: 10
  })
myMap.behaviors.disable('scrollZoom');
myMap.behaviors.disable('drag');
}

Но, вопрос остаётся: как отключить эту возможность только на мобильных устройствах, а на desktop — оставить?


Ответы

Ответ 1



Вот здесь подробно об этом - map.behavior.Manager function init() { var myMap = new ymaps.Map('map', { center: [55.76, 37.64], zoom: 10, behaviors: ["drag", "dblClickZoom", "rightMouseButtonMagnifier", "multiTouch"] }), /** * Создание мультимаршрута. * @param {Object} model Модель маршрута. Задается объектом с полями: referencePoints и params. * referencePoints - описание опорных точек мультимаршрута (обязательное поле); * params - параметры мультимаршрута. * @param {Object} [options] Опции маршрута. * @see http://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/multiRouter.MultiRoute.xml */ multiRoute1 = new ymaps.multiRouter.MultiRoute({ referencePoints: [ "Москва, метро Речной вокзал", "Москва, метро Водный стадион", ] }, { // Радиус транзитных точек на маршруте. viaPointIconRadius: 10, // Радиус точечных маркеров в путевых точках. pinIconRadius: 10, wayPointStartIconColor: "#80C257", wayPointFinishIconColor: "#8470FF", wayPointIconColor: "black", routeStrokeWidth: 2, routeActiveStrokeWidth: 6, routeStrokeColor: "000088", routeActiveStrokeColor: "#FF4500", pinIconFillColor: "#BFEFFF", viaPointIconFillColor: "#FFD39B", transportMarkerIconColor: "#FFE4E1" }), multiRoute2 = new ymaps.multiRouter.MultiRoute({ referencePoints: [ "Москва, метро Войковская", "Москва, метро Сокол" ] }, { routeStrokeWidth: 2, routeActiveStrokeWidth: 4, routeStrokeColor: "000088", routeActiveStrokeColor: "#66CDAA" }), buttonRoute1 = new ymaps.control.Button({ data: { content: "Первый маршрут" }, options: { maxWidth: 300 } }), buttonRoute2 = new ymaps.control.Button({ data: { content: "Второй маршрут" }, options: { maxWidth: 300 } }); myMap.controls.add(buttonRoute2); myMap.controls.add(buttonRoute1); myMap.geoObjects.add(multiRoute1); myMap.geoObjects.add(multiRoute2); buttonRoute1.events.add('select', function () { if (buttonRoute2.isSelected()) { buttonRoute2.deselect(); } myMap.setBounds(multiRoute1.getBounds()); }); buttonRoute2.events.add('select', function () { if (buttonRoute1.isSelected()) { buttonRoute1.deselect(); } myMap.setBounds(multiRoute2.getBounds()); }); multiRoute.model.events.add("requestsuccess", function () { var wayPoints = multiRoute1.getWayPoints(); wayPoints.get(0).properties.set('name', 'текст'); //Для метро Речной Вокзал }); } ymaps.ready(init); body { height: 100%; } #map { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }


Ответ 2



var isMobile = { Android: function() {return navigator.userAgent.match(/Android/i);}, BlackBerry: function() {return navigator.userAgent.match(/BlackBerry/i);}, iOS: function() {return navigator.userAgent.match(/iPhone|iPad|iPod/i);}, Opera: function() {return navigator.userAgent.match(/Opera Mini/i);}, Windows: function() {return navigator.userAgent.match(/IEMobile/i);}, any: function() { return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); } }; // после вызова карты if(isMobile.any()){ myMap.behaviors.disable('scrollZoom'); myMap.behaviors.disable('drag'); }

Ответ 3



В принципе, вот неплохая статья на эту тему. Там с помощью несложного скрипта и дива-обёртки данная проблема решается в несколько строк кода: https://blog.lisogorsky.ru/ignor-scroll-iframe-maps Если в двух словах, то: оборачиваем iframe в div с определённым классом, либо идентификатором. Для iframe указываем через css свойство pointr-events со значением none. Затем по клику на обёрточный div с помощью несложного JavaScript убираем свойство pointr-events

Ответ 4



Вообще, решил так map.behaviors.disable('scrollZoom'); map.behaviors.disable('drag'); Но, вопрос остается: как отключить эту возможность только на мобильных устройствах, а на десктоп оставить?

Ответ 5



Проще всего сгенерить карту через конструктор карт, и добавить флаг scroll=false, таким образом скролл (масштабирование) будет отключено. Пример:

вторник, 7 апреля 2020 г.

Яндекс пробки получить цифру

#javascript #yandex_maps_api #яндекс_карты

                    
Нужно получить балл пробок в определённом городе от Яндекс пробок.
В документации не нашёл получения отдельно бала, есть только карта с включенным уже
отображением пробок.
Есть ли возможность получить его?
    


Ответы

Ответ 1



В Яндекс.Карты API нельзя получить отдельно какой-то параметр карт с пробками, например, балл пробок, без отображения слоя пробок, а наоборот - можно (иначе нарушение правил пользования Яндекс.Картами). Подробнее тут. С другой стороны был уже подобный топик.

вторник, 31 марта 2020 г.

Не правильно строится маршрут яндекс карта (api)

#javascript #yandex_maps_api #яндекс #map #яндекс_карты


Я строю маршрут с использованием путевых и транзитных точек. Но яндекс карта не правильно
строит маршрут. Она соединяется там где не должна.

Вот ссылка на codepen и код:



function init () {

  var multiRoute = [];

  function createMultiRoute(routeData, viaData, color) {
    multiRoute.push( new ymaps.multiRouter.MultiRoute({
        referencePoints: routeData,
        params: viaData
      }, {
        editorDrawOver: false,
        wayPointDraggable: true,
        viaPointDraggable: true,
        routeStrokeColor: "000088",
        routeActiveStrokeColor: color,
        pinIconFillColor: color,
        boundsAutoApply: true,
        zoomMargin: 30
    }));
  }

  // Создаем карту с добавленными на нее кнопками.
  var myMap = new ymaps.Map('map', {
    center: [55.750625, 37.626],
    zoom: 14
  });

  createMultiRoute([
        [60.014919, 30.649850],
        [60.014958, 30.648536],
        [60.017671, 30.646447],
        [60.019146, 30.645540],
        [60.024197, 30.645711],
        [60.025782, 30.644554],
        [60.028975, 30.640299],
        [60.027754, 30.630244],
        [60.024331, 30.631359],
        [60.023627, 30.637576],
        [60.023723, 30.638850],
        [60.024200, 30.645713]
      ], {
      viaIndexes: [1,2,3,4,5,6,7,8,9,10]
      }, "ff0000");

    myMap.geoObjects.add(multiRoute[0]);

}

ymaps.ready(init);
#map {
  width: 600px;
  height: 400px;
  background: #000;
}

Как сделать так, чтобы не было подобных соединений?


Ответы

Ответ 1



Может у вас там по Плоткина одностороннее движение? Точнее, на неё нет поворота с перекрёстка. Маршрут построен правильно, чтобы пройти по точкам, приходится делать круг.. Более простой маршрут Знак на gmaps

понедельник, 30 марта 2020 г.

Создать обрамляющую обводку для полигона в яндекс картах

#javascript #yandex_maps_api #gis


В конструкторе карт Яндекса при наведении мыши на полигон появляется обрамляющий
квадрат - https://yandex.ru/map-constructor/:

Подскажите как можно реализовать такой эффект?


    


Ответы

Ответ 1



Задача полностью решается средствами API: Вам нужно слушать на многоугольниках событие наведения мыши mouseenter По наведению мыши определять прямоугольную область, в которую вписан полигон. Для этого есть метод геометрии geometry.getBounds() - он возвращает координаты прямоугольника, который можно добавить на карту. В ответ на событие mouseleave полигона нужно скрывать прямоугольник-рамку, например, методом карты myMap.geoObjects.remove(). Ниже пример для одного полигона (для "универсальности" его понадобится доработать): ymaps.ready(init); function init() { var myMap = new ymaps.Map("map", { center: [55.73, 37.75], zoom: 10 }, { searchControlProvider: 'yandex#search' }); // Создаем многоугольник, используя вспомогательный класс Polygon. var myPolygon = new ymaps.Polygon([ // Указываем координаты вершин многоугольника. // Координаты вершин внешнего контура. [ [55.75, 37.50], [55.80, 37.60], [55.75, 37.70], [55.70, 37.70], [55.70, 37.50] ], // Координаты вершин внутреннего контура. [ [55.75, 37.52], [55.75, 37.68], [55.65, 37.60] ] ], { // Описываем свойства геообъекта. // Содержимое балуна. hintContent: "Многоугольник" }, { // Задаем опции геообъекта. // Цвет заливки. fillColor: '#00FF0088', // Ширина обводки. strokeWidth: 5 }); // Добавляем многоугольник на карту. myMap.geoObjects.add(myPolygon); var boundsRectangle; myPolygon.events.add("mouseenter", function(e) { bounds = myPolygon.geometry.getBounds(); boundsRectangle = new ymaps.Rectangle(bounds, { hintContent: 'Рамка многоугольника' }, { // Опции. // Цвет и прозрачность заливки. fillColor: '#777', fillOpacity: 0, // Цвет обводки. strokeColor: '#777', strokeOpacity: 0.7, // Ширина линии. strokeWidth: 5, zIndex: 0 }); myMap.geoObjects.add(boundsRectangle); }); myPolygon.events.add("mouseleave", function() { myMap.geoObjects.remove(boundsRectangle); }); } html, body, #map { width: 100%; height: 100%; padding: 0; margin: 0; }


пятница, 28 февраля 2020 г.

Перемещение точки на карте на определенное расстояние в метрах

#javascript #алгоритм #yandex_maps_api


На карте есть несколько точек. Все эти точки требуется переместить на 30 метров от
первоначального положения.
Мысль, которая есть у меня - перевести эти 30 метров в градусы и задать новое значение
точки. Расстояние в 1 градусе, если я не ошибаюсь, около 111 км. Но результат перемещения
скорее всего будет очень не точным.
Есть ли какие-нибудь функции для упрощения этой задачи?
    


Ответы

Ответ 1



У Апи Яндекс карт есть специальный метод для этого, в документации ниже есть пример : https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/ICoordSystem-docpage/#method_detail__solveDirectProblem // Начальная точка var startPoint = [60, 30], // Движемся на северо-восток, азимут 45 градусов // или pi/4 радиан. azimuth = Math.PI / 4, // Направление движения. direction = [Math.cos(azimuth), Math.sin(azimuth)], // Путевая функция path = ymaps.coordSystem.geo .solveDirectProblem(startPoint, direction, 2e5).pathFunction;

Ответ 2



При движении по меридиану изменится широта на 30/111111 градуса, при движении по параллели на широте φ изменится долгота на 30/111111/(cos φ) Для общего случая при движении по произвольному азимуту можно воспользоваться формулами отсюда (раздел Destination point given distance and bearing from start point ) Formula: φ2 = asin( sin φ1 ⋅ cos δ + cos φ1 ⋅ sin δ ⋅ cos θ ) λ2 = λ1 + atan2( sin θ ⋅ sin δ ⋅ cos φ1, cos δ − sin φ1 ⋅ sin φ2 ) where φ is latitude, λ is longitude, θ is the bearing (clockwise from north), δ is the angular distance d/R; d being the distance travelled, R the earth’s radius JavaScript: (all angles in radians) var φ2 = Math.asin( Math.sin(φ1)*Math.cos(d/R) + Math.cos(φ1)*Math.sin(d/R)*Math.cos(brng) ); var λ2 = λ1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(φ1), Math.cos(d/R)-Math.sin(φ1)*Math.sin(φ2));

Ответ 3



Считать лучше непосредственно через Яндекс, если Вы получаете координаты от него, если для Вас критично получить точные значения. Это связано с тем, что координаты могут отличаться, в зависимости от того, какие проекции использует Яндекс при геокодировании. YandexMaps Api обладает 3мя возможностями посчитать расстояние между точками: Во фронте На бэке Через маршруты. Во фронте: ymaps.route(['Минск','Москва']); В бекенде: Если координат нет, то их можно получить через геокодер: https://geocode-maps.yandex.ru/1.x/?geocode=Москва&format=json https://geocode-maps.yandex.ru/1.x/?geocode=Минск&format=json Считаем расстояние: https://api.routing.yandex.net/v1.0.0/distancematrix?origins=55.753215,37.622504&destinations=27.561481,53.902496&mode=driving&apikey={{ваш ключ}} Но есть одно "Но". В итоге мы можем получить разные дистанции. Чтобы этого избежать следует использовать API Маршрутизатора. Этот API возвращает сразу и геометрию маршрута (полилинию), которую можно отобразить на карте. Но здесь следует учитывать тот факт, что

воскресенье, 2 февраля 2020 г.

Как вывести точки на яндекс карте на основании json файла?

#javascript #яндекс #yandex_maps_api


День добрый!
Например, вот json файл data.json

{
"Points":[{
    "MapPoinName": "Город 1",
    "MapPointPopulation": 125000,
    "MapPointCoordinates": "58.211748, 59.979321"
}, {
    "MapPoinName": "Город 2",
    "MapPointPopulation": 105000,
    "MapPointCoordinates": "51.221748, 53.929321"
}]


}

Вывожу так:



    


    Карта возможностей и проблем
    
	
    	





Данные из json получаю, но код внутри for (var i = 0; i < data.Points.length; i++) не выполняется


Ответы

Ответ 1



Вот пример JavaScript кода для вывода точек с кластеризацией: ymaps.ready(init); function init() { var map = new ymaps.Map("map", { center: [55.76, 37.57], zoom: 5, controls: ['zoomControl', 'searchControl'] }); $.getJSON('data.json', function(data) { // Создадим объект точек из data.Points var myGeoObjects = data.Points.map(item => { return new ymaps.GeoObject({ geometry: { type: "Point", // Переведем строку с координатами в массив coordinates: item.MapPointCoordinates.split(', ') }, properties: { clusterCaption: 'Описание в кластере', balloonContentBody: [ '
', '

Данные

', 'Данные: МО "Название МО"
', 'Данные: ФИО Главы МО
', '
' ].join('') } }, { preset: "islands#darkGreenDotIcon", }); }) // Создадим кластеризатор после получения и добавления точек var clusterer = new ymaps.Clusterer({ preset: 'islands#invertedDarkGreenClusterIcons', clusterDisableClickZoom: true, clusterBalloonContentLayoutWidth: 800, clusterBalloonLeftColumnWidth: 160 }); clusterer.add(myGeoObjects); map.geoObjects.add(clusterer); map.setBounds(clusterer.getBounds(), { checkZoomRange: true }); }) }

Ответ 2



Yandex api Maps имеет вот такую хорошую функцию addOverlay при помощи которой можно добавить точки на карте. Сделал стандартную инициализацию yandex api maps первой точкой сделал текущую геопозицию пользователя, Потом после парсинга json данных циклом проходим по нему и добовляем наши метки на карте, после добавления всех меток рисуем карту с заданными данными. var points_json = '{"Points":[{"MapPoinName": "Город 1","MapPointPopulation": 125000,"MapPointCoordinates": "58.211748, 59.979321"}, {"MapPoinName": "Город 2","MapPointPopulation": 105000,"MapPointCoordinates": "51.221748, 53.929321"}]}'; var points = $.parseJSON(points_json); // Создание обработчика для события window.onLoad YMaps.jQuery(function () { // Создание экземпляра карты и его привязка к созданному контейнеру var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]), // Центр карты center, // Масштаб zoom = 10; // Получение информации о местоположении пользователя if (YMaps.location) { center = new YMaps.GeoPoint(YMaps.location.longitude, YMaps.location.latitude); if (YMaps.location.zoom) { zoom = 3; } map.openBalloon(center, "Место вашего предположительного местоположения:
" + (YMaps.location.country || "") + (YMaps.location.region ? ", " + YMaps.location.region : "") + (YMaps.location.city ? ", " + YMaps.location.city : "") ) }else { center = new YMaps.GeoPoint(37.64, 55.76); } for(var i=0;i < points.Points.length;i++){ var tmp_points = points.Points[i]['MapPointCoordinates'].split(', '); var placemark = new YMaps.Placemark(new YMaps.GeoPoint(tmp_points[0],tmp_points[1])); placemark.description = "point "+i+" description"; map.addOverlay(placemark); center = new YMaps.GeoPoint(tmp_points[0], tmp_points[1]); } // Рисуем карту map.setCenter(center, zoom); });
Более подробно об этом можете прочитать здесь.

пятница, 24 января 2020 г.

Не биндятся данные на балун

#yandex_maps_api #knockoutjs #yandexmapkit


Использую KnockoutJS и Яндекс Карты.

Данные на страницу биндятся, а в балун нет. Можно ли так биндить данные на яндекс
карту? Если нет, то какое решение подскажите, может библиотека какая есть?

Пример:






    Showing pixel and tile coordinates
    
    
    
    
    
    


    
# Заголовок Содержимое


Ответы

Ответ 1



myPlacemark.events.add('balloonopen', function (args) { // TODO reapply knockout bindings });

суббота, 11 января 2020 г.

В чем заключается отличие Яндекс Map Kit от Яндекс Карты API?

#java #android #yandex_maps_api #яндекс_карты #yandexmapkit


Стоит задача: добавить карты Яндекс в мобильное приложение. В ходе поиска информации
выяснил, что это можно сделать двумя способами: Яндекс Map Kit и Яндекс Карты API.
В чем состоит их отличие? Что из этого лучше использовать для мобильного приложения
на Android? Работаю в Android Studio, пишу на Java.
    


Ответы

Ответ 1



яндекс карты API - веб апи (для сайтов чаще всего) yandex mapkit - sdk для приложений, есть конкретно под Android, в данном случае он и требуется.

четверг, 9 января 2020 г.

Как использовать геотаргетинг яндекса без карты?

#javascript #yandex_maps_api #геолокация #геокодирование


Определяю местоположение пользователя так:




    
        
    
    
        
        
        
Как в данном примере не создавать карту в DOM? Если убираю div(точнее id="YMapsID"), то возникает ошибка Uncaught TypeError: Cannot read property 'push' of undefined Если убираю - переменную map - тоже ошибка. Установить св-во hidden - тоже не хотелось бы.


Ответы

Ответ 1



Вот и вариант когда мы только получаем данные геопозиции пользователя, и не инициализируем карту. Делаем только инициализацию YMaps и после этого он уже получает данные геопозиции пользователя, В примере я после этого просто вывел эти данные в console․


Нарисовать полукруг / сектор круга на карте

#yandex_maps_api #yandex_maps_jsapi


Можно ли с помощью API создать полуокружность на карте или сектор (не в виде треугольника,
а чтобы на конце была дуга), посоветуйте как это сделать.

В качестве известных данных. Радиус, Направление, угол ф, начальная точка. Знаю что
есть прямая и обратная геодезическая задача, но у меня нет конечной точки, только расстояние
и направление. По большому счёту интересует вопрос отрисовки секторов на карте.
    


Ответы

Ответ 1



Можно просто нарисовать полигон нужной формы. Самое простое решение выглядит так: http://jsfiddle.net/tLs0d51u/ Но там получился не совсем круг, поскольку круг формируется в сферических координатах (в широте и долготе), а не в декартовых. Чтобы нарисовать нормальный круг, нужно работать с глобальными пиксельными координатами, а затем перевести их в сферические. Это можно сделать так: var zoom = map.getZoom(); var projection = map.options.get('projection'); // широта и долгота -> пиксели projection.toGlobalPixels([55.73, 37.75], zoom); // пиксели -> широта и долгота projection.fromGlobalPixels([158560.7111111111, 82211.42703728657], zoom); Сектор нормального круга: http://jsfiddle.net/tLs0d51u/1/

Ответ 2



Отрисовывал сектор через решение прямой геодезической задачи, при этом в исходных данных имел радиус, угол, координаты начальной точки. function getAreaCoord(point, azimut, corner, length) {// получение координат сектора var sector = []; var firstSide = Math.PI * ((360 - azimut) + 90) / 180, // азимут в радианах secondSide = firstSide - (Math.PI * corner / 180), dir2 = [Math.sin(firstSide), Math.cos(firstSide)]; // направление по азимуту sector[0] = ymaps.coordSystem.geo.solveDirectProblem(point, dir2, length).endPoint; var i = 1; for(var sectopPoint = 5; sectopPoint <= corner; sectopPoint += 5) { var middlePoint = sectopPoint; var side = firstSide - (Math.PI * middlePoint / 180); var dir4 = [Math.sin(side), Math.cos(side)]; sector[i] = ymaps.coordSystem.geo.solveDirectProblem(point, dir4, length).endPoint; i++ } return sector; }

вторник, 7 января 2020 г.

Как установить яндекс карту на фон слоя?

#javascript #html #css #yandex_maps_api


Необходимо чтобы у определенного слоя или у всего сайта на фоне была яндекс карта.
    


Ответы

Ответ 1



Вот пример http://jsfiddle.net/znf4pbbd/ // Как только будет загружен API и готов DOM, выполняем инициализацию ymaps.ready(init); function init () { // Создание экземпляра карты и его привязка к контейнеру с // заданным id ("map") var myMap = new ymaps.Map('map', { // При инициализации карты, обязательно нужно указать // ее центр и коэффициент масштабирования center: [56.326944, 44.0075], // Нижний Новгород zoom: 13 }); } *{ padding: 0; margin: 0; box-sizing: border-box; } html { height:100% } body { height: 100%; margin:0px; padding:0px } #map{ height:100%; width: 100%; position: absolute; top: 0; left: 0; } .content{ width: 300px; min-height: 200px; margin: 0 auto; background: #fff; position: relative; z-index: 1; }


пятница, 27 декабря 2019 г.

Как ограничить область поиска в Яндекс Картах?

#javascript #yandex_maps_api


Как можно ограничить область поиска на Яндекс Картах? То есть, чтобы искал в отдельном
прямоугольнике, заданным координатами, либо отдельно по городу? Я пробовал сделать
так, эффекта ноль (пример взят из документации Яндекс.Карт)

myMap.setBounds([
                  /* Координаты юго-западного угла области просмотра
                     карты */
                  [56.366411 , 60.032195],
                  /* Координаты северо-восточного угла области
                       просмотра карты */
                  [56.584157, 60.463256]
                  ], {
                      // Включить проверку доступного
                      // диапазона масштабов (исключает
                      // возможность попасть в "серые тайлы")
                      checkZoomRange: true,
                      // Можно анимировать перемещение карты
                      duration: 500
                  }
                );
var myGeocoder = ymaps.geocode(
                      /* Строка с адресом, который нужно
                         геокодировать */
                      "Екатеринбург", {
                        /* Опции поиска:
                            - область поиска */
                        boundedBy: myMap.getBounds(),
                        // - искать только в этой области
                        strictBounds: true,
                        // - требуемое количество результатов
                        results: 1
                    });

                /* После того, как поиск вернул результат, вызывается
                   callback-функция */
                myGeocoder.then(function (res) {
                  /* Размещение полученной коллекции 
                     геообъектов на карте */
                  myMap.geoObjects.add(res.geoObjects);
                });

    


Ответы

Ответ 1



Все работает как описано в документации. Может у вас в заданном прямоугольнике нету искомого объекта. В этом случае ничего не будет найдено и не будет добавлено меток на карту. Я попробовал найти объект, который явно присутствует на карте и он нашелся. Вот, для примера, поиск улицы Ленина в некоторых городах (сначала думал искать площадь Ленина, но Челябинск оказался настолько суров что там такой площади нету). ymaps.ready(function() { var myMap, cityList, lookAtLenin; myMap = new ymaps.Map('map', { center: [56.70, 60.20], zoom: 10 }); cityList = new ymaps.control.ListBox({ data: { content: 'Выбрать город' }, items: [ new ymaps.control.ListBoxItem({ data: { content: 'Екатеринбург' }, options: { selectOnClick: false } }), new ymaps.control.ListBoxItem({ data: { content: 'Москва' }, options: { selectOnClick: false } }), new ymaps.control.ListBoxItem({ data: { content: 'Челябинск' }, options: { selectOnClick: false } }), ] }); cityList.get(0).events.add('click', function() { lookAtLenin('Екатеринбург'); }); cityList.get(1).events.add('click', function() { lookAtLenin('Москва'); }); cityList.get(2).events.add('click', function() { lookAtLenin('Челябинск'); }); myMap.controls.add(cityList, { floatIndex: 0 }); lookAtLenin = function(city) { var cityCenter = { 'Екатеринбург': [56.79, 60.61], 'Москва': [55.66, 37.64], 'Челябинск': [55.15, 61.50] }; myMap.setCenter(cityCenter[city], 9, { checkZoomRange: true, duration: 500 }).then(function(res) { return ymaps.geocode('ул. Ленина', { boundedBy: myMap.getBounds(), strictBounds: true, results: 1 }); }).then(function(res) { myMap.geoObjects.add(res.geoObjects); }); }; });


Ответ 2



У меня заработало, когда убрал из кода примера кусок: , { // Включить проверку доступного // диапазона масштабов (исключает // возможность попасть в "серые тайлы") checkZoomRange: true, // Можно анимировать перемещение карты duration: 500 }

среда, 25 декабря 2019 г.

Callback загрузки карты yandex map

#javascript #yandex_maps_api


Имеется пустая страница с картой для печати. С помощью window.print() вызывается
на печать. Проблема заключается в том, что карта не успевает отрисоваться. Никак не
могу нагуглить и нарыть в их замечательной документации какой-то вариант события или
callback'a именно на готовность карты.  

Есть предложения, коллеги?

ymaps.ready(function() {
  ymaps.ready(init);
  var map,
    object;

  function init() {
    var center = settings.map.center,
      zoom = parseInt(settings.map.zoom),
      coords_point = settings.map.coords_point;

    center = center.split(',').map(parseFloat);
    coords_point = coords_point.split(',').map(parseFloat);

    map = new ymaps.Map('yamap', {
      center: center,
      zoom: zoom,
      controls: [],
    });

    object = new ymaps.GeoObject({
      geometry: {
        type: "Point",
        coordinates: coords_point
      },
    }, {
      preset: 'custom#point_green',
    });

    map.geoObjects.add(object);
  }

  ymaps.option.presetStorage.add('custom#point_green', {
    iconLayout: 'default#image',
    iconImageHref: settings.themePath + '/img/yamap_point_g.png',
    iconImageSize: [48, 41],
    iconImageOffset: [-15, -41],
    hideIconOnBalloonOpen: false,
  });
});


Обновление

Пример вызова window.print():

Пример на JsFiddle



ymaps.ready(function() {
  ymaps.ready(init);
  var map,
    object;

  function init() {
    var center = "56.83676954481658,60.61677207117298",
      zoom = 15,
      coords_point = "56.836098132297586,60.61771118192043";

    center = center.split(',').map(parseFloat);
    coords_point = coords_point.split(',').map(parseFloat);

    map = new ymaps.Map('yamap', {
      center: center,
      zoom: zoom,
      controls: [],
    });

    object = new ymaps.GeoObject({
      geometry: {
        type: "Point",
        coordinates: coords_point
      },
    });

    map.geoObjects.add(object);
  }
});

window.print();
#yamap {
  width: 300px;
  height: 200px;
}


Ответы

Ответ 1



Поместите хотя бы window.print() внутрь ymaps.ready() и вместо ymaps.ready(init) вызывайте просто init(). Дополнено Событий, однозначно показывающих полное окончание всех процедур составления карты пока нет. Однако, как показывает практика, загрузка карты заканчивается загрузкой всех тайлов. И в документации есть описание как можно добавлять новые слои с тайлами. Это делается при помощи классов layer.tileContainer.CanvasContainer и layer.tileContainer.DomContainer. У этих-то классов есть событие ready, которое вызывается когда все тайлы слоя загружены. И они даже используются при отображении карт, но до их экземпляра не так просто добраться. Если вы ничего не делаете со слоями, то на карте есть один единственный слой (если слоев все-таки несколько, придется обрабатывать все слои в циклах), к которому можно достучаться вот так var layer = map.layers.get(0).get(0); /* Сначала мы получаем первый экземпляр коллекции слоев, потом первый слой коллекции */ Так мы получаем экземпляр Layer, но в его описании нету ничего про tileContainer, однако это поле там есть, только оно как бы приватное и при минимизации становится неудобоваримым (в debug версии это поле _tileContainer). Чтобы его найти можно воспользоваться вот такой функцией: function getTileContainer(layer) { for (var k in layer) { if (layer.hasOwnProperty(k)) { if ( layer[k] instanceof ymaps.layer.tileContainer.CanvasContainer || layer[k] instanceof ymaps.layer.tileContainer.DomContainer ) { return layer[k]; } } } return null; } Теперь можно сделать так: var tc = getTileContainer(layer); tc.events.once("ready", function() { // Вызываем, например, печать документа window.print(); }); Одно плохо. Мы не узнаем о загрузке всех тайлов если выяснится, что мы не успели начать слушать событие до окончания загрузки тайлов. Неплохо было бы знать вообще чего-то ждем или нет. Для этого перед "подслушиванием" события нужно узнать есть-ли "неготовые" тайлы. Это можно проверить если перебрать все тайлы в контейнере и вызвать методы isReady() для layer.tile.CanvasTile или layer.tile.DomTile, после этого, если неготовые тайлы есть подключать событие. Будет удобно сделать такую функцию, которая будет возвращать промис. function waitForTilesLoad(layer) { return new ymaps.vow.Promise(function (resolve, reject) { var tc = getTileContainer(layer), readyAll = true; tc.tiles.each(function (tile, number) { if (!tile.isReady()) { readyAll = false; } }); if (readyAll) { resolve(); } else { tc.events.once("ready", function() { resolve(); }); } }); } В вашем случае этой функцией можно воспользоваться так: waitForTilesLoad(layer).then(function() { window.print(); });

Ответ 2



Привожу код, написанный @tutankhamun. // Здесь ваша загрузка карты. Ниже допишем строки. /* Поймаем событие завершения загрузки карты. */ // Сначала мы получаем первый экземпляр коллекции слоев, потом первый слой коллекции. var layer = myMap.layers.get(0).get(0); // Отслеживаем событие окончания отрисовки тайлов. waitForTilesLoad(layer).then(function() { // Вызываем, например, печать документа window.print(); alert('Карта загружена'); }); } // Получить слой, содержащий тайлы. function getTileContainer(layer) { for (var k in layer) { if (layer.hasOwnProperty(k)) { if ( layer[k] instanceof ymaps.layer.tileContainer.CanvasContainer || layer[k] instanceof ymaps.layer.tileContainer.DomContainer ) { return layer[k]; } } } return null; } // Определить, все ли тайлы загружены. Возвращает Promise. function waitForTilesLoad(layer) { return new ymaps.vow.Promise(function (resolve, reject) { var tc = getTileContainer(layer), readyAll = true; tc.tiles.each(function (tile, number) { if (!tile.isReady()) { readyAll = false; } }); if (readyAll) { resolve(); } else { tc.events.once("ready", function() { resolve(); }); } }); }

воскресенье, 22 декабря 2019 г.

Как определить текущее местоположение пользователя и что лучше использовать?

#javascript #google_maps_api #yandex_maps_api #геолокация


Есть интернациональный проект. При совершении пользователем определенных действий,
необходимо получать данные о его местоположении (страна, город, улица(если возможно)),
и после уже отсылаем эти данные на наш сервер. Я видел примеры от гугл и яндекс карт,
там можно получить координаты. Я все же более склонен к использованию гугла. 

Есть ли пример получения этих данных при этом сделав как можно меньше запросов?

P.S. При этом мне не нужно что-либо отрисовывать на карте и рисовать саму карту
    


Ответы

Ответ 1



Силами HTML5 — navigator.geolocation.getCurrentPosition(). Браузер спрашивает у пользователя разрешение и в случае согласия отдает ОЧЕНЬ (в большинстве случаев) точные данные в виде широты и долготы. Потом это можно скормить https://developers.google.com/maps/documentation/geocoding/intro без карты. upd 2018: данный способ работает для https-сайтов Определять по IP. Есть бесплатная (но не самая полная) база — https://dev.maxmind.com/ru/geolite2/ Вот есть библиотека под нее — https://github.com/maxmind/GeoIP2-php В этом случае данные доступны сразу, но они не точные (Страна, город).

Ответ 2



Если на js, могу дать совет воспользоваться запросом, на сторонний сервис, после чего получить json данные с него, через jsonp.
На codepen: https://codepen.io/AndreyMyP/pen/gzXVXV

Ответ 3



Яндекс, кстати, предоставляет "API Geocoder" для HTTP запросов: https://tech.yandex.ru/maps/doc/geocoder/desc/concepts/input_params-docpage/ Ответ геокодера может быть сформирован в следующих форматах: XML, согласно спецификации YMapsML; JSON или JSONP. Чтобы начать работать с HTTP API Геокодера, нужно получить ключ для пакета «JavaScript API и HTTP Геокодер». Но есть ограничение на кол-во бесплатных запросов 25тыс в сутки. И определенные условия, например проект должен находиться в открытом доступе, т.е. если есть регистрация, то она должна быть открыта для всех.

пятница, 20 декабря 2019 г.

Получить адрес по координатам в Yandex maps

#яндекс #yandex_maps_api


Подскажите, пожалуйста, как можно по гео координатам получить адрес?

Т.е. есть координаты 30.524933, 50.447218 и нужно определить адрес или объект в данном
случае - Украина, Киев, метро Крещатик. В гугле искал, все ищут наоборот.
    


Ответы

Ответ 1



В яндекс картах есть как прямой так и обратный геокодер. Прямой - это когда по адресу определяем координаты. Обратный, соответственно, обратно. Вот ссылка на документацию: geocode. Вот тут есть пример использования геокодера как прямого так и обатного Примеры использования JavaScript API. Еще примеры: Помещение в balloonContentBody адреса. Используя обратное геокодирование, вывести полный адрес.

Ответ 2





понедельник, 16 декабря 2019 г.

Яндекс апи: Как определить город?

#javascript #yandex_maps_api #геолокация





Также на этапе 2 можно добавить "по вкусу" цвет фона, обводку, прозрачность и многое
другое см. Polygon


вторник, 26 ноября 2019 г.

Выделение произвольной области на яндекс картах(не полигон)


Как сделать выделение произвольной области, как на domofond.ru? Удерживая нажато
левую кнопку мыши, двигаем курсор. Когда отпускаем, крайние точки замыкаются прямой, если фигура получилась незамкнутой. 

Хочется реализовать так же, НЕ используя полигон и полилайн. Понятно, что в конечном итоге получится всё-равно полигон из очень маленьких отрезков. 

Готовых решений не нашел. Все рекомендуют полигон, однако, повторюсь, он не подходит.

Допустим, я нарисую кривую на канвасе. Как разделить эту кривую на отрезки и ка
определить координаты точек на этой кривой? В какую сторону копать? 

    


Ответы

Ответ 1



Внимание - в конце сообщения - обновление! Если вы рисуете карандашом - то, по сути, это набор точек, или полилиния - только с маленьким шагом. Как я понял проблема в аппроксимации этого набора точек. Есть такая библиотека Simplify.js, она может упростить набор точек в ломанную линию. Работает это по алгоритму Алгоритм Рамера — Дугласа — Пекера Вот написал пример его работы - рисуйте на области канваса мышкой. var canv = document.getElementById('canv'), ctx = canv.getContext('2d'), line = []; var startX = 0, startY = 0; function mouseDown(e) { ctx.clearRect(0, 0, canv.width, canv.height); startX = e.pageX - e.target.offsetLeft; startY = e.pageY - e.target.offsetTop; canv.addEventListener('mouseup', mouseUp); canv.addEventListener('mousemove', mouseMove); line = []; line.push({ x: startX, y: startY }); } function mouseMove(e) { var x = e.pageX - e.target.offsetLeft, y = e.pageY - e.target.offsetTop; ctx.beginPath(); ctx.moveTo(startX, startY); ctx.lineTo(x, y); ctx.stroke(); startX = x; startY = y; line.push({ x: x, y: y }); } function mouseUp() { canv.removeEventListener('mouseup', mouseUp); canv.removeEventListener('mousemove', mouseMove); aproximate(); } function aproximate() { ctx.clearRect(0, 0, canv.width, canv.height); var res = simplify(line, 5); console.log(res); ctx.save(); ctx.strokeStyle = 'red'; ctx.beginPath(); ctx.moveTo(res[0].x, res[0].y); res.forEach(function(el) { ctx.lineTo(el.x, el.y); }); ctx.stroke(); ctx.restore(); } canv.addEventListener('mousedown', mouseDown); canvas { border: 1px solid #aaa; } Обновление: Набросок кода для рисования подобных линий на карте Извиняюсь, что не очень красивый код - торопился. var Map = (function() { ymaps.ready(init); var myMap; function init() { myMap = new ymaps.Map("map", { center: [57.5262, 38.3061], // Углич zoom: 11 }, { balloonMaxWidth: 200, searchControlProvider: 'yandex#search' }); addPolygon() } function convert(coords) { var projection = myMap.options.get('projection'); return coords.map(function(el) { var c = projection.fromGlobalPixels(myMap.converter.pageToGlobal([el.x, el.y]), myMap.getZoom()); return c; }); } function addPolygon(coord) { var myGeoObject = new ymaps.GeoObject({ geometry: { type: "Polygon", coordinates: [coord], }, }, { fillColor: '#00FF00', strokeColor: '#0000FF', opacity: 0.5, strokeWidth: 3 }); myMap.geoObjects.add(myGeoObject); } return { addPolygon: addPolygon, convert: convert }; })(); //---------------------- var canv = document.getElementById('canv'), ctx = canv.getContext('2d'), line = []; var map = document.getElementById('map'); canv.width = map.offsetWidth; canv.height = map.offsetWidth; var startX = 0, startY = 0; function mouseDown(e) { ctx.clearRect(0, 0, canv.width, canv.height); startX = e.pageX - e.target.offsetLeft; startY = e.pageY - e.target.offsetTop; canv.addEventListener('mouseup', mouseUp); canv.addEventListener('mousemove', mouseMove); line = []; line.push({ x: startX, y: startY }); } function mouseMove(e) { var x = e.pageX - e.target.offsetLeft, y = e.pageY - e.target.offsetTop; ctx.beginPath(); ctx.moveTo(startX, startY); ctx.lineTo(x, y); ctx.stroke(); startX = x; startY = y; line.push({ x: x, y: y }); } function mouseUp() { canv.removeEventListener('mouseup', mouseUp); canv.removeEventListener('mousemove', mouseMove); aproximate(); } function aproximate() { ctx.clearRect(0, 0, canv.width, canv.height); var res = simplify(line, 5); res = Map.convert(res); Map.addPolygon(res); } canv.addEventListener('mousedown', mouseDown); html, body, #map { width: 100%; height: 100%; padding: 0; margin: 0; overflow: hidden; } canvas { border: 1px solid #aaa; position: absolute; z-index: 99999; top: 0; left: 0; }


Ответ 2



Скорее всего, вам подойдет Polyline (документация). Очень просто будет получить координаты всех точек и обработать их как вам угодно.

Ответ 3



Изначально хотел предложить повесить канвас поверх карт, потом увидел, что polylin позволяет получить желаемый результат, если конечно нет необходимости именно как карандашом проводить линии. Вот пример: http://jsfiddle.net/at138o5y/
Скрипт: var polyline; ymaps.ready(init); function init () { var myMap = new ymaps.Map('map', { center: [55.426541,37.768788], zoom: 13 }); myMap.controls .add('zoomControl') .add('typeSelector') .add('mapTools') polyline = new ymaps.Polyline([], {}, {}); myMap.geoObjects.add(polyline); polyline.editor.startEditing(); polyline.editor.startDrawing(); }

вторник, 16 июля 2019 г.

Яндекс карты: менять в зависимости от размеров экрана

Здравствуйте! Подскажите, пожалуйста, как можно сделать яндекс карту, что бы менялась в зависимости от размеров экрана.? Я знаю, что это можно сделать, а вот как?? Может вы знаете:)


Ответ

может поможет, кому то... нашла ответ... нужно просто задать ширину в % и высоту фиксированную(родительскому контейнеру карты), что бы можно было отсчитывать %.. А для того что бы изменялась высота нужно через js вычислять....

суббота, 13 июля 2019 г.

Переместить метку Яндекс.Карты 2.1

Приветствую. Есть отличный пример по изменению координат.
Как его дополнить, что бы при первом клике появлялся маркер (отметка) и при клике в другое место карты он переставлялся?
Заранее прошу подробно, т.к. новичок.


Ответ

Например так:
ymaps.ready(init); var myMap, myPlacemark; function init() { myMap = new ymaps.Map('map', { center: [57.5262, 38.3061], // Углич zoom: 13 }); myPlacemark = new ymaps.Placemark(); myMap.events.add('click', function(e) { myPlacemark.geometry.setCoordinates(e.get('coords')); // устанавливаем метке координаты, высчитанные из положения клика myMap.geoObjects.add(myPlacemark); // ставим метку на карту }); } html, body, #map { width: 100%; height: 100%; padding: 0; margin: 0; }