/** * Traverses the FeatureCollection<SimpleFeatureType, SimpleFeature> <code>selection</code> * creating a buffered geometry on each SimpleFeature's default geometry and stores the result in * a new SimpleFeature on the <code>target</code> FeatureStore. * * <p>Note the buffer computation is made with a slightly {@link BufferOp modified version} of the * JTS <code>BufferOp</code> in order to allow the operation to be cancelled while inside the * buffer computation. * * @param params buffer parameters * @param selection source layer's selected features in its native CRS * @throws SOProcessException if {@link #createBufferedFeature(SimpleFeature, SimpleFeatureType, * Geometry)} fails * @throws IOException if it is thrown while adding the resulting features to the target * FeatureStore<SimpleFeatureType, SimpleFeature> or while commiting the transaction * @throws InterruptedException if the user cancelled the operation */ private void performBuffer( IBufferParameters params, FeatureCollection<SimpleFeatureType, SimpleFeature> selection) throws SOProcessException, InterruptedException { assert selection != null; final int featureCount = selection.size(); final ILayer sourceLayer = this.sourceLayer; final CoordinateReferenceSystem sourceCrs = LayerUtil.getCrs(sourceLayer); final CoordinateReferenceSystem mapCrs = MapUtil.getCRS(sourceLayer.getMap()); final CoordinateReferenceSystem targetCrs = this.targetStore.getSchema().getDefaultGeometry().getCRS(); final Unit sourceUnits = GeoToolsUtils.getDefaultCRSUnit(mapCrs); final Unit targetUnits = params.getUnitsOfMeasure(); final int quadSegments = params.getQuadrantSegments().intValue(); final Double width = params.getWidth().doubleValue(); SimpleFeature sourceFeature = null; // the one to use if params.isMergeGeometry() == true Geometry mergedGeometry = null; FeatureIterator<SimpleFeature> iterator = null; try { int processingCount = 0; Geometry geometry; String subTaskName; iterator = selection.features(); while (iterator.hasNext()) { processingCount++; subTaskName = MessageFormat.format( Messages.BufferProcess_subTask_BufferingFeatureN, processingCount, featureCount); getMonitor().subTask(subTaskName); checkCancelation(); sourceFeature = iterator.next(); geometry = (Geometry) sourceFeature.getDefaultGeometry(); geometry = GeoToolsUtils.reproject(geometry, sourceCrs, mapCrs); geometry = makeBufferGeometry( geometry, width, sourceUnits, targetUnits, quadSegments, getMonitor()); geometry = GeoToolsUtils.reproject(geometry, mapCrs, targetCrs); checkCancelation(); if (params.isMergeGeometries()) { if (mergedGeometry == null) { mergedGeometry = geometry; } else { mergedGeometry = mergedGeometry.union(geometry); } } else { createAndStoreBufferedFeature(sourceFeature, geometry, this.targetStore); } getMonitor().worked(1); } checkCancelation(); if (params.isMergeGeometries()) { createAndStoreBufferedFeature(null, mergedGeometry, this.targetStore); } getMonitor().subTask(Messages.BufferProcess_subtastCommittingTransaction); } catch (OperationNotFoundException e) { String message = MessageFormat.format( Messages.BufferProcess_failed_transforming, sourceFeature.getID(), e.getMessage()); throw new SOProcessException(message, e); } catch (TransformException e) { String message = MessageFormat.format( Messages.BufferProcess_failed_transforming_feature_to_crs, sourceFeature.getID(), e.getMessage()); throw new SOProcessException(message, e); } finally { if (iterator != null) iterator.close(); getMonitor().done(); } }
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 IllegalStateException( "Could not reproject to map crs:" + onfe.getLocalizedMessage(), onfe); } catch (TransformException te) { throw new IllegalStateException( "Could not reproject to map crs:" + te.getLocalizedMessage(), 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 IllegalStateException("null geom"); } // backproject resulting geom from map crs to layer's crs try { geom = GeoToolsUtils.reproject(geom, mapCrs, layerCrs); } catch (OperationNotFoundException onfe) { throw new IllegalStateException( "Could not reproject back to data crs:" + onfe.getLocalizedMessage(), onfe); } catch (TransformException te) { throw new IllegalStateException( "Could not reproject back to data crs:" + te.getLocalizedMessage(), te); } EditCommandFactory editCmdFac = AppGISMediator.getEditCommandFactory(); ILayer layer = editLayer; SimpleFeatureType schema = layer.getSchema(); SimpleFeature feature; try { feature = SimpleFeatureBuilder.build(schema, (Object[]) null, null); Class type = schema.getDefaultGeometry().getType().getBinding(); geom = GeometryUtil.adapt(geom, type); feature.setDefaultGeometry(geom); } catch (IllegalAttributeException e) { // consider using the bubble feedback throw new IllegalStateException("Could not create Arc:" + e, e); } UndoableMapCommand command = editCmdFac.createAddFeatureCommand(feature, layer); handler.setCurrentShape(null); handler.setCurrentState(EditState.NONE); return command; }