/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * JUMP is Copyright (C) 2003 Vivid Solutions * * This program implements extensions to JUMP and is * Copyright (C) Stefan Steiniger. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU 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. * * For more information, contact: * Stefan Steiniger * perriger@gmx.de */ /***************************************************** * created: by Vivid Solutions * last modified: 22.05.2005 by sstein * 28.01.2006 new MultiInputDialog without cancel button * * description: * draws a circle for a given radius (showing the circle on mouse endpoint) * *****************************************************/ package org.openjump.core.ui.plugin.edittoolbox.cursortools; import java.awt.BasicStroke; import java.awt.Container; import java.awt.Cursor; import java.awt.Frame; import java.awt.Shape; import java.awt.event.MouseEvent; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import javax.swing.AbstractButton; import javax.swing.Icon; import javax.swing.ImageIcon; //import org.openjump.core.ui.MultiInputDialogWithoutCancel; import com.vividsolutions.jump.workbench.ui.MultiInputDialog; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.operation.buffer.BufferOp; import com.vividsolutions.jts.operation.valid.IsValidOp; import com.vividsolutions.jump.I18N; import com.vividsolutions.jump.feature.Feature; import com.vividsolutions.jump.feature.FeatureCollection; import com.vividsolutions.jump.workbench.WorkbenchContext; import com.vividsolutions.jump.workbench.model.Layer; import com.vividsolutions.jump.workbench.plugin.PlugInContext; import com.vividsolutions.jump.workbench.ui.EditTransaction; import com.vividsolutions.jump.workbench.ui.GUIUtil; import com.vividsolutions.jump.workbench.ui.LayerNamePanelProxy; import com.vividsolutions.jump.workbench.ui.LayerViewPanel; import com.vividsolutions.jump.workbench.ui.LayerViewPanelContext; import com.vividsolutions.jump.workbench.ui.MultiInputDialog; import com.vividsolutions.jump.workbench.ui.WorkbenchFrame; import com.vividsolutions.jump.workbench.ui.cursortool.AbstractCursorTool; import com.vividsolutions.jump.workbench.ui.cursortool.CursorTool; import com.vividsolutions.jump.workbench.ui.cursortool.DragTool; import com.vividsolutions.jump.workbench.ui.cursortool.MultiClickTool; import com.vividsolutions.jump.workbench.ui.cursortool.NClickTool; import com.vividsolutions.jump.workbench.ui.cursortool.editing.DrawPointTool; import com.vividsolutions.jump.workbench.ui.cursortool.editing.FeatureDrawingUtil; import com.vividsolutions.jump.workbench.ui.images.IconLoader; public class DrawCircleWithGivenRadiusTool extends NClickTool{ //---- from DragTool ----------------- /** Modify using #setDestination */ protected Coordinate modelDestination = null; //------------------------------------ private FeatureDrawingUtil featureDrawingUtil; private Shape selectedFeaturesShape; private GeometryFactory geometryFactory = new GeometryFactory(); private boolean valuesWereSet = false; private double radius= 50.0; //in m private Point mp = null; private int points = 8; private double tolerance = 0.1; private int deactivateCount=0; //private String T1 = "Circle Radius"; private String T1 = I18N.get("org.openjump.core.ui.plugin.edittoolbox.cursortools.DrawCircleWithGivenRadiusTool.Cirlce-Radius") + ":"; //private String T2 = "Number of segments per circle quarter"; private String T2 = I18N.get("org.openjump.core.ui.plugin.edittoolbox.cursortools.DrawCircleWithGivenRadiusTool.Number-of-segments-per-circle-quarter") + ":"; //private String name = "Draw circle with given radius and center."; private String name = I18N.get("org.openjump.core.ui.plugin.edittoolbox.cursortools.DrawCircleWithGivenRadiusTool.Draw-circle-with-given-radius-and-center"); //private String sidebarstring = "Draws a circle by specifiying the radius, the number of segments per circle quarter and the center position by mouse click"; //private String sidebarstring = I18N.get("org.openjump.core.ui.plugin.edittoolbox.cursortools.DrawCircleWithGivenRadiusTool.Draws-a-circle-by-specifiying-the-radius-the-number-of-segments-per-circle-quarter-and-the-centre-position-by-mouse-click"); private String sidebarstring = I18N.get("org.openjump.core.ui.plugin.edittoolbox.cursortools.DrawCircleWithGivenRadiusTool.Draws-a-circle-by-specifiying-the-radius-and-the-circle-accuracy-and-the-centre-position-by-mouse-click"); private String sAccuracy = I18N.get("org.openjump.core.ui.plugin.edittoolbox.cursortools.DrawCircleWithGivenRadiusTool.Circle-Accuracy"); private String sReset = I18N.get("org.openjump.core.ui.plugin.edittoolbox.cursortools.DrawCircleWithGivenRadiusTool.too-small-tolerance-reset-to-300-segments"); private DrawCircleWithGivenRadiusTool(FeatureDrawingUtil featureDrawingUtil) { super(1); this.featureDrawingUtil = featureDrawingUtil; setStroke( new BasicStroke( 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 3 }, 0)); this.allowSnapping(); } public static CursorTool create(LayerNamePanelProxy layerNamePanelProxy) { FeatureDrawingUtil featureDrawingUtil = new FeatureDrawingUtil(layerNamePanelProxy); return featureDrawingUtil.prepare( new DrawCircleWithGivenRadiusTool(featureDrawingUtil), true); } /****************** events ********************************/ protected void gestureFinished() throws Exception { reportNothingToUndoYet(); Point p = new GeometryFactory().createPoint(this.getModelDestination()); this.mp = p; //-- calculate number of points per quarter double tmp = Math.acos((this.radius-this.tolerance)/this.radius); if (tmp != 0){ int pts = (int)Math.floor((Math.PI/tmp)/4.0); if(pts < 3){ pts = 3; } if(pts > 300){ pts = 300; AbstractCursorTool.workbenchFrame(this.getPanel()).warnUser(sReset); } this.points=pts; } //------------------- //points-1 = segments Geometry circle = BufferOp.bufferOp(p,this.radius,this.points-1); this.checkCircle(circle); if (circle instanceof Polygon){ featureDrawingUtil.drawRing( (Polygon)circle, isRollingBackInvalidEdits(), this, getPanel()); } } protected boolean checkCircle(Geometry circle) throws NoninvertibleTransformException { IsValidOp isValidOp = new IsValidOp(circle); if (!isValidOp.isValid()) { getPanel().getContext().warnUser(isValidOp.getValidationError() .getMessage()); if (getWorkbench().getBlackboard().get(EditTransaction.ROLLING_BACK_INVALID_EDITS_KEY, false)) { return false; } } return true; } public void activate(LayerViewPanel layerViewPanel){ super.activate(layerViewPanel); try{ if (this.valuesWereSet == false){ this.makeDialogThings(layerViewPanel); this.valuesWereSet = true; } Envelope viewportEnvelope = layerViewPanel.getViewport().getEnvelopeInModelCoordinates(); double x = viewportEnvelope.getMinX() + viewportEnvelope.getWidth()/2; double y = viewportEnvelope.getMinY() + viewportEnvelope.getHeight()/2; Coordinate initCoords = new Coordinate(x,y); this.calcuateCircle(initCoords, layerViewPanel); } catch(Exception e){ //System.out.println("DrawCirclyByRadiusTool: Exception eaten"); System.out.println(e); } } public void deactivate(){ //System.out.println("deactivate"); super.deactivate(); this.deactivateCount = this.deactivateCount + 1; if (this.deactivateCount == 2){ this.valuesWereSet = false; //-- to show dialog if tool is again activated this.deactivateCount=0; } } public Cursor getCursor() { return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); } public String getName() { return name; } public Icon getIcon() { return new ImageIcon(getClass().getResource("DrawCircleByRadius.gif")); } /** * overwritten super method to show the circle on any mouse move */ public void mouseMoved(MouseEvent e){ try { setViewDestination(e.getPoint()); redrawShape(); } catch (Throwable t) { getPanel().getContext().handleThrowable(t); } } /****************** other methods ********************************/ /** * changed to get circle around mouse pointer */ protected Shape getShape(){ this.calcuateCircle(this.modelDestination, this.getPanel()); return this.selectedFeaturesShape; } /** * called from constructor and by mouse move event<p> * calculates a cirle around the mouse pointer and converts it to a java shape * @param middlePoint coordinates of the circle */ private void calcuateCircle(Coordinate middlePoint, LayerViewPanel panel){ //--calculate circle; Point p = new GeometryFactory().createPoint(middlePoint); this.mp = p; Geometry buffer = p.buffer(this.radius); Geometry[] geomArray = new Geometry[1]; geomArray[0] = buffer; GeometryCollection gc = geometryFactory.createGeometryCollection(geomArray); try{ this.selectedFeaturesShape = panel.getJava2DConverter().toShape(gc); } catch(NoninvertibleTransformException e){ System.out.println("DrawCircleWithGivenRadiusTool:Exception " + e); } } public boolean makeDialogThings(LayerViewPanel panel) throws Exception{ LayerViewPanelContext context = (LayerViewPanelContext)panel.getContext(); WorkbenchFrame fr = (WorkbenchFrame)(context); //MultiInputDialogWithoutCancel dialog = new MultiInputDialogWithoutCancel(fr, getName(), true); MultiInputDialog dialog = new MultiInputDialog(fr, getName(), true); dialog.setCancelVisible(false); setDialogValues(dialog); GUIUtil.centreOnWindow(dialog); dialog.setVisible(true); if (! dialog.wasOKPressed()) { return false; } getDialogValues(dialog); return true; } //private void setDialogValues(MultiInputDialogWithoutCancel dialog) private void setDialogValues(MultiInputDialog dialog) { dialog.setSideBarDescription(this.sidebarstring); dialog.addDoubleField(T1,this.radius,7,T1); dialog.addDoubleField(this.sAccuracy,this.tolerance, 7,this.sAccuracy); } //private void getDialogValues(MultiInputDialogWithoutCancel dialog) { private void getDialogValues(MultiInputDialog dialog) { this.radius = dialog.getDouble(T1); this.tolerance = dialog.getDouble(this.sAccuracy); } //----------- from drag tool ------------// protected void setViewDestination(Point2D destination) throws NoninvertibleTransformException { this.setModelDestination(getPanel().getViewport().toModelCoordinate(destination)); } protected void setModelDestination(Coordinate destination) { this.modelDestination = snap(destination); } }