Display military messages

Military software used for Situation Awareness and Command & Control pass secure communications between mobile devices in the field and command centers. These special communications consist of either voice or data transmissions. Data communications can contain military messages that define where specific military symbols are located on a map.

You can build an application using the ArcGIS Runtime SDK for Java to take these military messages and convert them into military symbols to be displayed in a map control on a desktop or laptop device. This release supports military symbol formats including the Department of Defense (DoD) MIL-STD-2525C specification.

Message processor

For your application to process a military message and display it on the map, a MessageProcessor instance is required. This message processor uses a map layer called the MessageGroupLayer to display the specialized military graphics that the messages represent. A DictionaryRenderer then controls the labels (for example, the unique designator) of the symbols created by the message processor. This dictionary renderer also allows labels to be turned on and off and controls the scale thresholds for which they are displayed.

Process military messages

Follow these four steps to process military messages and display them in your map application:

  1. Create the message group layer to be used by the message processor, specifying the type of symbol dictionary to use. Add this layer to a map after adding a tiled layer, . The following code shows how to create a MessageGroupLayer that processes and displays MIL-STD-2525C symbology:

    // create and add a tiled layer
    ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer(
     	"http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
    map.getLayers().add(tiledLayer);
    // create and add the message group layer
    MessageGroupLayer msgGroupLayer = new MessageGroupLayer(SymbolDictionary.DictionaryType.Mil2525C);
    map.getLayers().add(msgGroupLayer);

    You will later obtain the MessageProcessor from the message group layer by calling messageGroupLayer.getMessageProcessor().

  2. Create a message. Once the message group layer is fully initialized, messages can be processed using the message processor. Before you can process messages, you need to create them—that is, create Message instances.
    // create a new (empty) message			
    Message message = new Message();
  3. Populate the message. Messages consist of a message ID and a set of properties stored as key-value pairs. These properties depend on the chosen military symbology (SymbolDictionary.DictionaryType) set in the MessageGroupLayer constructor in step 1.
    message.setID("1879");
    message.setProperty("_type", "position_report");
    message.setProperty("_action", "update");
    message.setProperty("_control_points", "7843536.41455,4088224.16202");
    message.setProperty("_wkid", 3857);
    message.setProperty("sic","GFGPOPP-------X");
    message.setProperty("uniquedesignation", "1");

    The API provides a MessageHelper class to facilitate creating messages manually, as shown above. For more information, see the Construct a message section below.

  4. Process the message. The populated message can now be processed using the message processor that's associated with the MessageGroupLayer created above. Obtain the message processor from your group layer, then call the processMessage method on it
    msgGroupLayer.getMessageProcessor().processMessage(message);

    Once processed, this message will be visible in the map.

    Note:

    In the example above, the message has been supplied in the WGS_1984_Web_Mercator_Auxiliary_Sphere (wkid = 3857) spatial reference. If the spatial reference of the message is not supplied, the default spatial reference of the message processor will be used.

Construct a message

In many cases when processing military messages, the message components will be taken directly from the wire format and passed into the message processor for processing. While this makes coding simple for this use case, it makes creating messages from scratch more challenging, as you need to have a detailed understanding of the message format to make a valid message.

The MessageHelper class makes the process of creating a new message easier, but a reasonable level of understanding of the message type is still needed. The MessageHelper methods take a DictionaryType as their first parameter, specifying the symbology to be used, for example, MIL-STD-2525C.

The following example shows how to create a message to update an existing symbol on the map to a new position:

// make up an (x, y) location for the symbol
Point pt = new Point(-500000, 0);
		
// put it into a control point
List<Point> controlPoints = new ArrayList<Point>();
controlPoints.add(pt);		

// create a message to update the location of the message with ID '1'
Message message = MessageHelper.createUpdateMessage(
  DictionaryType.Mil2525C, "1", "position_report", controlPoints);
// process the message created
messageProcessor.processMessage(message);

Control label visibility

Military symbols are rendered on the map using dictionary renderers. Using the API, you can use a dictionary renderer to control the visibility and scale thresholds of labels displayed alongside military symbols.

Military symbols are displayed in a message group layer that's associated with a message processor instance. This message group layer contains several graphics layers and each of these layers has a dictionary renderer controlling the particulars of symbol rendering. This dictionary renderer can be obtained from a graphics layer by calling getRenderer. The renderer instances can then be altered using the API methods to show or hide labels and to set min and max label scale thresholds.

The following code sample takes a MessageGroupLayer instance and loops through all of the graphics layers it contains to toggle the visibility of the labels. The getLayers method is used to return the graphics layers in the message group layer:

for (Layer layer : msgGroupLayer.getLayers()) {
  // get the graphics layer
	 GraphicsLayer graphicsLayer = (GraphicsLayer) layer;
			
	 // get the dictionary renderer 
	 dictionaryRenderer = (DictionaryRenderer) graphicsLayer.getRenderer();
			
	 // toggle label visibility
	 if (dictionaryRenderer.getLabelsVisible() == true) {
		  dictionaryRenderer.setLabelsVisible(false);
  }
	 else {
    dictionaryRenderer.setLabelsVisible(true);
	 }
			
  // apply dictionary renderer back to graphics layer
	 graphicsLayer.setRenderer(dictionaryRenderer);
}

Sample code

To view interactive sample applications related to displaying military messages, launch the ArcGIS Runtime SDK for Java sample viewer, installed with the SDK. Explore relevant samples and their source code in the Information display section.

For a larger demo application, explore Esri's Vehicle Commander template whose full Java source code is available on github.com.