arcgissamples\cartography\PointDispersalRenderer.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.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; } }