This sample demonstrates use of the message processing
functionality to display military symbols on the map. Military symbol messages are displayed on the map via
GraphicsLayers within a MessageGroupLayer. In this application, an
empty MessageGroupLayer based on the SymbolDictionaryType Mil2525C
is declared in XAML. An event handler is also assigned to handle
the Initialized event raised when the MessageGroupLayer's
associated MessageProcessor object is initialized by the map. The
initialized event is used to indicate that the MessageProcessor is
ready to begin processing messages. In this application, the event
is simply used to enable UI components which allow the user to
manually initiate the processing of messages which here are being
read from a static XML file on disk. GraphicsLayers which contain
the Graphics representing individual messages are automatically
added to the MessageGroupLayer by the API.
<UserControlx:Class="ArcGISWPFSDK.MessageProcessing"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:esri="http://schemas.esri.com/arcgis/client/2009"><Grid><Grid.Resources><BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter"/><LinearGradientBrushx:Key="PanelGradient"EndPoint="0.5,1"StartPoint="0.5,0"><LinearGradientBrush.RelativeTransform><TransformGroup><ScaleTransformCenterY="0.5"CenterX="0.5"/><SkewTransformCenterY="0.5"CenterX="0.5"/><RotateTransformAngle="176"CenterY="0.5"CenterX="0.5"/><TranslateTransform/></TransformGroup></LinearGradientBrush.RelativeTransform><GradientStopColor="#FF145787"Offset="0.16"/><GradientStopColor="#FF3D7FAC"Offset="0.502"/><GradientStopColor="#FF88C5EF"Offset="0.984"/></LinearGradientBrush></Grid.Resources><esri:Mapx:Name="_map"UseAcceleratedDisplay="True"WrapAround="True"Extent="-245200 , 6665900, -207000 , 6687300"><esri:ArcGISTiledMapServiceLayerID="World Topo Map"Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"/><esri:MessageGroupLayerx:Name="_messageGroupLayer"MessageProcessorInitialized="HandleMessageProcessorInitialized"SymbolDictionaryType="Mil2525C"/></esri:Map><BorderBackground="{ StaticResource PanelGradient}"BorderThickness="1"CornerRadius="5"HorizontalAlignment="Right"VerticalAlignment="Top"Margin="20"Padding="10"BorderBrush="Black"><StackPanel><TextBlockFontWeight="Bold"Foreground="White">
Click on the button below to run the message processor.<LineBreak/>
It will read simulated messages from an XML file and <LineBreak/>
display military symbols on the map <LineBreak/>
using Mil2525C Symbols.
</TextBlock><Buttonx:Name="ProcessMessagesButton"Content="Process Messages"Click="ProcessMessagesButton_Click"Width="140"Height="24"VerticalAlignment="Top"HorizontalAlignment="Left"Margin="0,5,0,0"/></StackPanel></Border><ProgressBarx:Name="MyProgressBar"IsIndeterminate="True"VerticalAlignment="Bottom"Width="200"Height="20"Margin="10"Visibility="{Binding Path=IsBusy, Converter={StaticResource BooleanToVisibilityConverter}}"></ProgressBar></Grid></UserControl>
using System.Linq;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows;
using ESRI.ArcGIS.Client.AdvancedSymbology;
using System.Xml.Linq;
using System.IO;
using System.Reflection;
using System.ComponentModel;
namespace ArcGISWPFSDK
{
publicpartialclass MessageProcessing : UserControl , INotifyPropertyChanged
{
publicevent PropertyChangedEventHandler PropertyChanged;
privatebool _isBusy = true;
publicbool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsBusy"));
}
}
}
string messagesXmlFilePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), @"..\Data\Symbology\Mil2525CMessages.xml");
public MessageProcessing()
{
InitializeComponent();
// Disable the UI button until the MessageProcessor is initialized
ProcessMessagesButton.IsEnabled = false;
}
privatevoid HandleMessageProcessorInitialized(object sender, System.EventArgs e)
{
// The MessageProcessor is initialized - enable the UI button
ProcessMessagesButton.IsEnabled = true;
DataContext = this;
IsBusy = false;
}
privatevoid ProcessMessagesButton_Click(object sender, RoutedEventArgs e)
{
// This function simulates real time message processing by processing a static set of messages from an XML document./*
* |== Example Message ==|
*
* <message>
* <_type>position_report</_type>
* <_action>update</_action>
* <_id>16986029-8295-48d1-aa6a-478f400a53c0</_id>
* <_wkid>3857</_wkid>
* <sic>GFGPOLKGS-----X</sic>
* <_control_points>-226906.99878,6679149.88998;-228500.51759,6677576.8009;-232194.67644,6675625.78198</_control_points>
* <UniqueDesignation>DIRECTION OF ATTACK</UniqueDesignation>
* </message>
*/// Load the XML document
XDocument xmlDocument = XDocument.Load(messagesXmlFilePath, LoadOptions.None);
// Create a collection of messages
IEnumerable<XElement> messagesXml = from n in xmlDocument.Root.Elements() where n.Name == "message"select n;
// Iterate through the messages passing each to the ProcessMessage method on the MessageProcessor.// The MessageGroupLayer associated with this MessageProcessor will handle the creation of any // GraphicsLayers and Graphic objects necessary to display the message.foreach (XElement messageXml in messagesXml)
{
Message message = new Message(from n in messageXml.Elements() selectnew KeyValuePair<string, string>(n.Name.ToString(), n.Value));
_messageGroupLayer.MessageProcessor.ProcessMessage(message);
}
/*
*Alternatively you can programmatically construct the message and set the attributes.
* e.g.
*
* // Create a new message
* Message msg = new Message();
*
* //set the ID and other parts of the message
* msg.Id = messageID;
* msg.Add("_type", "position_report");
* msg.Add("_action", "update");
* msg.Add("_control_points", X.ToString() + "," + Y.ToString());
* msg.Add("_wkid", "3857");
* msg.Add("sic", symbolID);
* msg.Add("UniqueDesignation", "1");
*
* //Process the message using the MessageProcessor within the MessageGroupLayer
* _messageGroupLayer.MessageProcessor.ProcessMessage(msg);
*/
}
}
}
Imports System.Linq
Imports System.Windows.Controls
Imports System.Collections.Generic
Imports System.Windows
Imports ESRI.ArcGIS.Client.AdvancedSymbology
Imports System.Xml.Linq
Imports System.ComponentModel
Namespace ArcGISWPFSDK
PartialPublicClass MessageProcessing
Inherits UserControl
Implements INotifyPropertyChanged
PublicEvent PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private _isBusy AsBoolean = TruePublicProperty IsBusy() AsBooleanGetReturn _isBusy
EndGetSet(value AsBoolean)
_isBusy = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsBusy"))
EndSetEndPropertyPrivate messagesXmlFilePath AsString = "..\Data\Symbology\Mil2525CMessages.xml"PublicSubNew()
InitializeComponent()
' Disable the UI button until the MessageProcessor is initialized
ProcessMessagesButton.IsEnabled = FalseEndSubPrivateSub HandleMessageProcessorInitialized(sender AsObject, e As System.EventArgs)
' The MessageProcessor is initialized - enable the UI button
ProcessMessagesButton.IsEnabled = True
DataContext = Me
IsBusy = FalseEndSubPrivateSub ProcessMessagesButton_Click(sender AsObject, e As RoutedEventArgs)
' This function simulates real time message processing by processing a static set of messages from an XML document.'* |== Example Message ==|'* '* <message>'* <_type>position_report</_type>'* <_action>update</_action>'* <_id>16986029-8295-48d1-aa6a-478f400a53c0</_id>'* <_wkid>3857</_wkid>'* <sic>GFGPOLKGS-----X</sic>'* <_control_points>-226906.99878,6679149.88998;-228500.51759,6677576.8009;-232194.67644,6675625.78198</_control_points>'* <UniqueDesignation>DIRECTION OF ATTACK</UniqueDesignation>'* </message>' Load the XML documentDim xmlDocument As XDocument = XDocument.Load(messagesXmlFilePath, LoadOptions.None)
' Create a collection of messagesDim messagesXml As IEnumerable(Of XElement) = From n In xmlDocument.Root.Elements() Where n.Name = "message"' Iterate through the messages passing each to the ProcessMessage method on the MessageProcessor.' The MessageGroupLayer associated with this MessageProcessor will handle the creation of any ' GraphicsLayers and Graphic objects necessary to display the message.ForEach messageXml As XElement In messagesXml
Dim message AsNew Message(From n In messageXml.Elements() SelectNew KeyValuePair(Of String, String)(n.Name.ToString(), n.Value))
_messageGroupLayer.MessageProcessor.ProcessMessage(message)
Next'* Alternatively you can programmatically construct the message and set the attributes.'* e.g.'* '* // Create a new message'* Message msg = new Message(); '* '* //set the ID and other parts of the message'* msg.Id = messageID;'* msg.Add("_type", "position_report");'* msg.Add("_action", "update");'* msg.Add("_control_points", X.ToString() + "," + Y.ToString());'* msg.Add("_wkid", "3857");'* msg.Add("sic", symbolID);'* msg.Add("UniqueDesignation", "1");'* '* //Process the message using the MessageProcessor within the MessageGroupLayer'* _messageGroupLayer.MessageProcessor.ProcessMessage(msg); EndSubEndClassEndNamespace