2012-06-02 14 views
14

私は、上のデフォルト位置ではなく、マーカーの横にボックスが開いているカスタムinfoBubbleを実装しようとしています。これは予想以上に難しいことが判明しました。Google Maps InfoBubble pixelOffset(マーカーの上のデフォルト位置から移動)

通常のinfoWindowを使用すると、pixelOffsetを使用できます。 documentation

これを使用すると、これは当てはまりません。 infoBubbleでpixelOffsetを使用しているのですか、それとも同じことをするものがありますか?

私は、これは何の関連性の高い結果Google Search

以下は、私が使用しているすべての私のリソースがあるが返さないなどのGoogle検索を使用して、検索するには、この非常に困難を発見しました。

  • infoBubble hereの例。

  • 地図と情報を設定するJavaScriptがバブルhereです。

ここで私のjavascriptはちょうどここjsfiddleリンクが壊れています。

<script type="text/javascript"> 

    $(document).ready(function() { 
     init(); 
    }); 

    function init() { 

     //Setup the map 
     var googleMapOptions = { 
      center: new google.maps.LatLng(53.5167, -1.1333), 
      zoom: 13, 
      mapTypeId: google.maps.MapTypeId.ROADMAP 
     }; 

     //Start the map 
     var map = new google.maps.Map(document.getElementById("map_canvas"), 
     googleMapOptions); 

     var marker = new google.maps.Marker({ 
      position: new google.maps.LatLng(53.5267, -1.1333), 
      title: "Just a test" 
     }); 

     marker.setMap(map); 

     infoBubble = new InfoBubble({ 
      map: map, 
      content: '<div class="phoneytext">Some label</div>', 
      //position: new google.maps.LatLng(-35, 151), 
      shadowStyle: 1, 
      padding: '10px', 
      //backgroundColor: 'rgb(57,57,57)', 
      borderRadius: 5, 
      minWidth: 200, 
      arrowSize: 10, 
      borderWidth: 1, 
      borderColor: '#2c2c2c', 
      disableAutoPan: true, 
      hideCloseButton: false, 
      arrowPosition: 7, 
      backgroundClassName: 'phoney', 
      pixelOffset: new google.maps.Size(130, 120), 
      arrowStyle: 2 
     }); 
     infoBubble.open(map, marker); 

    } 
</script> 

更新

私は一緒にここでテストケース を入れているこの質問に答えるを支援します。重要な行は行38 & 39で、ラベルの位置を指定する必要があります。私はinfoBubbleの例を参照する必要が授与される報奨金については

アップデート2

は、マーカー上のデフォルトの位置から離れて配置しました。好ましくは、マーカーの右側にある。

アップデート3

それは私の古い会社のサーバー上でホストされているので、私は、更新1からテストケースを削除しました。

+0

:あなたは、マーカーの位置を知っている場合:(LNG、緯度)、そして(LNGは+ X、緯度)右、バブルのための位置でなければなりません? – Gavriel

+0

それはうまく動作するように聞こえます – Undefined

答えて

9

infoBubbleライブラリ自体は、バブルがバインドされているマーカーの上にバブルを配置するようにデフォルト設定されています。ライブラリに含まれているサンプルファイル(http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/examples/example.html)を見てください。特に行99から行122への通知と2つのinfobubblesの使用。最初のものはマーカにバインドされていますが、2番目のものはスタンドアロンなので、106行目を見ればその位置を定義できます。今、この理解に基づいて私はこのフィドルであなたのための例を作ったhttp://jsfiddle.net/pDFc3/。 infoBubbleは、マーカーの右側に配置されます。

infoBubble jsライブラリにはsetPosition(http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/src/infobubble.js?r=206)の行1027を参照してください。しかし、DOMがロードされるのを待ってからinfoBubble.setPosition(newLatLng);に移動して位置を変更しようとすると何らかの理由で動作しません。逆に、DOMロード後にinfoBubble.getPosition();と宣言すると、infoBubbleがバインドされているマーカーの現在位置がわかります。だからsetPosition()はjsライブラリにバグを持っているかもしれません。私はそれがまだ働いていると信じているからです(バグかもしれません)。


は私が中とズームアウトし、それに応じて(http://jsfiddle.net/pDFc3/)infoBubbleを配置するときのために、あなたの問題を解決するために、私のjsFiddleを修正しました。論理を最初に説明しましょう。まず、Googleマップでの道路地図タイプの最大ズームレベルは21です。この値は衛星画像では一貫しませんが、ユーザーが移動できる最大ズームは21です.21から、ズームアウトするたびに2つのポイントの差が次のロジックに基づいて、「画面上の」一貫性の維持:

consitent_screen_dist = initial_dist * (2^(21 - zoomlevel)) 

を我々の場合には、初期距離の妥当な値は(マーカーおよびinfoBubble間)0.00003度でした。だから、このロジックに基づいて、私は、マーカーとinfoBubble間の最初の長手方向の距離を見つけるために、次の作品を追加しました:

var newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom()))); 

同様に、距離を確保するためには、各ズームレベルの変更に一貫性のあるまま、我々は単に私たちのように、新たな経度を宣言しますズームレベルの変化を聞く:

google.maps.event.addListener(map, "zoom_changed", function() { 
     newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom()))); 
     infoBubble.setPosition(new google.maps.LatLng(marker.getPosition().lat(), newlong));     
    }); 

は、あなたがメソッドを介して呼び出されmarker.getPositionと他の値のための変数を宣言することによって、このコードは、はるかに効率的に行うことができます覚えておいてください。そのため、メソッド呼び出しは繰り返されず、コードが遅くなります。

+0

それは私が探しているものです、1つの問題は、マーカに対してマーカの動きをズームイン、ズームアウトするときに、これは解決できるものだと思いますか? – Undefined

+0

これは、特定のズームレベルでマーカーとの関係でinfoBubbleの位置を設定するためです。しかし、一度ズームレベルを変更すると、マーカーと情報泡(間の緯度/経度の差)の距離は変わりません。ズームアウトすると、その差は小さく、マーカーの上にあるinfoBubbleを表示します。 –

+0

この問題は修正されていますが、infoBubbleをメーカーにバインドしないと、実際にinfoBubble.setPosition(latlng)メソッドを使用できることがわかりました。これは、Googleマップイベントリスナー 'zoom_changed'を使ってズームの変更を聞き取り、' getZoom() '関数を使ってズームレベルに基づいてマーカーとの関係でinfoBubbleの位置を決めるクラスを決定することを意味します。私はこの可能性のある修正で自分のjsfiddleを更新しますが、この原則に基づいて実験を自由にしてください。 –

1

残念ながらInfoBubbleのpixelOffsetなどのオプションはありません。しかし、例のマーカーの上にあるBubbleを上に移動したい場合は、mapパラメータをバブル初期化に設定しないでください。次のフィドルを考えてみましょう(私はあなたのためにそれを固定):

http://jsfiddle.net/ssrP9/5/


P.S.をリソースを正しく追加していなかったため、フィドルがうまくいきませんでした。 http://doc.jsfiddle.net/basic/introduction.html#add-resources

+0

言及を忘れました。私の答えは、ソース分析に基づいています。 マーカーに対してカスタムオフセットを設定する必要が本当にある場合は、次の2通りの方法があります。 1.このライブラリのソースを取得し、必要な機能を追加してください。 2. [非常に奇妙な]オリジナルとオープンバブルから必要なオフセットそれ。 –

+0

そのことをありがとうjsfiddle私は私の質問にそれを含めます。残念ながら私は、マーカーの上から別の位置にinfoBubbleを配置するために探しています – Undefined

1

まったく同じ問題が発生しましたが、どこでも答えが見つかりませんでした。少しの試行錯誤を経て、私はそれを試してみました。

"infoBubble"にはGoogle JSファイルを使用します。私にとって

InfoBubble.prototype.buildDom_ = function() { 

...このファイルに移動し、を検索し、これはライン203上にある(それは、前のシャッフリングおよび編集の結果である可能性があります)。

この関数内では、位置 "絶対"宣言が表示されます。新しい行にmarginTop、marginRight、marginBottom、およびmarginLeftを追加できます。これは、デフォルトの位置(あなたの設定の矢印位置の宣言にも依存します)からバブルを微調整します。

これは、バブルをマーカの上に配置するバブルJSファイル(設計機能のため)...

var bubble = this.bubble_ = document.createElement('DIV'); 
bubble.style['position'] = 'absolute'; 
bubble.style['marginTop'] = this.px(21); 
bubble.style['marginLeft'] = this.px(1); 
bubble.style['zIndex'] = this.baseZIndex_; 

希望に役立ちます。InfoBubble buildDom機能で

0

、追加:

bubble.className = 'bubble-container'; 

は、今あなたがCSSのマージンを使用して、それをシフトすることができ、各InfoBubbleのCSSクラスを持っています。

8

これは私のソリューションです。 InfoBubbleライブラリで

/* 
* Sets InfoBubble Position 
* */ 
InfoBubble.prototype.setBubbleOffset = function(xOffset, yOffset) { 
    this.bubbleOffsetX = parseInt(xOffset); 
    this.bubbleOffsetY = parseInt(yOffset); 
} 


/* 
* Gets InfoBubble Position 
* */ 
InfoBubble.prototype.getBubbleOffset = function() { 
    return { 
    x: this.bubbleOffsetX || 0, 
    y: this.bubbleOffsetY || 0 
    } 
} 

/** 
* Draw the InfoBubble 
* Implementing the OverlayView interface 
*/ 
InfoBubble.prototype.draw = function() { 
    var projection = this.getProjection(); 

    if (!projection) { 
    // The map projection is not ready yet so do nothing 
    return; 
    } 

    var latLng = /** @type {google.maps.LatLng} */ (this.get('position')); 

    if (!latLng) { 
    this.close(); 
    return; 
    } 

    var tabHeight = 0; 

    if (this.activeTab_) { 
    tabHeight = this.activeTab_.offsetHeight; 
    } 

    var anchorHeight = this.getAnchorHeight_(); 
    var arrowSize = this.getArrowSize_(); 
    var arrowPosition = this.getArrowPosition_(); 

    arrowPosition = arrowPosition/100; 

    var pos = projection.fromLatLngToDivPixel(latLng); 
    var width = this.contentContainer_.offsetWidth; 
    var height = this.bubble_.offsetHeight; 

    if (!width) { 
    return; 
    } 

    // Adjust for the height of the info bubble 
    var top = pos.y - (height + arrowSize) + this.getBubbleOffset().y; 

    if (anchorHeight) { 
    // If there is an anchor then include the height 
    top -= anchorHeight; 
    } 

    var left = pos.x - (width * arrowPosition) + this.getBubbleOffset().x; 

    this.bubble_.style['top'] = this.px(top); 
    this.bubble_.style['left'] = this.px(left); 

    var shadowStyle = parseInt(this.get('shadowStyle'), 10); 

    switch (shadowStyle) { 
    case 1: 
     // Shadow is behind 
     this.bubbleShadow_.style['top'] = this.px(top + tabHeight - 1); 
     this.bubbleShadow_.style['left'] = this.px(left); 
     this.bubbleShadow_.style['width'] = this.px(width); 
     this.bubbleShadow_.style['height'] = 
     this.px(this.contentContainer_.offsetHeight - arrowSize); 
     break; 
    case 2: 
     // Shadow is below 
     width = width * 0.8; 
     if (anchorHeight) { 
     this.bubbleShadow_.style['top'] = this.px(pos.y); 
     } else { 
     this.bubbleShadow_.style['top'] = this.px(pos.y + arrowSize); 
     } 
     this.bubbleShadow_.style['left'] = this.px(pos.x - width * arrowPosition); 

     this.bubbleShadow_.style['width'] = this.px(width); 
     this.bubbleShadow_.style['height'] = this.px(2); 
     break; 
    } 
}; 

全体InfoBubble.prototype.draw方法

を交換した後、あなたが

var infoBubble = new InfoBubble({ 
    map: map, 
    content: "My Content", 
    position: new google.maps.LatLng(1, 1), 
    shadowStyle: 1, 
    padding: 0, 
    backgroundColor: 'transparent', 
    borderRadius: 7, 
    arrowSize: 10, 
    borderWidth: 1, 
    borderColor: '#2c2c2c', 
    disableAutoPan: true, 
    hideCloseButton: true, 
    arrowPosition: 50, 
    backgroundClassName: 'infoBubbleBackground', 
    arrowStyle: 2 

}); 
ことで、これを使用することができます

は、最終的に、我々はあなたがまた、定義されたアンカーの高さを使用することができます

infoBubble.setBubbleOffset(0,-32); 
1

InfoBubble位置を設定するには、このメソッドsetBubbleOffset(x,y);を使用する必要があります。

var anchorHeight = YOURNUMBER; 

ライン874 infobubble.jsだけでブレーンストーミング

関連する問題