In this article, I’m going to walk through the steps involved in integrating ArcGIS into your STK Engine (4DX) Java applications. Due to the dependencies on the ESRI ArcObjects library, the STKesriDisplay library (available starting at STK 8.1) does not ship with out-of-the-box Java wrappers. But Java developers should have no reason to fret; it is extremely easy to generate the Java layer for this library using the traditional ESRI approach and toolset.
This walkthrough will assume you have a familiarity with Java, STK, and ArcGIS. Here are the steps we will go through:
Have you ever wondered how to use 4DX (STK Engine) in your Java applications? Have you wondered what are your options? Well look no further, this is the article for you!! Please note that I am assuming you are already familiar with Java, AWT/Swing, SWT, COM/OLE, and 4DX (STK Engine). I'll discuss the integration of 4DX (STK Engine) with the following APIs:
1) AWT/Swing API.
2) SWT OLE Win32 API
3) SWT_AWT Bridge API
4) Pure SWT based STK Java API
5) Summary of Java / 4DX (STK Engine) Integration Options:
Swing/AWT API:
The STK Java API was officially released with 4DX/STK on Windows 8.1 and 4DX on UNIX 7.0.2. Under the hood it leverages Sun Microsystems's AWT/Swing UI window framework and threading model. It provides a reference/binary implementation to access the STK Engine's Object Model and Map/Globe control API's with which it is released (1 to 1 version dependency). The Globe/Map controls are derived from AWT/Swing Component/JComponent, hence can be directly coded into a AWT/Swing application like any other AWT/Swing component. You can also access the thousands of Object Model and STKX classes/interfaces from Java, straight out of the box. What this means is you can begin right away to develop the domain logic of your very own Java AWT/Swing application utilizing AGI's 4DX (STK Engine) technology. The STK Java API hides all the details of communicating with the native code DLLs and Microsoft COM, and provides a regular Java look and feel to Java developers. For more details please refer to the 4DX (STK Engine) installation help and search for "STK Java API" and/or the following online links...
The 4DX (STK Engine) installation provides sample applications for 4DX (STK Engine) integration with SWT without using the STK Java API. An example is provided here. While analyzing this sample one will notice that it makes use of SWT's OLE WIN32 API, specifically the OleControlSite, OleAutomation, OleFrame, OleListener, Variant, etc. within the org.eclipse.swt.ole.win32 package space. This SWT OLE Win32 API implementation is a generic API that can be used to embed any MS Active X Control within a SWT Java application on Windows ONLY. In addition, please note if one uses this SWT OLE Win32 feature within their Java application, one will have to write wrapper Java classes/interfaces to access each object provided by the 4DX (STK Engine) Object Model API using the OleAutomation class. Ultimately this could mean that thousands of Java classes/interfaces must be written before you begin to develop the domain logic of your own Java application. The example shows an attempt at starting to wrap some classes that are available in the STKX typelib. AGI development team does not recommend the use of this approach with the 4DX (STK Engine) if one is attempting to use a majority of the STK Engine Object Model, however, it could be a valid alternative if one is merely wishing to use only a handful of classes, interfaces, etc provided by the STK Engine Object Model. Remember, this API is not available on UNIX/Linux platforms.
SWT_AWT Bridge API:
The STK Java API is implemented using the Sun Microsystems's AWT/Swing UI window framework and threading model. However, thanks to those forward thinking developers of SWT, it is possible to integrate/merge a Java AWT/Swing based application with a SWT based application using the SWT_AWT Bridge class, which is documented here and SWT threading discussed here. An example of a SWT_AWT Bridge standalone application can be found here. An example of a SWT_AWT Bridge Eclipse Plugin application can be found here.
Please note if you read the above articles thoroughly, you will notice the mention of threading issues due to the Multiple Event threads/queues of the AWT Event Dispatch thread and the SWT UI Thread. As mentioned in the articles it is very important to schedule particular tasks to be done in the proper UI thread by invoking the UI thread's work scheduler. Specifically, in AWT, use the SwingUtilities.invokeLater() and invokeAndWait() methods. And for SWT, use the Display.asyncExec() and synExec() methods. Note, however, that if you issue an Object Model call from the SWT UI thread utilizing the SwingUtilities.invokeAndWait() call, which causes the STK Engine Map or Globe controls to issue event notification to its parent window toolkit (i.e. SWT in this case) then you might cause a dead lock to occur. Note that the STK Java API Object Model implementation uses the SwingUtilities.invokeAndWait() work scheduler to help ensure calls are executed in sequence on the AWT Event Dispatch thread. However, if the developer of the SWT application wraps each Object Model call or for better performance a set of Object Model calls in a SwingUtilities.invokeLater() call then the STK Java API will bypass the calls to the SwingUtilities.invokeAndWait() and thereby avoiding the possible deadlock issues between the AWT and SWT Event loops. The reason for this is that the SwingUtilities.invokeLater() call does not block the current thread it is issued from like the SwingUtilities.invokeAndWait() method does. However, if you are depending on the Object Model calls to complete before you continue processing within your SWT UI thread (i.e. to update SWT widget controls) then you will have to create a mechanism to check when the Object Model calls have completed.
Pure SWT based STK Java API:
AGI development is investigating into the development of a pure SWT based STK Java API for the Map(2D), Globe(3D), and Object Model to be released in a for a future version of STK. This pure SWT API will provide an alternative for the SWT_AWT bridge and the SWT OLE Win32 solutions for SWT based Java applications. This alternative will also theoretically bypass any of the SWT/AWT UI dead locks due to the fact that the implementation will run purely in the SWT UI thread and not at all in the AWT UI thread.
Summary of Java / 4DX (STK Engine) Integration Options:
As I discussed above there are several Java / 4DX (STK Engine) integration options available. Each alternative has advantages and disadvantages. I've attempted to summarize this blog article's discussion in the below table in hopes that it will help you choose the best option for your development plans/schedule. Thanks for reading and have a successful Java / 4DX (STK Engine) development cycle!
A context within the STK Object Model is an object holding the unit preferences, the Object Identify Cache (OIC) as well as access restrictions. Contexts are not directly accessible to the users, yet users can influence their behavior to a certain degree (see the following article "Root Object Isolation"). Any object created or accessible through the Object Model is associated with a context through which the object accesses the unit preferences to perform the unit conversion. The diagram below shows the two root objects sharing the same context.
STK Object Model: Root Object Isolation
In the version 8.1 we have introduced a new feature called ‘Root Object Isolation’. In a nutshell, the isolation is designed to provide a way for the 4DX developers to make multiple copies of the unit preferences. Here is a short example how to use the isolation to configure two distinct, non-overlapping unit preference sets. The code creates two independent root objects and configure each with its own set of unit preferences. This process is referred to as "isolation".
AgStkObjectRootClassrootA = new AgStkObjectRootClass();
root.UnitPreferences.SetCurrentUnit("DistanceUnit", "km"); AgStkObjectRootClass rootB = new AgStkObjectRootClass();
rootB.Isolate(); // rootA and rootB are now using non-overlapping unit preferences, i.e. the changes to the unit preferences via object “rootA” do not interfere with the unit preferences of the object “rootB”.
Note: The isolation must be done right after a new root object is instantiated. Once the root object becomes “tainted”, i.e. changed, any attempts to isolate it will not succeed and will throw an exception.
The benefits of having multiple roots isolated from each other becomes more obvious when building enterprise applications where it is necessary to make individual components as independent and isolated from each other as possible. Another example where Isolation becomes a must-have is in a type of application that is constructed out of many components, for example the Application Framework. Each add-in, to prevent interfering with other add-ins, must isolate itself from the rest of the add-ins so that each one manipulates with its own private set of unit preferences. The following diagram shows two root objects isolated from each other:
Note: the references to the STK objects are local to the context so use the “Path” property of the IAgStkObject interface to compare two instances to find whether they represent the same object within STK engine.
STK Object Model: Restricted Contexts and STK Plug-ins
Contexts are also useful for the STK engine plug-ins. A while ago, while in the process of exposing the Object Model to the Constraint Plug-ins, we realized that simply giving a full read/write access is not an option and here is why. When computing the access constraints, the engine expects its state to stay the same before and after the access computation is completed. Now imagine a custom access constraint plugin which changes a position of a facility, re-propagates a satellite or does something else that changes the state of the application. So what, one may ask? Well, changes to the object’s position will trigger the access computations and the access plug-in will be called again, and again, and again… To address this, we have introduced a "restricted" context which purpose is to provide a safe mechanism for accessing the STK object state via the Object Model while protecting its state. How does this work?
When accessing the STK Object Model configured using a restricted context, the users are given read-only access to the STK Object Model objects and their methods and properties. Any attempt to change the application state by calling a method or changing a property value will result in an exception. The diagram below shows the restricted STK Object Model Root object accessed by the access constraint plug-in. Any action via the Object Model will first consult the associated context and throw an exception in case if the action is marked unsafe. So, if you are writing an access constraint plug-in and intent to use the Object Model, beware of the restricted contexts.
A few weeks ago I was at the 2008 ESRI Developer Summit in Palm Springs. This was a pretty impressive developer conference, with more than a thousand developers registered. A wide range of development organizations were represented, from one man GIS shops to large development teams. I enjoyed interacting with the ESRI developers, and discussing the evolution of the ArcGIS platform.
I could go on talking about ArcGIS for a while… However there are already other blogs covering the conference from a GIS point of view (see James Fee or Matty Lobo blogs for instance). Therefore, here, I would rather concentrate on how ArcGIS can be used with 4DX, and how some of the new capabilities announced at the DevSummit can be exploited in conjunction with STK.
But first some background information...
Background
(Note: This discussion assumes that you are familiar with GIS concepts, OGC standards and the ArcGIS product line.)
The STKesriDisplay library was added to STK at 8.1. This library is the equivalent of the ArcObjects esriDisplay library but for STK. This is the library behind the STK Globe Manager ArcGIS tab.
Using this library, you can:
Load and visualize a map document (mxd file) on the STK globe.
Manipulate ArcObjects and STK components side by side in your custom application.
Visualize (in 3D) vector and raster GIS data (the data can either be local or streamed from a GIS server).
Identify GIS features.
Convert GIS data to STK objects (through easy to use, one-step APIs), enabling further analysis using the regular STK workflows.
In terms of software and authorization on the ESRI side, you have two options. The first option is to use a regular ArcGIS Desktop (ArcMap) install. This means that if you already have ArcMap installed, you are all set and ready to go. The second option is to obtain a GIS Analyst license from AGI. This license then enables ArcGIS Engine.
Getting started
The following lines of code show how to load a MXD document into the STK globe. First a factory is created, and then the factory is used to return the renderer for the globe of interest. IAgEsri3dRendererFactory factory = newAgEsri3dRendererFactoryClass(); AGI.STKesriDisplay.IAgEsri3dRenderer renderer = factory.GetRenderer(1); renderer.OpenMapDocument(mapDocumentPath, "");
Using the renderer you can then access the underlying map document and ArcObjects. One important point is that the ArcObjects used by STK live in different threads and COM apartments. Therefore special caution needs to be applied when interacting with the ArcObjects exposed through the STK Esri Display library (more details on this topic are available here).
Now let’s review a few examples (created with STK 8.1.3 and ArcGIS 9.2).
GISDemo example on the CD
The GISDemo example is provided as part of the STK 8.1 install at [C:\Program Files\AGI\STK 8\Help\stkX\Samples\CSharp\GISDemo]. It loads a STK scenario and a MXD document. An ArcGIS address locator can be used to create a STK facility/target at a specific address. Similarly you can use an ArcGIS route locator to create a STK vehicle based on driving directions.
In addition to the example provided on the install, I have just posted two additional examples on ADN to further illustrate how to use the GIS capabilities in your custom application.
ArcGIS Online Demo on ADN The first example posted on ADN demonstrates how to benefit from ArcGIS Online in your custom STK applications.
At the DevSummit ESRI detailed how ArcGIS Online is growing with more data, and detailed imagery. The content from ArcGIS Online can also be delivered to your organization as a data appliance, which is a ready-to-use pre-configured server.
Wouldn’t it be nice to use this data in your STK globes?
Wait! That’s already possible! In STK use the Globe Manager to load one of the MXDs available on ArcGIS Online.
In 4DX, the ArcGIS Online example shows how to use ArcObjects to consume maps from ArcGIS Online through the Internet, and display them on the STK globe. As you can see on the video below, you can get access to a variety of globes and overlays, including some detailed resolution imagery (1 m resolution in the US).
Here is a video showing this example:
(This video is also available in avi format here).
In ArcGIS 9.3, with the expansion of ArcGIS online, you will have more options for your STK globes. If your organization hosts an ArcGIS server or uses an ArcGIS data appliance, you can also very easily consume this data in STK. The map layers are draped on terrain (the example uses AGI globe server for the elevation data). Accessing the attribute information associated with the GIS data using the Identify tool is fully supported.
Simple WMS Client Example on ADN The second example posted on ADN visualizes WMS data in an STK engine application.The application loads a WMS layer into the STK globe. This could also be applied to WFS (using the free ESRI data interoperability extension).
Here is a video showing this example:
(This video is also available in avi format here).
Improved support for the OGC standards was announced at the ESRI DevSummit. In ArcGIS 9.3 you will be able to visualize WCS data as well. For WMS, support for SLDs is being added. Overall WMS and WFS capabilities are also improved, which means that you will be able to connect to a larger range of OGC servers.
Future directions Combining the STK and ArcGIS engines opens up lots of possibilities for your applications. The AGI and the ESRI worlds can co-exist and share information. In future versions of STK, we are looking into draping vector GIS data on terrain for better visualization and performance. On the PointBreak side, support for WMS without requiring ArcGIS is also on the horizon.
Welcome to the 4DX development team blog! We are the AGI development team behind 4DX. Our job is to design, maintain and extend the 4DX controls and APIs.
First of all a very quick description for those of you who don’t know what 4DX is (please let me know how you managed to end up here if you do not know what 4DX is, just curious…). 4DX was first introduced 4 years ago in response to feedback from developers at the 2003 AGI User’s conference. In a nutshell, 4DX allows you to embed the STK analysis and visualization engine in your own applications. This means that your applications can benefit from the high accuracy STK aerospace algorithms, and also from the STK 2D & 3D visualizations with high performing temporal animations. As usual, a picture is worth a thousand words, and you can find some screenshots and descriptions of real world 4DX applications on the AGI web site at this link.
The 4DX libraries are built from the same code base as STK. They can be consumed from many different environments and from several operating systems. Therefore expect this blog to be eclectic. It will touch many different technologies, tools and environments. In one entry we may talk about Java. Then in the next entry switch to C# or VB.Net. Later we will wander in the Matlab world, etc…
The range of topics will be broad as well. We will talk about how we build 4DX and our day-to-day developer experience. We will discuss some useful tips and tricks about how to use 4DX more efficiently. Additional explanations about some advanced, little known or poorly understood features may also be provided. To spice it up we will occasionally show some undocumented backdoors and features (with the clear understanding that there is no guarantee that they will be maintained moving forward).
We will also attempt to help you understand how the various pieces of the AGI technology puzzle fit together. So we will sometimes mention other products and refer to other AGI blogs. If you did not have a chance yet, you may want to take a look at the Custom Application Framework blog, the Point Break blog and the DGL blog.
With this blog our goal is to foster the 4DX developer community and create a communication channel where we can expose and discuss ideas about our product. We want to share our knowledge. We will give you some insights into our development processes, and clarify some of the design decisions that were or are made. Hopefully this will help you to optimize your use of 4DX, and will also enable us to gather (hopefully constructive) feedback on your experience so we can improve our platform in return.
In summary, this blog will be a mix of “How It’s Made”, “Myth Busters” and “Survivorman” (not 100% sure about that one, we’ll see how it goes). But, unlike these TV shows, we strongly encourage you to try everything we say at home work!