/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2003-2008, 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.gui.swing.map.map2d.stream.handler; import java.awt.Cursor; import java.awt.Toolkit; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ResourceBundle; import javax.swing.ImageIcon; import javax.swing.event.MouseInputListener; import org.geotools.gui.swing.icon.IconBundle; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.GeometryFactory; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import org.geotools.gui.swing.map.map2d.stream.NavigableMap2D; /** * Zoom out handler * * @author Johann Sorel * * @source $URL$ */ public class DefaultZoomOutHandler implements NavigationHandler { private static final ImageIcon ICON = IconBundle.getResource().getIcon("16_select_default"); private Cursor CUR_ZOOM_OUT; private static final String title = ResourceBundle.getBundle("org/geotools/gui/swing/map/map2d/handler/Bundle").getString("default"); protected final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(); private final MouseListen mouseInputListener = new MouseListen(); private final ZoomPanDecoration zoompanPanel = new ZoomPanDecoration(); private double zoomFactor = 2; private NavigableMap2D map2D = null; private boolean installed = false; protected Cursor CUR_SELECT; public DefaultZoomOutHandler() { buildCursors(); } private void buildCursors() { Toolkit tk = Toolkit.getDefaultToolkit(); ImageIcon ico_zoomOut = IconBundle.getResource().getIcon("16_zoom_out"); BufferedImage img2 = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); img2.getGraphics().drawImage(ico_zoomOut.getImage(), 0, 0, null); CUR_ZOOM_OUT = tk.createCustomCursor(img2, new Point(1, 1), "in"); } public void install(NavigableMap2D map) { installed = true; map2D = map; map2D.addDecoration(zoompanPanel); map2D.getComponent().addMouseListener(mouseInputListener); map2D.getComponent().addMouseMotionListener(mouseInputListener); map2D.getComponent().addMouseWheelListener(mouseInputListener); } public void uninstall() { map2D.removeDecoration(zoompanPanel); map2D.getComponent().removeMouseListener(mouseInputListener); map2D.getComponent().removeMouseMotionListener(mouseInputListener); map2D.getComponent().removeMouseWheelListener(mouseInputListener); map2D = null; installed = false; } public boolean isInstalled() { return installed; } public String getTitle() { return title; } public ImageIcon getIcon() { return ICON; } //---------------------PRIVATE CLASSES-------------------------------------- private class MouseListen implements MouseInputListener, MouseWheelListener { private int startX; private int startY; private int lastX; private int lastY; private int mousebutton = 0; private void drawRectangle(boolean view, boolean fill) { int left = Math.min(startX, lastX); int right = Math.max(startX, lastX); int top = Math.max(startY, lastY); int bottom = Math.min(startY, lastY); int width = right - left; int height = top - bottom; zoompanPanel.setFill(fill); zoompanPanel.setCoord(left, bottom, width, height, view); //graphics.drawRect(left, bottom, width, height); } private void processDrag(int x1, int y1, int x2, int y2, boolean pan) { Envelope mapArea = map2D.getRenderingStrategy().getMapArea(); if ((x1 == x2) && (y1 == y2)) { return; } Rectangle bounds = map2D.getComponent().getBounds(); double mapWidth = mapArea.getWidth(); double mapHeight = mapArea.getHeight(); double startX = ((x1 * mapWidth) / (double) bounds.width) + mapArea.getMinX(); double startY = (((bounds.getHeight() - y1) * mapHeight) / (double) bounds.height) + mapArea.getMinY(); double endX = ((x2 * mapWidth) / (double) bounds.width) + mapArea.getMinX(); double endY = (((bounds.getHeight() - y2) * mapHeight) / (double) bounds.height) + mapArea.getMinY(); double left; double right; double bottom; double top; Coordinate ll; Coordinate ur; if (!pan) { double deltaX1 = endX - startX; double deltaY1 = endY - startY; // make the dragged rectangle in screen coords the new map size? left = Math.min(startX, endX); right = Math.max(startX, endX); bottom = Math.min(startY, endY); top = Math.max(startY, endY); double nWidth = (mapWidth * mapWidth) / (right - left); double nHeight = (mapHeight * mapHeight) / (top - bottom); deltaX1 = left - mapArea.getMinX(); double nDeltaX1 = (deltaX1 * nWidth) / mapWidth; deltaY1 = bottom - mapArea.getMinY(); double nDeltaY1 = (deltaY1 * nHeight) / mapHeight; ll = new Coordinate(mapArea.getMinX() - nDeltaX1, mapArea.getMinY() - nDeltaY1); double deltaX2 = mapArea.getMaxX() - right; double nDeltaX2 = (deltaX2 * nWidth) / mapWidth; double deltaY2 = mapArea.getMaxY() - top; double nDeltaY2 = (deltaY2 * nHeight) / mapHeight; ur = new Coordinate(mapArea.getMaxX() + nDeltaX2, mapArea.getMaxY() + nDeltaY2); map2D.getRenderingStrategy().setMapArea(new Envelope(ll, ur)); } else { // move the image with the mouse // calculate X offsets from start point to the end Point double deltaX1 = endX - startX; // System.out.println("deltaX " + deltaX1); // new edges left = mapArea.getMinX() - deltaX1; right = mapArea.getMaxX() - deltaX1; // now for Y double deltaY1 = endY - startY; // System.out.println("deltaY " + deltaY1); bottom = mapArea.getMinY() - deltaY1; top = mapArea.getMaxY() - deltaY1; ll = new Coordinate(left, bottom); ur = new Coordinate(right, top); map2D.getRenderingStrategy().setMapArea(new Envelope(ll, ur)); } } public void mouseClicked(MouseEvent e) { mousebutton = e.getButton(); Envelope mapArea = map2D.getRenderingStrategy().getMapArea(); Rectangle bounds = map2D.getComponent().getBounds(); double x = (double) (e.getX()); double y = (double) (e.getY()); double width = mapArea.getWidth(); double height = mapArea.getHeight(); double width2 = mapArea.getWidth() / 2.0; double height2 = mapArea.getHeight() / 2.0; double mapX = ((x * width) / (double) bounds.width) + mapArea.getMinX(); double mapY = (((bounds.getHeight() - y) * height) / (double) bounds.height) + mapArea.getMinY(); double zlevel = 1.0; // left mouse button if (e.getButton() == MouseEvent.BUTTON1) { zlevel = 1.0 / zoomFactor; Coordinate ll = new Coordinate(mapX - (width2 / zlevel), mapY - (height2 / zlevel)); Coordinate ur = new Coordinate(mapX + (width2 / zlevel), mapY + (height2 / zlevel)); map2D.getRenderingStrategy().setMapArea(new Envelope(ll, ur)); } //right mouse button : pan action else if (e.getButton() == MouseEvent.BUTTON3) { zlevel = 1.0; Coordinate ll = new Coordinate(mapX - (width2 / zlevel), mapY - (height2 / zlevel)); Coordinate ur = new Coordinate(mapX + (width2 / zlevel), mapY + (height2 / zlevel)); map2D.getRenderingStrategy().setMapArea(new Envelope(ll, ur)); } } public void mousePressed(MouseEvent e) { startX = e.getX(); startY = e.getY(); lastX = 0; lastY = 0; mousebutton = e.getButton(); if (mousebutton == MouseEvent.BUTTON1) { } else if (mousebutton == MouseEvent.BUTTON3 ) { zoompanPanel.setCoord(0, 0, map2D.getComponent().getWidth(), map2D.getComponent().getHeight(), true); } } public void mouseReleased(MouseEvent e) { int endX = e.getX(); int endY = e.getY(); if (mousebutton == MouseEvent.BUTTON1) { drawRectangle(false, true); processDrag(startX, startY, endX, endY, false); } //right mouse button : pan action else if (mousebutton == MouseEvent.BUTTON3) { zoompanPanel.setFill(false); zoompanPanel.setCoord(0, 0, 0, 0, false); processDrag(startX, startY, endX, endY, true); } lastX = 0; lastY = 0; } public void mouseEntered(MouseEvent e) { map2D.getComponent().setCursor(CUR_ZOOM_OUT); } public void mouseExited(MouseEvent e) { zoompanPanel.setFill(false); zoompanPanel.setCoord(0, 0, 0, 0, true); } public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); // left mouse button if (mousebutton == MouseEvent.BUTTON1) { if ((lastX > 0) && (lastY > 0)) { drawRectangle(true, true); } // draw new box lastX = x; lastY = y; drawRectangle(true, true); } //right mouse button : pan action else if (mousebutton == MouseEvent.BUTTON3) { if ((lastX > 0) && (lastY > 0)) { int dx = lastX - startX; int dy = lastY - startY; zoompanPanel.setFill(false); zoompanPanel.setCoord(dx, dy, map2D.getComponent().getWidth(), map2D.getComponent().getHeight(), true); } lastX = x; lastY = y; } } public void mouseMoved(MouseEvent e) { } public void mouseWheelMoved(MouseWheelEvent e) { int val = e.getWheelRotation(); Coordinate coord = map2D.getRenderingStrategy().toMapCoord(e.getX(), e.getY()); if (val > 0) { Envelope env = map2D.getRenderingStrategy().getMapArea(); double width = env.getWidth(); double height = env.getHeight(); Coordinate nw = new Coordinate(coord); nw.x -= width; nw.y -= height; Coordinate se = new Coordinate(coord); se.x += width; se.y += height; Envelope env2 = new Envelope(nw, se); map2D.getRenderingStrategy().setMapArea(env2); } else if (val < 0) { Envelope env = map2D.getRenderingStrategy().getMapArea(); double width = env.getWidth(); double height = env.getHeight(); Coordinate nw = new Coordinate(coord); nw.x -= width / 4; nw.y -= height / 4; Coordinate se = new Coordinate(coord); se.x += width / 4; se.y += height / 4; Envelope env2 = new Envelope(nw, se); map2D.getRenderingStrategy().setMapArea(env2); } } } }