/* Spatial Operations & Editing Tools for uDig * * Axios Engineering under a funding contract with: * Diputación Foral de Gipuzkoa, Ordenación Territorial * * http://b5m.gipuzkoa.net * http://www.axios.es * * (C) 2006, Diputación Foral de Gipuzkoa, Ordenación Territorial (DFG-OT). * DFG-OT agrees to license under Lesser General Public License (LGPL). * * 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 es.axios.udig.ui.editingtools.arc.internal; import net.refractions.udig.project.ILayer; import net.refractions.udig.project.command.UndoableMapCommand; import net.refractions.udig.project.command.factory.EditCommandFactory; import net.refractions.udig.project.internal.commands.edit.CreateFeatureCommand; import net.refractions.udig.tools.edit.Behaviour; import net.refractions.udig.tools.edit.EditState; import net.refractions.udig.tools.edit.EditToolHandler; import net.refractions.udig.tools.edit.support.PrimitiveShape; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.opengis.feature.IllegalAttributeException; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.OperationNotFoundException; import org.opengis.referencing.operation.TransformException; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Point; import es.axios.geotools.util.GeoToolsUtils; import es.axios.lib.geometry.util.GeometryUtil; import es.axios.udig.ui.commons.mediator.AppGISMediator; import es.axios.udig.ui.commons.util.DialogUtil; import es.axios.udig.ui.commons.util.LayerUtil; /** * Acceptance behaviour for the arc creation tool. * <p> * This behaviour uses an ArcBuilder to create an arc's approximation as a JTS * LineString and returns {@link CreateFeatureCommand} with the arc * approximation as default geometry. * </p> * <p> * The geometry is created in the current map's * {@link CoordinateReferenceSystem} and then projected back to the current * layer's CRS. * </p> * * @author Aritz Davila (www.axios.es) * @author Mauricio Pazos (www.axios.es) * @since 1.1.0 * @see ArcBuilder */ public class CreateArcBehaviour implements Behaviour { /** * Valid if current shape is not null and has exactly three points. */ public boolean isValid(EditToolHandler handler) { PrimitiveShape currentShape = handler.getCurrentShape(); if (currentShape == null) { return false; } int nCoords = currentShape.getNumCoords(); return nCoords == 3; } public UndoableMapCommand getCommand(EditToolHandler handler) { final PrimitiveShape currentShape = handler.getCurrentShape(); final ILayer editLayer = handler.getEditLayer(); // need to use map coordinates in order to avoid // possible inconsistencies between what the user // drawn and the projected result GeometryFactory gf = new GeometryFactory(); CoordinateReferenceSystem layerCrs = LayerUtil.getCrs(editLayer); CoordinateReferenceSystem mapCrs = editLayer.getMap().getViewportModel().getCRS(); Point p1 = gf.createPoint(currentShape.getCoord(0)); Point p2 = gf.createPoint(currentShape.getCoord(1)); Point p3 = gf.createPoint(currentShape.getCoord(2)); try { p1 = (Point) GeoToolsUtils.reproject(p1, layerCrs, mapCrs); p2 = (Point) GeoToolsUtils.reproject(p2, layerCrs, mapCrs); p3 = (Point) GeoToolsUtils.reproject(p3, layerCrs, mapCrs); } catch (OperationNotFoundException onfe) { throw new RuntimeException(onfe); } catch (TransformException te) { throw new RuntimeException(te); } ArcBuilder builder = new ArcBuilder(); builder.setPoints(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY()); // TODO: especificar la cantidad de segmentos por cuadrante // mediante una preferencia Geometry geom = builder.getGeometry(15); if (geom == null) { throw new RuntimeException("null geom"); } // backproject resulting geom from map crs to layer's crs try { geom = GeoToolsUtils.reproject(geom, mapCrs, layerCrs); } catch (OperationNotFoundException onfe) { throw new RuntimeException(onfe); } catch (TransformException te) { throw new RuntimeException(te); } EditCommandFactory editCmdFac = AppGISMediator.getEditCommandFactory(); ILayer layer = editLayer; SimpleFeatureType schema = layer.getSchema(); SimpleFeature feature; try { feature = SimpleFeatureBuilder.build(schema, new Object[1], null); assert feature != null : "feature creation fail."; Class<? extends Geometry> type = (Class<? extends Geometry>) schema.getGeometryDescriptor().getType() .getBinding(); geom = GeometryUtil.adapt(geom, type); feature.setDefaultGeometry(geom); } catch (IllegalAttributeException e) { throw new RuntimeException(e); } UndoableMapCommand command = editCmdFac.createAddFeatureCommand(feature, layer); handler.setCurrentShape(null); handler.setCurrentState(EditState.NONE); return command; } public void handleError(EditToolHandler handler, Throwable error, UndoableMapCommand command) { error.printStackTrace(); DialogUtil.openError("Create arc failed to execute", error.getMessage()); } }