arcgissamples\cartography\TrimUniqueValues.java—ArcObjects 10.4 Help for Java | ArcGIS for Desktop
Trim unique values
arcgissamples\cartography\TrimUniqueValues.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.cartography;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.UIManager;

import com.esri.arcgis.beans.TOC.TOCBean;
import com.esri.arcgis.beans.map.MapBean;
import com.esri.arcgis.carto.FeatureLayer;
import com.esri.arcgis.carto.IGeoFeatureLayer;
import com.esri.arcgis.carto.ILayer;
import com.esri.arcgis.carto.SimpleRenderer;
import com.esri.arcgis.carto.UniqueValueRenderer;
import com.esri.arcgis.carto.esriViewDrawPhase;
import com.esri.arcgis.display.IColor;
import com.esri.arcgis.display.IDisplayTransformation;
import com.esri.arcgis.display.IEnumColors;
import com.esri.arcgis.display.ISymbol;
import com.esri.arcgis.display.RandomColorRamp;
import com.esri.arcgis.display.SimpleFillSymbol;
import com.esri.arcgis.geodatabase.ICursor;
import com.esri.arcgis.geodatabase.IFeature;
import com.esri.arcgis.geodatabase.IFeatureClass;
import com.esri.arcgis.geodatabase.IFeatureCursor;
import com.esri.arcgis.geodatabase.IRow;
import com.esri.arcgis.geodatabase.QueryFilter;
import com.esri.arcgis.geodatabase.SpatialFilter;
import com.esri.arcgis.geodatabase.esriSpatialRelEnum;
import com.esri.arcgis.geometry.Envelope;
import com.esri.arcgis.interop.AutomationException;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;

/**
 * This sample demonstrate the technique of triming legend group of UniqueValueRenderer.
 * Set the scale and click on the original or trimed renderer buttons.
 * Legend group size will be recalculate according to the features shown on the screen.
 */
public class TrimUniqueValues extends JFrame implements ActionListener {

  private static final long serialVersionUID = 1L;
  static AoInitialize aoInit;
  MapBean mapBean = new MapBean();
  TOCBean tocBean = new TOCBean();
  String fieldName = null;
  Button buttonZoomIn = new Button();
  Button buttonZoomOut = new Button();
  Button buttonSetOriginalUnuqueValueRenderer = new Button();
  Button buttonSetTrimUnuqueValues = new Button();

  FeatureLayer featureLayer = null;
  UniqueValueRenderer uniqueValueRenderer = null;
  UniqueValueRenderer newUVRend = null;
  int fieldNumber = 0;

  /**
   * Method to start the program execution.
   * @param s String[]
   */
  public static void main(String s[]) {
    System.out.println("Starting \"Trim Unique Values\" - An ArcObjects Java SDK Developer Sample");

    //Get DEVKITHOME Home
    String devKitHome = System.getenv("AGSDEVKITJAVA");
    
    if (!(new File(devKitHome).exists())) {
      System.out.println(devKitHome + " does not exist.\nExiting...");
      System.exit(-1);
    }
    String workspacePath = devKitHome + "java" + File.separator + "samples" + File.separator + "data" + File.separator + "usa";
    String featureClassName = "states";
    File shapefileFile = new File(workspacePath, featureClassName + ".shp");
    if (!shapefileFile.exists()) {
      System.out.println("Shapefile does not exist: " + shapefileFile.getAbsolutePath());
      System.exit(0);
    }

    try {
      EngineInitializer.initializeVisualBeans();
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      
      initializeArcGISLicenses();
      
      TrimUniqueValues thisApp = new TrimUniqueValues();
      thisApp.initUI(workspacePath, featureClassName);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  static void initializeArcGISLicenses() {
    try {
      aoInit = new AoInitialize();
      
      if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeBasic) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeBasic);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }



  /*
   * Lays out the User Interface, and sets up event listeners
   */
  private void initUI(String path, String name) throws AutomationException, IOException {
    this.setTitle("TrimUniqueValues Java Sample");
    this.setSize(new Dimension(600, 500));
    this.getContentPane().setLayout(new BorderLayout());

    this.buttonZoomIn.setLabel("ZoomIn");
    this.buttonZoomOut.setLabel("ZoomOut");
    this.buttonSetOriginalUnuqueValueRenderer.setLabel("Set Original Unique Value Renderer");
    this.buttonSetTrimUnuqueValues.setLabel("Set Trim Renderer");

    Panel buttonPanel = new Panel(new FlowLayout(FlowLayout.LEADING));
    buttonPanel.add(this.buttonZoomIn);
    buttonPanel.add(this.buttonZoomOut);
    buttonPanel.add(this.buttonSetOriginalUnuqueValueRenderer);
    buttonPanel.add(this.buttonSetTrimUnuqueValues);

    this.getContentPane().add(this.mapBean, BorderLayout.CENTER);
    this.getContentPane().add(this.tocBean, BorderLayout.WEST);
    this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);

    if( this.featureLayer != null ) {
      this.featureLayer.setRendererByRef( new SimpleRenderer() );
    }
    this.mapBean.refresh(esriViewDrawPhase.esriViewGeography, null, null);
    this.mapBean.clearLayers();
    this.mapBean.addShapeFile(path, name); // first layer
    this.tocBean.setBuddyControl(this.mapBean);
    ILayer layer = this.mapBean.getLayer(0);
    this.featureLayer = (FeatureLayer) layer;
    this.mapBean.refresh(esriViewDrawPhase.esriViewGeography, null, null);
    this.setVisible(true);

    // set listeners
    this.buttonZoomIn.addActionListener(this);
    this.buttonZoomOut.addActionListener(this);
    this.buttonSetOriginalUnuqueValueRenderer.addActionListener(this);
    this.buttonSetTrimUnuqueValues.addActionListener(this);
    this.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        try {
          aoInit.shutdown();
        } catch(IOException ex) {
          // exit anyway
        }
        System.exit(0);
      }
    });
  }

  /**
   * implements interface ActionListener
   * @see ActionListener#actionPerformed
   * @param event
   */
  public void actionPerformed(ActionEvent event) {
    Object eventSource = event.getSource();
    if (eventSource == this.buttonZoomIn) {
      try {
        double mapScale = this.mapBean.getMapScale();
        this.mapBean.setMapScale(mapScale / 1.2);
        this.tocBean.update();
        this.mapBean.refresh(esriViewDrawPhase.esriViewGeography, null, null);
      } catch (java.io.IOException ex) {
        ex.printStackTrace(); // never happened
      }
    }
    if (eventSource == this.buttonZoomOut) {
      try {
        double mapScale = this.mapBean.getMapScale();
        this.mapBean.setMapScale(mapScale * 1.2);
        this.tocBean.update();
        this.mapBean.refresh(esriViewDrawPhase.esriViewGeography, null, null);
      } catch (java.io.IOException ex) {
        ex.printStackTrace(); // never happened
      }
    }
    if (eventSource == this.buttonSetOriginalUnuqueValueRenderer) {
      try {
        setOriginalUniqueValueRenderer();
        this.tocBean.update();
        this.mapBean.refresh(esriViewDrawPhase.esriViewGeography, null, null);
      } catch (java.io.IOException ex) {
        System.out.println("Set Original Unique Value Renderer, exception:" + ex);
      }
    }
    if (eventSource == this.buttonSetTrimUnuqueValues) {
      try {
        setTrimUniqueValues();
        this.tocBean.update();
        this.mapBean.refresh(esriViewDrawPhase.esriViewGeography, null, null);
      } catch (java.io.IOException ex) {
        System.out.println("Trim Unique Value Renderer, exception:" + ex);
      }
    }
  }
  /**
   * set original UniqueValueRenderer
   * @throws IOException
   * @throws AutomationException
   */
  private void setOriginalUniqueValueRenderer() throws IOException, AutomationException {
    if( this.featureLayer == null )
      return;
    if( this.uniqueValueRenderer == null ) {
      String strNameField = "STATE_NAME";
      this.uniqueValueRenderer = new UniqueValueRenderer();
      FeatureLayer table = this.featureLayer;
      this.fieldNumber = table.findField(strNameField);
      this.uniqueValueRenderer.setFieldCount(1);
      this.uniqueValueRenderer.setField(0, strNameField);

      RandomColorRamp colorRamp = new RandomColorRamp();
      colorRamp.setStartHue(0);
      colorRamp.setMinValue(99);
      colorRamp.setMaxSaturation(15);
      colorRamp.setEndHue(360);
      colorRamp.setMaxValue(100);
      colorRamp.setMaxSaturation(30);
      colorRamp.setSize(100);
      boolean rampBool[] = new boolean[1];
      rampBool[0] = true;
      colorRamp.createRamp(rampBool);
      IEnumColors colors = colorRamp.getColors();

      QueryFilter queryFilter = new QueryFilter();
      queryFilter.addField(strNameField);
      ICursor cursor = table.ITable_search(queryFilter, true);

      IRow nextRow = cursor.nextRow();
      while (nextRow != null) {
        Object codeValue = nextRow.getValue(this.fieldNumber);
        IColor nextUniqueColor = colors.next();
        if (nextUniqueColor == null) {
          colors.reset();
          nextUniqueColor = colors.next();
        }
        SimpleFillSymbol sym = new SimpleFillSymbol();
        sym.setColor(nextUniqueColor);
        // When adding a value, ifyou specify the heading too, you'll get categories
        // in the TOC which will look wrong in this case.
        this.uniqueValueRenderer.addValue((String) codeValue, null, (ISymbol) sym);
        nextRow = cursor.nextRow();
      }
    }
    this.featureLayer.setRendererByRef(this.uniqueValueRenderer);
  }

   /**
    * set TrimUniqueValues renderer
    * @throws IOException
    * @throws AutomationException
    */
  private void setTrimUniqueValues() throws IOException, AutomationException {
    if( this.featureLayer == null )
      return;
    IGeoFeatureLayer geoFeatLayer = this.featureLayer;
    IFeatureClass featClass = geoFeatLayer.getFeatureClass();
    this.newUVRend = new UniqueValueRenderer();
    int iFieldCount = this.uniqueValueRenderer.getFieldCount();
    this.newUVRend.setFieldCount(iFieldCount);
    String[] strField = new String[iFieldCount];
    
    for (int i = 0; i < iFieldCount; i++) {
      String field = this.uniqueValueRenderer.getField(i);
      strField[i] = field;
      this.newUVRend.setField(i, field);
    }
    
    this.newUVRend.setDefaultSymbol(this.uniqueValueRenderer.getDefaultSymbol());
    this.newUVRend.setUseDefaultSymbol(this.uniqueValueRenderer.isUseDefaultSymbol());
    this.newUVRend.setDefaultLabel(this.uniqueValueRenderer.getDefaultLabel());
    this.newUVRend.setColorScheme(this.uniqueValueRenderer.getColorScheme());
    IDisplayTransformation displayTransform = this.mapBean.getActiveView().getScreenDisplay().getDisplayTransformation();
    Envelope envelope = (Envelope) displayTransform.getFittedBounds();
    SpatialFilter spatialFilter = new SpatialFilter();
    spatialFilter.setGeometryByRef(envelope);
    spatialFilter.setGeometryField("Shape");
    spatialFilter.setSpatialRel(esriSpatialRelEnum.esriSpatialRelContains);
    IFeatureCursor featCursor = featClass.search(spatialFilter, true);
    // loop thru features, storing info for new renderer in two temp arrays
    ArrayList<ISymbol> rendSym = new ArrayList<ISymbol>();
    ArrayList<String> strRendVal = new ArrayList<String>();
    IFeature feat = featCursor.nextFeature();
    while (feat != null) {
      String strValueString = (String) feat.getValue(this.fieldNumber);
      boolean noValueFound = true;
      // search array to see if we've already added this value
      for (int j = 0; j < strRendVal.size(); j++) {
        if (((String) strRendVal.get(j)).compareTo(strValueString) == 0) {
          noValueFound = false;
          break;
        }
      }
      if (noValueFound) {
        ISymbol sym = this.uniqueValueRenderer.getSymbol(strValueString); // get symbol from old renderer
        if (sym != null) {
          rendSym.add(sym);
          strRendVal.add(strValueString);
        }
      }
      feat = featCursor.nextFeature();
    }
    for (int i = 0; i < this.uniqueValueRenderer.getValueCount(); i++) {
      String value = this.uniqueValueRenderer.getValue(i);
      for (int j = 0; j < strRendVal.size(); j++) {
        if (((String) strRendVal.get(j)).compareTo(value) == 0) {
          ISymbol sym = (ISymbol) rendSym.get(j);
          this.newUVRend.addValue(value, this.uniqueValueRenderer.getHeading(value), sym);
          this.newUVRend.setLabel(value, this.uniqueValueRenderer.getLabel(value));
          break;
        }
      }
    }
    this.featureLayer.setRendererByRef(this.newUVRend);
    System.out.println("Trimmed to " + this.newUVRend.getValueCount() + " values.");
  }
}