我在使用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)。 重要 - 这在本地服务器上运行没有问题,但是当我将其部署到谷歌应用引擎时,它正如我上面所描述的那样工作。
答案 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 < markers.length; i++) {
markers[i].setMap(null);
}
markers=[];
}
function addMarkers() {
for (var i = 0; i < 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()");
经过测试,对我有用。