//$Head URL$ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2008 by: Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de 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; either version 2.1 of the License, or (at your option) any later version. 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. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.igeo.views; import java.awt.Graphics; import java.awt.Point; import java.util.ArrayList; import java.util.List; import org.deegree.framework.util.GeometryUtils; import org.deegree.framework.util.Pair; import org.deegree.framework.utils.LineUtils; import org.deegree.graphics.transformation.GeoTransform; import org.deegree.igeo.ApplicationContainer; import org.deegree.igeo.mapmodel.MapModel; import org.deegree.igeo.modules.DigitizerModule; import org.deegree.model.feature.FeatureCollection; import org.deegree.model.spatialschema.GeometryFactory; import org.deegree.model.spatialschema.Position; /** * * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author$ * * @version. $Revision$, $Date$ */ public abstract class GeoDrawingPane implements DrawingPane { /** * List of points drawn so far. * */ protected List<org.deegree.model.spatialschema.Point> points = null; protected int currentX; protected int currentY; protected boolean isDrawing = false; protected boolean stopped = false; protected Graphics g; protected MapModel mapModel; protected FeatureCollection fc; protected Snapper snapper; private ApplicationContainer<?> appCont; private Point tmpPoint = new Point(); /** * */ public GeoDrawingPane( ApplicationContainer<?> appCont ) { this.appCont = appCont; } /** * sets the {@link MapModel} used by a {@link GeoDrawingPane} to enable an implementing class to geo coordinates * instead of pixel coordinates * * @param mapModel */ public void setMapModel( MapModel mapModel ) { this.mapModel = mapModel; } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#finishDrawing() */ public void finishDrawing() { isDrawing = false; if ( snapper != null ) { snapper.dispose(); } } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#isDrawingStopped() */ public boolean isDrawingStopped() { return stopped; } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#isDrawing() */ public boolean isDrawing() { return isDrawing; } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#getCurrent() */ public Point getCurrent() { return new Point( this.currentX, this.currentY ); } /** * * @return current x/y coordinate as geographic coordinate according to the underlying {@link MapModel} */ public org.deegree.model.spatialschema.Point getCurrentAsGeoPoint() { return null; } /* * (non-Javadoc) * * @see org.deegree.igeo.views.GeoDrawingPane#getDrawObjectsAsGeoPoints() */ public List<org.deegree.model.spatialschema.Point> getDrawObjectsAsGeoPoints() { return points; } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#undrawLastPoint() */ public void undrawLastPoint() { if ( points.size() > 1 ) { points.remove( points.size() - 1 ); } } /** * sets the features that has been selected and now shall be moved * * @param fc */ public void setFeatureCollection( FeatureCollection fc ) { this.fc = fc; } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#setSnapper(org.deegree.igeo.views.swing.Snapper) */ public void setSnapper( Snapper snapper ) { this.snapper = snapper; } /** * corrects current x/y coordinates read from mouse position using definitions for digitizing angle, edge-length or * snapping * * @param x * @param y * @return corrected point */ protected Pair<Position, Point> correctPoint( int x, int y ) { // read digitizing angle and edge length from instance settings if available double angle = -1; double length = -1; Object o = appCont.getInstanceSetting( DigitizerModule.ANGLE ); if ( o != null ) { angle = ( (Number) o ).doubleValue(); } o = appCont.getInstanceSetting( DigitizerModule.LENGTH ); if ( o != null ) { length = ( (Number) o ).doubleValue(); } Position tmpPos = null; // if a fixed angle for digitizing has been defined snapping will be ignored GeoTransform gt = mapModel.getToTargetDeviceTransformation(); if ( angle > -1 && points.size() > 0 ) { org.deegree.model.spatialschema.Point p = null; if ( length <= 0 ) { // if no length has been defined use distance between current (mouse) position // and last digitized point instead double cx = gt.getSourceX( x ); double cy = gt.getSourceY( y ); p = GeometryFactory.createPoint( cx, cy, points.get( 0 ).getCoordinateSystem() ); length = GeometryUtils.distance( p.getPosition(), points.get( points.size() - 1 ).getPosition() ); } if ( points.size() > 1 ) { angle -= 180; if ( angle >= 0 ) { angle -= 180; } else { angle = 180 - angle; } p = GeometryUtils.vectorByAngle( points.get( points.size() - 2 ), points.get( points.size() - 1 ), length, Math.toRadians( angle ), true ); } else { double cx = gt.getSourceX( x ); double cy = gt.getSourceY( y ); double firstX = points.get( 0 ).getX(); double firstY = points.get( 0 ).getY(); // get line equation for line intersecting start position and current mouse position double[] line = LineUtils.getLineFromPoints( firstX, firstY, cx, cy ); Pair<Position, Position> intersection = LineUtils.getSymmetricPoints( firstX, firstY, line[0], length ); if ( cx > firstX && ( gt.getDestX( firstX ) != x || cy <= firstY ) ) { // cursor is left of first point or it has same x coordinate and is // above first point p = GeometryFactory.createPoint( intersection.first, points.get( 0 ).getCoordinateSystem() ); } else if ( gt.getDestX( firstX ) != x || cy <= firstY ) { p = GeometryFactory.createPoint( intersection.second, points.get( 0 ).getCoordinateSystem() ); } } if ( p != null ) { tmpPos = p.getPosition(); tmpPoint.x = (int) Math.round( gt.getDestX( p.getX() ) ); tmpPoint.y = (int) Math.round( gt.getDestY( p.getY() ) ); } } else { if ( snapper != null ) { tmpPos = snapper.snapPos( new Point( x, y ) ); tmpPoint.x = (int) Math.round( gt.getDestX( tmpPos.getX() ) ); tmpPoint.y = (int) Math.round( gt.getDestY( tmpPos.getY() ) ); } } if ( tmpPos == null ) { double xx = gt.getSourceX( x ); double yy = gt.getSourceY( y ); tmpPos = GeometryFactory.createPosition( xx, yy ); tmpPoint.x = x; tmpPoint.y = y; } return new Pair<Position, Point>( tmpPos, tmpPoint ); } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#setGraphicContext(java.awt.Graphics) */ public void setGraphicContext( Graphics g ) { this.g = g; } /* * (non-Javadoc) * * @see org.deegree.igeo.views.DrawingPane#getDrawnObject() */ public List<java.awt.Point> getDrawnObject() { GeoTransform gt = mapModel.getToTargetDeviceTransformation(); List<java.awt.Point> list = new ArrayList<java.awt.Point>( points.size() ); for ( org.deegree.model.spatialschema.Point point : points ) { int x = (int) Math.round( gt.getDestX( point.getX() ) ); int y = (int) Math.round( gt.getDestY( point.getY() ) ); list.add( new Point( x, y ) ); } return list; } }