arcgissamples\analyst3d\Convert2DPointsTo3D.java—ArcObjects 10.4 Help for Java | ArcGIS for Desktop
Convert 2D points to 3D
arcgissamples\analyst3d\Convert2DPointsTo3D.java
/* Copyright 2015 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 at <your ArcGIS install location>/DeveloperKit10.4/userestrictions.txt.
* 
*/
package arcgissamples.analyst3d;

import java.io.File;

import com.esri.arcgis.datasourcesfile.ShapefileWorkspaceFactory;
import com.esri.arcgis.geodatabase.Feature;
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.Workspace;
import com.esri.arcgis.geodatabase.esriFeatureType;
import com.esri.arcgis.geodatabase.esriFieldType;
import com.esri.arcgis.geometry.Point;
import com.esri.arcgis.geometry.UnknownCoordinateSystem;
import com.esri.arcgis.geometry.esriGeometryType;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.Cleaner;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;

public class Convert2DPointsTo3D {

  public Convert2DPointsTo3D(){
    
  }

  /**
   * Main Method - The console application entry point.
   * 
   * @param args String[] Command line argument
   */
  public static void main(String[] args) {
    System.out.println("Starting Convert2DPointsTo3D - An ArcObjects SDK Developer Sample");
    
    try{
      //Initialize engine console application
      EngineInitializer.initializeEngine();
      
      //Initialize ArcGIS license
      AoInitialize aoInit = new AoInitialize();
      initializeArcGISLicenses(aoInit);
      
      //Get DEVKITHOME Home
      String devKitHome = System.getenv("AGSDEVKITJAVA");
      
      //Data access setup
      String inputPath = devKitHome + "java" + File.separator + "samples" + File.separator 
                      + "data" + File.separator + "usa";
      System.out.println(inputPath);
      String inputShapefile = "wind.shp";
      
      //Data output setup
      String outputPath = getOutputDir() + File.separator + "convert2dto3d";
      String outputShapefile = "3DShape.shp";
      String zFieldName = "VELOCITY";
      
      File outShapefileDir = new File(outputPath);
      outShapefileDir.mkdir();

      File outShapefileFile = new File(outShapefileDir, outputShapefile);
    
      if (outShapefileFile.exists()) {
        System.out.println("Output shapefile already exists: " + outShapefileFile.getAbsolutePath());
        System.out.println("Delete it (plus related files) and rerun");
        System.exit(0);
      }
      
      //Execute sample
      Convert2DPointsTo3D convert2DTo3D = new Convert2DPointsTo3D();
      convert2DTo3D.create3DShape(inputPath, inputShapefile, zFieldName, outputPath, outputShapefile);
      
      System.out.println("Done.  Output shapefile created in " + outShapefileDir.getAbsolutePath());
      
      //Ensure any ESRI libraries are unloaded in the correct order
      aoInit.shutdown();
    }catch(Exception e){
      System.out.println("Error: " + e.getMessage());
      e.printStackTrace();
      System.exit(-1);
    }
  }

  /**
   * Checks to see if an ArcGIS Engine Runtime license or an Basic License
   * is available. If so, then the appropriate ArcGIS License is initialized.
   * 
   * @param aoInit The AoInitialize object instantiated in the main method.
   */
  private static void initializeArcGISLicenses(AoInitialize aoInit) {
    try {
      if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeBasic) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeBasic);
      else{
        System.err.println("Could not initialize an Engine or Basic License. Exiting application.");
        System.exit(-1);
      }
    } catch (Exception e) {e.printStackTrace();}
  }

  /**
   * 
   * 
   * @param inShapePath Path to input shapefile
   * @param inShapeName Name of input shapefile
   * @param zFieldName Name of attribute containing z value
   * @param outShapePath Path to output shapefile
   * @param outShapeName Name of output shapefile
   */
  private void create3DShape(String inShapePath, String inShapeName, String zFieldName, String outShapePath, String outShapeName) {
    try{
      //Open input feature classes
      ShapefileWorkspaceFactory shapefileWorkspaceFactory = new ShapefileWorkspaceFactory();
      Workspace workspace = new Workspace(shapefileWorkspaceFactory.openFromFile(inShapePath, 0));
      FeatureClass inFeatureClass = new FeatureClass(workspace.openFeatureClass(inShapeName));
      
      //Define an UnknownCoordinateSystem, used when creating a FeatureClass
      UnknownCoordinateSystem spatialRef = new UnknownCoordinateSystem();
      
      //Define a Grid Size
      int gridSize = 1000;
      
      //Create new output feature classes 
      FeatureClass outFeatureClass = 
        createFeatureClass(outShapePath, outShapeName, esriGeometryType.esriGeometryPoint, true, true, spatialRef, gridSize);

      //Copy the input feature class' fields to the output feature class w/o overwriting system fields
      Field field;
      for(int index = 0; index < inFeatureClass.getFields().getFieldCount(); index++) {
        field = (Field) inFeatureClass.getFields().getField(index);
        
        //If the field is editable and not the geometry field and the attribute does not
        //already exist, then add the new field to the output feature class
        if(field.isEditable() 
            && field.getType() != esriFieldType.esriFieldTypeGeometry
            && outFeatureClass.getFields().findField(field.getName()) == -1){
          outFeatureClass.addField(field);
        }
      }

      //Create a search cursor for the input feature class
      FeatureCursor inCursor = new FeatureCursor(inFeatureClass.search(null, false));

      //Create an insert cursor for the output feature class
      FeatureCursor outCursor = new FeatureCursor(outFeatureClass.IFeatureClass_insert(true));
      
      //Create a feature buffer when creating new features with an insert cursor
      Feature outFeature = (Feature) outFeatureClass.createFeatureBuffer();
      
      //Get the first feature from the search cursor
      Feature inFeature = (Feature) inCursor.nextFeature();

      //This sample only supports point data
      if (!(inFeature.getShape() instanceof Point)) {
        System.out.println("This tool requires a point shapefile as the input");
        System.out.println("Exiting...");
        System.exit(0);
      }

      //Loop through all the input features, cloning the shape,
      //looking up and adding the z value from the input table
      //and adding the new feature to the output feature class
      for (int featureCounter = 1; inFeature != null; inFeature = (Feature) inCursor.nextFeature(), featureCounter++) {
        int zField = inFeature.getFields().findField(zFieldName);
        
        if(zField < 0) {
          System.out.println("  Field: " + zFieldName + " was not found in the input feature class: ");
          continue;
        }
        
        double zValue = Double.parseDouble(inFeature.getValue(zField).toString());
        
        //Get the input geometry and clone it and set ZAware on it.
        Point featureShapeAsPoint = (Point) inFeature.getShape();
        Point outPoint = (Point) featureShapeAsPoint.esri_clone();
        outPoint.setZAware(true);
        outPoint.setZ(zValue);
        outFeature.setShapeByRef(outPoint);

        System.out.println("  Point feature #" + featureCounter + ": (" + outPoint.getX() + ", " + outPoint.getY() + ", " + outPoint.getZ() + ")");

        //Copy field values from input feature to output feature, 
        //except for the OID and shape value
        for(int fieldCounter = 0; fieldCounter < inFeatureClass.getFields().getFieldCount(); fieldCounter++){
          int outFeatureFieldIndex = outFeature.getFields().findField(inFeatureClass.getFields().getField(fieldCounter).getName());
          
          //Check if the field exists, then make sure the 
          //field is editable and not the shape field
          if (outFeatureFieldIndex >= 0){
            if(outFeature.getFields().getField(outFeatureFieldIndex).isEditable() &&
                outFeature.getFields().getField(outFeatureFieldIndex).getType() != esriFieldType.esriFieldTypeGeometry) {
              //Set the value for the feature
              outFeature.setValue(outFeatureFieldIndex, inFeature.getValue(outFeatureFieldIndex));
            }
          }
        }
        
        //Insert the feature with the insert cursor
        outCursor.insertFeature(outFeature);
        
        //Release ArcObject references
        Cleaner.release(featureShapeAsPoint);
        Cleaner.release(outPoint);
      }
      //Flush the cursor
      inCursor.flush();
      
      //Release the cursor after all inserts are made
      Cleaner.release(outCursor);
    } catch(Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }
  }

  /**
   * Creates a new feature class based upon the parameters passed in to the method
   * at run time.
   * 
   * @param outShapePath Path to the output shapefile
   * @param outShapeName The name of the output shapefile
   * @param shapeType The geometry type for the shapefile (will always be point in this sample)
   * @param hasM Measure awareness
   * @param hasZ Elevation awareness
   * @param spatialRef Defines the spatial coordinate system for the new shapefile
   * @param gridSize Specified value used to override default grid size
   * @return A new feature class with an OID and shape fields defined
   */
  private FeatureClass createFeatureClass(String outShapePath, String outShapeName, int shapeType, boolean hasM, boolean hasZ, UnknownCoordinateSystem spatialRef, int gridSize) {
    FeatureClass outFeatureClass = null;
    
    try{
      //Get the workspace of the output feature class
      ShapefileWorkspaceFactory shapefileWorkspaceFactory = new ShapefileWorkspaceFactory();
      Workspace outFeatureWorkspace = new Workspace(shapefileWorkspaceFactory.openFromFile(outShapePath, 0));
      
      //Define the OID field
      Field oidField = new Field();
      oidField.setName("OBJECTID");
      oidField.setAliasName("OBJECTID");
      oidField.setType(esriFieldType.esriFieldTypeOID);
      
      //Define the geometry definition for the geometry (i.e. Shape) field
      GeometryDef geometryDef = new GeometryDef();
      geometryDef.setGeometryType(shapeType);
      geometryDef.setHasM(hasM); 
      geometryDef.setHasZ(hasZ); 
      geometryDef.setSpatialReferenceByRef(spatialRef); 
      geometryDef.setGridCount(1);
      geometryDef.setGridSize(0, gridSize);

      //Define the geometry field (i.e. Shape)
      Field geometryField = new Field();
      geometryField.setName("Shape");
      geometryField.setIsNullable(true);
      geometryField.setType(esriFieldType.esriFieldTypeGeometry);
      geometryField.setGeometryDefByRef(geometryDef);
      geometryField.setRequired(true);

      //Create a fields collection and add individual field objects to collection
      Fields fields = new Fields();
      fields.addField(oidField);
      fields.addField(geometryField);

      //Create the new feature class (i.e. Shapefile in this sample)
      outFeatureClass = new FeatureClass(
          outFeatureWorkspace.createFeatureClass(outShapeName, fields, null, null, esriFeatureType.esriFTSimple, "Shape", ""));
    }catch(Exception e){
      System.out.println("Unable to create a feature class. \nExiting after stack trace...");
      e.printStackTrace();
      System.exit(-1);
    }
    
    //Return the new feature class
    return outFeatureClass;
  }

  
  /**
   * Convenience method to generate an output directory based on the operating
   * system that the sample is being executed on. 
   * 
   * @return A path to the new directory is return
   */
  private static String getOutputDir() {
    String userDir;
    
    //Get the operating systems user profile or home location depending
    //on which operating system this sample is executed on.
    if(System.getProperty("os.name").toLowerCase().indexOf("win") > -1){
      userDir = System.getenv("UserProfile");
    }else{
      userDir = System.getenv("HOME");
    }
      
    String outputDir = userDir + File.separator + "arcgis_sample_output";
    
    System.out.println("Creating output directory - " + outputDir);
    
    new File(outputDir).mkdir();
    
    return outputDir;
  }
}