GWT GoogleMaps API:具有相对大小的多个地图

GWT GoogleMaps API: Multiple Maps with Relative Sizes

我正在使用 GWT 以及可用的 GoogleMaps api 包装程序 here

我试图在一个页面上显示 4 个 Google 地图。每张地图应占屏幕的 25%。问题是,只有当我将地图大小指定为绝对大小(px)时它才有效,但我需要能够将它们指定为相对大小(百分比)。

这很好用:

package com.test.multimap.client;

import com.google.gwt.ajaxloader.client.AjaxLoader;
import com.google.gwt.ajaxloader.client.AjaxLoader.AjaxLoaderOptions;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.maps.gwt.client.GoogleMap;
import com.google.maps.gwt.client.LatLng;
import com.google.maps.gwt.client.MapOptions;
import com.google.maps.gwt.client.MapTypeId;


public class GwtMultiMapTest implements EntryPoint {

    DockLayoutPanel mapParent1 = new DockLayoutPanel(Unit.PX);
    DockLayoutPanel mapParent2 = new DockLayoutPanel(Unit.PX);
    DockLayoutPanel mapParent3 = new DockLayoutPanel(Unit.PX);
    DockLayoutPanel mapParent4 = new DockLayoutPanel(Unit.PX);
    GoogleMap map1;
    GoogleMap map2;
    GoogleMap map3;
    GoogleMap map4;

    public void onModuleLoad() {

        mapParent1.setSize("500px", "500px");
        mapParent2.setSize("500px", "500px");
        mapParent3.setSize("500px", "500px");
        mapParent4.setSize("500px", "500px");
        
        VerticalPanel leftPanel = new VerticalPanel();
        leftPanel.add(mapParent1);
        leftPanel.add(mapParent2);
        
        VerticalPanel rightPanel = new VerticalPanel();
        rightPanel.add(mapParent3);
        rightPanel.add(mapParent4);
        
        HorizontalPanel hp = new HorizontalPanel();
        hp.add(leftPanel);
        hp.add(rightPanel);
        
        RootLayoutPanel.get().add(hp);

        AjaxLoaderOptions options = AjaxLoaderOptions.newInstance();
        options.setOtherParms("sensor=false");
        Runnable callback = new Runnable() {
            public void run() {
                createMaps();
            }
        };
        AjaxLoader.loadApi("maps", "3", callback, options);
    }

    public void createMaps() {
        
        MapOptions mo1 = MapOptions.create();
        mo1.setZoom(4);
        mo1.setCenter(LatLng.create(37.09024, -95.712891));
        mo1.setMapTypeId(MapTypeId.TERRAIN);
        mo1.setStreetViewControl(false);
        map1 = GoogleMap.create(mapParent1.getElement(), mo1);

        MapOptions mo2 = MapOptions.create();
        mo2.setZoom(4);
        mo2.setCenter(LatLng.create(37.09024, -95.712891));
        mo2.setMapTypeId(MapTypeId.TERRAIN);
        mo2.setStreetViewControl(false);
        map2 = GoogleMap.create(mapParent2.getElement(), mo2);
        
        MapOptions mo3 = MapOptions.create();
        mo3.setZoom(4);
        mo3.setCenter(LatLng.create(37.09024, -95.712891));
        mo3.setMapTypeId(MapTypeId.TERRAIN);
        mo3.setStreetViewControl(false);
        map3 = GoogleMap.create(mapParent3.getElement(), mo3);
        
        MapOptions mo4 = MapOptions.create();
        mo4.setZoom(4);
        mo4.setCenter(LatLng.create(37.09024, -95.712891));
        mo4.setMapTypeId(MapTypeId.TERRAIN);
        mo4.setStreetViewControl(false);
        map4 = GoogleMap.create(mapParent4.getElement(), mo4);
    }
}

但是,我不想以绝对像素为单位指定地图的大小。我希望每张地图占据屏幕的 25%。但如果我这样做:

mapParent1.setSize("50%", "50%");
mapParent2.setSize("50%", "50%");
mapParent3.setSize("50%", "50%");
mapParent4.setSize("50%", "50%");

...然后地图根本不显示。

更奇怪的是

通过一些鸟枪式调试,我发现了一种有效的方法,但只适用于 chrome:

public void onModuleLoad() {

    mapParent1.setSize("100%", "100%");
    mapParent2.setSize("100%", "100%");
    mapParent3.setSize("100%", "100%");
    mapParent4.setSize("100%", "100%");
    
    VerticalPanel leftPanel = new VerticalPanel();
    leftPanel.add(mapParent1);
    leftPanel.add(mapParent2);
    leftPanel.setSize("100%", "100%");
    
    VerticalPanel rightPanel = new VerticalPanel();
    rightPanel.add(mapParent3);
    rightPanel.add(mapParent4);
    rightPanel.setSize("100%", "100%");
    
    HorizontalPanel hp = new HorizontalPanel();
    hp.add(leftPanel);
    hp.add(rightPanel);
    hp.setSize("100%", "100%");
    
    TabLayoutPanel tabPanel = new TabLayoutPanel(2, Unit.EM);
    tabPanel.add(hp, "Maps");
    
    RootLayoutPanel.get().add(tabPanel);

    AjaxLoaderOptions options = AjaxLoaderOptions.newInstance();
    options.setOtherParms("sensor=false");
    Runnable callback = new Runnable() {
        public void run() {
            createMaps();
        }
    };
    AjaxLoader.loadApi("maps", "3", callback, options);
}

如果我使用它,那么它的工作原理基本上与您在 chrome 中所期望的一样。但是 Internet Explorer 有很多问题(地图不断调整自己的大小,用户输入非常慢),而 firefox 什么都不显示。

问题

据我所知,这个问题是在您的页面上使用 GoogleMaps 时固有的。 我记得使用另一个 GoogleMaps 包装器,我还必须以 px 为单位指定所有尺寸,因为 % 不起作用。 我不知道为什么会这样。

我只计算宽度和高度,并添加一个 windowResizeHandler 来更新尺寸。

我最终使用嵌套 DockLayoutPanels 而不是 VerticalPanelsHorizontalPanels。这行得通,我相信这是因为 DockLayoutPanel 实现了 ProvidesResize,而 VerticalPanelHorizontalPanel 没有实现。

至于为什么我的怪异示例在 chrome 中有效,但在其他浏览器中无效,我仍然一头雾水。如果有人能回答这个问题,我将不接受这个答案并接受你的答案。

package com.test.multimap.client;

import com.google.gwt.ajaxloader.client.AjaxLoader;
import com.google.gwt.ajaxloader.client.AjaxLoader.AjaxLoaderOptions;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
import com.google.maps.gwt.client.GoogleMap;
import com.google.maps.gwt.client.LatLng;
import com.google.maps.gwt.client.MapOptions;
import com.google.maps.gwt.client.MapTypeId;


public class GwtMultiMapTest implements EntryPoint {

    DockLayoutPanel parentPanel;

    SimpleLayoutPanel mapParent1 = new SimpleLayoutPanel();
    SimpleLayoutPanel mapParent2 = new SimpleLayoutPanel();
    SimpleLayoutPanel mapParent3 = new SimpleLayoutPanel();
    SimpleLayoutPanel mapParent4 = new SimpleLayoutPanel();
    GoogleMap map1;
    GoogleMap map2;
    GoogleMap map3;
    GoogleMap map4;

    public void onModuleLoad() {

        final DockLayoutPanel leftPanel = new DockLayoutPanel(Unit.PCT);
        leftPanel.addNorth(mapParent1, 50);
        leftPanel.add(mapParent2);

        final DockLayoutPanel rightPanel = new DockLayoutPanel(Unit.PCT);
        rightPanel.addNorth(mapParent3, 50);
        rightPanel.add(mapParent4);

        parentPanel = new DockLayoutPanel(Unit.PCT){
            public void onResize(){
                setWidgetSize(leftPanel, 50);
                leftPanel.setWidgetSize(mapParent1, 50);
                rightPanel.setWidgetSize(mapParent3, 50);
                super.onResize();
            }

        };
        parentPanel.addWest(leftPanel, 50);
        parentPanel.add(rightPanel);

        RootLayoutPanel.get().add(parentPanel);

        AjaxLoaderOptions options = AjaxLoaderOptions.newInstance();
        options.setOtherParms("sensor=false");
        Runnable callback = new Runnable() {
            public void run() {
                createMaps();
            }
        };
        AjaxLoader.loadApi("maps", "3", callback, options);
    }

    public void createMaps() {

        MapOptions mo1 = MapOptions.create();
        mo1.setZoom(4);
        mo1.setCenter(LatLng.create(37.09024, -95.712891));
        mo1.setMapTypeId(MapTypeId.TERRAIN);
        mo1.setStreetViewControl(false);
        map1 = GoogleMap.create(mapParent1.getElement(), mo1);

        MapOptions mo2 = MapOptions.create();
        mo2.setZoom(4);
        mo2.setCenter(LatLng.create(37.09024, -95.712891));
        mo2.setMapTypeId(MapTypeId.TERRAIN);
        mo2.setStreetViewControl(false);
        map2 = GoogleMap.create(mapParent2.getElement(), mo2);

        MapOptions mo3 = MapOptions.create();
        mo3.setZoom(4);
        mo3.setCenter(LatLng.create(37.09024, -95.712891));
        mo3.setMapTypeId(MapTypeId.TERRAIN);
        mo3.setStreetViewControl(false);
        map3 = GoogleMap.create(mapParent3.getElement(), mo3);

        MapOptions mo4 = MapOptions.create();
        mo4.setZoom(4);
        mo4.setCenter(LatLng.create(37.09024, -95.712891));
        mo4.setMapTypeId(MapTypeId.TERRAIN);
        mo4.setStreetViewControl(false);
        map4 = GoogleMap.create(mapParent4.getElement(), mo4);
    }
}