arcgissamples\cartography\ColorBivariateRend.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.io.IOException; import com.esri.arcgis.carto.ClassBreaksRenderer; import com.esri.arcgis.carto.IBivariateRenderer; import com.esri.arcgis.carto.IClassBreaksRenderer; import com.esri.arcgis.carto.IFeatureIDSet; import com.esri.arcgis.carto.IFeatureRenderer; import com.esri.arcgis.carto.ILegendGroup; import com.esri.arcgis.carto.ILegendInfo; import com.esri.arcgis.carto.ILegendItem; import com.esri.arcgis.carto.LegendClass; import com.esri.arcgis.carto.LegendGroup; import com.esri.arcgis.display.AlgorithmicColorRamp; import com.esri.arcgis.display.IDisplay; import com.esri.arcgis.display.IFillSymbol; import com.esri.arcgis.display.ISymbol; import com.esri.arcgis.display.esriColorRampAlgorithm; import com.esri.arcgis.geodatabase.IFeature; import com.esri.arcgis.geodatabase.IFeatureClass; import com.esri.arcgis.geodatabase.IFeatureCursor; import com.esri.arcgis.geodatabase.IFeatureDraw; import com.esri.arcgis.geodatabase.IQueryFilter; import com.esri.arcgis.geodatabase.esriDrawStyle; import com.esri.arcgis.geometry.esriGeometryType; import com.esri.arcgis.system.IClone; import com.esri.arcgis.system.ITrackCancel; import com.esri.arcgis.system.esriDrawPhase; import com.esri.arcgis.interop.AutomationException; /** * Class definition for ColorBivariateRend. * In general, bivariate renderer is useful for representing the relationship * between two data distributions. Two variables are classified independently, * and their combination is represented using some combination of symbol colors. */ public class ColorBivariateRend implements IFeatureRenderer, // generic renderer interface IBivariateRenderer, // ESRI's bivariate renderer interface ILegendInfo { // support TOC and legend private static final long serialVersionUID = 1L; // data members IClassBreaksRenderer mainColorRend; IClassBreaksRenderer variationColorRend; ILegendGroup[] legendGroups; AlgorithmicColorRamp algorithmicColorRamp; boolean[] ok; /** * Default constructor. */ public ColorBivariateRend() { try { this.ok = new boolean[1]; this.algorithmicColorRamp = new AlgorithmicColorRamp(); this.algorithmicColorRamp.setAlgorithm(esriColorRampAlgorithm.esriLabLChAlgorithm); this.algorithmicColorRamp.setSize(3); } catch (java.io.IOException e) { // never happens } } // IFeatureRenderer interface /** * @see IFeatureRenderer#canRender * @param featureClass IFeatureClass * @param display IDisplay * @throws IOException * @throws AutomationException * @return boolean */ public boolean canRender(IFeatureClass featureClass, IDisplay display) throws IOException, AutomationException { return (featureClass.getShapeType() == esriGeometryType.esriGeometryPolygon); } /** * Implements IFeatureRenderer interface * @see IFeatureRenderer#prepareFilter * @param featureClass * @param queryFilter * @throws IOException * @throws AutomationException */ public void prepareFilter(IFeatureClass featureClass, IQueryFilter queryFilter) throws IOException, AutomationException { queryFilter.addField(featureClass.getOIDFieldName()); IFeatureRenderer rend = (IFeatureRenderer)this.variationColorRend; rend.prepareFilter(featureClass, queryFilter); rend = (IFeatureRenderer)this.mainColorRend; rend.prepareFilter(featureClass, queryFilter); } /** * Implements IFeatureRenderer interface * @see IFeatureRenderer#draw */ public void draw(IFeatureCursor featureCursor, int drawPhase, IDisplay display, ITrackCancel trackCancel) throws IOException, AutomationException { if (display == null) return; if (drawPhase != esriDrawPhase.esriDPGeography) return; IFeature feat = featureCursor.nextFeature(); boolean bContinue = true; // while there are still more features and drawing has not been canceled IFeatureRenderer featRend = (IFeatureRenderer)this.mainColorRend; IFeatureRenderer featRend2 = (IFeatureRenderer)this.variationColorRend; while (feat != null && bContinue == true) { ISymbol mainSym = featRend.getSymbolByFeature(feat); ISymbol variationSym = featRend2.getSymbolByFeature(feat); ISymbol sym = mergedSymbol(mainSym, variationSym); // merge symbols display.setSymbol(sym); IFeatureDraw featDraw = (IFeatureDraw)feat; featDraw.draw(drawPhase, display, sym, true, null, esriDrawStyle.esriDSNormal); // draw the feature feat = featureCursor.nextFeature(); if (trackCancel != null) bContinue = trackCancel.esri_continue(); } } /** * Implements IFeatureRenderer interface * @see IFeatureRenderer#getSymbolByFeature * @param feature * @throws IOException * @throws AutomationException * @return ISymbol */ public ISymbol getSymbolByFeature(IFeature feature) throws IOException, AutomationException { IFeatureRenderer featureRendererMain = (IFeatureRenderer)this.mainColorRend; ISymbol colorSymbol = featureRendererMain.getSymbolByFeature(feature); IFeatureRenderer featureRendererVariation = (IFeatureRenderer)this.variationColorRend; ISymbol sizeSymbol = featureRendererVariation.getSymbolByFeature(feature); return mergedSymbol(colorSymbol, sizeSymbol); } /** * Implements IFeatureRenderer interface * @see IFeatureRenderer#isRenderPhase * @param drawPhase * @return boolean */ public boolean isRenderPhase(int drawPhase) { return (drawPhase == esriDrawPhase.esriDPGeography); } /** * Implements IFeatureRenderer interface * @see IFeatureRenderer#setExclusionSetByRef * @param featureIDSet IFeatureIDSet */ public void setExclusionSetByRef(IFeatureIDSet featureIDSet) { // nothing implemented } // IBivariateRenderer interface /** * Implements IBivariateRenderer interface. * Creates the TOC entry for the renderer. * Call after setting all other properties. * @see IBivariateRenderer#createLegend * @throws IOException * @throws AutomationException */ public void createLegend() throws IOException, AutomationException { ILegendInfo variationLegendInfo = (ILegendInfo)this.variationColorRend; ILegendInfo mainLegendInfo = (ILegendInfo)this.mainColorRend; this.legendGroups = new ILegendGroup[mainLegendInfo.getLegendGroup(0).getClassCount()]; // first LegendGroup (0) contains only a heading this.legendGroups[0] = new LegendGroup(); this.legendGroups[0].setHeading(variationLegendInfo.getLegendGroup(0).getHeading()); // all other LegendGroups (1 thru MainLegendInfo.LegendGroup(0).ClassCount) // contain symbology for (int i = 0; i < mainLegendInfo.getLegendGroup(0).getClassCount(); i++) { // build new legend group this.legendGroups[i] = new LegendGroup(); String strTemp = mainLegendInfo.getLegendGroup(0).getHeading() + ":" + mainLegendInfo.getLegendGroup(0).esri_getClass(i).getLabel(); this.legendGroups[i].setHeading(strTemp); this.legendGroups[i].setEditable(false); // TOC NOT editable for (int j = 0; j < variationLegendInfo.getLegendGroup(0).getClassCount(); j++) { // build new legend class LegendClass legendClass = new LegendClass(); legendClass.setLabel(variationLegendInfo.getLegendGroup(0).esri_getClass(j).getLabel()); // clone the main symbol before merging IClone cloneSource = (IClone)mainLegendInfo.getLegendGroup(0).esri_getClass(i).getSymbol(); IClone cloneTarget = cloneSource.esri_clone(); ISymbol symbol = (ISymbol)cloneTarget; legendClass.setSymbolByRef(mergedSymbol(symbol, variationLegendInfo.getLegendGroup(0).esri_getClass(j).getSymbol())); // add legend class to legend group this.legendGroups[i].addClass(legendClass); } } } /** * Implements IBivariateRenderer interface. * @see IBivariateRenderer#setMainRendererByRef * @param featureRenderer * @throws IOException * @throws AutomationException */ public void setMainRendererByRef(IFeatureRenderer featureRenderer) throws IOException, AutomationException { this.mainColorRend = (ClassBreaksRenderer)featureRenderer; } /** * Implements IBivariateRenderer interface. * @see IBivariateRenderer#getMainRenderer * @throws IOException * @throws AutomationException * @return IFeatureRenderer */ public IFeatureRenderer getMainRenderer() throws IOException, AutomationException { return (IFeatureRenderer)this.mainColorRend; } /** * Implements IBivariateRenderer interface. * @see IBivariateRenderer#setVariationRendererByRef * @param featureRenderer * @throws IOException * @throws AutomationException */ public void setVariationRendererByRef(IFeatureRenderer featureRenderer) throws IOException, AutomationException { this.variationColorRend = (IClassBreaksRenderer)featureRenderer; } /** * Implements IBivariateRenderer interface. * @see IBivariateRenderer#getVariationRenderer * @throws IOException * @throws AutomationException * @return IFeatureRenderer */ public IFeatureRenderer getVariationRenderer() throws IOException, AutomationException { return (IFeatureRenderer)this.variationColorRend; } // ILegendInfo interface /** * Implements ILegendInfo interface. * @see ILegendInfo#getLegendGroupCount * @return int */ public int getLegendGroupCount() { return this.legendGroups.length; } /** * Implements ILegendInfo interface. * @see ILegendInfo#getLegendGroup * @param index * @return ILegendGroup */ public ILegendGroup getLegendGroup(int index) { if (index >= 0 && index < this.legendGroups.length) return this.legendGroups[index]; return null; } /** * Implements ILegendInfo interface. * @see ILegendInfo#getLegendItem * @return ILegendItem */ public ILegendItem getLegendItem() { return null; } /** * Implements ILegendInfo interface. * @see ILegendInfo#isSymbolsAreGraduated * @return boolean */ public boolean isSymbolsAreGraduated() { return false; } /** * Implements ILegendInfo interface * @see ILegendInfo#setSymbolsAreGraduated * @param b boolean */ public void setSymbolsAreGraduated(boolean b) { // nothing implemented } // private own methods /** * Auxiliary private method merges two symbols in one. * @param mainSym ISymbol * @param variationSym ISymbol * @throws IOException * @throws AutomationException * @return ISymbol */ private ISymbol mergedSymbol(ISymbol mainSym, ISymbol variationSym) throws IOException, AutomationException { IFillSymbol colorMain = (IFillSymbol)mainSym; IFillSymbol colorVariation = (IFillSymbol)variationSym; this.algorithmicColorRamp.setFromColor(colorMain.getColor()); this.algorithmicColorRamp.setToColor(colorVariation.getColor()); this.algorithmicColorRamp.createRamp(this.ok); colorMain.setColor(this.algorithmicColorRamp.getColor(1)); return (ISymbol)colorMain; } }