package org.diretto.web.richwebclient.view.widgets.googlemap.server.base;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.diretto.api.client.base.data.BoundingBox;
import org.diretto.api.client.base.data.TopographicPoint;
import org.diretto.web.richwebclient.view.widgets.googlemap.client.base.MapType;
import org.diretto.web.richwebclient.view.widgets.googlemap.server.event.GoogleMapListener;
import org.diretto.web.richwebclient.view.widgets.googlemap.server.event.MapSectionListener;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.AbstractComponent;
/**
* This {@code abstract} class provides a default implementation and class
* constraints for {@code GoogleMap} server side components.
*
* @author Tobias Schlecht
*/
public abstract class AbstractGoogleMap extends AbstractComponent
{
private static final long serialVersionUID = -9063410826820373961L;
private final List<MapSectionListener> mapSectionListeners = new Vector<MapSectionListener>();
protected int zoomLevel;
protected double centerLatitude;
protected double centerLongitude;
protected MapType mapType;
protected boolean scrollWheelZoomingEnabled;
protected boolean draggingEnabled;
protected double lowerLeftLatitude = 0.0d;
protected double lowerLeftLongitude = 0.0d;
protected double upperRightLatitude = 0.0d;
protected double upperRightLongitude = 0.0d;
/**
* Provides base implementation to construct a {@code GoogleMap}.
*
* @param zoomLevel The initial zoom level
* @param centerLatitude The initial center latitude in degrees
* @param centerLongitude The initial center longitude in degrees
* @param mapType The initial {@code MapType}
*/
public AbstractGoogleMap(int zoomLevel, double centerLatitude, double centerLongitude, MapType mapType)
{
this(zoomLevel, centerLatitude, centerLongitude, mapType, true, true);
}
/**
* Provides base implementation to construct a {@code GoogleMap}.
*
* @param zoomLevel The initial zoom level
* @param centerLatitude The initial center latitude in degrees
* @param centerLongitude The initial center longitude in degrees
* @param mapType The initial {@code MapType}
* @param scrollWheelZoomingEnabled {@code true} if scroll wheel zooming is
* enabled; otherwise {@code false}
* @param draggingEnabled {@code true} if dragging is enabled; otherwise
* {@code false}
*/
public AbstractGoogleMap(int zoomLevel, double centerLatitude, double centerLongitude, MapType mapType, boolean scrollWheelZoomingEnabled, boolean draggingEnabled)
{
this.zoomLevel = zoomLevel;
this.centerLatitude = centerLatitude;
this.centerLongitude = centerLongitude;
this.mapType = mapType;
this.scrollWheelZoomingEnabled = scrollWheelZoomingEnabled;
this.draggingEnabled = draggingEnabled;
}
@Override
public void paintContent(PaintTarget target) throws PaintException
{
super.paintContent(target);
target.addVariable(this, "zoomLevel", zoomLevel);
target.addVariable(this, "centerLatitude", centerLatitude);
target.addVariable(this, "centerLongitude", centerLongitude);
target.addVariable(this, "mapType", mapType.toString());
target.addAttribute("applicationURL", getApplication().getURL().toString());
target.addAttribute("scrollWheelZoomingEnabled", scrollWheelZoomingEnabled);
target.addAttribute("draggingEnabled", draggingEnabled);
}
@Override
public void changeVariables(Object source, Map<String, Object> variables)
{
super.changeVariables(source, variables);
boolean mapSectionChanged = false;
if(variables.containsKey("zoomLevel"))
{
zoomLevel = (Integer) variables.get("zoomLevel");
}
if(variables.containsKey("centerLatitude"))
{
centerLatitude = (Double) variables.get("centerLatitude");
}
if(variables.containsKey("centerLongitude"))
{
centerLongitude = (Double) variables.get("centerLongitude");
}
if(variables.containsKey("mapType"))
{
mapType = MapType.valueOf((String) variables.get("mapType"));
}
if(variables.containsKey("lowerLeftLatitude"))
{
double lowerLeftLatitude = (Double) variables.get("lowerLeftLatitude");
if(this.lowerLeftLatitude != lowerLeftLatitude)
{
this.lowerLeftLatitude = lowerLeftLatitude;
mapSectionChanged = true;
}
}
if(variables.containsKey("lowerLeftLongitude"))
{
double lowerLeftLongitude = (Double) variables.get("lowerLeftLongitude");
if(this.lowerLeftLongitude != lowerLeftLongitude)
{
this.lowerLeftLongitude = lowerLeftLongitude;
mapSectionChanged = true;
}
}
if(variables.containsKey("upperRightLatitude"))
{
double upperRightLatitude = (Double) variables.get("upperRightLatitude");
if(this.upperRightLatitude != upperRightLatitude)
{
this.upperRightLatitude = upperRightLatitude;
mapSectionChanged = true;
}
}
if(variables.containsKey("upperRightLongitude"))
{
double upperRightLongitude = (Double) variables.get("upperRightLongitude");
if(this.upperRightLongitude != upperRightLongitude)
{
this.upperRightLongitude = upperRightLongitude;
mapSectionChanged = true;
}
}
if(mapSectionChanged)
{
final BoundingBox boundingBox = new BoundingBox(lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude);
for(final MapSectionListener mapSectionListener : mapSectionListeners)
{
new Thread(new Runnable()
{
@Override
public void run()
{
mapSectionListener.onMapSectionChanged(boundingBox);
}
}).start();
}
}
}
/**
* Returns the zoom level.
*
* @return The zoom level
*/
public int getZoomLevel()
{
return zoomLevel;
}
/**
* Sets the zoom level.
*
* @param zoomLevel The zoom level
*/
public void setZoomLevel(int zoomLevel)
{
this.zoomLevel = zoomLevel;
requestRepaint();
}
/**
* Increases the zoom level.
*/
public void zoomIn()
{
zoomLevel++;
requestRepaint();
}
/**
* Reduces the zoom level.
*/
public void zoomOut()
{
zoomLevel--;
requestRepaint();
}
/**
* Returns the map focus.
*
* @return The map focus
*/
public TopographicPoint getMapFocus()
{
return new TopographicPoint(centerLatitude, centerLongitude);
}
/**
* Sets the map focus to the given coordinates.
*
* @param centerLatitude The center latitude in degrees
* @param centerLongitude The center longitude in degrees
*/
public void setMapFocus(double centerLatitude, double centerLongitude)
{
this.centerLatitude = centerLatitude;
this.centerLongitude = centerLongitude;
requestRepaint();
}
/**
* Returns the {@link MapType}.
*
* @return The {@code MapType}
*/
public MapType getMapType()
{
return mapType;
}
/**
* Sets the {@link MapType}.
*
* @param mapType The {@code MapType}
*/
public void setMapType(MapType mapType)
{
this.mapType = mapType;
requestRepaint();
}
/**
* Returns the map section.
*
* @return The map section
*/
public BoundingBox getMapSection()
{
return new BoundingBox(lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude);
}
/**
* Adds the given {@link MapSectionListener}.
*
* @param mapSectionListener A {@code MapSectionListener}
*/
public synchronized void addMapSectionListener(MapSectionListener mapSectionListener)
{
if(!mapSectionListeners.contains(mapSectionListener))
{
mapSectionListeners.add(mapSectionListener);
}
}
/**
* Removes the given {@link GoogleMapListener}.
*
* @param googleMapListener A {@code GoogleMapListener}
*/
public synchronized void removeListener(GoogleMapListener googleMapListener)
{
if(googleMapListener instanceof MapSectionListener)
{
mapSectionListeners.remove(googleMapListener);
}
}
}