如何在使用新标记更新gmap后刷新primefaces p:gmap中的gmap标记

时间:2013-07-25 09:19:35

标签: google-maps jsf-2 primefaces

我在使用Primefaces 3.5的Gmap组件的项目上遇到问题我正在使用JSF2.0。 我有这个命令按钮,对标记和最重要的更新mapForm

进行过滤
<h:form id="epsFilterForm">
      <p:commandButton action="#{mapMB.filterProjects}" value="#{bundle['filter'] }" update=":mapForm" />
</h:form>

mapForm:

<h:form id="mapForm">  
<p:gmap id="googleMap" center="48.849988,2.3805715" zoom="11"  type="TERRAIN" fitBounds="false" model="#{mapMB.advancedModel}" 
    widgetVar="wmap" style="width:1000px;height:700px;display: inline-block;" >

    <p:ajax event="overlaySelect"  listener="#{mapMB.onMarkerSelect}" />   
    <p:gmapInfoWindow>  
        <p:outputPanel style="text-align:center;display:block;margin:auto:">
            <p:panelGrid columns="2" styleClass="InfoTable" >

                <p:outputLabel value="#{bundle['ep.operation.name'] }" />
                <p:outputLabel value="#{mapMB.selectedEp.opName}" />
            </p:panelGrid>
        </p:outputPanel>  
    </p:gmapInfoWindow> 
</p:gmap>

MapMB - 范围 - 会话范围 populateAdvancedModel()

public void populateAdvancedModel(List<EP> eps) {
    advancedModel = new DefaultMapModel();
    int count = 0;
    Marker marker;
    for (EP ep :eps) {
        //advancedModel.addOverlay(new Marker(coord1, "Konyaalti", "konyaalti.png", "http://maps.google.com/mapfiles/ms/micons/blue-dot.png"));
        System.out.println("Integer.toString(ep.getId()):"+Integer.toString(ep.getId()));
        marker =  new Marker(new LatLng(  Double.parseDouble(ep.getLatitude()) ,  Double.parseDouble(ep.getLongitude())));
        marker.setTitle( Integer.toString(count));
        advancedModel.addOverlay(marker);
        count++;
    }
}

filterProjects()

public String filterProjects() {
    //FilterMB filterMB = (FilterMB) JSFUtil.getManagedObject("filterMB");
    eps = EPDAO.filterEPs(client, architect, realizationType, state, selectedCert);
    populateAdvancedModel(eps);
    return null;
}

onMarkerSelect()

public void onMarkerSelect(OverlaySelectEvent event) {
    Marker marker = (Marker) event.getOverlay();
    String markerTitle = marker.getTitle();
    selectedEp = eps.get(Integer.parseInt(markerTitle));
}

第一次加载页面时一切正常。 Info(p:gmapInfoWindow)窗口正在加载,EP变量的信息就在那里。但是当我单击epsFilterForm中的命令按钮(它有一些我没有在这里发布的输入字段)时,地图会更新并且过滤的标记就在那里,当我将鼠标悬停在它们上时它们显然有标题,但overlaySelect事件不起作用以同样的方式。我认为当页面第一次加载时会有一些初始脚本将该行为放在标记上,但是当我刷新地图时,这个初始脚本没有再次运行,这就是为什么当我点击标记并且overlaySelect事件是在onMarkerSelect()方法中我有空指针Exception(marker为null)。 重要 - 这在本地服务器上运行没有问题,但是当我将其部署到谷歌应用引擎时,它正如我上面所描述的那样工作。

3 个答案:

答案 0 :(得分:2)

gmap的DefaultMapModel(从p:gmap元素中的'model'属性引用)没有适当的清除功能,不像其他Model对象,例如p:schedule的EventModel。

如果您从SessionScoped控制器提供该对象,即使您从头开始重新创建该对象,p:gmap由于某种原因仍然保持对第一个提供的mapModel的引用。实际上,这意味着除了第一个之外没有使用所有新的/更新的mapmodel对象。

因此,要更新的gmap(添加/删除标记,叠加等)的一个棘手问题是应该从RequestScoped对象中检索mapmodel对象。

现在,另一种选择是迭代所有标记。你可以找到类似的帖子here。这样你可以将你的支持bean保持为SessionScoped,但同样,你不应该创建一个新的mapModel。

编辑:我的印象是视图无法更新标记,而不是mapModel本身。无论如何,解决方案是一样的。只是有时你不能放弃bean范围来请求(例如在overlaySelect上获取信息窗口),所以你最终刷新标记

答案 1 :(得分:0)

我使用onGeocode事件,在支持bean中检查是否有任何加载的标记。在添加新标记之前删除这些标记。希望这会有所帮助。

public void onGeocode(GeocodeEvent event) {

    try {

        List<GeocodeResult> results = event.getResults();

        if (results != null && !results.isEmpty()) {
            LatLng center = results.get(0).getLatLng();
            centerGeoMap = center.getLat() + "," + center.getLng();

            List<Marker> markers = geoModel.getMarkers();

            if (markers != null && markers.size() > 0) {

                geoModel.getMarkers().removeAll(markers);
            }

            for (int i = 0; i < results.size(); i++) {
                GeocodeResult result = results.get(i);
                geoModel.addOverlay(new Marker(result.getLatLng(), result.getAddress()));

            }
        }
    } catch (Exception e) {
        logger.error("Could not update GMap from geoCode", e);
    }
}

答案 2 :(得分:0)

我有类似的情况。实际上,我要做的是在渲染gmap后更新gmap中的标记。正如@yannicuLar所说,mapModel在渲染地图时从头开始检索一次。稍后在mapModel上的更新不会反映在地图上。

我的解决方案是使用primefaces功能来触发从服务器端执行javascript。

在xhtml中:

            var markers = [];
            function clearMarkers() {
                for (var i = 0; i &lt; markers.length; i++) {
                      markers[i].setMap(null);
                 }
                markers=[];
            }
            function addMarkers() {
                for (var i = 0; i &lt; markers.length; i++) {
                    PF('yourMap').addOverlay(markers[i]);
                   }
            }

在java / server端,在你应该用lat / lng更新mapModel的地方,你可以添加如下代码:

清除标记:

RequestContext.getCurrentInstance().execute("clearMarkers()");

假设你有多个标记,迭代地将所有标记添加到标记数组:

RequestContext.getCurrentInstance().execute("var currentMarker = new google.maps.Marker({ position:new google.maps.LatLng("
                    + latitude + ", " + longitude
                    + "), map:PF('yourMap').getMap()});"
                    + "markers.push(currentMarker);");

在填充标记数组后添加标记以进行贴图:

RequestContext.getCurrentInstance().execute("addMarkers()");

经过测试,对我有用。