arcgissamples\geoprocessing\customtool\FindIntersections.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.geoprocessing.customtool; import java.io.File; import java.io.IOException; import com.esri.arcgis.datasourcesfile.ShapefileWorkspaceFactory; import com.esri.arcgis.geodatabase.DEFeatureClass; import com.esri.arcgis.geodatabase.DEFeatureClassType; import com.esri.arcgis.geodatabase.DENetworkDataset; import com.esri.arcgis.geodatabase.DENetworkDatasetType; import com.esri.arcgis.geodatabase.EnumNetworkElement; import com.esri.arcgis.geodatabase.FeatureClass; import com.esri.arcgis.geodatabase.FeatureCursor; import com.esri.arcgis.geodatabase.Field; import com.esri.arcgis.geodatabase.Fields; import com.esri.arcgis.geodatabase.GeometryDef; import com.esri.arcgis.geodatabase.IFeature; import com.esri.arcgis.geodatabase.IFeatureBuffer; import com.esri.arcgis.geodatabase.IFeatureClass; import com.esri.arcgis.geodatabase.IGPMessages; import com.esri.arcgis.geodatabase.IGPValue; import com.esri.arcgis.geodatabase.INetworkElement; import com.esri.arcgis.geodatabase.INetworkJunction; import com.esri.arcgis.geodatabase.IWorkspaceFactory; import com.esri.arcgis.geodatabase.NetworkDataset; import com.esri.arcgis.geodatabase.Workspace; import com.esri.arcgis.geodatabase.esriFeatureType; import com.esri.arcgis.geodatabase.esriFieldType; import com.esri.arcgis.geodatabase.esriGPMessageSeverity; import com.esri.arcgis.geodatabase.esriNetworkElementType; import com.esri.arcgis.geometry.ISpatialReference; import com.esri.arcgis.geometry.esriGeometryType; import com.esri.arcgis.geoprocessing.BaseGeoprocessingTool; import com.esri.arcgis.geoprocessing.GPCompositeDataType; import com.esri.arcgis.geoprocessing.GPEnvironment; import com.esri.arcgis.geoprocessing.GPNetworkDatasetLayerType; import com.esri.arcgis.geoprocessing.GPParameter; import com.esri.arcgis.geoprocessing.IGPEnvironmentManager; import com.esri.arcgis.geoprocessing.IGPParameter; import com.esri.arcgis.geoprocessing.esriGPParameterDirection; import com.esri.arcgis.geoprocessing.esriGPParameterType; import com.esri.arcgis.interop.AutomationException; import com.esri.arcgis.system.AoInitialize; import com.esri.arcgis.system.Array; import com.esri.arcgis.system.IArray; import com.esri.arcgis.system.IName; import com.esri.arcgis.system.ITrackCancel; import com.esri.arcgis.system.esriLicenseExtensionCode; import com.esri.arcgis.system.esriLicenseProductCode; import com.esri.arcgis.system.esriLicenseStatus; public class FindIntersections extends BaseGeoprocessingTool { private static final long serialVersionUID = 1L; private String toolName = "FindIntersections"; private String displayName = "Java Find Intersections"; private String metadataFileName = "FindIntersections.xml"; private static String outputFolder = null; public FindIntersections() { } /** * Returns name of the tool This name appears when executing the tool at the * command line or in scripting. This name should be unique to each toolbox * and must not contain spaces. */ public String getName() throws IOException, AutomationException { return toolName; } /** * Returns Display Name of the tool, as seen in ArcToolbox. */ public String getDisplayName() throws IOException, AutomationException { return displayName; } /** * Returns the full name of the tool */ public IName getFullName() throws IOException, AutomationException { return (IName) new FIFunctionFactory().getFunctionName(toolName); } /** * Returns an array of paramInfo This is the location where the parameters to * the Function Tool are defined. This property returns an IArray of parameter * objects (IGPParameter). These objects define the characteristics of the * input and output parameters. */ public IArray getParameterInfo() throws IOException, AutomationException { IArray parameters = new Array(); // Using a composite data type for parameter <name of parameter>; GPCompositeDataType compositeDataType1 = new GPCompositeDataType(); compositeDataType1.addDataType(new DENetworkDatasetType()); compositeDataType1.addDataType(new GPNetworkDatasetLayerType()); GPParameter parameter1 = new GPParameter(); parameter1.setName("in_nds"); parameter1.setDirection(esriGPParameterDirection.esriGPParameterDirectionInput); parameter1.setDisplayName("Input Network Dataset Parameter"); parameter1.setParameterType(esriGPParameterType.esriGPParameterTypeRequired); parameter1.setDataTypeByRef(compositeDataType1); parameter1.setValueByRef(new DENetworkDataset()); parameters.add(parameter1); GPParameter parameter2 = new GPParameter(); parameter2.setName("out_intersections"); parameter2.setDirection(esriGPParameterDirection.esriGPParameterDirectionOutput); parameter2.setDisplayName("Output Intersections Parameter"); parameter2.setParameterType(esriGPParameterType.esriGPParameterTypeRequired); parameter2.setDataTypeByRef(new DEFeatureClassType()); parameter2.setValueByRef(new DEFeatureClass()); parameters.add(parameter2); return parameters; } /** * Called each time the user changes a parameter in the tool dialog or Command * Line. This updates the output data of the tool, which extremely useful for * building models. After returning from UpdateParameters(), the GP framework * calls its internal validation routine to check that a given set of * parameter values are of the appropriate number, DataType, and value. */ public void updateParameters(IArray paramvalues, IGPEnvironmentManager envMgr) { try { // retrieve the environment value for scratch workspace GPEnvironment scratchWorkspaceEnv = (GPEnvironment) envMgr.findEnvironment("scratchWorkspace"); IGPValue swValue = scratchWorkspaceEnv.getValue(); if(!swValue.isEmpty()) { outputFolder = swValue.getAsText(); } // Retrieve parameter 1 IGPParameter inputNDParameter = (IGPParameter) paramvalues.getElement(0); IGPValue inputNDParameterValue = gpUtilities.unpackGPValue(inputNDParameter); // Retrieve parameter 2 IGPParameter outputFCParameter = (IGPParameter) paramvalues.getElement(1); IGPValue outputFCParameterValue = gpUtilities.unpackGPValue(outputFCParameter); if (!inputNDParameterValue.isEmpty()) { String outputFCName = outputFolder + File.separator + "intersections.shp"; outputFCParameterValue.setAsText(outputFCName); } } catch (Exception e) { e.printStackTrace(); } } /** * Called after returning from the internal validation routine. You can * examine the messages created from internal validation and change them if * desired. */ public void updateMessages(IArray paramvalues, IGPEnvironmentManager envMgr, IGPMessages gpMessages) { try { if (gpMessages.getMaxSeverity() == esriGPMessageSeverity.esriGPMessageSeverityError) { for (int i = 0; i < gpMessages.getCount(); i++) { System.out.println(gpMessages.getMessage(i).getDescription()); } } } catch (Exception e) { e.printStackTrace(); } } /** * Executes the tool */ public void execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages messages) throws IOException, AutomationException { // Retrieve parameter 1 IGPParameter inputNDParameter = (IGPParameter) paramvalues.getElement(0); IGPValue inputNDParameterValue = gpUtilities.unpackGPValue(inputNDParameter); String nd = inputNDParameterValue.getAsText(); String ndPath = nd.substring(0, nd.lastIndexOf(File.separator)); messages.addMessage("Reading input Network Dataset..."); NetworkDataset nds = new NetworkDataset(gpUtilities.openDataset(inputNDParameterValue)); // Create a new point feature class and get a reference to it. messages.addMessage("Creating Point feature class to hold intersections..."); FeatureClass intersectionsFC = createIntersectionsFC("intersections", outputFolder, nds.getSpatialReference()); // Get the field index for the fields that will be used to set their values int indexSourceID = intersectionsFC.findField("SourceID"); int indexSourceOID = intersectionsFC.findField("SourceOID"); int indexSourceName = intersectionsFC.findField("SourceName"); // Open an insert cursor FeatureCursor featureCursor = new FeatureCursor(intersectionsFC.insert(true)); IFeatureBuffer junctionFeature = intersectionsFC.createFeatureBuffer(); // Get the INetworkQuery and figure out number of edges coincident at every // junction messages.addMessage("Reading intersections from input Network Dataset..."); EnumNetworkElement allJunctions = new EnumNetworkElement(nds.getElements(esriNetworkElementType.esriNETJunction)); allJunctions.reset(); INetworkElement aJunction = allJunctions.next(); INetworkJunction netJunction = null; while (aJunction != null) { netJunction = (INetworkJunction) aJunction; if (netJunction.getEdgeCount() >= 3) { int srcID = netJunction.getSourceID(); int srcOID = netJunction.getOID(); String srcName = nds.getSourceByID(srcID).getName(); // Get the workspace for the NDS // Open the network source feature class Workspace ws = new Workspace(nds.getWorkspace()); IFeatureClass srcFC = ws.openFeatureClass(srcName); // Get the geometry for the junction IFeature srcFeature = srcFC.getFeature(srcOID); // Insert the junction feature into the new feature class. junctionFeature.setShapeByRef(srcFeature.getShape()); junctionFeature.setValue(indexSourceID, srcID); junctionFeature.setValue(indexSourceOID, srcOID); junctionFeature.setValue(indexSourceName, srcName); featureCursor.insertFeature(junctionFeature); } aJunction = allJunctions.next(); } // Clear the buffer featureCursor.flush(); messages.addMessage("Done reading intersections and updating Point feature class..."); // Retrieve parameter 2 IGPParameter outputFCParameter = (IGPParameter) paramvalues.getElement(1); DEFeatureClass outputFCParameterValue = (DEFeatureClass) gpUtilities.unpackGPValue(outputFCParameter); outputFCParameterValue.setAsText(intersectionsFC.getName()); messages.addMessage("Packing output param..."); gpUtilities.packGPValue(outputFCParameterValue, outputFCParameter); messages.addMessage("Done."); } /** * Returns metadata file */ public String getMetadataFile() throws IOException, AutomationException { return metadataFileName; } /** * Returns status of license */ public boolean isLicensed() throws IOException, AutomationException { AoInitialize ao = new AoInitialize(); int available = esriLicenseStatus.esriLicenseAvailable; boolean status = false; // check which license level is available if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) == available || ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB) == available || ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcView) == available) { status = true; } // check out extensions, if applicable. if (status) { ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork); } return status; } /*************************************************************************************************************** * Util methods ****************************************************************************************************************/ /** * Creates a Point FC based on specified name, path, geometryType and fields * from templateFC. * * @param name * @param path * @param geometryType * @param templateFC * @return * @throws Exception */ private FeatureClass createIntersectionsFC(String name, String path, ISpatialReference sr) { FeatureClass fc = null; try { IWorkspaceFactory factory = new ShapefileWorkspaceFactory(); String wsPath = null; // create a FC Workspace ws = (Workspace) factory.openFromFile(wsPath, 0); Fields fields = new Fields(); // iod field Field field = new Field(); field.setName("OBJECTID"); field.setType(esriFieldType.esriFieldTypeOID); fields.addField(field); field = null; // shape field field = new Field(); GeometryDef gdef = new GeometryDef(); gdef.setGeometryType(esriGeometryType.esriGeometryPoint); gdef.setHasM(false); gdef.setHasZ(false); gdef.setSpatialReferenceByRef(sr); field.setName("shape"); field.setType(esriFieldType.esriFieldTypeGeometry); field.setGeometryDefByRef(gdef); fields.addField(field); field = null; // source id field field = new Field(); field.setName("SourceID"); field.setType(esriFieldType.esriFieldTypeSmallInteger); fields.addField(field); field = null; // source oid field field = new Field(); field.setName("SourceOID"); field.setType(esriFieldType.esriFieldTypeInteger); fields.addField(field); field = null; // source name field field = new Field(); field.setName("SourceName"); field.setType(esriFieldType.esriFieldTypeString); fields.addField(field); field = null; // create and return feature class fc = new FeatureClass(ws.createFeatureClass(name, fields, null, null, esriFeatureType.esriFTSimple, "shape", "default")); } catch (Exception e) { e.printStackTrace(); } return fc; } }