プログラミングノート

一からものを作ることが好きなエンジニアの開発ブログです。

GoogleMapの問題解消

昨日の方法ではGoogleMapの処理がどうも最初のフルスクリーンサイズで計算されていたようで、地図の中心がずれるというバグが出てしまったので改善。何とか使える感じになったのでソースを載せときます。



基本的にMap生成時に地図のサイズが明示的に指定されていなければ、親コンテナのサイズが利用されるとAPIリファレンス(&各種サイト)に書いてあったけど、サイズの指定方法を変えてみたり、ウィンドウリサイズの度にid=mapのサイズを変えてみたりしても同様のバグがなくならず…。色々悩んだ末にIFRAMEを使ってみたところ全て解決。

  • main.html (sandbox)

デフォルトのメインウィンドウをスクリーンサイズに拡大、非表示に。

<html>
<head>
<script type="text/javascript" src="AIRAliases.js"></script>
<script>
  window.moveTo(0, 0);
  window.resizeTo(screen.width, screen.height);  
  var parentInterface = {
    nativeClose : function(){
      window.nativeWindow.close();
    }
  };
  window.onload = function(){    
    document.getElementById('sandbox').contentWindow.parentSandboxBridge = parentInterface;
  };
</script>
</head>
<body>
<iframe id="sandbox"
  src='http://localhost/non-app.html'
  sandboxRoot='http://localhost/'
  documentRoot="app:/"
  style="width:100%; height:100%;border:none;overflow:hidden"
  />
</body>
</html>
  • non-app.html (non-application sandbox)

Extウィンドウを生成し、GoogleMapをIFRAMEでロード。同じドメインなのでフレーム間でのJavascriptアクセスも大丈夫です。Extウィンドウをリサイズする度にIFRAMEのサイズも変更しています。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="ext/adapter/jquery/jquery.js"></script>
<script type="text/javascript" src="ext/adapter/jquery/jquery-plugins.js"></script>
<script type="text/javascript" src="ext/adapter/jquery/ext-jquery-adapter.js"></script>
<script type="text/javascript" src="ext/ext-all.js"></script>
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"/>
<script type="text/javascript">
  /*
   * メインウィンドウを生成
   */
  Ext.onReady(function(){
    var MAIN_WIN = new Ext.Window({
      el:'win',
      width:400,
      height:400,
      resizable: true,
      maximizable: true,
      constrain: true,
      listeners: {
        close: function() { parentSandboxBridge.nativeClose(); },
        bodyresize: function(p, width, height){
          $("#map").width(width+'px').height(height+'px');
        }
      },
      items: new Ext.Panel({
        el: 'panel'
      })
    }).show(this);    
  });

  /*
   * IFRAMEからの接続テスト
   */
  function parentTest(str){
    alert("parentTest実行");
  };

  /*
   * IFRAMEへの接続テスト
   */
  function go(){
    document.getElementById("map").contentWindow.childTest();
  }
</script>
</head>
<body>
<div id="win" class="x-hidden">
  <div class="x-window-header">Google Map Test</div>
  <div id="panel" style="width:100%; height:100%;">
    <button onclick="go()">IFRAMEのFunctionを実行</button>
    <iframe id="map" src="http://localhost/gmap.html" style="width:100%; height:100%; border:none;" \>
  </div>
</div>
</body>
</html>
  • gmap.html

GoogleMapをロードしてるだけ。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://maps.google.co.jp/maps?file=api&amp;v=2&amp;key=(GoogleMapKey)" type="text/javascript"></script>
<script>
  /*
   * GoogleMap初期化
   */  
  function load() {
    if (GBrowserIsCompatible()) {
      var GMAP = new GMap2(document.getElementById('gmap_full'));
      GMAP.enableContinuousZoom();
      GMAP.enableScrollWheelZoom();
      GMAP.addControl(new GLargeMapControl());
      GMAP.addControl(new GMapTypeControl());      
      GMAP.setCenter(new GLatLng(35.681126, 139.764998), 13);
      GEvent.addListener(GMAP, "click", function(marker, point) {
        GMAP.addOverlay(new GMarker(point));
        GMAP.panTo(point);
      });      
    }
  }

  /*
   * 親からの接続テスト 
   */
  function childTest(){
    alert("childTest実行");
  };
  
  /*
   * 親への接続テスト 
   */
  function go(){
    parent.parentTest();
  }
</script>
</head>
<body onload="load()">
  <button onclick="go()">親のFunctionを実行</button>
  <div id="gmap_full" style="width:100%; height:100%;"></div>
</body>
</html>


ExtとAIRの組み合わせは色々面倒です…。