Package org.vaadin.hezamu.googlemapwidget

Source Code of org.vaadin.hezamu.googlemapwidget.GoogleMap$MarkerClickListener

package org.vaadin.hezamu.googlemapwidget;

import java.awt.geom.Point2D;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.vaadin.hezamu.googlemapwidget.overlay.BasicMarkerSource;
import org.vaadin.hezamu.googlemapwidget.overlay.InfoWindowTab;
import org.vaadin.hezamu.googlemapwidget.overlay.Marker;
import org.vaadin.hezamu.googlemapwidget.overlay.MarkerSource;
import org.vaadin.hezamu.googlemapwidget.overlay.PolyOverlay;
import org.vaadin.hezamu.googlemapwidget.overlay.Polygon;
import org.vaadin.hezamu.googlemapwidget.widgetset.client.ui.VGoogleMap;

import com.vaadin.Application;
import com.vaadin.terminal.ApplicationResource;
import com.vaadin.terminal.DownloadStream;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.ClientWidget;

/**
* Server side component for the VGoogleMap widget.
*/
@ClientWidget(VGoogleMap.class)
public class GoogleMap extends AbstractComponent {
  private static final long serialVersionUID = -7237970245561106947L;

  public enum MapControl {
    SmallMapControl, HierarchicalMapTypeControl, LargeMapControl, MapTypeControl, MenuMapTypeControl, OverviewMapControl, ScaleControl, SmallZoomControl
  }

  private Point2D.Double center;

  private Point2D.Double boundsNE;

  private Point2D.Double boundsSW;

  private int zoom;

  private final List<MapMoveListener> moveListeners = new ArrayList<MapMoveListener>();

  private final List<MapClickListener> mapClickListeners = new ArrayList<MapClickListener>();

  private final List<MarkerClickListener> markerListeners = new ArrayList<MarkerClickListener>();

  private final List<MarkerMovedListener> markerMovedListeners = new ArrayList<MarkerMovedListener>();

  private MarkerSource markerSource = null;

  private Marker clickedMarker = null;

  private boolean closeInfoWindow = false;

  private final Map<Long, PolyOverlay> overlays = new HashMap<Long, PolyOverlay>();

  // private boolean overlaysChanged = false;

  private boolean scrollWheelZoomEnabled = true;

  private boolean clearMapTypes = false;

  private final List<MapControl> controls = new ArrayList<MapControl>();

  private final List<CustomMapType> mapTypes = new ArrayList<CustomMapType>();

  private boolean mapTypesChanged = false;

  private boolean reportMapBounds = false;

  private final ApplicationResource markerResource = new ApplicationResource() {
    private static final long serialVersionUID = -6926454922185543547L;

    public Application getApplication() {
      return GoogleMap.this.getApplication();
    }

    public int getBufferSize() {
      return markerSource.getMarkerJSON().length;
    }

    public long getCacheTime() {
      return -1;
    }

    public String getFilename() {
      return "markersource.txt";
    }

    public DownloadStream getStream() {
      return new DownloadStream(new ByteArrayInputStream(
          markerSource.getMarkerJSON()), getMIMEType(), getFilename());
    }

    public String getMIMEType() {
      return "text/plain";
    }
  };

  private String apiKey = "";

  private int clientLogLevel = 0;

  /**
   * Construct a new instance of the map with given size.
   *
   * @param application
   * @link Application owning this instance.
   */
  public GoogleMap(Application application) {
    application.addResource(markerResource);

    // Greewich Royal Observatory
    center = new Point2D.Double(-0.001475, 51.477811);
    zoom = 14;
  }

  /**
   * Construct a new instance of the map with given parameters.
   *
   * @param application
   * @link Application owning this instance.
   * @param center
   *            center of the map as a {@link Point2D.Double}
   * @param zoom
   *            initial zoom level of the map
   */
  public GoogleMap(Application application, Point2D.Double center, int zoom) {
    this(application);

    this.center = center;
    this.zoom = zoom;
  }

  /**
   * Construct a new instance of the map with given size.
   *
   * @param application
   * @link Application owning this instance.
   * @param apiKey
   *            - the API key to be used for Google Maps
   */
  public GoogleMap(Application application, String apiKey) {
    application.addResource(markerResource);
    this.apiKey = apiKey;

    // Greewich Royal Observatory
    center = new Point2D.Double(-0.001475, 51.477811);
    zoom = 14;
  }

  /**
   * Construct a new instance of the map with given parameters.
   *
   * @param application
   * @link Application owning this instance.
   * @param center
   *            center of the map as a {@link Point2D.Double}
   * @param zoom
   *            initial zoom level of the map
   * @param apiKey
   *            - the API key to be used for Google Maps
   */
  public GoogleMap(Application application, Point2D.Double center, int zoom,
      String apiKey) {
    this(application);
    this.apiKey = apiKey;

    this.center = center;
    this.zoom = zoom;
  }

  @Override
  public void paintContent(PaintTarget target) throws PaintException {
    super.paintContent(target);
    target.addVariable(this, "center_lat", center.y);
    target.addVariable(this, "center_lng", center.x);
    target.addVariable(this, "zoom", zoom);
    target.addVariable(this, "swze", scrollWheelZoomEnabled);
    target.addAttribute("apikey", apiKey);
    target.addAttribute("loglevel", clientLogLevel);

    for (MapControl control : controls) {
      target.addAttribute(control.name(), true);
    }

    // TODO this feels like a kludge, but unsure how to implement correctly
    if (clickedMarker != null) {
      target.addAttribute("marker", clickedMarker.getId().toString());
      target.startTag("tabs");
      InfoWindowTab[] tabs = clickedMarker.getInfoWindowContent();
      for (int i = 0; i < tabs.length; i++) {
        target.startTag("tab");
        if (tabs.length > 1) {
          target.addAttribute("selected", tabs[i].isSelected());
          target.addAttribute("label", tabs[i].getLabel());
        }
        tabs[i].getContent().paint(target);

        target.endTag("tab");
      }
      target.endTag("tabs");

      clickedMarker = null;
    } else if (markerSource != null) {
      target.addAttribute("markerRes", markerResource);
    }

    if (closeInfoWindow) {
      target.addAttribute("closeInfoWindow", true);
      closeInfoWindow = false;
    }

    // if (overlaysChanged) {
    target.startTag("overlays");

    for (PolyOverlay poly : overlays.values()) {
      target.startTag("o");
      target.addAttribute("id", poly.getId());

      // Encode polyline points as a string attribute
      StringBuilder sb = new StringBuilder();
      Point2D.Double[] points = poly.getPoints();
      for (int i = 0; i < points.length; i++) {
        if (i > 0) {
          sb.append(" ");
        }
        sb.append("" + points[i].y + "," + points[i].x);
      }
      target.addAttribute("points", sb.toString());

      target.addAttribute("color", poly.getColor());
      target.addAttribute("weight", poly.getWeight());
      target.addAttribute("opacity", poly.getOpacity());
      target.addAttribute("clickable", poly.isClickable());

      if (poly instanceof Polygon) {
        Polygon polygon = (Polygon) poly;
        target.addAttribute("fillcolor", polygon.getFillColor());
        target.addAttribute("fillopacity", polygon.getFillOpacity());
      }
      target.endTag("o");
    }

    target.endTag("overlays");
    //
    // overlaysChanged = false;
    // }

    if (clearMapTypes) {
      target.addAttribute("clearMapTypes", true);
      clearMapTypes = false;
    }

    if (mapTypesChanged) {
      target.startTag("mapTypes");

      for (CustomMapType mapType : mapTypes) {
        mapType.paintContent(target);
      }

      target.endTag("mapTypes");

      mapTypesChanged = false;
    }

    if (reportMapBounds) {
      target.addAttribute("reportBounds", true);
      reportMapBounds = false;
    }
  }

  /**
   * Receive and handle events and other variable changes from the client.
   *
   * {@inheritDoc}
   */
  @Override
  public void changeVariables(Object source, Map<String, Object> variables) {
    super.changeVariables(source, variables);

    if (variables.containsKey("click_pos")) {
      fireClickEvent(variables.get("click_pos"));
      requestRepaint();
    }

    boolean moveEvent = false;
    Integer intVar;
    if ((intVar = (Integer) variables.get("zoom")) != null) {
      zoom = intVar;
      moveEvent = true;
    }

    String stringVar;
    if ((stringVar = (String) variables.get("center")) != null
        && !stringVar.trim().equals("")) {
      center = GoogleMap.strToLL(stringVar);
      moveEvent = true;
    }

    if ((stringVar = (String) variables.get("bounds_ne")) != null
        && !stringVar.trim().equals("")) {
      boundsNE = GoogleMap.strToLL(stringVar);
      moveEvent = true;
    }

    if ((stringVar = (String) variables.get("bounds_sw")) != null
        && !stringVar.trim().equals("")) {
      boundsSW = GoogleMap.strToLL(stringVar);
      moveEvent = true;
    }

    if (moveEvent) {
      fireMoveEvent();
    }

    if (variables.containsKey("marker")) {
      clickedMarker = markerSource.getMarker(variables.get("marker")
          .toString());
      if (clickedMarker != null) {
        fireMarkerClickedEvent(clickedMarker);
        if (clickedMarker.getInfoWindowContent() != null) {
          requestRepaint();
        }
      }
    }

    if (variables.containsKey("markerMovedId")) {
      String markerID = variables.get("markerMovedId").toString()
          .replaceAll("\"", "");
      List<Marker> markers = markerSource.getMarkers();

      for (Marker mark : markers) {
        if (mark.getId() == Long.parseLong(markerID)) {

          double lat = new Double(variables.get("markerMovedLat")
              .toString());
          double lng = new Double(variables.get("markerMovedLong")
              .toString());
          mark.getLatLng().setLocation(lng, lat);

          fireMarkerMovedEvent(mark);
          break;
        }
      }
    }
  }

  private void fireMoveEvent() {
    for (MapMoveListener listener : moveListeners) {
      listener.mapMoved(zoom, center, boundsNE, boundsSW);
    }
  }

  private void fireClickEvent(Object object) {
    Point2D.Double clickPos = GoogleMap.strToLL(object.toString());
    for (MapClickListener listener : mapClickListeners) {
      listener.mapClicked(clickPos);
    }
  }

  private void fireMarkerClickedEvent(Marker clickedMarker) {
    for (MarkerClickListener m : markerListeners) {
      m.markerClicked(clickedMarker);
    }
  }

  private void fireMarkerMovedEvent(Marker movedMarker) {
    for (MarkerMovedListener m : markerMovedListeners) {
      m.markerMoved(movedMarker);
    }
  }

  /**
   * Interface for listening map move and zoom events.
   *
   * @author Henri Muurimaa
   */
  public interface MapMoveListener {
    /**
     * Handle a MapMoveEvent.
     *
     * @param newZoomLevel
     *            New zoom level
     * @param newCenter
     *            New center coordinates
     * @param boundsNE
     *            Coordinates of the north-east corner of the map
     * @param boundsSW
     *            Coordinates of the south-west corner of the map
     */
    public void mapMoved(int newZoomLevel, Point2D.Double newCenter,
        Point2D.Double boundsNE, Point2D.Double boundsSW);
  }

  /**
   * Interface for listening map click events.
   *
   * @author Henri Muurimaa
   */
  public interface MapClickListener {
    /**
     * Handle a MapClickEvent.
     *
     * @param clickPos
     *            coordinates of the click event.
     *
     */
    public void mapClicked(Point2D.Double clickPos);
  }

  /**
   * Interface for listening marker click events.
   *
   */
  public interface MarkerClickListener {
    /**
     * Handle a MarkerClickEvent.
     *
     * @param clickedMarker
     *            the marker that was clicked.
     *
     */
    public void markerClicked(Marker clickedMarker);
  }

  /**
   * Interface for listening marker move events.
   *
   */
  public interface MarkerMovedListener {
    /**
     * Handle a MarkerMovedEvent.
     *
     * @param movedMarker
     *            the marker that was moved.
     *
     */
    public void markerMoved(Marker movedMarker);
  }

  /**
   * Register a new {@link MapClickListener}.
   *
   * @param listener
   *            new {@link MapClickListener} to register
   */
  public void addListener(MapClickListener listener) {
    if (!mapClickListeners.contains(listener)) {
      mapClickListeners.add(listener);
    }
  }

  /**
   * Deregister a {@link MapClickListener}.
   *
   * @param listener
   *            {@link MapClickListener} to deregister
   */
  public void removeListener(MapClickListener listener) {
    if (mapClickListeners.contains(listener)) {
      mapClickListeners.remove(listener);
    }
  }

  /**
   * Register a new {@link MapMoveListener}.
   *
   * @param listener
   *            new {@link MapMoveListener} to register
   */
  public void addListener(MapMoveListener listener) {
    if (!moveListeners.contains(listener)) {
      moveListeners.add(listener);
    }
  }

  /**
   * Register a new {@link MarkerMovedListener}.
   *
   * NOTE!! The marker that is clicked MUST have some information window
   * content! This is due to the implementation of the Widget, as the marker
   * click events do not propagate if there is not a information window
   * opened.
   *
   * @param listener
   *            new {@link MarkerClickListener} to register
   */
  public void addListener(MarkerClickListener listener) {
    if (!markerListeners.contains(listener)) {
      markerListeners.add(listener);
    }
  }

  /**
   * Register a new {@link MarkerMovedListener}.
   *
   *
   *
   * @param listener
   *            new {@link MarkerMovedListener} to register
   */
  public void addListener(MarkerMovedListener listener) {
    if (!markerMovedListeners.contains(listener)) {
      markerMovedListeners.add(listener);
    }
  }

  /**
   * Deregister a {@link MapMoveListener}.
   *
   * @param listener
   *            {@link MapMoveListener} to deregister
   */
  public void removeListener(MapMoveListener listener) {
    if (moveListeners.contains(listener)) {
      moveListeners.remove(listener);
    }
  }

  /**
   * Deregister a {@link MarkerClickListener}.
   *
   * @param listener
   *            {@link MarkerClickListener} to deregister
   */
  public void removeListener(MarkerClickListener listener) {
    if (markerListeners.contains(listener)) {
      markerListeners.remove(listener);
    }
  }

  /**
   * Deregister a {@link MarkerMovedListener}.
   *
   * @param listener
   *            the {@link MarkerMovedListener} to deregister
   */
  public void removeListener(MarkerMovedListener listener) {
    if (markerMovedListeners.contains(listener)) {
      markerMovedListeners.remove(listener);
    }
  }

  /**
   * Get current center coordinates of the map.
   *
   * @return
   */
  public Point2D.Double getCenter() {
    return center;
  }

  /**
   * Set the current center coordinates of the map. This method can be used to
   * pan the map programmatically.
   *
   * @param center
   *            the new center coordinates
   */
  public void setCenter(Point2D.Double center) {
    this.center = center;
    requestRepaint();
  }

  /**
   * Get the current zoom level of the map.
   *
   * @return the current zoom level
   */
  public int getZoom() {
    return zoom;
  }

  /**
   * Set the zoom level of the map. This method can be used to zoom the map
   * programmatically.
   *
   * @param zoom
   */
  public void setZoom(int zoom) {
    this.zoom = zoom;
    requestRepaint();
  }

  /**
   * Set the level of verbosity the client side uses for tracing or displaying
   * error messages.
   *
   * @param level
   */
  public void setClientLogLevel(int level) {
    this.clientLogLevel = level;
    requestRepaint();
  }

  /**
   * Get the level of verbosity the client side uses for tracing or displaying
   * error messages.
   */
  public int getClientLogLevel() {
    return clientLogLevel;
  }

  /**
   * Get the coordinates of the north-east corner of the map.
   *
   * @return
   */
  public Point2D.Double getBoundsNE() {
    return boundsNE;
  }

  /**
   * Get the coordinates of the south-west corner of the map.
   *
   * @return
   */
  public Point2D.Double getBoundsSW() {
    return boundsSW;
  }

  /**
   * Set the {@link MarkerSource} for the map.
   *
   * @param markerSource
   */
  public void setMarkerSource(MarkerSource markerSource) {
    this.markerSource = markerSource;
  }

  /**
   * Close the currently open info window, if any.
   */
  public void closeInfoWindow() {
    closeInfoWindow = true;
    requestRepaint();
  }

  /**
   * Add a new {@link PolyOverlay} to the map. Does nothing if the overlay
   * already exist on the map.
   *
   * @param overlay
   *            {@link PolyOverlay} to add
   *
   * @return True if the overlay was added.
   */
  public boolean addPolyOverlay(PolyOverlay overlay) {
    if (!overlays.containsKey(overlay.getId())) {
      overlays.put(overlay.getId(), overlay);
      // overlaysChanged = true;
      requestRepaint();
      return true;
    }

    return false;
  }

  /**
   * Update a {@link PolyOverlay} on the map. Does nothing if the overlay does
   * not exist on the map.
   *
   * @param overlay
   *            {@link PolyOverlay} to update
   *
   * @return True if the overlay was updated.
   */
  public boolean updateOverlay(PolyOverlay overlay) {
    if (overlays.containsKey(overlay.getId())) {
      overlays.put(overlay.getId(), overlay);
      // overlaysChanged = true;
      requestRepaint();
      return true;
    }

    return false;
  }

  /**
   * Remove a {@link PolyOverlay} from the map. Does nothing if the overlay
   * does not exist on the map.
   *
   * @param overlay
   *            {@link PolyOverlay} to remove
   *
   * @return True if the overlay was removed.
   */
  public boolean removeOverlay(PolyOverlay overlay) {
    if (overlays.containsKey(overlay.getId())) {
      overlays.remove(overlay.getId());
      // overlaysChanged = true;
      requestRepaint();
      return true;
    }

    return false;
  }

  /**
   * Get the collection of {@link PolyOverlay}s currently in the map.
   *
   * @return a {@link Collection} of overlays.
   */
  public Collection<PolyOverlay> getOverlays() {
    return overlays.values();
  }

  private static Point2D.Double strToLL(String latLngStr) {
    if (latLngStr == null) {
      return null;
    }

    String nums[] = latLngStr.split(", ");
    if (nums.length != 2) {
      return null;
    }

    double lat = Double.parseDouble(nums[0].substring(1));

    double lng = Double.parseDouble(nums[1].substring(0,
        nums[1].length() - 1));

    return new Point2D.Double(lng, lat);
  }

  /**
   * Add a Marker to the current MarkerSource. If the map has no marker source
   * a new {@link BasicMarkerSource} is created.
   *
   * @param marker
   *            Marker to add
   */
  public void addMarker(Marker marker) {
    if (markerSource == null) {
      markerSource = new BasicMarkerSource();
    }

    markerSource.addMarker(marker);
    requestRepaint();
  }

  /**
   * Removes the marker from the map
   *
   * @param marker
   */
  public void removeMarker(Marker marker) {
    if (markerSource != null) {
      markerSource.getMarkers().remove(marker);
      requestRepaint();
    }
  }

  public void removeAllMarkers() {
    if (markerSource != null) {
      markerSource.getMarkers().clear();
      requestRepaint();
    }
  }

  public void setScrollWheelZoomEnabled(boolean isEnabled) {
    scrollWheelZoomEnabled = isEnabled;
  }

  public boolean isScrollWheelZoomEnabled() {
    return scrollWheelZoomEnabled;
  }

  public boolean addControl(MapControl control) {
    if (!controls.contains(control)) {
      controls.add(control);
      return true;
    }

    return false;
  }

  public boolean hasControl(MapControl control) {
    return controls.contains(control);
  }

  public boolean removeControl(MapControl control) {
    if (controls.contains(control)) {
      controls.remove(control);
      return true;
    }

    return false;
  }

  public void addMapType(String name, int minZoom, int maxZoom,
      String copyright, String tileUrl, boolean isPng, double opacity) {
    mapTypes.add(new CustomMapType(name, minZoom, maxZoom, copyright,
        tileUrl, isPng, opacity));

    mapTypesChanged = true;

    requestRepaint();
  }

  public void clearMapTypes() {
    mapTypes.clear();
    clearMapTypes = true;
    requestRepaint();
  }

  public void reportMapBounds() {
    reportMapBounds = true;
    requestRepaint();
  }

  class CustomMapType {
    private final double opacity;
    private final String tileUrl;
    private final boolean isPng;
    private final int minZoom;
    private final int maxZoom;
    private final String copyright;
    private final String name;

    public CustomMapType(String name, int minZoom, int maxZoom,
        String copyright, String tileUrl, boolean isPng, double opacity) {
      this.name = name;
      this.minZoom = minZoom;
      this.maxZoom = maxZoom;
      this.copyright = copyright;
      this.tileUrl = tileUrl;
      this.isPng = isPng;
      this.opacity = opacity;
    }

    public void paintContent(PaintTarget target) throws PaintException {
      target.startTag("maptype");
      target.addAttribute("name", name);
      target.addAttribute("minZoom", minZoom);
      target.addAttribute("maxZoom", maxZoom);
      target.addAttribute("copyright", copyright);
      target.addAttribute("tileUrl", tileUrl);
      target.addAttribute("isPng", isPng);
      target.addAttribute("opacity", opacity);
      target.endTag("maptype");
    }

    public double getOpacity() {
      return opacity;
    }

    public String getTileUrl() {
      return tileUrl;
    }

    public boolean isPng() {
      return isPng;
    }

    public int getMinZoom() {
      return minZoom;
    }

    public int getMaxZoom() {
      return maxZoom;
    }

    public String getCopyright() {
      return copyright;
    }
  }
}
TOP

Related Classes of org.vaadin.hezamu.googlemapwidget.GoogleMap$MarkerClickListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.