arcgissamples\cartography\TrimUniqueValues.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.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.esriLicenseProductCodeArcView) == esriLicenseStatus.esriLicenseAvailable) aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeArcView); } 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."); } }