//$HeadURL: svn+ssh://aschmitz@wald.intevation.org/deegree/base/trunk/resources/eclipse/files_template.xml $ /*---------------------------------------------------------------------------- This file is part of deegree, http://deegree.org/ Copyright (C) 2001-2011 by: - Department of Geography, University of Bonn - and - lat/lon GmbH - 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 information: lat/lon GmbH Aennchenstr. 19, 53177 Bonn Germany http://lat-lon.de/ Department of Geography, University of Bonn Prof. Dr. Klaus Greve Postfach 1147, 53001 Bonn Germany http://www.geographie.uni-bonn.de/deegree/ e-mail: info@deegree.org ----------------------------------------------------------------------------*/ package org.deegree.igeo.modules.georef; import static org.deegree.igeo.modules.georef.ControlPointModel.State.Left; import static org.deegree.igeo.modules.georef.ControlPointModel.State.Right; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import javax.swing.table.AbstractTableModel; import javax.xml.namespace.QName; import org.deegree.datatypes.QualifiedName; import org.deegree.datatypes.UnknownTypeException; import org.deegree.graphics.transformation.GeoTransform; import org.deegree.igeo.dataadapter.MemoryFeatureAdapter; import org.deegree.igeo.i18n.Messages; import org.deegree.igeo.mapmodel.Layer; import org.deegree.igeo.mapmodel.MapModel; import org.deegree.model.feature.Feature; import org.deegree.model.feature.FeatureCollection; import org.deegree.model.feature.FeatureFactory; import org.deegree.model.feature.FeatureProperty; import org.deegree.model.feature.schema.FeatureType; import org.deegree.model.feature.schema.PropertyType; import org.deegree.model.spatialschema.GeometryFactory; /** * * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> * @author last edited by: $Author: stranger $ * * @version $Revision: $, $Date: $ */ public class ControlPointModel extends AbstractTableModel { private static final long serialVersionUID = -4947856920124504250L; private static FeatureType GEOREF_FTYPE; static { try { QualifiedName ptname = new QualifiedName( new QName( "http://www.opengis.net/gml", "GeometryPropertyType" ) ); PropertyType pt = FeatureFactory.createPropertyType( new QualifiedName( new QName( "geometry" ) ), ptname, false ); GEOREF_FTYPE = FeatureFactory.createFeatureType( "georef", false, new PropertyType[] { pt } ); } catch ( UnknownTypeException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } private LinkedList<Point> points = new LinkedList<Point>(); private State state = Left; private MapModel left, right; private Layer leftLayer, rightLayer; public ControlPointModel() { newPoint(); } public void updateMaps( MapModel left, Layer leftLayer, MapModel right, Layer rightLayer ) { this.left = left; this.leftLayer = leftLayer; this.right = right; this.rightLayer = rightLayer; } @Override public int getRowCount() { return points.size(); } @Override public int getColumnCount() { return 6; } @Override public String getColumnName( int columnIndex ) { switch ( columnIndex ) { case 0: return "<html>" + Messages.get( "$DI10079" ) + "<br>x"; case 1: return "<html>" + Messages.get( "$DI10079" ) + "<br>y"; case 2: return "<html>" + Messages.get( "$DI10080" ) + "<br>x"; case 3: return "<html>" + Messages.get( "$DI10080" ) + "<br>y"; case 4: return "<html>" + Messages.get( "$DI10084" ) + "<br>x (m)"; case 5: return "<html>" + Messages.get( "$DI10084" ) + "<br>y (m)"; } return null; } @Override public Class<?> getColumnClass( int columnIndex ) { return Double.class; } @Override public boolean isCellEditable( int rowIndex, int columnIndex ) { return columnIndex <= 3; } @Override public Object getValueAt( int rowIndex, int columnIndex ) { Point p = points.get( rowIndex ); switch ( columnIndex ) { case 0: return p.x0; case 1: return p.y0; case 2: return p.x1; case 3: return p.y1; case 4: return p.resx; case 5: return p.resy; } return null; } @Override public void setValueAt( Object aValue, int rowIndex, int columnIndex ) { Double val = (Double) aValue; Point p = points.get( rowIndex ); switch ( columnIndex ) { case 0: p.x0 = val; if ( p.y0 == null ) { p.y0 = 0d; } break; case 1: p.y0 = val; if ( p.x0 == null ) { p.x0 = 0d; } break; case 2: p.x1 = val; if ( p.y1 == null ) { p.y1 = 0d; } if ( rowIndex == points.size() - 1 ) { newPoint(); } break; case 3: p.y1 = val; if ( p.x1 == null ) { p.y1 = null; } if ( rowIndex == points.size() - 1 ) { newPoint(); } break; } updateMaps(); AffineTransformation.approximate( points ); fireTableDataChanged(); } public void newPoint() { points.add( new Point() ); state = Left; fireTableDataChanged(); } public void removeAll() { points.clear(); state = Left; fireTableDataChanged(); updateMaps(); } public void remove( int[] idx ) { List<Point> list = new ArrayList<Point>(); for ( int i : idx ) { list.add( points.get( i ) ); } points.removeAll( list ); fireTableDataChanged(); if ( !points.isEmpty() && points.getLast().x0 != null && points.getLast().x1 != null ) { newPoint(); } } public void next( double x, double y ) { if ( points.isEmpty() ) { newPoint(); } switch ( state ) { case Left: state = Right; points.getLast().x0 = x; points.getLast().y0 = y; break; case Right: points.getLast().x1 = x; points.getLast().y1 = y; newPoint(); state = Left; break; } fireTableDataChanged(); } public State getState() { return state; } public List<Point> getPoints() { return points; } public void updateMaps() { if ( leftLayer == null || rightLayer == null ) { return; } MemoryFeatureAdapter leftData = (MemoryFeatureAdapter) leftLayer.getDataAccess().get( 0 ); MemoryFeatureAdapter rightData = (MemoryFeatureAdapter) rightLayer.getDataAccess().get( 0 ); FeatureCollection col = leftData.getFeatureCollection(); // the memory fa seems to work on the live feature collection... while ( col.size() > 0 ) { leftData.deleteFeature( col.getFeature( 0 ) ); } col = rightData.getFeatureCollection(); while ( col.size() > 0 ) { rightData.deleteFeature( col.getFeature( 0 ) ); } int cnt = 0; for ( Point p : points ) { ++cnt; if ( p.x0 == null ) { continue; } org.deegree.model.spatialschema.Point geom = GeometryFactory.createPoint( p.x0, p.y0, null ); FeatureProperty prop = FeatureFactory.createFeatureProperty( new QualifiedName( new QName( "geometry" ) ), geom ); Feature f = FeatureFactory.createFeature( "left_" + cnt, GEOREF_FTYPE, new FeatureProperty[] { prop } ); leftData.insertFeature( f ); if ( p.x1 == null ) { continue; } geom = GeometryFactory.createPoint( p.x1, p.y1, null ); prop = FeatureFactory.createFeatureProperty( new QualifiedName( new QName( "geometry" ) ), geom ); f = FeatureFactory.createFeature( "right_" + cnt, GEOREF_FTYPE, new FeatureProperty[] { prop } ); rightData.insertFeature( f ); } } public void clickedLeft( int x, int y ) { if ( state == State.Left ) { GeoTransform gt = left.getToTargetDeviceTransformation(); double dx = gt.getSourceX( x ); double dy = gt.getSourceY( y ); next( dx, dy ); org.deegree.model.spatialschema.Point p = GeometryFactory.createPoint( dx, dy, null ); FeatureProperty prop = FeatureFactory.createFeatureProperty( new QualifiedName( new QName( "geometry" ) ), p ); Feature f = FeatureFactory.createFeature( "left_" + points.size(), GEOREF_FTYPE, new FeatureProperty[] { prop } ); ( (MemoryFeatureAdapter) leftLayer.getDataAccess().get( 0 ) ).insertFeature( f ); } } public void clickedRight( int x, int y ) { if ( state == State.Right ) { GeoTransform gt = right.getToTargetDeviceTransformation(); double dx = gt.getSourceX( x ); double dy = gt.getSourceY( y ); next( dx, dy ); org.deegree.model.spatialschema.Point p = GeometryFactory.createPoint( dx, dy, null ); FeatureProperty prop = FeatureFactory.createFeatureProperty( new QualifiedName( new QName( "geometry" ) ), p ); Feature f = FeatureFactory.createFeature( "right_" + points.size(), GEOREF_FTYPE, new FeatureProperty[] { prop } ); ( (MemoryFeatureAdapter) rightLayer.getDataAccess().get( 0 ) ).insertFeature( f ); } } public static enum State { Left, Right } static class Point { Double x0, y0, x1, y1, resx, resy; } public void savePointsToFile( File saveFile ) throws IOException { PrintStream ps = null; try { ps = new PrintStream( saveFile ); for ( Point p : points ) { if ( p.x0 != null && p.y0 != null && p.x1 != null && p.y1 != null ) { ps.println( "\"" + p.x0 + "\";\"" + p.y0 + "\";\"" + p.x1 + "\";\"" + p.y1 + "\"" ); } else if ( ( p.x0 != null && p.y0 != null ) && ( p.x1 == null && p.y1 == null ) ) { ps.println( "\"" + p.x0 + "\";\"" + p.y0 + "\";\"\";\"\"" ); } else { System.out.println( "ERROR" ); // TODO: proper error handling } } } finally { if ( ps != null ) { ps.close(); } } } public void loadPointsFromFile( File openFile ) throws IOException { removeAll(); BufferedReader br = null; try { br = new BufferedReader( new FileReader( openFile ) ); while ( br.ready() != false ) { String[] splittedCsvLine = br.readLine().split( ";" ); double x = Double.valueOf( splittedCsvLine[0].substring( 1, splittedCsvLine[0].length() - 1 ) ); double y = Double.valueOf( splittedCsvLine[1].substring( 1, splittedCsvLine[1].length() - 1 ) ); next( x, y ); x = Double.valueOf( splittedCsvLine[2].substring( 1, splittedCsvLine[2].length() - 1 ) ); y = Double.valueOf( splittedCsvLine[3].substring( 1, splittedCsvLine[3].length() - 1 ) ); next( x, y ); } updateMaps(); } finally { if ( br != null ) { br.close(); } } } }