arcgissamples\editing\CustomVertexTools.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.IFeatureLayer; import com.esri.arcgis.carto.IFeatureSelection; import com.esri.arcgis.controls.BaseTool; import com.esri.arcgis.controls.EngineEditor; import com.esri.arcgis.controls.EngineSketchOperation; import com.esri.arcgis.controls.HookHelper; import com.esri.arcgis.controls.IEngineEditTask; import com.esri.arcgis.controls.esriEngineEditState; import com.esri.arcgis.controls.esriEngineSketchOperationType; import com.esri.arcgis.geodatabase.ISelectionSet; import com.esri.arcgis.geometry.IGeometry; import com.esri.arcgis.geometry.IGeometryCollection; import com.esri.arcgis.geometry.IHitTest; import com.esri.arcgis.geometry.IPoint; import com.esri.arcgis.geometry.IPointCollection; import com.esri.arcgis.geometry.Point; import com.esri.arcgis.geometry.esriGeometryHitPartType; import com.esri.arcgis.geometry.esriGeometryType; import com.esri.arcgis.interop.AutomationException; import com.esri.arcgis.systemUI.ICommandSubType; class CustomVertexTools extends BaseTool implements ICommandSubType { private static final long serialVersionUID = -418758068047848768L; private EngineEditor editor; private HookHelper hookHelper; private IEngineEditTask modifyFeatureTask; private int type; @Override public void onCreate(Object hook) { super.onCreate(hook); try { this.hookHelper = new HookHelper(); this.hookHelper.setHookByRef(hook); this.editor = new EngineEditor(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onClick() { try { // find the Modify Feature task and set it as the current task // so the vertices will be automatically highlighted when tool is // clicked this.modifyFeatureTask = editor .getTaskByUniqueName("ControlToolsEditing_ModifyFeatureTask"); editor.setCurrentTaskByRef(this.modifyFeatureTask); } catch (Exception e) { e.printStackTrace(); } } @Override public void onMouseUp(int button, int shift, int x, int y) { try { IGeometry editShape = editor.getGeometry(); // location clicked as a point object IPoint clickedPt = hookHelper.getActiveView().getScreenDisplay() .getDisplayTransformation().toMapPoint(x, y); IHitTest hitShape = (IHitTest) editShape; IPoint hitPoint = new Point(); double[] hitDistance = { -1 }; int[] hitPartIndex = { -1 }; int[] hitSegmentIndex = { -1 }; boolean[] bRightSide = { false }; int hitPartType = esriGeometryHitPartType.esriGeometryPartNone; // the searchRadius is the maximum distance away, in map units, from // the shape that will be used // for the test - change to an appropriate value. double searchRadius = 1; switch (type) { case 1: // Insert Vertex hitPartType = esriGeometryHitPartType.esriGeometryPartBoundary; break; case 2: // Delete Vertex hitPartType = esriGeometryHitPartType.esriGeometryPartVertex; break; } hitShape.hitTest(clickedPt, searchRadius, hitPartType, hitPoint, hitDistance, hitPartIndex, hitSegmentIndex, bRightSide); // check whether the HitTest was successful (i.e within the search // radius) if (!hitPoint.isEmpty()) { EngineSketchOperation sketchOp = new EngineSketchOperation(); sketchOp.start(editor); int opType = esriEngineSketchOperationType.esriEngineSketchOperationGeneral; // Get the PointCollection for a specific path or ring by // hitPartIndex to handle multi-part features IGeometryCollection geometryCol = (IGeometryCollection) editShape; IPointCollection pathOrRingPointCollection = (IPointCollection) geometryCol .getGeometry(hitPartIndex[0]); switch (this.type) { case 1: // Insert Vertex // add new vertex to the path or ring PointCollection pathOrRingPointCollection.addPoint(clickedPt, null, hitSegmentIndex[0]); sketchOp.setMenuString("Insert Vertex (Custom)"); opType = esriEngineSketchOperationType.esriEngineSketchOperationVertexAdded; break; case 2: // Delete Vertex. // delete a vertex from the path or ring PointCollection pathOrRingPointCollection.removePoints(hitSegmentIndex[0], 1); sketchOp.setMenuString("Delete Vertex (Custom)"); opType = esriEngineSketchOperationType.esriEngineSketchOperationVertexDeleted; break; } // remove the old PointCollection from the GeometryCollection // and replace with the new one geometryCol.removeGeometries(hitPartIndex[0], 1); geometryCol.addGeometry((IGeometry) pathOrRingPointCollection, hitPartIndex[0], null); sketchOp.finish(null, opType, clickedPt); } } catch (Exception ex) { ex.printStackTrace(); } } @Override public boolean isEnabled() { try { if (editor.getEditState() == esriEngineEditState.esriEngineStateNotEditing) { return false; } // check for appropriate geometry types int geomType = ((IFeatureLayer) editor.getTargetLayer()) .getFeatureClass().getShapeType(); if ((geomType != esriGeometryType.esriGeometryPolygon) && (geomType != esriGeometryType.esriGeometryPolyline)) { return false; } // check that only one feature is currently selected IFeatureSelection featureSelection = (IFeatureSelection) editor .getTargetLayer(); ISelectionSet selectionSet = featureSelection.getSelectionSet(); if (selectionSet.getCount() != 1) { return false; } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public int getCount() throws IOException, AutomationException { // The number of subtypes in this tool return 2; } public void setSubType(int index) throws IOException, AutomationException { type = index; this.category = "Vertex Cmds (Java)"; switch (type) { case 1: // Insert Vertex using the custom command this.caption = "Insert vertex (custom)"; this.message = "Insert vertex at clicked location using custom command"; this.toolTip = "Insert vertex at clicked location using custom command"; this.name = "VertexCommands_CustomInsertVertex"; this.cursorPath = this.getClass().getClassLoader().getResource( "InsertVertexCursor.cur").getPath(); this.bitmapPath = this.getClass().getClassLoader().getResource( "InsertVertex.bmp").getPath(); if(System.getProperty("os.name").toLowerCase().indexOf("win")>-1){ this.cursorPath =this.cursorPath.substring(1).replaceAll("%20"," "); this.bitmapPath =this.bitmapPath.substring(1).replaceAll("%20"," "); } break; case 2: // Delete vertex at clicked location using the custom command this.caption = "Delete vertex (custom)"; this.message = "Delete vertex at clicked location using custom command"; this.toolTip = "Delete vertex at clicked location using custom command"; this.name = "VertexCommands_CustomDeleteVertex"; this.cursorPath = this.getClass().getClassLoader().getResource( "DeleteVertexCursor.cur").getPath(); ; this.bitmapPath = this.getClass().getClassLoader().getResource( "DeleteVertex.bmp").getPath(); if(System.getProperty("os.name").toLowerCase().indexOf("win")>-1){ this.cursorPath =this.cursorPath.substring(1).replaceAll("%20"," "); this.bitmapPath =this.bitmapPath.substring(1).replaceAll("%20"," "); } break; } } }