New markers are not shown in PrimeFaces gmap (JSF 2.2) - google-maps

I'm using PrimeFaces 8.0.3. The first time the page loads, the gmap has no markers because the table where I store the coordinates is empty. When a new marker is added, the page refreshes but the map still doesn't show the marker. This problem only happens when I run the application on the server, because when I run it locally, the new marker is shown without problems. The page refreshes every ten seconds to check if there are new rows in the table.
Html:
<script type="text/javascript" src="https://maps.google.com/maps/api/js?key=[provided api key]"></script>
<h:form>
<p:panel>
<p:gmap center="-0.2727324,-78.5489364" zoom="18" type="ROADMAP" style="width:90%;height:700px" model="#{mapaCtrl.simpleModel}" />
<p:poll interval="10" listener="#{contadorCtrl.recargarMapa()}" />
</p:panel>
</h:form>
MapaCtrl:
#ManagedBean
#RequestScoped
public class MapaCtrl implements Serializable
{
private MapModel simpleModel;
...
public void dibujarMarcadores()
{
for(int i = 0; i < listaSolicitud.size(); i++)
{
LatLng coord = new LatLng(Double.parseDouble(listaSolicitud.get(i).getLatitud()), Double.parseDouble(listaSolicitud.get(i).getLongitud()));
simpleModel.addOverlay(new Marker(coord, listaSolicitud.get(i).getDescripcionsolicitud()));
}
}
}
ContadorCtrl:
#ManagedBean
#RequestScoped
public class MapaCtrl implements Serializable
{
...
public void recargarMapa()
{
...
if(solicitudesActuales != MapaCtrl.solicitudesIniciales)
{
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
try
{
ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());
}
catch(IOException ex)
{
Logger.getLogger(ContadorCtrl.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
How can I show the new markers in the map?

You need to assign an id to your map component, and then update it when polling:
<p:gmap id="myMap" center="-0.2727324,-78.5489364" zoom="18" type="ROADMAP" style="width:90%;height:700px" model="#{mapaCtrl.simpleModel}" />
<p:poll interval="10" listener="#{contadorCtrl.recargarMapa()}" update="myMap"/>

Related

How can I draw a Polygon on the Gmap without refreshing the whole Gmap component?

I'm developing an app with JSF and PrimeFaces.
I have a PrimeFaces Gmap component on a page. I want to allow the user to draw a map polygon on screen, simply clicking each vertex, and see how the polygon constructs on the fly with each click. And also receive each point data in the Backing Bean, so I can store/persist the data in the database.
I followed the logic "For each click I want to update the map, and the model in the backing bean", so I did put update="#this" in the <p:ajax> tag in the <p:gmap> component. Problem is, making so, the whole Gmap component totally reloads, and loses its position, zoom and center. Resetting to its init values. This makes the draw operation extremely problematic because user has to zoom and pan to the zone where the polygon is wanted to be drawn, with each click.
I need the Gmap to update without totally reload it. I know the solution involves JS, sadly I'm not very expert in that language.
I made a Minimal reproducible example.
JSF page:
<h:head>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=true"></script>
</h:head>
<h:body>
<h:form id="frmMap2">
<p:gmap center="41.381542, 2.122893"
zoom="15"
type="HYBRID"
style="width:100%;height:400px"
model="#{testMapBean.polygonModel}">
<p:ajax event="pointSelect"
listener="#{testMapBean.onPointSelect}"
update="#this"/>
</p:gmap>
</h:form>
</h:body>
The backing bean (View Scoped):
#Named(value = "testMapBean")
#ViewScoped
public class TestMapBean implements Serializable {
private MapModel polygonModel;
private Polygon polygon;
public TestMapBean()
{
}
#PostConstruct
public void init()
{
polygonModel = new DefaultMapModel();
polygon = new Polygon();
polygon.setStrokeColor("#FF9900");
polygon.setFillColor("#FF9900");
polygon.setStrokeOpacity(0.7);
polygon.setFillOpacity(0.7);
polygonModel.addOverlay(polygon);
}
public void onPointSelect(PointSelectEvent event)
{
LatLng latlng = event.getLatLng();
polygon.getPaths().add(latlng);
}
// public getters and setters omitted for brevity...
I'm using:
JSF 2.3 (mojarra),
Primefaces 10.0,
Wildfly 26.1.
EDIT
Finally made it., for anyone interested, this is the code:
View:
<h:head>
<script type="text/javascript"
src="https://maps.google.com/maps/api/js?sensor=true"></script>
<script type="application/javascript">
var map;
var pl;
function initbs()
{
// Get map through the PF widget
map = PF('wmaptest').map;
// Create Polygon
pl = new google.maps.Polygon({
strokeColor: "#777777",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
});
}
// Have a function to set coordinates to the line
function drline(coords)
{
// Add the (empty) line to the map
pl.setMap(map);
pl.setPath(coords);
}
</script>
</h:head>
<h:body>
<h:form id="frmMap2">
<p:gmap widgetVar="wmaptest"
center="41.381542, 2.122893"
zoom="15"
type="ROADMAP"
style="width:100%;height:800px">
<p:ajax event="pointSelect"
listener="#{testMapBean.onPointSelect}"/>
</p:gmap>
</h:form>
</h:body>
Bean:
#Named(value = "testMapBean")
#ViewScoped
public class TestMapBean implements Serializable {
private Set<LatLng> latLngList = new HashSet<LatLng>();
public TestMapBean()
{
}
#PostConstruct
public void init()
{
PrimeFaces.current().executeInitScript("initbs()");
}
public void drawLine()
{
String str = latLngList.stream()
.map(this::toJavaScript)
.collect(Collectors.joining(",", "drline([", "])"));
PrimeFaces.current().executeScript(str);
}
public String toJavaScript(LatLng latLng) {
return "{lat:" + latLng.getLat() + ",lng:" + latLng.getLng() + "}";
}
public void onPointSelect(PointSelectEvent event)
{
LatLng latlng = event.getLatLng();
latLngList.add(latlng);
drawLine();
}
public Set<LatLng> getLatLngList() {
return latLngList;
}
public void setLatLngList(Set<LatLng> latLngList) {
this.latLngList = latLngList;
}
}
I did something similar which you can use here as well. In my case I have a set of markers which you can select a few of to plan appointments at the selected markers.
Basically I added an empty Polyline (you can do something similar using a Polygon), and a function to add coordinates to that line at the client side like:
// Get map through the PF widget
let map = PF('yourWidgetVarName').map;
// Create Polyline
let pl = new google.maps.Polyline({
geodesic: true,
strokeColor: '#ff0000',
strokeOpacity: 1,
strokeWeight: 2
});
// Add the (empty) line to the map
pl.setMap(map);
// Have a function to set coordinates to the line
function line(coords) {
pl.setPath(coords);
}
See also:
https://developers.google.com/maps/documentation/javascript/shapes#polylines
And in the backend I filter my markers to the selected set, get their lat long position and transform them to a JavaScript array and call the line function to draw them on the map. Instead of markers you will probably just have a list of LatLng objects. So you can probably do:
public void drawLine() {
PrimeFaces.current().executeScript(
latLngList.stream()
.map(this::toJavaScript)
.collect(Collectors.joining(",", "line([", "])"))
);
}
public String toJavaScript(LatLng latLng) {
return "{lat:" + latLng.getLat() + ",lng:" + latLng.getLng() + "}";
}

Displaying marker data in primefaces gmap

I am using primefaces to manage a gmap.
I display some markers on the map that result of a query using some parameters passed by the user.
I would like to display more informations when a user click on the marker but I don't succeed in displaying the marker.data.
map.xhtml :
<p:gmap center="53.483959, -2.244644" zoom="7" type="HYBRID" style="width:100%;height:800px" model="#{poc_InputManager.mymap}" >
<p:ajax event="overlaySelect" listener="#{poc_InputManager.onMarkerSelect}" />
<p:gmapInfoWindow id="infoWindow">
<p:outputPanel style="text-align: center; display: block; margin: auto">
<h:outputText value="#{poc_InputManager.marker.data}" />
</p:outputPanel>
</p:gmapInfoWindow>
</p:gmap>
java code :
public MapModel getMymap() throws Exception {
mymap=new DefaultMapModel();
ArrayList<POC_LocationsPostalCode> ad = lpcdao.getCodesFiltered(selectedsta);
for (int i = 0 ;i<ad.size();i++){
LatLng tmpcoord = new LatLng(ad.get(i).getLat(),ad.get(i).getLng());
Marker m = new Marker(tmpcoord, ad.get(i).getLocationcode());
m.setData("TEST");
mymap.addOverlay(m);
}
return mymap;
}
In this example, when the user click on the marker it should display "TEST".
Ultimately the goal is to display some informations that are retrieved by a query using the title of the marker.
You should try something like this:
<p:gmap ... >
<p:ajax event="overlaySelect" listener="#{locationManager.onMarkerSelect}" />
<p:gmapInfoWindow id="infoWindow" >
<p:outputPanel style="text-align: left; display: block; margin: auto">
<p:outputLabel value="${locationManager.myMarker}" />
</p:outputPanel>
</p:gmapInfoWindow>
</p:gmap>
#ViewScoped
#Managedbean
public class LocationManager {
private String myMarker; //Your object
//Getter and Setters...
//your listener
public void onMarkerSelect(OverlaySelectEvent event) {
marker = (Marker) event.getOverlay();
myMarker = (String) marker.getData();
}
}

PrimeFaces GMap control doesn't work when I migrate from 3.4 to 5.0

I have a great problem.
I have a project wrote in PrimeFaces 3.4 with JSF 2.1 and JAVA6. I'm implementing the porting from PF 3.4 to PF 5.0
but with PF 5.0 the component GMap doesn't work at all! When I load the page, GMap isn't rendered and it appears totally white.
Firebug says : Google is not defined ...
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<f:view
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
contentType="text/html">
<h:head>
<script src="https://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="#{request.contextPath}/css/garantesStyles.css" />
<title>My App title</title>
</h:head>
<h:body >
<p:ajaxStatus onstart="PF('statusDialog').show();" onsuccess="PF('statusDialog').hide();"/>
<p:dialog modal="true" widgetVar="statusDialog" header="Attendere..."
draggable="false" closable="false">
<p:graphicImage value="/images/ajaxloadingbar.gif" />
</p:dialog>
<h:form id="formOggettoMappa">
<p:gmap widgetVar="oggettoMappa" id="oggettoMappa" center="#{mapUrbanBean.centerMap}"
zoom="#{mapUrbanBean.zoomFactor}" type="hybrid"
style="width:100%;height:600px" model="#{mapUrbanBean.puntiModel}" >
<p:ajax event="overlaySelect" listener="#{mapUrbanBean.onMarkerSelect}" />
</p:gmap>
</h:form>
This is the code about my bean
#ManagedBean(name="mapUrbanBean")
#SessionScoped
public class MapBean implements Serializable {
private static final long serialVersionUID = 1L;
private MapModel puntiModel;
private double centerX,centerY,zoomFactor;
private String centerMap;
public MapModel getPuntiModel() {
return puntiModel;
}
public void setPuntiModel(MapModel puntiModel) {
this.puntiModel = puntiModel;
}
public String getCenterMap() {
return centerMap;
}
public void setCenterMap(String centerMap) {
this.centerMap = centerMap;
}
public double getCenterX() {
return centerX;
}
public void setCenterX(double centerX) {
this.centerX = centerX;
}
public double getCenterY() {
return centerY;
}
public void setCenterY(double centerY) {
this.centerY = centerY;
}
public int getZoomFactor() {
return zoomFactor;
}
public void setZoomFactor(int zoomFactor) {
this.zoomFactor = zoomFactor;
}
#PostConstruct
public void init(){
this.data = new Date();
this.data2 = new Date();
popolaUltimiMappa();
}
public void popolaUltimiMappa(){
puntiModel= new DefaultMapModel();
LatLng coord = new LatLng(36.890257,30.707417);
puntiModel.addOverlay(new Marker(coord, "this marker","images/mapimg/"+img_a.get(i)));
this.centerX=36.890257;
this.centerY=30.707417;
this.zoomFactor=13;
this.centerMap= this.centerY+ "," +this.centerX;
}
}
This code works fine with PrimeFaces 3.4 but with PrimeFaces 5.0 it doesn't work.
I tried with Google but I found nothing.
Any idea????
Thank you in advance
EDIT: I saw that GMap control works (showing some layers) but any controls are disabled! I can't do anything, any pan movements, any zoom in or zoom out operations...
yes, same issue with me. but if you use ordinary javascript of google maps it will work, I think it will only work primefaces 5 on web application locally not on google app engine.

add dragable marker to google map

I have seen in PrimeFaces demo an example on Adding markers and on Draggable markers.i flow the two examples and it 's working, and know i'm trying to integrate both these examples into one working example but i couldn't ( i m' a biggenner ) could you please help me .
this is the example of adding marker :
this is the ponitBean:
#Component
#Scope
#ManagedBean (name = "pointBean")
public class PointBean {
// =========================================================================
// ATTRIBUTES
// =========================================================================
private Point point ;
private PointService pointService;
private MapModel emptyModel;
// =========================================================================
// CONSTRUCTORS
// =========================================================================
public PointBean() {
super();
// TODO Auto-generated constructor stub
}
// =========================================================================
// METHODS
// =========================================================================
public void savePoint(){
pointService.savePoint(point);
addMarker();
}
#SuppressWarnings("unchecked")
public List<Point>getAllPoint(){
return pointService.getAllPoint();
}
#PostConstruct
public void reint(){
point = new Point();
}
#PostConstruct
public void init() {
emptyModel = new DefaultMapModel();
}
public void addMarker() {
Marker marker=new Marker(new LatLng(point.getLatitude(), point.getLongitude()));
emptyModel.addOverlay((marker));
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Added", "Lat:" + point.getLatitude() + ", Lng:" + point.getLongitude()));
}
// =========================================================================
// GETTERS & SETTERS
// =========================================================================
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public MapModel getEmptyModel() {
return emptyModel;
}
public void setEmptyModel(MapModel emptyModel) {
this.emptyModel = emptyModel;
}
#Autowired
public void setPointService(PointService pointService) {
this.pointService = pointService;
}
}
and this is my xhtml file :
<h:head>
<title>Home</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
</h:head>
<h:body>
<p:growl id="messages" showDetail="true" />
<p:growl id="growl" showDetail="true" />
<p:gmap id="gmap" center="36.890257,10.365411" zoom="13" type="HYBRID" style="width:600px;height:400px"
model="#{pointBean.emptyModel}" onPointClick="handlePointClick(event);" widgetVar="map" >
</p:gmap>
<p:dialog widgetVar="dlg" showEffect="fade">
<h:form prependId="false">
<h:panelGrid columns="2">
<h:outputLabel for="title" value="Title:" />
<p:inputText id="title" value="#{pointBean.point.titre}" />
<f:facet name="footer">
<p:commandButton value="Add" actionListener="#{pointBean.savePoint}" update=":messages" oncomplete="markerAddComplete()" />
<p:commandButton value="Cancel" onclick="return cancel()" />
</f:facet>
</h:panelGrid>
<h:inputHidden id="longitude" value="#{pointBean.point.latitude}" />
<h:inputHidden id="latitude" value="#{pointBean.point.longitude}" />
</h:form>
</p:dialog>
<script type="text/javascript">
var currentMarker = null;
function handlePointClick(event) {
if(currentMarker === null) {
document.getElementById('longitude').value = event.latLng.lng();
document.getElementById('latitude').value = event.latLng.lat();
currentMarker = new google.maps.Marker({
position:new google.maps.LatLng(event.latLng.lat(), event.latLng.lng())
});
PF('map').addOverlay(currentMarker);
PF('dlg').show();
}
}
function markerAddComplete() {
var title = document.getElementById('title');
currentMarker.setTitle(title.value);
title.value = "";
currentMarker = null;
PF('dlg').hide();
}
function cancel() {
PF('dlg').hide();
currentMarker.setMap(null);
currentMarker = null;
return false;
}
</script>
</h:body>
</html>
what should i add in order to have an dragable marker !!
this is the example for the dragable marker from primefaces :
this is the dragableMarkerbean :
#ManagedBean
#ViewScoped
public class DraggableMarkersView implements Serializable {
private MapModel draggableModel;
private Marker marker;
#PostConstruct
public void init() {
draggableModel = new DefaultMapModel();
//Shared coordinates
LatLng coord1 = new LatLng(36.879466, 30.667648);
LatLng coord2 = new LatLng(36.883707, 30.689216);
LatLng coord3 = new LatLng(36.879703, 30.706707);
LatLng coord4 = new LatLng(36.885233, 30.702323);
//Draggable
draggableModel.addOverlay(new Marker(coord1, "Konyaalti"));
draggableModel.addOverlay(new Marker(coord2, "Ataturk Parki"));
draggableModel.addOverlay(new Marker(coord3, "Karaalioglu Parki"));
draggableModel.addOverlay(new Marker(coord4, "Kaleici"));
for(Marker premarker : draggableModel.getMarkers()) {
premarker.setDraggable(true);
}
}
public MapModel getDraggableModel() {
return draggableModel;
}
public void onMarkerDrag(MarkerDragEvent event) {
marker = event.getMarker();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Dragged", "Lat:" + marker.getLatlng().getLat() + ", Lng:" + marker.getLatlng().getLng()));
}
}
and this is the xhtml :
<h:form>
<p:growl id="growl" showDetail="true" />
<p:gmap id="gmap" center="36.890257,30.707417" zoom="13" type="HYBRID" model="#{draggableMarkersView.draggableModel}" style="width:600px;height:400px">
<p:ajax event="markerDrag" listener="#{draggableMarkersView.onMarkerDrag}" update="growl" />
</p:gmap>
</h:form>
please could you help me!! what should i add in order to have a draggable marker in the first example !!
You have to add in javascript handlePointClick.
add: currentMarker.setDraggable(true);
after: currentMarker = new google.maps.Marker ....

Primefaces Gmap markers issue

i have problem on na project with Gmap component of Primefaces 3.5 i using JSF2.0 and Jboss 1.7. So the problem is on page x.xhtml i have component gmap but gmap doesnt show model map from bean. The data is in the bean is correct. i include google api for gmaps, but markers doesnt work its only map.
I using this example->PrimeFaces Gmap
From this example i view a source from page and find a markers but on my page doesnt find.Managed bean its a Session scope.
Thanks for help
x.xhtml:
<p:ajax event="overlaySelect" listener="#{mapIskanjeBean.onMarkerSelect}" />
<p:gmapInfoWindow>
<p:outputPanel style="text-align:center;display:block;margin:auto:">
<p:graphicImage value="/img/#{mapBean.marker.data}" height="150"/>
<br />
<h:outputText value="#{mapIskanjeBean.marker.title}" />
</p:outputPanel>
</p:gmapInfoWindow>
</p:gmap>
mapIskanjeBean managed bean:
public class MapIskanjeBean implements Serializable {
private static final long serialVersionUID = 1L;
private MapModel advancedModel;
private Marker marker;
public MapIskanjeBean() {
advancedModel = new DefaultMapModel();
//Shared coordinates
LatLng coord1 = new LatLng(46.377291, 15.885323);
LatLng coord2 = new LatLng(36.883707, 30.689216);
LatLng coord3 = new LatLng(36.879703, 30.706707);
LatLng coord4 = new LatLng(36.885233, 30.702323);
LatLng coord5 = new LatLng(36.883333, 30.799323);
//Icons and Data
advancedModel.addOverlay(new Marker(coord1, "Konyaalti", "zelenjava.png", "http://maps.google.com/mapfiles/ms/micons/blue-dot.png"));
advancedModel.addOverlay(new Marker(coord2, "Ataturk Parki", "http://maps.google.com/mapfiles/ms/micons/pink-dot.png"));
advancedModel.addOverlay(new Marker(coord4, "Kaleici", "kaleici.png", "http://maps.google.com/mapfiles/ms/micons/pink-dot.png"));
advancedModel.addOverlay(new Marker(coord3, "Karaalioglu Parki", "karaalioglu.png", "http://maps.google.com/mapfiles/ms/micons/yellow-dot.png"));
advancedModel.addOverlay(new Marker(coord5,"hepan","http://maps.google.com/mapfiles/ms/micons/pink-dot.png","http://maps.google.com/mapfiles/ms/micons/pink-dot.png"));
}
public MapModel getAdvancedModel() {
return advancedModel;
}
public void onMarkerSelect(OverlaySelectEvent event) {
marker = (Marker) event.getOverlay();
}
public Marker getMarker() {
System.out.println("vzame marker");
return marker;
}
public void setAdvancedModel(MapModel advancedModel) {
System.out.println("nastavi model");
this.advancedModel = advancedModel;
}
public void setMarker(Marker marker) {
this.marker = marker;
}
}
Well, your code seems okay.
But if those images are with the wrong path, the markers will not show up.
So you can check out if the icons path are right!
good lucky!