arcgissamples\cartography\PointDispersalRenderer.java—ArcObjects 10.4 Help for Java | ArcGIS for Desktop
Point dispersal
arcgissamples\cartography\PointDispersalRenderer.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.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import com.esri.arcgis.carto.IFeatureIDSet;
import com.esri.arcgis.carto.IFeatureRenderer;
import com.esri.arcgis.carto.ILegendClass;
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.carto.SimpleRenderer;
import com.esri.arcgis.display.IColor;
import com.esri.arcgis.display.IDisplay;
import com.esri.arcgis.display.IDisplayTransformation;
import com.esri.arcgis.display.IMarkerSymbol;
import com.esri.arcgis.display.ISimpleMarkerSymbol;
import com.esri.arcgis.display.ISymbol;
import com.esri.arcgis.display.RgbColor;
import com.esri.arcgis.display.SimpleMarkerSymbol;
import com.esri.arcgis.display.esriSimpleFillStyle;
import com.esri.arcgis.display.esriSimpleMarkerStyle;
import com.esri.arcgis.geodatabase.IFeature;
import com.esri.arcgis.geodatabase.IFeatureClass;
import com.esri.arcgis.geodatabase.IFeatureCursor;
import com.esri.arcgis.geodatabase.IQueryFilter;
import com.esri.arcgis.geometry.GeometryBag;
import com.esri.arcgis.geometry.IGeometryCollection;
import com.esri.arcgis.geometry.IPoint;
import com.esri.arcgis.geometry.IPolygon;
import com.esri.arcgis.geometry.IRelationalOperator;
import com.esri.arcgis.geometry.Point;
import com.esri.arcgis.geometry.Polygon;
import com.esri.arcgis.geometry.esriGeometryType;
import com.esri.arcgis.interop.AutomationException;
import com.esri.arcgis.interop.extn.ArcGISExtension;
import com.esri.arcgis.system.IDocumentVersionSupportGEN;
import com.esri.arcgis.system.ITrackCancel;
import com.esri.arcgis.system.esriArcGISVersion;
import com.esri.arcgis.system.esriDrawPhase;

@ArcGISExtension
public class PointDispersalRenderer implements IFeatureRenderer, ILegendInfo, Externalizable, IDocumentVersionSupportGEN {

  private ILegendGroup legendGroup;
  private IFeatureIDSet exclusionSet;
  private double dispersalRatio = 0.75;
  private ISymbol sSymbol;

  public PointDispersalRenderer() {
    try {
      initialize();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void initialize() throws Exception {
    
    legendGroup = new LegendGroup();
    ILegendClass legendClass = new LegendClass();
    legendClass.setLabel("dispersed");
    legendGroup.addClass(legendClass);
    legendGroup.setVisible(true);
    legendGroup.setEditable(true);
    legendGroup.setHeading("My Legend");
    // Make a default marker symbol
    ISimpleMarkerSymbol simpleMarkerSym = new SimpleMarkerSymbol();
    simpleMarkerSym.setStyle(esriSimpleFillStyle.esriSFSSolid);
    simpleMarkerSym.setOutline(true);
    simpleMarkerSym.setSize(7);
    IColor color = new RgbColor();
    color.setRGB(255);
    simpleMarkerSym.setColor(color);
    sSymbol = (ISymbol) simpleMarkerSym;
    legendGroup.esri_getClass(0).setSymbolByRef(sSymbol);
    
  }

  public void terminate() {
    legendGroup = null;
  }

  public boolean canRender(IFeatureClass fc, IDisplay display) throws IOException, AutomationException {
    if (fc.getShapeType() == esriGeometryType.esriGeometryPoint)
      return true;
    else
      return false;
  }

  public void draw(IFeatureCursor featureCursor, int drawPhase,IDisplay display, ITrackCancel trackCancel) throws IOException,AutomationException {
    // do not draw features if no display or wrong drawphase
    if ((display == null) || (drawPhase != esriDrawPhase.esriDPGeography)) {
      // We throw this automation exception so that the selection will work when the custom renderer is applied
      AutomationException orefAE = new AutomationException(1, "PointDispersalRenderer.java", "For Selection");
      throw orefAE;
    }
    ISymbol symbol = legendGroup.esri_getClass(0).getSymbol();
    if (symbol == null) {
      return;
    }
    IDisplayTransformation displayTrans = display.getDisplayTransformation();
    IMarkerSymbol markerSym = (IMarkerSymbol) symbol;
    double dispersalDist = displayTrans.fromPoints(markerSym.getSize())* dispersalRatio;
    // Set the symbol on the display - we will just be using this symbol,
    // so there is no need to do this every time we draw
    display.setSymbol(symbol);
    // loop through the features and draw them using the symbol
    // build a GeometryBag as we go
    int lOID;
    IGeometryCollection geomColl = new GeometryBag();
    IPolygon symPoly = new Polygon();
    IPoint placedPoint = new Point();
    IFeature feature = featureCursor.nextFeature();
    boolean bContinue = false;
    if (trackCancel != null)
      bContinue = trackCancel.esri_continue();
    do {
      IPoint point = (IPoint) feature.getShape();
      // If there is an exclusion set specified, and this feature is
      // listed then skip it
      boolean bExclude = false;
      if (exclusionSet != null) {
        lOID = feature.getOID();
        if (exclusionSet.isContains(lOID)) {
          bExclude = true;
        }
      }
      if (!bExclude) {
        try {
          placeFeature(point, 0, geomColl, display, symbol,placedPoint, symPoly, dispersalDist);
        } catch (Exception e) {
          e.printStackTrace();
        }
        // Add an envelope to the dispersed points geometry bag
        geomColl.addGeometry(symPoly.getEnvelope(), null, null);
        // Draw the marker in the chosen place
        display.drawPoint(placedPoint);
      }
      feature = featureCursor.nextFeature();
      if (trackCancel != null)
        bContinue = trackCancel.esri_continue();
    } while ((feature != null) && (bContinue == true));
  }

  public ISymbol getSymbolByFeature(IFeature arg0) throws IOException,AutomationException {
    ISymbol symbol = legendGroup.esri_getClass(0).getSymbol();
    if (symbol == null) {
      System.exit(0);
    }
    return symbol;
  }

  public boolean isRenderPhase(int drawPhase) throws IOException,AutomationException {
    if ((drawPhase == esriDrawPhase.esriDPGeography))
      return true;
    else
      return false;
  }

  public void prepareFilter(IFeatureClass fc, IQueryFilter qFilter) throws IOException, AutomationException {
    // If an exclusion set is specified, make sure the Object ID field is present
    if (exclusionSet != null) {
      if (exclusionSet.getCount() > 0) {
        qFilter.addField(fc.getOIDFieldName());
      }
    }
  }

  public void setExclusionSetByRef(IFeatureIDSet featureIDSet) throws IOException, AutomationException {
      exclusionSet = featureIDSet;
  }

  // For Legend Group
  public ILegendGroup getLegendGroup(int arg0) throws IOException,AutomationException {
    if (legendGroup.esri_getClass(0).getSymbol() != null)
      return legendGroup;
    else
      return null;
  }

  public int getLegendGroupCount() throws IOException, AutomationException {
    if ((legendGroup != null) && (legendGroup.esri_getClass(0).getSymbol() != null))
      return 1;
    else
      return 0;
  }

  public ILegendItem getLegendItem() throws IOException, AutomationException {
    return null;
  }

  public boolean isSymbolsAreGraduated() throws IOException,AutomationException {
    return false;
  }

  public void setSymbolsAreGraduated(boolean arg0) throws IOException,AutomationException {
  }

  // ********** Utility Methods
  public void placeFeature(IPoint point, int lTried,
      IGeometryCollection geomColl, IDisplay display, ISymbol symbol,
      IPoint placedPoint, IPolygon symPoly, double dDispersalDist)
      throws Exception {
    double dDist = 0;
    // Calulate the place to try the feature
    if (lTried == 0) {
      placedPoint.putCoords(point.getX(), point.getY());
    } else {
      dDist = ((lTried - 1) / 4) * dDispersalDist;
      switch (lTried % 4) {
      case 0:
        placedPoint.putCoords(point.getX() - dDist, point.getY());
      case 1:
        placedPoint.putCoords(point.getX(), point.getY() + dDist);
        break;
      case 2:
        placedPoint.putCoords(point.getX() + dDist, point.getY());
        break;
      case 3:
        placedPoint.putCoords(point.getX(), point.getY() - dDist);
        break;
      }
    }
    // see if it intersects already drawn features
    IRelationalOperator relOp = (IRelationalOperator) geomColl;
    symbol.queryBoundary(display.getHDC(), display.getDisplayTransformation(), placedPoint, symPoly);
    if (!relOp.disjoint(symPoly.getEnvelope()))
      // Try a new place
      placeFeature(point, lTried + 1, geomColl, display, symbol,placedPoint, symPoly, dDispersalDist);
  }

  public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {
    sSymbol = (ISymbol) in.readObject();
    legendGroup.esri_getClass(0).setSymbolByRef(sSymbol);
    dispersalRatio = in.readDouble();
  }

  public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(sSymbol);
    out.writeDouble(dispersalRatio);  
  }

  public void setDispersalRatio(double ratio) {
    this.dispersalRatio = ratio;
  }

  public double getdispersalRatio() {
    return dispersalRatio;
  }

  public void setSymbol(ISymbol symbol) {
    try {
      this.sSymbol = symbol;
      legendGroup.esri_getClass(0).setSymbolByRef(sSymbol);
    } catch (Exception e) {
    }
  }

  public ISymbol getSymbol() {
    return sSymbol;
  }

  public Object convertToSupportedObject(int arg0) throws IOException,AutomationException {
    SimpleRenderer simpleRend = new SimpleRenderer();
    SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol();
    simpleMarkerSymbol.setSize(8);
    simpleMarkerSymbol.setStyle(esriSimpleMarkerStyle.esriSMSDiamond);
    simpleRend.setSymbolByRef(simpleMarkerSymbol);
    return simpleRend;
  }

  public boolean isSupportedAtVersion(int arg0) throws IOException,AutomationException {
    // Support all versions above or equal 9.3.1.
    if (arg0 >= esriArcGISVersion.esriArcGISVersion93)
      return true;
    else
      return false;
  }
}