YandexマップをGoogleとOSMで友達にする方法は?





Yandexのマップに基づいて動作するプロジェクトがあります。 私が選んだのは、ロシア語のドキュメンテーション、私たちの都市の良質な地図、そして素晴らしいインターフェースがあるからです。 後になって判明したように、素晴らしい機会もありました。

そのため、Yandex衛星はあまりにも小さなスケールでいくつかの場所を示しており、ルートの構築には適していないことに気付きました。

最初に、2つのスクリプトファイルを作成しました。1つはYandexで、もう1つはGoogleで作業するロジックを備えていました。 切り替えはプロファイルで発生し、サイト全体で行われ、サイト上のマップのすべての作業は擬似コード(プロキシ)で行われました。

Esosedi.ruは、このようなアプローチをカードの切り替えに使用しましたが、再起動はしませんでした。 ただし、マーカーと破線が使用されており、2つの異なるファイルを維持するのが難しいため、このオプションは私には不向きでした。



そして、私は別のオプションを探すことにしました。



オプション1:タイルをダウンロードする



私は見知らぬ人だとは思いません。 Yandexクラブclub clubs.ya.ru/mapsapi/replies.xml?item_no=7125でこのオプションを見つけました。 このオプションのすべてのロジックをやり直し、OSMを既に追加したため、すべての準備が整っており、すでに他のことを考えていたことがうれしかったのですが、その後、カードが正しく表示されないことがわかりました。 座標は同じですが、マップの一部がロードされていない場合、灰色のスポットが表示される場合があります。時には上から、下から表示されます。 問題は、緯度と経度が混同されただけでなく、根本的に異なる座標系が使用されたことでした。 Google座標に変換すると、タイルを一定量だけ垂直にシフトする必要がありました。 これはこの値であり、灰色の領域でした。

彼らはインターネット上で、このオプションは扱われないと書いた。 地図を上下に垂直に拡大しようとしましたが、非表示にしました。 グレーのストライプが上に表示されるだけでなく、マップのすぐ上に表示されることを確認した後、正方形の線が読み込まれない場合があります。 ただし、このオプションは残しませんでした。

Googleでは、APIを介してのみタイルを使用できます。つまり、とにかく地図を作成する必要がありますが、ある地図のラベルを別の地図にマッピングするにはどうすればよいですか。



オプション2.タイルのコピー



計画はこれでした。

Googleマップインスタンスは、負のインデックス、またはtopまたはleftの負の値を使用して、遠く、遠く、むしろどこかに作成されます。 その後、イベントハンドラーがYandexマップにハングアップし、Yandexマップが移動すると、Googleマップが移動します。 Googleマップにはモーションハンドラーがあります。このハンドラーでは、マップを含むdivが、Yandexタイルを含む「YMaps-tile-container」クラスを使用してYandexマップdivにコピーされます。

GEvent.addListener(gmap, "move" , function (overlay, latlng) {

var point = gmap.getCenter();

$layer = $( '#googlemap div img' ).parent().parent().parent();

$( '.GMaps-tile-container' ).html($layer.html()).width($layer.width()).height($layer.height());

$( '.GMaps-tile-container' ).css( 'left' ,$( '.YMaps-tile-container' ).css( 'left' ))

.css( 'top' ,$( '.YMaps-tile-container' ).css( 'top' ))

.css( 'width' ,$( '.YMaps-tile-container' ).css( 'width' ))

.css( 'height' ,$( '.YMaps-tile-container' ).css( 'height' ));

$( '.YMaps-tile-container' ).hide();

}, this );

GEvent.addListener(gmap, "tilesloaded" , function (overlay, latlng) {

var point = gmap.getCenter();

$layer = $( '#googlemap div img' ).parent().parent().parent();

$( '.GMaps-tile-container' ).html($layer.html()).width($layer.width()).height($layer.height());

$( '.GMaps-tile-container' ).css( 'left' ,$( '.YMaps-tile-container' ).css( 'left' ))

.css( 'top' ,$( '.YMaps-tile-container' ).css( 'top' ))

.css( 'width' ,$( '.YMaps-tile-container' ).css( 'width' ))

.css( 'height' ,$( '.YMaps-tile-container' ).css( 'height' ));



}, this );



* This source code was highlighted with Source Code Highlighter .






カードのサイズが小さい場合、すべてがうまく機能しますが、ここから段落全体が始まるため、フルスクリーンで開く価値があります。



オプション3.マップを移動する



頭に浮かんだ次のオプションは、別のカードの中にあるカードを単に移動することでした。

Googleマップ自体は、クラス「YMaps-tile-container」を持つdivで作成されます。 Yandexタイルを含むdivは非表示になっていますが、すべてのカードの動きを処理するのはこのdivであるため、非表示ではなく、透明度0になります。

Yandexマップにイベントハンドラーを追加します。 Yandexカードが移動すると、Yandexマップの中心がGoogleマップと同期します。

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

gmap.setCenter( new GLatLng(map.getCenter().getLat(), map.getCenter().getLng()), map.getZoom());

});

YMaps.Events.observe(map, map.Events.BoundsChange, function () {

gmap.setCenter( new GLatLng(map.getCenter().getLat(), map.getCenter().getLng()), map.getZoom());

});




* This source code was highlighted with Source Code Highlighter .






繰り返しますが、小さなカードサイズですべてがうまく機能しますが、展開されると、顕著なブレーキングと不快なアーティファクトが始まります。

これはおそらく、Yandexカードが同時にロードされているという事実によるものですが、それらは表示されていません。 空のマップタイプを作成して設定します。

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" ], '' ,{minZoom:1, maxZoom:17}));




* This source code was highlighted with Source Code Highlighter .






何度も試行しますが、速度が低下します。 経験的に、メインブレーキは、Yandexがカードを動かすときにスムーズにブレーキをかけるという事実によることがわかりました。 長い検索の後、オフにする方法が見つかりませんでした。つまり、このオプションは適合しません。



オプション3.1。 moveByを使用する



このページのapi.yandex.ru/maps/jsapi/examples/synhromaps.htmlは、2枚のYandexカードを互いに同期する方法の例です。 センタリングの代わりに、そこで一定の間隔のシフトが使用されます(明らかに、このオプションは負荷を軽減します)。 Googleマップの機能はまったく同じですが、Yandexマップのシフト値は適切ではありません。 いくつかの実験の後、私はこのベンチャーを去りました。



オプション4.マーカーを移動する



タイルの移動を伴うオプションが重い負荷のために回転しなかった場合、オブジェクトの移動を伴うオプションの方が優れているはずです。

計画はオプション3に似ていますが、1つの例外があります。イベントハンドラはGoogleマッププロセッサで処理する必要があります。 これを行うには、イベントの処理を担当するYandexレイヤーを非表示にします。

そして、ここで失望を待っています。 不明な理由により、このバージョンのGoogleマップはマウスクリックのみを処理し、移動とリリースは処理しません。 結果の検索に費やした時間は数えませんでした。

標準的なYandex Mapsハンドラーを削除しようとする長い実験の後、少し異なる方法でそれを行う必要があり、すべてが機能することが判明しました。

最初に、Googleマップをdiv YMaps-tile-containerからルート、つまりYandexマップ自体が作成されるdivに転送する必要があります。 これで、マップは灰色の背景で覆われました。 クラス「YMaps-layer-container」で歌姫の背景値を透明に設定します。 これで、マップとオブジェクトの両方が表示されますが、Googleはイベントを受け取りません。 z-index googleマップを1に設定し、「YMaps-layer-container」をautoに設定します。 しようとしている...完了!



そしてオオカミは食べられ、羊は安全です!



すべてが2つの関数に収まり、そのコードを以下に示します。

OSMに接続することもできます。

// .

function unbindGoogleMap()

{

$( '#googlemap' ).hide();

$( '.YMaps-map-type-layer-container' ).show();

$( '.YMaps-layer YMaps-common-object-layer' ).show();

if (mapevents[0])

mapevents[0].cleanup();

}

/ Google

function bindGoogleMap(type)

{

var selector = '#' +$(map.getContainer()).attr( 'id' );

map.setType( new YMaps.MapType([ "none#layer" ], '' ,{minZoom:1, maxZoom:17}));

map.redraw();

if ($( '#googlemap' ).length==0)

{

var $div = $( '<div>' ).attr( 'id' , 'googlemap' ).width($(selector).width()).height($(selector).height()).css({zIndex:1});

$( '#routemap' ).prepend($div);

}

$( '#googlemap' ).show();

$( '.YMaps-layer-container' ).css({background: 'transparent' ,zIndex: 'auto' });

$( '.YMaps-map-type-layer-container' ).hide();

$( '.YMaps-layer YMaps-common-object-layer' ).hide();

if (!gmap)

{

gmap = new GMap2( document .getElementById( 'googlemap' ));

gmap.enableContinuousZoom();

gmap.enableScrollWheelZoom();

}

switch (type)

{

case 'gotsat' : case 4:

gmap.setMapType(G_SATELLITE_MAP);;

break ;

case 'gothyb' : case 5:

gmap.setMapType(G_HYBRID_MAP);;

break ;

case 'gotrel' : case 6:

gmap.setMapType(G_PHYSICAL_MAP);;

break ;

default : gmap.setMapType(G_NORMAL_MAP);

}

gmap.setCenter( new GLatLng(map.getCenter().getLat(), map.getCenter().getLng()), map.getZoom());

//

GEvent.addListener(gmap, "move" , function (overlay, latlng) {

map.setCenter( new YMaps.GeoPoint(gmap.getCenter().lng(), gmap.getCenter().lat()), gmap.getZoom());

}, this );

//-

GEvent.addListener(gmap, "update" , function (overlay, latlng) {

map.setCenter( new YMaps.GeoPoint(gmap.getCenter().lng(), gmap.getCenter().lat()), gmap.getZoom());

}, this );

//

mapevents[0] = YMaps.Events.observe(map, map.Events.BoundsChange, function () {

gmap.setCenter( new GLatLng(map.getCenter().getLat(), map.getCenter().getLng()), map.getZoom());

});

}




* This source code was highlighted with Source Code Highlighter .










以上です。 ライブ例はbikecamp.ru/mapで見ることができます



All Articles