3

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

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

地图形式:

<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++;
    }
}

过滤器项目()

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));
}

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

4

3 回答 3

2

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

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

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

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

编辑:我得到的印象是视图无法更新标记,而不是 mapModel 本身。无论如何,解决方案都是一样的。只是有时您无法删除 bean Scope 来请求(例如,在 overlaySelect 上获取信息窗口),因此您最终会刷新标记

于 2014-01-13T10:16:58.033 回答
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()");

它经过测试,对我有用。

于 2017-02-26T04:21:52.343 回答
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);
    }
}
于 2016-05-12T16:47:42.160 回答