Reputation: 13
I'm trying to make a web application that periodically updates position of several markers and then display new positions every few seconds. I managed to achieve almost exactly what i want to do with PrimeFaces and but everytime POLL updates the map, it return to it's original position. Below is the working piece of code:
<p:gmap id="presentation-map" center="41.381542, 2.122893" zoom="15" type="ROADMAP" model="#{pBean.mapModel}" style="width:400px;height:400px" />
<p:poll interval="5" listener="#{pBean.printLocation}" update="presentation-map" />
Now, I tried to use to keep track of position but in order to use it, map has to take it's original position from backing bean. This part for some reason prevents map from being rendered at all.
xhtml map content:
<p:gmap id="presentation-map" center="#{pBean.center}" zoom="#{pBean.zoom}" type="ROADMAP" model="#{pBean.mapModel}" style="width:400px;height:400px" >
<p:ajax event="stateChange" listener="#{pBean.onStateChange}" />
</p:gmap>
<p:poll interval="5" listener="#{pBean.printLocation}" update="presentation-map" />
backing bean content:
import org.primefaces.event.map.StateChangeEvent;
import org.primefaces.model.map.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import java.io.Serializable;
import java.util.List;
@Component
@ManagedBean(name = "pBean")
@ViewScoped
public class PBean implements Serializable{
private MapModel mapModel;
private Marker marker;
private long id;
private int zoom;
private LatLng center;
@Autowired
TService service;
@Autowired
Pocket pocket;
@PostConstruct
public void init(){
zoom = 15;
center = new LatLng(41.381542, 2.122893);
mapModel = new DefaultMapModel();
}
public void printLocation(){
double[] buffer = pocket.retrieveLocation(15);
LatLng position = new LatLng(buffer[0],buffer[1]);
List<Marker> markers = mapModel.getMarkers();
if(markers != null && !markers.isEmpty()){
mapModel.getMarkers().removeAll(markers);
}
mapModel.addOverlay(new Marker(position,"test position"));
}
public void onStateChange(StateChangeEvent event){
this.zoom = event.getZoomLevel();
this.center = event.getCenter();
}
public int getZoom(){...}
public void setZoom(int zoom){...}
public LatLng getCenter(){...}
public void setCenter(LatLng center){...}
public Marker getMarker(){...}
public void setMarker(Marker marker){...}
public long getId(){...}
public void setId(long id){...}
public MapModel getMapModel(){...}
public void setMapModel(MapModel mapModel){...}
Can anyone here tell me why map cannot be rendered, or offer some alternative?
Any suggestions to the code in general are also welcome.
PS. I know there are examples of similar things being done through the use of JavaScript, but I couldn't get them to work, and I'm not sure why. I'm open to to this approach but due to the lack of experience with JS I would need some 100% working example to work with.
Edit 1
As per @chaeschuechli suggestion, I used browser console. It showed the following error:
SyntaxError: missing ) after argument list
It pointed to following line:
<div id="j_idt12:presentation-map" style="width:400px;height:400px"></div><script id="j_idt12:presentation-map_s" type="text/javascript">$(function() {PrimeFaces.cw('GMap','widget_j_idt12_presentation_map',{id:'j_idt12:presentation-map',mapTypeId:google.maps.MapTypeId.ROADMAP,center:new google.maps.LatLng(Lat:51.730726, Lng:19.478617),zoom:15,fitBounds:false,behaviors:{stateChange:function(ext,event) {PrimeFaces.ab({s:"j_idt12:presentation-map",e:"stateChange",p:"j_idt12:presentation-map"},ext);}}});});</script><script id="j_idt12:j_idt14_s" type="text/javascript">$(function(){PrimeFaces.cw("Poll","widget_j_idt12_j_idt14",{id:"j_idt12:j_idt14",frequency:5,autoStart:true,fn:function(){PrimeFaces.ab({s:"j_idt12:j_idt14",f:"j_idt12",u:"j_idt12:presentation-map"});}});});</script><input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:1" value="5249292647095880660:-5542792410948729336" autocomplete="off" />
And the problem appers to be:
center:new google.maps.LatLng(Lat:51.730726, Lng:19.478617)
where browser apparently expects "," or ")" instead of ":" after Lat.
while this clearly shows that gmap gets all data it should from the bean, which is good, I have no idea how to deal with this problem.
Upvotes: 1
Views: 773
Reputation: 12336
The return type of your getter for your center field is not as it is expected by PrimeFaces. According to the PrimeFaces showcase it should be a String and not a LatLng.
And (also according to the showcase) you need to set the center then by using
center = event.getCenter().getLat() + "," + event.getCenter().getLng();
I never used this component but by a little investigation of differences between your static center version and dynamic one and looking at the showcase and google, it was not to difficult to find. Heck, it took more time to write this answer than the actual investigation ;-)
Upvotes: 1