/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2003-2011, Open Source Geospatial Foundation (OSGeo) * * This library 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; * version 2.1 of the License. * * This library 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. */ package org.geotools.swing.event; import java.awt.Component; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.geotools.geometry.DirectPosition2D; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.swing.MapPane; /** * A {@code MouseEvent} with methods to retrieve position in world coordinates. * * @author Michael Bedward (adapted from code by Cameron Shorter) * @since 2.6 * @source $URL$ * @version $Id$ */ public final class MapMouseEvent extends MouseEvent { private final DirectPosition2D worldCoords; private final boolean isWheelEvent; private final int wheelAmount; /** * Creates a new event instance. * * @param pane the source map pane * @param event the source mouse event */ public MapMouseEvent(MapPane pane, MouseEvent event) { super((Component) pane, event.getID(), event.getWhen(), event.getModifiers(), event .getX(), event.getY(), event.getClickCount(), event.isPopupTrigger(), event .getButton()); worldCoords = calculateWorldPos(pane, event); isWheelEvent = false; wheelAmount = 0; } /** * Creates a new event instance for a mouse wheel event. * * @param pane the source map pane * @param event the source mouse wheel event */ public MapMouseEvent(MapPane pane, MouseWheelEvent event) { super((Component) pane, event.getID(), event.getWhen(), event.getModifiers(), event .getX(), event.getY(), event.getClickCount(), event.isPopupTrigger()); worldCoords = calculateWorldPos(pane, event); isWheelEvent = true; wheelAmount = event.getWheelRotation(); } /** * Gets the source map pane for this event. */ @Override public MapPane getSource() { return (MapPane) super.getSource(); } /** * Queries whether this event was generated by a mouse wheel action. * * @return {@codetrue} if a mouse event */ public boolean isWheelEvent() { return isWheelEvent; } /** * Gets the wheel travel amount for a mouse wheel event. * * @return wheel travel, or 0 if this is not a mouse wheel event */ public int getWheelAmount() { return wheelAmount; } /** * Gets the position, in map (world) coordinates of this mouse event * * @return a new DirectPosition2D object for the world coordinates * * @deprecated Please use {@link #getWorldPos} instead */ public DirectPosition2D getMapPosition() { return getWorldPos(); } /** * Gets the mouse position in world coordinates. * * @return world position */ public DirectPosition2D getWorldPos() { return new DirectPosition2D( worldCoords.getCoordinateReferenceSystem(), worldCoords.x, worldCoords.y); } /** * Gets an envelope of specified width (in world distance units) which is * centred on the mouse position. * * @param widthWorld envelope width in world units * @return the envelope * * @throws IllegalArgumentException if {@code widthWorld} is less than zero */ public ReferencedEnvelope getEnvelopeByWorld(double widthWorld) { if (widthWorld < 0) { throw new IllegalArgumentException("invalid value for widthWorld: " + widthWorld); } double halfw = widthWorld / 2; DirectPosition2D worldPos = getWorldPos(); return new ReferencedEnvelope( worldPos.x - halfw, worldPos.x + halfw, worldPos.y - halfw, worldPos.y + halfw, worldPos.getCoordinateReferenceSystem()); } /** * Gets an envelope of specified width (in pixels) which is * centred on the mouse position. * * @param widthPixels envelope width in pixels * @return the envelope * * @throws IllegalArgumentException if {@code widthPixels} is less than zero */ public ReferencedEnvelope getEnvelopeByPixels(double widthPixels) { if (widthPixels < 0) { throw new IllegalArgumentException("invalid value for widthPixels: " + widthPixels); } Rectangle2D screenRect = new Rectangle2D.Double( getX() - (widthPixels / 2), getY() - (widthPixels / 2), widthPixels, widthPixels); MapPane pane = getSource(); Rectangle2D worldRect = pane.getScreenToWorldTransform().createTransformedShape( screenRect).getBounds2D(); return new ReferencedEnvelope(worldRect, pane.getMapContent().getCoordinateReferenceSystem()); } /** * Helper for constructors to calculate mouse position in world coordinates. * * @param pane source map pane * @param event source mouse event * @return position in world coordinates */ private DirectPosition2D calculateWorldPos(MapPane pane, MouseEvent event) { AffineTransform tr = pane.getScreenToWorldTransform(); DirectPosition2D pos = new DirectPosition2D(event.getX(), event.getY()); tr.transform(pos, pos); pos.setCoordinateReferenceSystem(pane.getMapContent().getCoordinateReferenceSystem()); return pos; } }