arcgissamples\editing\BufferSnapAgent.java
/* Copyright 2010 ESRI * * All rights reserved under the copyright laws of the United States * and applicable international laws, treaties, and conventions. * * You may freely redistribute and use this sample code, with or * without modification, provided you include the original copyright * notice and use restrictions. * * See the use restrictions. * */ package arcgissamples.editing; import java.io.IOException; import com.esri.arcgis.carto.FeatureCache; import com.esri.arcgis.carto.IFeatureLayer; import com.esri.arcgis.carto.IMap; import com.esri.arcgis.controls.EngineEditor; import com.esri.arcgis.controls.IEngineSnapAgent; import com.esri.arcgis.controls.IEngineSnapAgentCategory; import com.esri.arcgis.geodatabase.IFeature; import com.esri.arcgis.geodatabase.IFeatureClass; import com.esri.arcgis.geometry.IGeometry; import com.esri.arcgis.geometry.IPoint; import com.esri.arcgis.geometry.IProximityOperator; import com.esri.arcgis.geometry.Point; import com.esri.arcgis.geometry.Polygon; import com.esri.arcgis.geometry.esriGeometryType; import com.esri.arcgis.geometry.esriSegmentExtension; import com.esri.arcgis.interop.AutomationException; /* The Buffer Snap agent is based on a buffer around the points of the first editable point feature class. A buffer of 1000 map units is created and if the next point feature created is within the tolerance it is snapped to the buffer ring. */ public class BufferSnapAgent implements IEngineSnapAgent, IEngineSnapAgentCategory { private static final long serialVersionUID = 1L; private EngineEditor editor; private IFeatureClass golfFeatureClass; private FeatureCache cache; private boolean once = true; public BufferSnapAgent() { try { this.editor = new EngineEditor(); } catch (Exception e) { e.printStackTrace(); } } public String getName() throws IOException, AutomationException { return "Buffer Snap Agent"; } public boolean snap(IGeometry arg0, IPoint point, double tolerance) throws IOException, AutomationException { getFeatureClass(); if (golfFeatureClass == null || editor == null) return false; if (golfFeatureClass.getShapeType() != esriGeometryType.esriGeometryPoint) return false; //Check if a feature cache has been created. if (once) { cache = new FeatureCache(); once = false; } //Fill the cache with the geometries. //It is up to the developer to choose an appropriate value //given the map units and the scale at which editing will be undertaken. fillCache(golfFeatureClass, point, 10000); IProximityOperator proximityOp = (IProximityOperator)point; double minDist = tolerance; Point cachePt = new Point(); Point snapPt = new Point(); Polygon outPoly = new Polygon(); IFeature feature; int index = 0; for (int i = 0; i < cache.getCount(); i++) { feature = cache.getFeature(i); cachePt = (Point)feature.getShape(); //Set the buffer distance to an appropriate value //given the map units and data being edited outPoly = (Polygon) cachePt.buffer(1000); double distance = proximityOp.returnDistance(outPoly); if (distance < minDist) { index = i; minDist = distance; } } //Make sure minDist is within the search tolerance. if (minDist >= tolerance) return false; //Retrieve the feature and its part again. feature = cache.getFeature(index); cachePt = (Point)feature.getShape(); //Set the buffer distance to an appropriate value //given the map scale and data being edited outPoly = (Polygon)cachePt.buffer(1000); snapPt = (Point)outPoly.returnNearestPoint(point,esriSegmentExtension.esriNoExtension); //Since point was passed in ByValue, we have to modify its values instead. //of giving it a new address. point.putCoords(snapPt.getX(), snapPt.getY()); return true; } private void fillCache(IFeatureClass FClass, IPoint pPoint, double Distance) throws IOException, AutomationException { cache.initialize(pPoint, Distance); cache.addFeatures(FClass); } private void getFeatureClass() throws IOException, AutomationException { IMap map = editor.getMap(); IFeatureLayer featLayer = (IFeatureLayer) editor.getTargetLayer(); // Search the editable layers and set the snap feature class to the // point layer. for (int i = 0; i < map.getLayerCount(); i++) { if (featLayer == null) return; if (featLayer.getFeatureClass().getShapeType() != esriGeometryType.esriGeometryPoint) { return; } else { golfFeatureClass = featLayer.getFeatureClass(); } } } public String getCategory() throws IOException, AutomationException { return "Custom Snap Agents (Java)"; } }