Military message processor

Download Sample Viewer

Description

This sample shows how to use the message processing functionality to display military symbology on a map. A MessageProcessor supporting 2525C symbology is created and processes messages, in this case coming from an XML file. The messages are converted to symbols which are displayed in a graphics layer on a map. The message processor is created using a group layer which has been added to an initialized map, and graphics layers are automatically added by the message processor as required when new messages are received.

Code snippet


    // create and add message group layer to map
    msgGroupLayer = new MessageGroupLayer(SymbolDictionary.DictionaryType.Mil2525C);
    map.getLayers().add(msgGroupLayer);
    // obtain the message processor from the message group layer
    messageProcessor = msgGroupLayer.getMessageProcessor();

    // process a message
    messageProcessor.processMessage(wireMessage);
  

Sample Code

/* Copyright 2014 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 com.esri.client.samples.displayinfo;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import com.esri.map.ArcGISTiledMapServiceLayer;
import com.esri.map.JMap;
import com.esri.map.MessageGroupLayer;
import com.esri.runtime.ArcGISRuntime;

import com.esri.core.geometry.Envelope;
import com.esri.core.symbol.advanced.Message;
import com.esri.core.symbol.advanced.MessageProcessor;
import com.esri.core.symbol.advanced.SymbolDictionary;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

/**
 * This sample shows how to use the message processing functionality to
 * display military symbology on a map. A {@link MessageProcessor} supporting
 * 2525C symbology is created and processes messages, in this case coming
 * from an XML file.  The messages are converted to symbols which are
 * displayed in a graphics layer on a map.
 * <p>
 * The message processor is created using a message group layer which has been
 * added to an initialized map, and graphics layers are automatically
 * added by the message processor as required when new messages are received.
 */
public class MessageProcessorApp {

  private JMap map;
  private MessageGroupLayer msgGroupLayer;
  private MessageProcessor messageProcessor;
  private String xmlFilename = "Mil2525CMessages.xml";
  private static final int PANEL_WIDTH = 260;
  private static final int PANEL_HEIGHT = 140;
  private static final String FSP = System.getProperty("file.separator");

  // ------------------------------------------------------------------------
  // Constructor
  // ------------------------------------------------------------------------
  public MessageProcessorApp() {

  }

  // ------------------------------------------------------------------------
  // Core functionality
  // ------------------------------------------------------------------------
  /**
   * Creates and displays the UI, including the map, for this application.
   * Creates a message group layer (of type Mil2525C) and obtains from it the 
   * message processor.
   */
  public JComponent createUI() throws Exception {

    // application content
    JLayeredPane contentPane = createContentPane();

    // button to process messages from the XML file
    JButton button = new JButton("Run Message Processor");
    button.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        // run the message processor, reading messages from an XML file
        processMessages();
      }
    });

    // create user panel
    JPanel userPanel = createUserPanel(button);
    contentPane.add(userPanel);

    // create map
    map = new JMap();
    contentPane.add(map);

    // create and add tiled layer to map
    ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer(
        "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
    map.getLayers().add(tiledLayer);

    // create and add message group layer to map
    msgGroupLayer = new MessageGroupLayer(SymbolDictionary.DictionaryType.Mil2525C, 1.0);
    map.getLayers().add(msgGroupLayer);

    // obtain the message processor from the message group layer
    messageProcessor = msgGroupLayer.getMessageProcessor();

    // set default extent to United Kingdom
    map.setExtent(new Envelope(-1406416, 6416535, 464994, 7664776));

    return contentPane;
  }

  /* Example Message */
  //     <message>
  //            <_type>position_report</_type>
  //            <_action>update</_action>
  //            <_id>102991b1-ad06-412a-9e46-1d6464a4ba64</_id>
  //            <_control_points>7849574.03524,4093250.29644;7849738.4868,4093246.66984</_control_points>
  //            <_wkid>3857</_wkid>
  //            <sic>GFGPOAO-------X</sic>
  //            <uniquedesignation>PIRATES</UniqueDesignation>
  //     </message>

  private void processMessages() {
    try {
      DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
      Document doc = docBuilder.parse(new File(getPathSampleData() + "symbology" + FSP + xmlFilename));

      // normalize text representation
      doc.getDocumentElement().normalize();
      NodeList listOfMessages = doc.getElementsByTagName("message");

      // loop through each message
      for (int msgNo = 0; msgNo < listOfMessages.getLength(); msgNo++) {
        Message wireMessage = new Message();
        Node messageNode = listOfMessages.item(msgNo);
        NodeList messageElements = messageNode.getChildNodes();

        // loop through message elements
        for (int elem = 0; elem < messageElements.getLength(); elem++) {
          Node MsgNode = messageElements.item(elem);
          // set the message component
          wireMessage.setProperty(MsgNode.getNodeName(), MsgNode.getTextContent());
        }
        // process the message
        messageProcessor.processMessage(wireMessage);
      }
    }
    catch (SAXParseException err) {
      System.err.println ("** Parsing error" + ", line " + err.getLineNumber() + ", uri " + err.getSystemId());
      System.err.println(" " + err.getMessage());
    }
    catch (SAXException e) {
      Exception x = e.getException();
      ((x == null) ? e: x).printStackTrace();
    }
    catch (Throwable t) {
      t.printStackTrace();
    }
    finally {
      // zoom to the area of interest
      SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
          map.zoomTo(new Envelope(-242472, 6665230, -213231, 6684733));
        }
      });
    }
  }

  // ------------------------------------------------------------------------
  // Static methods
  // ------------------------------------------------------------------------
  /**
   * Main method: launches the application
   * @param args
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          MessageProcessorApp mpApp = new MessageProcessorApp();

          // create the UI, including the map, for the application.
          JFrame appWindow = mpApp.createWindow();
          appWindow.add(mpApp.createUI());
          appWindow.setVisible(true);
        } catch (Exception e) {
          // on any error, display the stack trace.
          e.printStackTrace();
        }
      }
    });
  }

  // ------------------------------------------------------------------------
  // Private methods
  // ------------------------------------------------------------------------
  /**
   * Creates the panel to display description and button
   */
  private JPanel createUserPanel(JButton button) {

    // description
    JTextArea description = createDescription();

    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout(0, 0));
    panel.setLocation(10, 10);
    panel.setSize(PANEL_WIDTH, PANEL_HEIGHT);
    panel.setBackground(new Color(0, 0, 0, 0));
    panel.setBorder(new LineBorder(new Color(0, 0, 0, 60), 5, false));

    // group description and input in a panel
    panel.add(description, BorderLayout.CENTER);
    panel.add(button, BorderLayout.SOUTH);

    return panel;
  }

  /**
   * Creates a description for this application.
   * @return description
   */
  private JTextArea createDescription() {
    JTextArea description = new JTextArea(
        "Click on the button below to run the message processor. " +
        "It will read simulated messages from an XML file and " +
        "display the military data using Mil2525C Symbols.");
    description.setFont(new Font("Verdana", Font.PLAIN, 11));
    description.setForeground(Color.WHITE);
    description.setBackground(new Color(0, 0, 0, 180));
    description.setBorder(BorderFactory.createEmptyBorder(5,10,5,5));
    description.setEditable(false);
    description.setWrapStyleWord(true);
    description.setLineWrap(true);
    return description;
  }

  /**
   * Creates a window.
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame("Message Processor Application");
    window.setBounds(100, 100, 1000, 700);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout(0, 0));
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        map.dispose();
      }
    });
    return window;
  }

  /**
   * Creates a content pane.
   * @return a content pane.
   */
  private static JLayeredPane createContentPane() {
    JLayeredPane contentPane = new JLayeredPane();
    contentPane.setLayout(new BorderLayout(0, 0));
    contentPane.setVisible(true);
    return contentPane;
  }

  private String getPathSampleData() {
    String dataPath = null;
    String javaPath = ArcGISRuntime.getInstallDirectory();
    if (javaPath != null) {
      if (!(javaPath.endsWith("/") || javaPath.endsWith("\\"))){
        javaPath += FSP;
      }
      dataPath = javaPath + "sdk" + FSP + "samples" + FSP + "data" + FSP;
    }
    File dataFile = new File(dataPath);
    if (!dataFile.exists()) { 
      dataPath = ".." + FSP + "data" + FSP;
    }
    return dataPath;
  }
}
Feedback on this topic?