Package _org.geoforge.amd.wwwx.examples.measuretool

Source Code of _org.geoforge.amd.wwwx.examples.measuretool.GfrMeasureToolController

/*
*  Copyright (C) 2011-2013 GeoForge Project
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

package _org.geoforge.amd.wwwx.examples.measuretool;

import gov.nasa.worldwind.event.PositionEvent;
import gov.nasa.worldwind.event.PositionListener;
import gov.nasa.worldwind.event.RenderingEvent;
import gov.nasa.worldwind.event.RenderingListener;
import gov.nasa.worldwind.event.SelectEvent;
import gov.nasa.worldwind.event.SelectListener;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.pick.PickedObject;
import gov.nasa.worldwind.pick.PickedObjectList;
import gov.nasa.worldwind.util.BasicDragger;
import gov.nasa.worldwind.util.Logging;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/**
*
* @author Amadeus.Sowerby
*
* email: Amadeus.Sowerby_AT_gmail.com ... please remove "_AT_" from the above
* string to get the right email address
*/
public class GfrMeasureToolController extends MouseAdapter
        implements MouseListener, MouseMotionListener, SelectListener, PositionListener, RenderingListener
{

   protected GfrMeasureTool measureTool;

   protected boolean armed = false;

   protected boolean active = false;

   protected boolean moving = false;

   protected boolean useRubberBand = true;

   protected boolean freeHand = false;

   protected double freeHandMinSpacing = 100;

   protected ControlPoint rubberBandTarget;

   protected ControlPoint movingTarget;

   protected ControlPoint lastPickedObject;

   protected BasicDragger dragger;

   /**
    * Set the <code>GfrMeasureTool</code> that this controller will be operating on.
    *
    * @param measureTool the <code>GfrMeasureTool</code> that this controller will be operating on.
    */
   public void setMeasureTool(GfrMeasureTool measureTool)
   {
      if (measureTool == null)
      {
         String msg = Logging.getMessage("nullValue.MeasureToolIsNull");
         Logging.logger().severe(msg);
         throw new IllegalArgumentException(msg);
      }

      this.measureTool = measureTool;
   }

   /**
    * Get the <code>GfrMeasureTool</code> that this controller is operating on.
    *
    * @return the <code>GfrMeasureTool</code> that this controller is operating on.
    */
   public GfrMeasureTool getMeasureTool()
   {
      return this.measureTool;
   }

   /**
    * Returns true if this controller is using rubber band during shape creation. When using rubber band, new control
    * points are added by first pressing the left mouse button, then dragging the mouse toward the proper position,
    * then releasing the mouse button. Otherwise new control point are added for each new click of the mouse.
    *
    * @return true if this controller is using rubber band during shape creation.
    */
   public boolean isUseRubberBand()
   {
      return this.useRubberBand;
   }

   /**
    * Set whether this controller should use rubber band during shape creation. When using rubber band, new control
    * points are added by first pressing the left mouse button, then dragging the mouse toward the proper position,
    * then releasing the mouse button. Otherwise new control point are added for each new click of the mouse.
    *
    * @param state true if this controller should use rubber band during shape creation.
    */
   public void setUseRubberBand(boolean state)
   {
      this.useRubberBand = state;
   }

   /**
    * Get whether this controller allows free hand drawing of path and polygons while using rubber band mode.
    *
    * @return true if free hand drawing of path and polygons in rubber band mode.
    */
   public boolean isFreeHand()
   {
      return this.freeHand;
   }

   /**
    * Set whether this controller allows free hand drawing of path and polygons while using rubber band mode.
    *
    * @param state true to allow free hand drawing of path and polygons in rubber band mode.
    */
   public void setFreeHand(boolean state)
   {
      this.freeHand = state;
   }

   /**
    * Get the minimum distance in meters between two control points for free hand drawing.
    *
    * @return the minimum distance in meters between two control points for free hand drawing.
    */
   public double getFreeHandMinSpacing()
   {
      return this.freeHandMinSpacing;
   }

   /**
    * Set the minimum distance in meters between two control points for free hand drawing.
    *
    * @param distance the minimum distance in meters between two control points for free hand drawing.
    */
   public void setFreeHandMinSpacing(double distance)
   {
      this.freeHandMinSpacing = distance;
   }

   /**
    * Identifies whether the measure tool controller is armed.
    *
    * @return true if armed, false if not armed.
    */
   public boolean isArmed()
   {
      return this.armed;
   }

   /**
    * Arms and disarms the measure tool controller. When armed, the controller monitors user input and builds the
    * shape in response to user actions. When disarmed, the controller ignores all user input.
    *
    * @param armed true to arm the controller, false to disarm it.
    */
   public void setArmed(boolean armed)
   {
      if (this.armed != armed)
      {
         this.armed = armed;
         this.measureTool.firePropertyChange(GfrMeasureTool.EVENT_ARMED, !armed, armed);
      }
   }

   /**
    * Returns true if the controller is in the middle of a rubber band operation.
    *
    * @return true if the controller is in the middle of a rubber band operation.
    */
   public boolean isActive()
   {
      return this.active;
   }

   protected void setActive(boolean state)
   {
      this.active = state;
   }

   /**
    * Returns true if the controller is moving the measure shape as a whole.
    *
    * @return true if the controller is moving the measure shape as a whole.
    */
   public boolean isMoving()
   {
      return this.moving;
   }

   protected void setMoving(boolean state)
   {
      this.moving = state;
   }

   // Handle mouse actions
   @Override
   public void mousePressed(MouseEvent mouseEvent)
   {
      if (this.isArmed() && this.isUseRubberBand() && mouseEvent.getButton() == MouseEvent.BUTTON1)
      {
         if ((mouseEvent.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0)
         {
            if (!mouseEvent.isControlDown())
            {
               this.setActive(true);
               measureTool.addControlPoint();
              
               if (measureTool.getControlPoints().size() == 1)
               {
                  measureTool.addControlPoint(); // Simulate a second click
               }

               rubberBandTarget = (ControlPoint) measureTool.getControlPoints().get(
                       measureTool.getControlPoints().size() - 1);

               measureTool.firePropertyChange(GfrMeasureTool.EVENT_RUBBERBAND_START, null, null);
            }
         }
         mouseEvent.consume();
      }
      else if (!this.isArmed() && mouseEvent.getButton() == MouseEvent.BUTTON1 && mouseEvent.isAltDown())
      {

         this.setMoving(true);
         this.movingTarget = this.lastPickedObject;

         mouseEvent.consume();
      }
          
   }

   @Override
   public void mouseReleased(MouseEvent mouseEvent)
   {
      if (this.isArmed() && this.isUseRubberBand() && mouseEvent.getButton() == MouseEvent.BUTTON1)
      {
         if (this.isUseRubberBand() && measureTool.getPositions().size() == 1)
            measureTool.removeControlPoint();
         this.setActive(false);
         rubberBandTarget = null;
         // Disarm after second control point of a line or regular shape
         autoDisarm();
         mouseEvent.consume();
         measureTool.firePropertyChange(GfrMeasureTool.EVENT_RUBBERBAND_STOP, null, null);
      }
      else if (this.isMoving() && mouseEvent.getButton() == MouseEvent.BUTTON1)
      {
         this.setMoving(false);
         this.movingTarget = null;
         mouseEvent.consume();
      }
   }

   // Handle single click for removing control points
   @Override
   public void mouseClicked(MouseEvent mouseEvent)
   {
      if (measureTool == null)
         return;

      if (this.isArmed() && mouseEvent.getButton() == MouseEvent.BUTTON1)
      {
         if (mouseEvent.isControlDown())
            measureTool.removeControlPoint();
         else if (!this.isUseRubberBand())
         {
            measureTool.addControlPoint();
            // Disarm after second control point of a line or regular shape
            autoDisarm();
         }
         mouseEvent.consume();
      }
     
     
   }

   // Handle mouse motion
   @Override
   public void mouseDragged(MouseEvent mouseEvent)
   {
      if (measureTool == null)
         return;

      if (this.isActive() && this.isArmed() && (mouseEvent.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0)
      {
         // Don't update the control point here because the wwd current cursor position will not
         // have been updated to reflect the current mouse position. Wait to update in the
         // position listener, but consume the event so the view doesn't respond to it.
         mouseEvent.consume();
      }
      else if (!this.isArmed() && this.isMoving()
              && (mouseEvent.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0
              && mouseEvent.isAltDown())
      {
         // Consume the ALT+Drag mouse event to ensure the View does not respond to it. Don't update the control
         // point here because the wwd current cursor position will not have been updated to reflect the current
         // mouse position. Wait to update in the position listener, but consume the event so the view doesn't
         // respond to it.
         mouseEvent.consume();
      }
   }

   @Override
   public void mouseMoved(MouseEvent mouseEvent)
   {
   }

   // Handle cursor position change for rubber band
   @Override
   public void moved(PositionEvent event)
   {
      if (measureTool == null || (!this.active && !this.moving))
         return;

      this.doMoved(event);
   }

   // Handle dragging of control points
   @Override
   public void selected(SelectEvent event)
   {
      // Ignore select events if the tools is armed, or in a move/rotate action. In either case we don't
      // want to change the currently selected or hightlighted control point.
      if (measureTool == null || (this.isArmed() && this.isUseRubberBand()) || this.isMoving())
         return;

      if (dragger == null)
         dragger = new BasicDragger(measureTool.getWwd());

      // Have rollover events highlight the rolled-over object.
      if (event.getEventAction().equals(SelectEvent.ROLLOVER) && !dragger.isDragging())
      {
         this.highlight(event.getTopObject());
         this.measureTool.getWwd().redraw();
      }

      this.doSelected(event);

      // We missed any roll-over events while dragging, so highlight any under the cursor now,
      // or de-highlight the dragged control point if it's no longer under the cursor.
      if (event.getEventAction().equals(SelectEvent.DRAG_END))
      {
         PickedObjectList pol = this.measureTool.getWwd().getObjectsAtCurrentPosition();
         if (pol != null)
         {
            this.highlight(pol.getTopObject());
            this.measureTool.getWwd().redraw();
         }
      }
   }

   // Wait for end of rendering to update metrics - length, area...
   @Override
   public void stageChanged(RenderingEvent event)
   {
      if (measureTool == null)
         return;

      if (event.getStage().equals(RenderingEvent.AFTER_BUFFER_SWAP))
      {
         measureTool.firePropertyChange(GfrMeasureTool.EVENT_METRIC_CHANGED, null, null);
      }
   }

   @SuppressWarnings(
   {
      "UnusedDeclaration"
   })
   protected void doMoved(PositionEvent event)
   {
      if (this.active && rubberBandTarget != null && this.measureTool.getWwd().getObjectsAtCurrentPosition() != null
              && this.measureTool.getWwd().getObjectsAtCurrentPosition().getTerrainObject() != null)
      {
         if (!isFreeHand() || (!measureTool.getMeasureShapeType().equals(GfrMeasureTool.SHAPE_PATH) /*&& !measureTool.getMeasureShapeType().equals(GfrMeasureTool.SHAPE_POLYGON)*/))
         {
            // Rubber band - Move control point and update shape
            Position lastPosition = rubberBandTarget.getPosition();
            PickedObjectList pol = measureTool.getWwd().getObjectsAtCurrentPosition();
            PickedObject to = pol.getTerrainObject();
            rubberBandTarget.setPosition(new Position(to.getPosition(), 0));
            measureTool.moveControlPoint(rubberBandTarget);
            measureTool.firePropertyChange(GfrMeasureTool.EVENT_POSITION_REPLACE,
                    lastPosition, rubberBandTarget.getPosition());
            measureTool.getWwd().redraw();
         }
         else
         {
            // Free hand - Compute distance from current control point (rubber band target)
            Position lastPosition = rubberBandTarget.getPosition();
            Position newPosition = measureTool.getWwd().getCurrentPosition();
            double distance = LatLon.greatCircleDistance(lastPosition, newPosition).radians
                    * measureTool.getWwd().getModel().getGlobe().getRadius();
            if (distance >= freeHandMinSpacing)
            {
               // Add new control point
               measureTool.addControlPoint();
               rubberBandTarget = (ControlPoint) getMeasureTool().getControlPoints().get(
                       getMeasureTool().getControlPoints().size() - 1);
               measureTool.getWwd().redraw();
            }
         }
      }
     
   }

   /**
    * Move the shape to the specified new position
    * @param oldPosition Previous position of shape
    * @param newPosition New position for shape
    */
   protected void moveToPosition(Position oldPosition, Position newPosition)
   {
      Angle distanceAngle = LatLon.greatCircleDistance(oldPosition, newPosition);
      Angle azimuthAngle = LatLon.greatCircleAzimuth(oldPosition, newPosition);
      measureTool.moveMeasureShape(azimuthAngle, distanceAngle);
      measureTool.firePropertyChange(GfrMeasureTool.EVENT_POSITION_REPLACE, oldPosition, newPosition);
   }

   protected void doSelected(SelectEvent event)
   {
      if (this.movingTarget != null)
         return;

      if (!event.getEventAction().equals(SelectEvent.DRAG) && !event.getEventAction().equals(SelectEvent.DRAG_END))
         return;

      if (event.getTopObject() == null || !(event.getTopObject() instanceof ControlPoint)
              || ((ControlPoint) event.getTopObject()).getParent() != measureTool)
         return;

      // Have drag events drag the selected object.
      this.dragSelected(event);
   }

   protected void dragSelected(SelectEvent event)
   {
      ControlPoint point = (ControlPoint) event.getTopObject();

      LatLon lastPosition = point.getPosition();
      if (point.getValue(GfrMeasureTool.CONTROL_TYPE_LOCATION_INDEX) != null)
         lastPosition = measureTool.getPositions().get((Integer) point.getValue(GfrMeasureTool.CONTROL_TYPE_LOCATION_INDEX));

      // Delegate dragging computations to a dragger.
      this.dragger.selected(event);

      measureTool.moveControlPoint(point);
      if (measureTool.isShowAnnotation())
         measureTool.updateAnnotation(point.getPosition());
      measureTool.firePropertyChange(GfrMeasureTool.EVENT_POSITION_REPLACE,
              lastPosition, point.getPosition());
      measureTool.getWwd().redraw();
   }

   protected void highlight(Object o)
   {
      // Manage highlighting of control points
      if (this.lastPickedObject == o)
         return; // Same thing selected

      // Turn off highlight if on.
      if (this.lastPickedObject != null)
      {
         this.lastPickedObject.getAttributes().setHighlighted(false);
         this.lastPickedObject.getAttributes().setBackgroundColor(null); // use default
         this.lastPickedObject = null;
         if (measureTool.isShowAnnotation())
            measureTool.updateAnnotation(null);
         this.setCursor(null);
      }

      // Turn on highlight if object selected is a control point and belongs to this controller's GfrMeasureTool.
      if (this.lastPickedObject == null && o instanceof ControlPoint
              && ((ControlPoint) o).getParent() == measureTool)
      {
         this.lastPickedObject = (ControlPoint) o;
         this.lastPickedObject.getAttributes().setHighlighted(true);
         // Highlite using text color
         this.lastPickedObject.getAttributes().setBackgroundColor(
                 this.lastPickedObject.getAttributes().getTextColor());
         if (measureTool.isShowAnnotation())
            measureTool.updateAnnotation(this.lastPickedObject.getPosition());
         this.setCursor(this.lastPickedObject);
      }
   }

   protected void setCursor(ControlPoint controlPoint)
   {
      // TODO: handle 'rotating' mode cursor is this.isRotating() - when using Alt key on regular shapes
      if (controlPoint == null)
      {
         setComponentCursor(null);
      }
      else
      {
         // Line, path and polygon
         setComponentCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));

      }
   }

   protected Cursor selectResizeCursor(Angle azimuth)
   {
      while (azimuth.degrees < 0)
      {
         azimuth = azimuth.addDegrees(360);
      }

      if (azimuth.degrees < 22.5)
         return Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
      else if (azimuth.degrees < 67.5)
         return Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
      else if (azimuth.degrees < 112.5)
         return Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
      else if (azimuth.degrees < 157.5)
         return Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
      else if (azimuth.degrees < 202.5)
         return Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
      else if (azimuth.degrees < 247.5)
         return Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
      else if (azimuth.degrees < 292.5)
         return Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
      else if (azimuth.degrees < 337.5)
         return Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
      else // if (azimuth.degrees < 360)
         return Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
   }

   protected void setComponentCursor(Cursor cursor)
   {
      ((Component) this.measureTool.getWwd()).setCursor(cursor != null ? cursor : Cursor.getDefaultCursor());
   }

   protected void autoDisarm()
   {
      // Disarm after second control point of a line
      if (measureTool.getMeasureShapeType().equals(GfrMeasureTool.SHAPE_LINE))
         if (measureTool.getControlPoints().size() > 1)
            this.setArmed(false);
   }

}
TOP

Related Classes of _org.geoforge.amd.wwwx.examples.measuretool.GfrMeasureToolController

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.