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.Vector; import com.esri.arcgis.carto.IDynamicLayer; import com.esri.arcgis.carto.ILayer; import com.esri.arcgis.display.CharacterMarkerSymbol; 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.esriDynamicSymbolRotationAlignment; 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._WKSPoint; import com.esri.arcgis.system.esriDrawPhase; public class MyDynamicLayer implements Runnable, IDynamicLayer,ILayer,IGeoDataset{ private static final long serialVersionUID = 1L; private boolean dynamicGlyphsCreated = false; private Vector <_WKSPoint> points = new Vector<_WKSPoint>(); private IDynamicSymbolProperties dynamicSymbolProps = null; private IDynamicGlyphFactory dynamicGlyphFactory= null; //private IDynamicCompoundMarker2 dynamicCompoundMarker =null; private int index=0; private String name=""; private IEnvelopeGEN extent=null; private ISpatialReference spatialRef = null; private boolean isCached = false; @SuppressWarnings("unused") private boolean isValid, isVisible = true; private double maximumScale, minimumScale = 0; private boolean showTips = false; private boolean isDirtyImmediate; private boolean isDirtyCompiled; private int recompileRate; private IDynamicGlyph markerGlyph; private Point point=null; private IDisplay display; private boolean endOfData=false; public MyDynamicLayer(Vector<_WKSPoint> points) { try { //set Name of the Layer this.setName("Dynamic Layer"); //Assign the data value this.points=points; //instantiate necessary variables point=new Point(); //Start the thread Thread dirtybitThread=new Thread(this); dirtybitThread.start(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //This method sets the dirty flag for the layer every 300ms public void run() { try { while(!endOfData){ if(isVisible()){ //Step 1: Get the current location of the item _WKSPoint currPoint = points.elementAt(index++); point.putCoords(currPoint.x, currPoint.y); if (display!=null){ //pan the map programmatically, so the marker will always be at the center centerMap(display); } //set the dirty property to true, so the marker can be drawn in new location this.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate,true); Thread.sleep(30); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } // This method renders the dynamic layer public void drawDynamicLayer(int phase, IDisplay display, IDynamicDisplay dynamicDisplay) throws IOException, AutomationException { try{ //Need to draw layers only in one phase for performance reasons if(phase==esriDynamicDrawPhase.esriDDPCompiled) return; //Assign the display variable to center map this.display=display; //Draw Dynamic marker at the current location of the item using Dynamic Display API's drawDynamicSymbols(dynamicDisplay); //Step 3: set the dirty bit to false this.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate,false); }catch(Exception e){ e.printStackTrace(); } } //This method creates a glyph from CharacterMarkerSymbol private void createDynamicSymbols() { try{ // Create Character Marker Symbols CharacterMarkerSymbol characterMarkerSymbol = new CharacterMarkerSymbol(); RgbColor color=new RgbColor(); color.setRGB(0xFFFFFF); characterMarkerSymbol.setColor(color); characterMarkerSymbol.setSize(40); characterMarkerSymbol.setAngle(0); characterMarkerSymbol.setCharacterIndex(73); //Create Glyph from symbol markerGlyph = dynamicGlyphFactory.createDynamicGlyph((ISymbol)characterMarkerSymbol); }catch(Exception e){ e.printStackTrace(); } } //This method draws the dynamic marker on the layer private void drawDynamicSymbols(IDynamicDisplay dynamicDisplay) throws AutomationException, IOException{ // Step 1: Create Glyphs & Symbols /* Best Practice:Need to do it only once to * avoid reinitializing variables * and creating glyphs,( glyphs are expensive) */ if (!dynamicGlyphsCreated) { dynamicSymbolProps = (IDynamicSymbolProperties2) dynamicDisplay; dynamicGlyphFactory =dynamicDisplay.getDynamicGlyphFactory(); //dynamicCompoundMarker = (IDynamicCompoundMarker2)dynamicDisplay; this.createDynamicSymbols(); dynamicGlyphsCreated = true; } //Step 2. Set the symbol alignment so that it will align with the screen dynamicSymbolProps.setRotationAlignment(esriDynamicSymbolType.esriDSymbolMarker, esriDynamicSymbolRotationAlignment.esriDSRAScreen); //Step 3. Scale the item dynamicSymbolProps.setScale(esriDynamicSymbolType.esriDSymbolMarker, 0.8f,0.8F); //Step 4. set the items' color dynamicSymbolProps.setColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f, 0.0f, 1.0f); //Step 5. assign the glyph to the dynamic-symbol dynamicSymbolProps.setDynamicGlyphByRef(esriDynamicSymbolType.esriDSymbolMarker, markerGlyph); //Step 6: draw the symbol dynamicDisplay.drawMarker(point); // //draw the item as a compound marker. This mean that you do not have to draw the items and its //accompanying labels separately, and thus allow you to write less code as well as get better //performance. //dynamicCompoundMarker.drawCompoundMarker2(point, String.valueOf(point.getX()) ,String.valueOf(point.getX())); } /* This method pans the map, * so that the dynamic marker will always be at the center */ public void centerMap(IDisplay display) throws Exception { if (index == (points.size() - 1)) { System.out.println("stopping..."); endOfData=true; return; } //get the current map visible extent IEnvelopeGEN envelope = (IEnvelopeGEN)display.getDisplayTransformation().getVisibleBounds(); //center the map around the current coordinate envelope.centerAt(point); _WKSPoint nextPoint=points.elementAt(index); //Calculate the azimuth and setRotation of the map double azimuth = (180.0 / Math.PI) * Math.atan2(nextPoint.x - point.getX(), nextPoint.y - point.getY()); display.getDisplayTransformation().setVisibleBounds((Envelope)envelope); display.getDisplayTransformation().setRotation(azimuth); } /* * @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; } /* * @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 dirtyBit) throws IOException, AutomationException { if (drawPhase == esriDynamicDrawPhase.esriDDPImmediate) isDirtyImmediate = dirtyBit; else isDirtyCompiled = dirtyBit; } /* * @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; } public String getName() throws IOException, AutomationException { return name; } public void setName(String layerName) throws IOException, AutomationException { name = layerName; } public boolean isValid() throws IOException, AutomationException { return true; } 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{ } }