Как подружить Yandex карты с Google и OSM?

Как подружить Yandex карты с Google и OSM?

Есть у меня проект, который работает на основе карт от Яндекса. Выбрал я их потому, что там документация на русском, хорошее качество карт наших городов и приятный интерфейс. Позже, как оказалось, еще и большие возможности. И вот я заметил, что некоторые места Яндекс спутник показывает в слишком маленьком масштабе, что не годиться для построения маршрутов. Изначально, я сделал два отдельных файла со скриптами, в одном из которых – была логика работы с Яндексом, а во втором – с Google. Переключение происходило в профиле и действовало на весь сайт, а вся работа с картами на сайте была в псевдокоде(прокси). Esosedi.ru использовали как раз такой подход с переключением карт, но без перезагрузки. Однако такой вариант мне не подходил потому, что используются маркеры и ломанные линии, к тому же вести два разных файла трудно.

И вот я решил поискать другой вариант.

Вариант 1. Загрузка тайлов

Себе приписывать чужого не буду. Этот вариант я нашел в клубе яндекс карт clubs.ya.ru/mapsapi/replies.xml?item_no=7125. Переделав всю логику под этот вариант и, добавив уже OSM, я было обрадовался, что все готово и уже думал о другом, но тут с ужасом увидел, что карты отображаются неправильно. Координаты совпадают, но где-то часть карт не подгружаются, появляются серые места, то сверху, то снизу. Проблема была в том, что не только широта с долготой перепутаны, а используются принципиально разные системы координат. При пересчете на гугловские координаты надо было сдвинуть тайлы по вертикали на определенную величину. Вот как раз эта величина и была серой областью. В интернете писали что такой вариант не лечиться. Я пробовал увеличить карту по вертикали сверху и снизу, но скрыть ее. После я уже увидел что не только серые полоски появляются сверху, а прям на карте, линия квадратов может не подгружаться. Однако оставил я этот вариант не потому. Google разрешает использовать свои тайлы только через API, а значит придется в любом случае создавать карту, но вот как отображать метки одной карты на другой?

Вариант 2. Копирование тайлов

GEvent.addListener(gmap, "move" , function (overlay, latlng) , this ); GEvent.addListener(gmap, "tilesloaded" , function (overlay, latlng) , this ); * This source code was highlighted with Source Code Highlighter .

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

Вариант 3. Двигать карту

YMaps.Events.observe(map, map.Events.Move, function (oMap, offset) ); YMaps.Events.observe(map, map.Events.BoundsChange, function () );

* This source code was highlighted with Source Code Highlighter .

var none = new YMaps.TileDataSource( '' , false , false ); var tnone = function () < return new YMaps.Layer(none)>; YMaps.Layers.add( "none#layer" , tnone); map.setType( new YMaps.MapType([ "none#layer" ], '' ,));

* This source code was highlighted with Source Code Highlighter .

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

Вариант 3.1. Использование moveBy

Вот на этой странице api.yandex.ru/maps/jsapi/examples/synhromaps.html находится пример, как синхронизировать две Яндекс карты между собой. Вместо центрирования там используется сдвиг на определенный интервал(видимо такой вариант снижает нагрузку). У карт Google есть точно такая же функция, но значения сдвига Яндекс карты не подходит. После нескольких опытов я оставил и эту затею.

Вариант 4. Двигать маркеры

Если вариант с движением тайлов не прокатил из-за большой нагрузки, то вариант с движением объектов должен быть лучше. План схож с вариантом 3, за одним исключением: обработкой событий должен заниматься обработчик Google карт. Для этого надо скрыть слои Яндекса, отвечающий за обработку событий. И вот тут нас ждет разочарование. По непонятным причинам Гугл карты в данном варианте обрабатывают только нажатие кнопки мыши, но не передвижение и отпускание. И сколько часов я потратил на поиск результатов не сосчитать. После долгих экспериментов в попытках удалить стандартные обработчики Яндекс Карт, оказалось, что надо сделать чуть-чуть по-другому и все заработает. Для начала надо перенести Гугла карты из дива «YMaps-tile-container» в самый корень, то есть в div, в котором создается сама Яндекс карта. Теперь карту покрывает серый фон. Установим значение background дива с классом «YMaps-layer-container» в transparent. Теперь мы видим и карту и объекты, но гугл не получает событий. Установим z-index гугл карт в 1, а у дива «YMaps-layer-container» поставим auto. Пробуем… Готово!

И волки сыты и овцы целы!

Все уместилось в две функции, код которых можно увидеть ниже. Тут же можно подключить и OSM.

//Вызывается при смене карты. function unbindGoogleMap() /Вызывается при выборе Google карты function bindGoogleMap(type) $( '#googlemap' ).show(); $( '.YMaps-layer-container' ).css(); $( '.YMaps-map-type-layer-container' ).hide(); $( '.YMaps-layer YMaps-common-object-layer' ).hide(); if (!gmap) switch (type) gmap.setCenter( new GLatLng(map.getCenter().getLat(), map.getCenter().getLng()), map.getZoom()); //Двигают картой GEvent.addListener(gmap, "move" , function (overlay, latlng) , this ); //Как-то изменяют область видимости GEvent.addListener(gmap, "update" , function (overlay, latlng) , this ); //Если нажимают на контроллер зума mapevents[0] = YMaps.Events.observe(map, map.Events.BoundsChange, function () ); >

* This source code was highlighted with Source Code Highlighter .

📎📎📎📎📎📎📎📎📎📎