_gt.SuspendUpdate = False System.Threading.Thread.Sleep(300) _gt.SuspendUpdate = True
public boolean isSuspendUpdate() throws IOException, AutomationException Disables automatic refreshing of the display until unsuspended or until the display is explicitly refreshed. Suspending automatic refresh is ideal before bulk updates.DescriptionSuspends update (i.e refresh) of the display. This property is false by default. This means the GraphicTracker will automatically refresh the display after each graphic is changed.Setting this property to true, moving the graphics and then setting this property to false will result in one refresh call and will draw all graphics at once. In an dynamic map, this property is not relevant.
I am developing an application using the GraphicTracker to display moving icons. I am using the Windows.Forms.Timer event to suspend the display updates for two seconds. I have another couple subroutines that creates and removes GraphicTrackerSymbols to the tracker. All this happens on the same thread as the Windows.Forms.Timer does excute on the main gui thread. I have also verified this in debug.Every so often the program will crash with an AccessViolationException while trying to set the GraphicTracker.SuspendUpdate property to FALSE; it ALWAYS fails on trying to set that property to "FALSE". What I noticed was that if I do not remove any items from the GraphicTracker it does not fail. When I am removing items here and there as needed at some point it will fail. It may be 30 seconds or 2 minutes. I use the exact same test data (geometry/symbols/coordinates) but it still fails at some "random" time. The map no longer updates on the screen and the whole map is unusable. I cannot seem to recover or continue on. Catching the exception makes no difference as the map just will not work anymore.Here is the timer code. The timer itself is set to run every 2 seconds._gt.SuspendUpdate = False System.Threading.Thread.Sleep(300) _gt.SuspendUpdate = TrueMy thoughts are that there is some timing issue while using the "Remove" method on the GraphicTracker object that conflicts with the "SuspendUpdate" property. I have tried setting the timer to be a longer or shorter interval and also changing the "Sleep" interval but nothing seems to help.
Here's a thought. Rather than use a timer, what would happen if you added code to test whether the GraphicsTracker count was divisible by 10 with a remainder of 0, then unsuspend the auto-refresh and re-suspend it? Then your display is refreshing for every 10 graphic objects you add, or you can set it to 20 or whatever.
Perhaps the threading is causing a problem.
import java.awt.event.MouseEvent; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import com.esri.arcgis.addins.desktop.Tool; import com.esri.arcgis.arcmapui.IMxDocument; import com.esri.arcgis.carto.IActiveView; import com.esri.arcgis.display.IDisplayTransformation; import com.esri.arcgis.display.IScreenDisplay; import com.esri.arcgis.display.ISymbol; import com.esri.arcgis.display.RgbColor; import com.esri.arcgis.display.SimpleMarkerSymbol; import com.esri.arcgis.display.esriSimpleMarkerStyle; import com.esri.arcgis.enginecore.GraphicTracker; import com.esri.arcgis.enginecore.IGraphicTrackerSymbol; import com.esri.arcgis.framework.IApplication; import com.esri.arcgis.geometry.IGeoTransformation; import com.esri.arcgis.geometry.IGeometry; import com.esri.arcgis.geometry.IPoint; import com.esri.arcgis.geometry.ISpatialReference; import com.esri.arcgis.geometry.Point; import com.esri.arcgis.geometry.SpatialReferenceEnvironment; import com.esri.arcgis.interop.AutomationException; public class GTTool extends Tool { /** * Called when the tool is activated by clicking it. * * @exception java.io.IOException if there are interop problems. * @exception com.esri.arcgis.interop.AutomationException if the component throws an ArcObjects exception. */ @Override public void activate() throws IOException, AutomationException { } @Override public void init(IApplication app) throws IOException, AutomationException { super.init(app); mxDoc = (IMxDocument)app.getDocument(); } @Override public void mousePressed(MouseEvent mouseEvent) { super.mousePressed(mouseEvent); try { // Create a point based on the user's mouse click. Point p1 = new Point(); p1.putCoords((double)mouseEvent.getX(), (double)mouseEvent.getY()); if(gt == null){ // Instantiate a GraphicTracker and initialize it once. // GraphicTracker by default will refresh after each geometry add gt = new GraphicTracker(); gt.initialize(mxDoc.getActiveView().getFocusMap()); // Tell the GraphicTracker that we want to suspend auto refresh. gt.setSuspendUpdate(true); // Create a timer task to toggle the automatic graphic tracker refresh for the duration in milliseconds. // intially for 5 seconds and every 5 seconds after that. Timer timer = new Timer(); timer.scheduleAtFixedRate(new UnSuspendTimerTask(), 5000, 5000); } // Create a color object that is red RgbColor color = new RgbColor(); color.setRed(255); // Create a simplemarkersymbol to be used as the symbol for the graphic placed by GraphicTracker twoDSymbol = new SimpleMarkerSymbol(); twoDSymbol.setStyle(esriSimpleMarkerStyle.esriSMSSquare); twoDSymbol.setSize(4); twoDSymbol.setColor(color); // Tell the GraphicTracker to create a symbol and assign it to the GraphicTrackerSymbol object gts = gt.createSymbol((ISymbol)twoDSymbol, null); // Conver the user's map click point to something useful.. Point mapPoint = (Point)getMapCoordinatesFromScreenCoordinates(p1, mxDoc.getActiveView()); // Declare ESRI named constants for projecting data between WGS1984 and NAD83 HARN AZ Central int wgs84 = com.esri.arcgis.geometry.esriSRGeoCSType.esriSRGeoCS_WGS1984; int geotransformId = com.esri.arcgis.geometry.esriSRGeoTransformationType.esriSRGeoTransformation_NAD1983_To_WGS1984_1; int geotransformDirection = com.esri.arcgis.geometry.esriTransformDirection.esriTransformForward; // Create a SpatialReferenceEnvironment, ISpatialReference and IGeoTransformation SpatialReferenceEnvironment spatialRef = new SpatialReferenceEnvironment(); ISpatialReference gcswgs84 = spatialRef.createGeographicCoordinateSystem(wgs84); IGeoTransformation iGeoTransformation = (IGeoTransformation)spatialRef.createGeoTransformation(geotransformId); // Set the spatial reference of the point to the spatial reference of the map window (activeView) mapPoint.setSpatialReferenceByRef(mxDoc.getActiveView().getScreenDisplay().getDisplayTransformation().getSpatialReference()); // Project the point from whatever the activeView spatial reference is to GCS_WGS_1984 World projection - Decimal Degrees mapPoint.projectEx(gcswgs84, geotransformDirection, iGeoTransformation, false, 0.0, 0.0); // Add the geometry and symbol to the GraphicTracker gt.add((IGeometry) mapPoint, gts); } catch (AutomationException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static IPoint getMapCoordinatesFromScreenCoordinates(IPoint screenPoint, IActiveView activeView)throws Exception{ if (screenPoint == null || screenPoint.isEmpty() || activeView == null) return null; IScreenDisplay screenDisplay = activeView.getScreenDisplay(); IDisplayTransformation displayTransformation = screenDisplay.getDisplayTransformation(); // Returns a point in whatever coordinate system the DataFrame is set to return displayTransformation.toMapPoint((int)screenPoint.getX(), (int) screenPoint.getY()); } public static GraphicTracker gt = null; private IGraphicTrackerSymbol gts; private SimpleMarkerSymbol twoDSymbol; public static IMxDocument mxDoc; } class UnSuspendTimerTask extends TimerTask{ @Override public void run() { try { if(GTTool.gt.isSuspendUpdate()){ // make it auto refresh GTTool.gt.setSuspendUpdate(false); } else { // don't make it auto refresh GTTool.gt.setSuspendUpdate(true); } } catch (AutomationException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
_gpsThread = New System.Threading.Thread(New System.Threading.ParameterizedThreadStart(Sub() CreateGPSData(mapCenter.X, mapCenter.Y)))
Any progress on this? Workarounds? This is kicking my &%#.
Thanks Jason,I found the graphics container to be far worse performance than the tracker. Although something that crashes and doesn't work at all isn't really better.
It was not too difficult overall, but was tricky to get it to work without redrawing all my objects (caused annoying flickering), so I had to put them into different layers to get them to draw independently.
Les membres connectés peuvent publier, suivre les mises à jour, et plus encore. Nouveau ici ? Inscrivez-vous gratuitement.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.