arcgissamples\display\MyDynamicLayer.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.display; import java.io.IOException; import java.net.UnknownHostException; import java.util.Random; import com.esri.arcgis.carto.IDynamicLayer; import com.esri.arcgis.carto.ILayer; import com.esri.arcgis.display.CharacterMarkerSymbol; import com.esri.arcgis.display.ICharacterMarkerSymbol; import com.esri.arcgis.display.IDisplay; import com.esri.arcgis.display.IDynamicDisplay; import com.esri.arcgis.display.IDynamicGlyph; import com.esri.arcgis.display.IDynamicGlyphFactory; import com.esri.arcgis.display.IDynamicSymbolProperties; import com.esri.arcgis.display.IDynamicSymbolProperties2; import com.esri.arcgis.display.ISymbol; import com.esri.arcgis.display.RgbColor; import com.esri.arcgis.display.esriDynamicDrawPhase; import com.esri.arcgis.display.esriDynamicSymbolType; import com.esri.arcgis.geodatabase.IGeoDataset; import com.esri.arcgis.geometry.Envelope; import com.esri.arcgis.geometry.IEnvelopeGEN; import com.esri.arcgis.geometry.ISpatialReference; import com.esri.arcgis.geometry.Point; import com.esri.arcgis.interop.AutomationException; import com.esri.arcgis.system.ITrackCancel; import com.esri.arcgis.system.IUID; import com.esri.arcgis.system.IVariantStream; import com.esri.arcgis.system.esriDrawPhase; public class MyDynamicLayer implements Runnable, IDynamicLayer,ILayer,IGeoDataset{ private static final long serialVersionUID = 1L; private IDynamicSymbolProperties dynamicSymbolProps = null; private IDynamicGlyphFactory dynamicGlyphFactory= null; private String name=""; private IEnvelopeGEN extent=null; private ISpatialReference spatialRef = null; private boolean isCached = false; private boolean isValid=true; private boolean isVisible = true; private double maximumScale, minimumScale = 0; private boolean showTips = false; private boolean isDirtyImmediate; private boolean isDirtyCompiled; private int recompileRate; private Point point=null; private boolean bOnce = true; private IDynamicGlyph markerGlyph = null; private double stepX = 0; private double stepY = 0; public MyDynamicLayer() { try { //set Name of the Layer this.setName("Dynamic Layer"); //Start the thread Thread dirtybitThread=new Thread(this); dirtybitThread.start(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /* * @see java.lang.Runnable#run() * This method sets the dirty flag for the layer every 30ms */ public void run() { try { while(true){ if(isVisible()) this.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate,true); Thread.sleep(30); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String getName() throws IOException, AutomationException { return name; } public void setName(String layerName) throws IOException, AutomationException { name = layerName; } /* * @see com.esri.arcgis.carto.IDynamicLayer#drawDynamicLayer(int, com.esri.arcgis.display.IDisplay, com.esri.arcgis.display.IDynamicDisplay) * This method renders the dynamic layer */ public void drawDynamicLayer(int dynamicDrawPhase, IDisplay display, IDynamicDisplay dynamicDisplay) { try { //Step i: If not valid or visible if (!(this.isValid())|| !(this.isVisible())) return; //Step ii: Check for the phase if (dynamicDrawPhase!=esriDynamicDrawPhase.esriDDPImmediate) return; //Step iii: get the current envelope IEnvelopeGEN visibleExtent = (IEnvelopeGEN)display.getDisplayTransformation().getFittedBounds(); /* *Best Practice:Need to do it only once to * avoid reinitializing variables * and creating glyphs,( glyphs are expensive) */ if (bOnce){ //Step iv: Create a simple glyph from marker symbol try { dynamicGlyphFactory = dynamicDisplay.getDynamicGlyphFactory(); dynamicSymbolProps = (IDynamicSymbolProperties2)dynamicDisplay; //Create a marker symbol ICharacterMarkerSymbol markerSymbol = new CharacterMarkerSymbol(); markerSymbol.setSize(25.0); //Set the symbol color to white RgbColor color=new RgbColor(); color.setRGB(0xFFFFFF); markerSymbol.setColor(color); markerSymbol.setCharacterIndex(92); //create the dynamic glyph from IDynamicGlyphFactory markerGlyph = dynamicGlyphFactory.createDynamicGlyph((ISymbol)markerSymbol); } catch (Exception e) { System.out.println("Exception in MyDynamicLayer#CreatingGlyph"); e.printStackTrace(); } //Step v: Initialize dynamic item's random initial position and define the Step increments Random r = new Random(); double X = visibleExtent.getXMin() + r.nextDouble() * visibleExtent.getWidth(); double Y = visibleExtent.getYMin() + r.nextDouble() * visibleExtent.getHeight(); stepX = visibleExtent.getWidth() / 250; stepY = visibleExtent.getHeight() / 250; //create a point location to draw point = new Point(); point.putCoords(X, Y); //set the once value to false bOnce = false; } //Step vi: define properties and draw the marker symbol dynamicSymbolProps.setDynamicGlyphByRef((esriDynamicSymbolType.esriDSymbolMarker), markerGlyph); //Set the color of the glyph dynamicSymbolProps.setColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f, 0.0f, 1.0f); //Set the scale of the glyph dynamicSymbolProps.setScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f); //Draw the marker symbol on the given point dynamicDisplay.drawMarker(point); //Step vii : update the point location for the next draw cycle point.setX(point.getX()+stepX); point.setY(point.getY()+stepY); //make sure that the point falls within the visible extent if (point.getX() > visibleExtent.getXMax()) stepX = - Math.abs(stepX); if (point.getX() < visibleExtent.getXMin()) stepX = Math.abs(stepX); if (point.getY() > visibleExtent.getYMax()) stepY = - Math.abs(stepY); if (point.getY() < visibleExtent.getYMin()) stepY = Math.abs(stepY); //Step viii: set the dirty flag to false in order to stop the drawing in immediate phase setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate, false); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * @see com.esri.arcgis.carto.IDynamicLayer#getDynamicRecompileRate() * This method is called by the DD framework to determine the recompile rate for the layer */ public int getDynamicRecompileRate() throws IOException, AutomationException { return this.recompileRate; } /* * @see com.esri.arcgis.carto.IDynamicLayer#setDynamicLayerDirty(int, boolean) * This method sets the dirty flag for the dynamic layer for the corresponding phases */ public void setDynamicLayerDirty(int drawPhase, boolean dirtyFlag) throws IOException, AutomationException { if (drawPhase == esriDynamicDrawPhase.esriDDPImmediate) isDirtyImmediate = dirtyFlag; else isDirtyCompiled = dirtyFlag; } /* * @see com.esri.arcgis.carto.IDynamicLayer#isDynamicLayerDirty(int) * This method is called by the DD framework every draw cycle to check whether the layer is dirty * If the layer is dirty the DD framework calls the drawDynamicLayer() method to render the layer */ public boolean isDynamicLayerDirty(int drawPhase) throws IOException, AutomationException { if (drawPhase == esriDynamicDrawPhase.esriDDPImmediate) return isDirtyImmediate; else return isDirtyCompiled; } public boolean isValid() throws IOException, AutomationException { return isValid; } public double getMinimumScale() throws IOException, AutomationException { return minimumScale; } public void setMinimumScale(double scale) throws IOException, AutomationException { minimumScale = scale; } public double getMaximumScale() throws IOException, AutomationException { return maximumScale; } public void setMaximumScale(double scale) throws IOException, AutomationException { maximumScale = scale; } public boolean isVisible() throws IOException, AutomationException { return isVisible; } public void setVisible(boolean visible) throws IOException, AutomationException { isVisible = visible; } public boolean isShowTips() throws IOException, AutomationException { return showTips; } public void setShowTips(boolean tips) throws IOException, AutomationException { showTips = tips; } public boolean isCached() throws IOException, AutomationException { return isCached; } public void setCached(boolean cached) throws IOException, AutomationException { isCached = cached; } public void setSpatialReferenceByRef(ISpatialReference spatialRef) throws IOException, AutomationException { this.spatialRef = spatialRef; } public ISpatialReference getSpatialReference() throws IOException, AutomationException { return spatialRef; } public Envelope getExtent() throws IOException, AutomationException { return (Envelope)extent; } public IUID getID() throws IOException, AutomationException { return null; } public void load(IVariantStream arg0) throws IOException, AutomationException { //Not Supported in Java } public void save(IVariantStream arg0) throws IOException, AutomationException { //Not Supported in Java } public Envelope getAreaOfInterest() throws IOException, AutomationException { return (Envelope)extent; } public double getLastMinimumScale() throws IOException, AutomationException { return 0; } public double getLastMaximumScale() throws IOException, AutomationException { return 0; } public String ILayerGeneralProperties_getLayerDescription() throws IOException, AutomationException { return null; } public void setLayerDescription(String arg0) throws IOException, AutomationException { } public String getTipText(double arg0, double arg1, double arg2) throws IOException, AutomationException { return null; } public int getSupportedDrawPhases() throws IOException, AutomationException { return esriDrawPhase.esriDPAnnotation; } //Method not implemented;Layer will be drawn only in dynamic mode public void draw(int arg0, IDisplay arg1, ITrackCancel arg2) throws IOException, AutomationException{ } }