view src/econnect/wp3_3/client/widgets/map/Map.java @ 61:eac73bf1ce6e CellTable

add overlay functionality (beta)
author Sebastian Kruse <skruse@mpiwg-berlin.mpg.de>
date Fri, 14 Dec 2012 16:33:36 +0100
parents cf06b77a8bbd
children d69066d16e45
line wrap: on
line source

package econnect.wp3_3.client.widgets.map;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;

import econnect.wp3_3.client.core.ApplicationConstants;
import econnect.wp3_3.client.core.DataObject;
import econnect.wp3_3.client.core.StiConstants;
import econnect.wp3_3.client.slider.JsSlider;
import econnect.wp3_3.client.slider.Slider;
import econnect.wp3_3.client.core.StiCore;
import econnect.wp3_3.client.widgets.map.StiMap;

import java.util.Date;

/**
 * Implementation of the Java component of the map widget
*/
public class Map {

	/**
     * The Javascript map object 
    */
	private StiMap jsMap;

	/**
     * The active map control element 
    */
	private MapControl activeControl;

	/**
     * The sti core component 
    */
	StiCore core;
	
	/**
     * The navigation control 
    */
	private MapControl navigate;

	/**
     * The slider component of the map controls 
    */
	private Slider zoomBar;

	/**
     * The sliders maximum value 
    */
    private int max = 1000;
    
    private Image connections;
    
    /**
     * Constructor for the map widget java component
     *
     * @param core object to allow interaction with all javascript components
     * @param window id of the window to embed the map widget
     * @param container id of the container, the window will be added
    */
	public Map( StiCore core, String window, String container ){
		this.core = core;
		this.jsMap = StiMap.createStiMap(core, window, container);
	}
	
    /**
     * initializes the controls needed for map interaction
     *
     * @return a grid of control elements
    */
	public Grid initMapControls(){

		final ApplicationConstants constants = (ApplicationConstants) GWT.create(ApplicationConstants.class);
		final StiConstants textConstants = (StiConstants) GWT.create(StiConstants.class);		

		this.navigate = new MapControl( this, constants.navigateClickImage(), constants.navigateImage(), "navigate", textConstants.navigate() );
		//MapControl add = new MapControl( this, constants.addClickImage(), constants.addImage(), "add", textConstants.addElement() );
		MapControl polygonDrilldown = new MapControl( this, constants.polygonClickImage(), constants.polygonImage(), "polygon", textConstants.polygonDrilldown() );
		MapControl circleDrilldown = new MapControl( this, constants.circleClickImage(), constants.circleImage(), "circle", textConstants.circleDrilldown() );
		MapControl countryDrilldown = new MapControl( this, constants.countryClickImage(), constants.countryImage(), "country", textConstants.countryDrilldown() );
		this.navigate.activate();
		
		this.connections = new Image(constants.connectionsImage());
		this.connections.setTitle(textConstants.showConnections());
		this.connections.addClickHandler(new ClickHandler() {
		      public void onClick(ClickEvent event) {
		    	  boolean active = jsMap.connectionsClick();
		    	  setConImage(active);
		      }
		    });		    	    
	    
	    VerticalPanel drilldown = new VerticalPanel();
	    drilldown.add(polygonDrilldown.getButton());
	    drilldown.add(circleDrilldown.getButton());
	    drilldown.add(countryDrilldown.getButton());
	    drilldown.setStyleName("center");
	    
		final MenuBar mapsMenu = new MenuBar(true);
		final Image maps = new Image(constants.mapsImage());

		mapsMenu.setAnimationEnabled(true);	    
	    for( int i=0; i<this.jsMap.getMapCount(); i++ ){
	    	final int index = i;
		    mapsMenu.addItem(this.jsMap.getMapName(i), new Command() {
			      public void execute() {
			    	  jsMap.setMap(index);
			    	  RootPanel.get().remove(mapsMenu);
		    		  maps.setUrl(constants.mapsImage());
			      }
			    });
	    }
	    mapsMenu.addStyleName("zHigh");
	    
		maps.setTitle(textConstants.mapLayers());
	    maps.addClickHandler(new ClickHandler() {
		      public void onClick(ClickEvent event) {
		    	  if( !RootPanel.get().remove(mapsMenu) ){
		    		  maps.setUrl(constants.mapsClickImage());
		    		  int left = maps.getParent().getAbsoluteLeft() + maps.getParent().getOffsetWidth() + 3;
		    		  int top = maps.getAbsoluteTop();
		    		  RootPanel.get().add(mapsMenu, left, top);
		    	  }
		    	  else {
		    		  maps.setUrl(constants.mapsImage());
		    	  }
		      }
		    });    

	    //TODO: add correct (better) image
	    final Image overlay = new Image(constants.addImage());
		final MenuBar overlayMenu = new MenuBar(true);

		overlayMenu.setAnimationEnabled(true);
		//TODO: add overlays from data
	    //for( int i=0; i<this.jsMap.getMapCount(); i++ ){
	    //	final int index = i;
		overlayMenu.addItem("Limes", new Command() {
			      public void execute() {
			    	  jsMap.setOverlay(0);
			    	  RootPanel.get().remove(overlayMenu);
			    	  overlay.setUrl(constants.addImage());
			      }
			    });
	    //}
		overlayMenu.addStyleName("zHigh");
	    
	    overlay.setTitle(textConstants.overlayLayers());
	    overlay.addClickHandler(new ClickHandler() {
		      public void onClick(ClickEvent event) {
		    	  if( !RootPanel.get().remove(overlay) ){
		    		  //TODO: set correct (better) image
		    		  overlay.setUrl(constants.addClickImage());
		    		  int left = overlay.getParent().getAbsoluteLeft() + overlay.getParent().getOffsetWidth() + 3;
		    		  int top = overlay.getAbsoluteTop();
		    		  RootPanel.get().add(overlayMenu, left, top);
		    	  }
		    	  else {
		    		  overlay.setUrl(constants.addImage());
		    	  }
		      }
		    });
	    
	    final Grid controlGrid = new Grid(6,1);
	    controlGrid.setWidget(1, 0, maps);
	    controlGrid.setWidget(2, 0, this.navigate.getButton());
	    controlGrid.setWidget(3, 0, drilldown);
//	    controlGrid.setWidget(4, 0, add.getButton());
	    controlGrid.setWidget(4, 0, overlay);
	    controlGrid.setWidget(5, 0, connections);

	    final int levels = this.jsMap.getNumZoomLevels();
	    DivElement zoomDiv = Document.get().createDivElement();
	    zoomBar = new Slider(zoomDiv,"vertical");
	    zoomBar.getSlider().setMaximum(max);
	    zoomBar.getSlider().setValue(Math.round(this.jsMap.getZoom()/levels*max));
	    zoomBar.getSlider().addChangeListener(jsMap,Document.get(),true);
	    
	    final JsSlider slider = zoomBar.getSlider();
	    Image zoomIn = new Image(constants.zoomInImage());
	    zoomIn.addClickHandler(new ClickHandler() {
		      public void onClick(ClickEvent event) {
		    	  	float zoom = ((float)slider.getValue() + (float)max/levels) / max;
		    	  	if( zoom > 1.0f ){
		    	  		zoom = 1.0f;
		    	  	}
			        jsMap.zoom(zoom);
			        slider.setValue(Math.round(jsMap.getZoom()/levels*max));
			      }
			    });
	    Image zoomOut = new Image(constants.zoomOutImage());
	    zoomOut.addClickHandler(new ClickHandler() {
		      public void onClick(ClickEvent event) {
		    	  	float zoom = ((float)slider.getValue() - (float)max/levels) / max;
		    	  	if( zoom < 0.0f ){
		    	  		zoom = 0.0f;
		    	  	}
			        jsMap.zoom(zoom);
			        slider.setValue(Math.round(jsMap.getZoom()/levels*max));
			      }
			    });
	    
	    SimplePanel zoom = new SimplePanel();
	    zoom.getElement().appendChild(zoomDiv);
	    
	    AbsolutePanel zoomPanel = new AbsolutePanel();	    
	    zoomPanel.addStyleName("sliderStyle");
	    zoomPanel.addStyleName("cellStyle");
	    zoomPanel.addStyleName("center");
	    zoomPanel.add(zoomIn,2,0);
	    zoomPanel.add(zoom,0,10);
	    zoomPanel.add(zoomOut,2,84);
	    zoomIn.addStyleName("zHigh");
	    zoomOut.addStyleName("zHigh");
	    zoomPanel.setTitle(textConstants.mapZoom());
	    
	    controlGrid.setWidget(0, 0, zoomPanel);	
	    
	    return controlGrid;
	    
	}

    /**
     * creates the add element context div
     *
     * @param lon longitude value to fill the corresponding textbox
     * @param lat latitude value to fill the corresponding textbox
     * @param left left style value of the clicked point inside the window
     * @param top top style value of the clicked point inside the window
     * @param width width of the window
     * @param height height of the window
    */
	@SuppressWarnings("deprecation")
	public void setAddElementContext( double lon, double lat, int left, int top, int width, int height ){

		final StiConstants textConstants = (StiConstants) GWT.create(StiConstants.class);		

		Label header = new Label(textConstants.addElementBlank());
		header.setStyleName("addTitle");
		
		Label nameLabel = new Label(textConstants.name());
		final TextBox name = new TextBox();
		nameLabel.setStyleName("addItem");
		
		Label descriptionLabel = new Label(textConstants.description());
		descriptionLabel.setStyleName("addItem");
		final TextArea description = new TextArea();
		description.setVisibleLines(5);
		
		Label dateLabel = new Label(textConstants.date());
		dateLabel.setStyleName("addItem");
		Label actualDateLabel = new Label(textConstants.actualTime());
		actualDateLabel.setStyleName("addActualTime");
		Label formatLabel = new Label("(yyyy/MM/dd HH:mm:ss)");
		formatLabel.setStyleName("addActualTime");
		final TextBox defineDateBox = new TextBox();
		
		final RadioButton actualDate = new RadioButton("dateRadioGroup");
	    RadioButton defineDate = new RadioButton("dateRadioGroup");
	    actualDate.setChecked(true);

	    Grid dateGrid = new Grid(3,2);
	    dateGrid.setWidget(0, 0, actualDate);
	    dateGrid.setWidget(1, 0, defineDate);
	    dateGrid.setWidget(0, 1, actualDateLabel);
	    dateGrid.setWidget(1, 1, defineDateBox);
	    dateGrid.setWidget(2, 1, formatLabel);
	    
		Label placeLabel = new Label(textConstants.placename());
		placeLabel.setStyleName("addItem");
		final TextBox placeName = new TextBox();

		Label latitudeLabel = new Label(textConstants.latitude());
		latitudeLabel.setStyleName("addItem");
		final TextBox latitude = new TextBox();
		latitude.setText((new Double(lat)).toString());

		Label longitudeLabel = new Label(textConstants.longitude());
		longitudeLabel.setStyleName("addItem");
		final TextBox longitude = new TextBox();
		longitude.setText((new Double(lon)).toString());
	    
		Grid inputGrid = new Grid(6,2);
		inputGrid.setWidget(0, 0, nameLabel);
		inputGrid.setWidget(1, 0, descriptionLabel);
		inputGrid.setWidget(2, 0, dateLabel);
		inputGrid.setWidget(3, 0, placeLabel);
		inputGrid.setWidget(4, 0, latitudeLabel);
		inputGrid.setWidget(5, 0, longitudeLabel);
		inputGrid.setWidget(0, 1, name);
		inputGrid.setWidget(1, 1, description);
		inputGrid.setWidget(2, 1, dateGrid);
		inputGrid.setWidget(3, 1, placeName);
		inputGrid.setWidget(4, 1, latitude);
		inputGrid.setWidget(5, 1, longitude);
		
	    final String yearPattern = "yyyy";
	    final String monthPattern = "yyyy/MM";
	    final String datePattern = "yyyy/MM/dd";
	    final String dateTimePattern = "yyyy/MM/dd HH:mm:ss";

		final Grid grid = new Grid(3,1);	    
	    
		Button searchButton = new Button(textConstants.addElementBlank());
		searchButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				String dataName = name.getText();
				String dataDescription = description.getText();
				String dataPlace = placeName.getText();
				String dataDate;
				int granularity = 0;
				try {
					Date d = new Date();
					if( !actualDate.isChecked() ){
					    String input = defineDateBox.getText();
					    if( input.indexOf(":") != -1 ){
					    	d = DateTimeFormat.getFormat(dateTimePattern).parse(input);
					    	granularity = core.getSecondGranularity();
					    }
					    else if( input.indexOf("/") != -1 ){
					    	if( input.indexOf("/") == input.lastIndexOf("/") ){
						    	d = DateTimeFormat.getFormat(monthPattern).parse(input);
						    	granularity = core.getMonthGranularity();
					    	}
					    	else {
					    		d = DateTimeFormat.getFormat(datePattern).parse(input);
						    	granularity = core.getDateGranularity();
					    	}
					    }
					    else {
					    	d = DateTimeFormat.getFormat(yearPattern).parse(input);
					    	granularity = core.getYearGranularity();
					    }
					}
					dataDate = (new Long(d.getTime())).toString();
				}
				catch( IllegalArgumentException e ){
					core.alert("Enter a valid date format!");
					return;
				}
				double dataLongitude, dataLatitude;
				try {
					dataLongitude = Double.parseDouble(longitude.getText());
					dataLatitude = Double.parseDouble(latitude.getText());
				}
				catch( NumberFormatException e ){
					return;
				}
				DataObject object = DataObject.createDataObject(dataName, dataDescription, dataPlace, dataDate, granularity, dataLongitude, dataLatitude); 
				core.addElement(object);
				RootPanel.get().remove(grid);
			}
		});
		
	    Button cancelButton = new Button(textConstants.cancel());
		cancelButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				RootPanel.get().remove(grid);
			}
		});
				
		Grid buttons = new Grid(1,2);
		buttons.setWidget(0, 0, searchButton);
		buttons.setWidget(0, 1, cancelButton);
		
		grid.setWidget(0, 0, header);
		grid.setWidget(1, 0, inputGrid);
		grid.setWidget(2, 0, buttons);
		grid.setStyleName("center");
	    grid.addStyleName("zHigh");
	    grid.addStyleName("addPanel");
	    
		RootPanel.get().add(grid,0,0);
	    int addLeft = 0;
	    int addTop = top - 10;
	    if( width - left - grid.getOffsetWidth() - 10 < 0 ){
	    	addLeft = left - grid.getOffsetWidth() - 10;
	    }
	    else {
	    	addLeft = left + 10;
	    }
		RootPanel.get().add(grid, addLeft, addTop);
		
		this.switchToNavigation();
		
	}

	public void switchToNavigation(){
	    this.activeControl.deactivate();
		this.navigate.activate();		
	}
	
    /**
     * Getter for the corresponding Javascript component of the Map
     *
     * @return the Javascript component of the Map
    */
	public StiMap getJsMap(){
		return this.jsMap;
	}
	
    /**
     * sets value of corresponding zoom slider
     *
     * @param value value to set
    */
	public void setValue( float value ){
	    zoomBar.getSlider().setValue(Math.round(max*value));		
	}

    /**
     * Getter for the active map control element
     *
     * @return active map control
    */
	public MapControl getActiveControl(){
		return this.activeControl;
	}

    /**
     * Setter for the active map control element
     *
     * @param control active map control to set
    */
	public void setActiveControl(MapControl control) {
		this.activeControl = control;		
	}
	
	public void setConImage(boolean active) {
		final StiConstants textConstants = (StiConstants) GWT.create(StiConstants.class);
		final ApplicationConstants constants = (ApplicationConstants) GWT.create(ApplicationConstants.class);
  	  if( active ){
  		  connections.setTitle(textConstants.hideConnections());
  		  connections.setUrl(constants.connectionsClickImage());
  	  }
  	  else {
  		  connections.setTitle(textConstants.showConnections());
  		  connections.setUrl(constants.connectionsImage());
  	  }
	}
	
}