| Richie 的个人资料The Sandpit - "We hack s...日志列表 | 帮助 |
|
4月15日 ArcGIS Server Explorer for SilverlightThe ArcGIS Server Explorer is a new contribution on the ESRI Code Gallery for dynamically generating a catalog of map services. The Silverlight control supports multiple servers. The contribution includes a sample web application that will preview map services selected in the treeview. Click here to view the live sample. The explorer control is based on the TreeView from the Silverlight 2 Toolkit. The snippet below demonstrates how to add a reference the ArcGIS Server Explorer control into a web application. The web application is listening to the page load event and the event that is raised when a user clicks on a map service. <UserControl x:Class="ServerExplorerSample.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:esri="clr-namespace:ESRI.ArcGIS;assembly=ESRI.ArcGIS" xmlns:se="clr-namespace:ESRI.ArcGIS.ServerExplorer;assembly=ESRI.ArcGIS.ServerExplorer" Loaded="UserControl_Loaded" > <Grid> <se:ServerTreeView x:Name="serverTreeView" LayerClicked="ServerTreeView_LayerClicked" /> </Grid> </UserControl> In this example, the page load event is used to add a reference to a public ArcGIS Server, namely, ArcGIS Online. You can only add a reference to local server if you are hosting the web application on your intranet. This is a Silverlight security limitation. private void UserControl_Loaded(object sender, RoutedEventArgs e) { Uri uri = new Uri("http://services.arcgisonline.com/arcgis/rest/services"); Server server = new Server(uri, "ArcGIS Online"); this.serverTreeView.Servers.Add(server); } And finally, the snippet below demonstrates how the web application is responding to the a clicked map service. The event handler contains a reference to a layer object that can be added directly to an Silverlight map control. private void ServerTreeView_LayerClicked(object sender, LayerEventArgs e) { // Add Selected Layer this.map.Layers.Clear(); e.Layer.Initialized += (evtsender, args) => { this.map.ZoomTo(e.Layer.InitialExtent); }; this.map.Layers.Add(e.Layer); } 4月9日 Geochat for SilverlightThe Prototype Lab at ESRI has just launched a geo-collaboration control for Silverlight. The control allows users to chat and exchange information such as graphics. Here is a live sample. Geochat is implemented in two parts.
The client/server implementation effectively allows the server to push information to the browser. This is also referred to as Comet. Source code to both of the client and server projects are provided in the download from the ESRI code gallery. Building the ServerCompiling and publishing the WCF service is straight forward. The only prerequisite is Microsoft .NET 3.5 SP1. If you are publishing the service on Microsoft Windows Vista then you may need to register the “svc” MIME type using the following command. C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation>ServiceModelReg.exe –i Building the ClientThe code gallery only includes the source code to the geochat user control rather than the entire web application. After adding a reference to the geochat assembly, the steps below will discuss how to configure it and send/receive messages. At the top of your code page add a using statement for the geochat namespace. using ESRI.ArcGIS.Chat;
In the your page (or user control) constructor use the ChatEnvironment singleton to set the name of the geochat service and begin listening to incoming messages. public Page() { InitializeComponent(); // Url to the geochat service ("service.svc" will be automatically appended) ChatEnvironment.Default.Server = "http://your.server.com/ChatService"; // Add event handler to listen for incoming messages ChatEnvironment.Default.NoteReceived += new EventHandler<NoteEventArgs>(this.ChatEnvironment_NoteReceived); } In the snippet below, geometry is converted to JSON and sent to all other Silverlight clients. if (ChatEnvironment.Default.IsConnected) { // Create data message and assign geometry DataMessage dataMessage = new DataMessage() { Text = this.GeometryToJson(new MapPoint(10,10)), Type = typeof(MapPoint).ToString() }; // Send data message to all silverlight clients ChatEnvironment.Default.SendMessage(dataMessage, null); } To send the message to an individual user rather than everyone, replace “null” with a user object. Use the following property to return a collection of all available users. ChatEnvironment.Default.Users
The snippet above referenced a method to convert ESRI’s Silverlight geometry into JSON. Since the message will be ultimately sent down the wire as a SOAP 1.1 message, the JSON string must be enclosed in a CDATA block. private string GeometryToJson(Geometry geometry) { MemoryStream memoryStream = new MemoryStream(); DataContractJsonSerializer serializer = new DataContractJsonSerializer(geometry.GetType()); serializer.WriteObject(memoryStream, geometry); memoryStream.Position = 0; StreamReader streamReader = new StreamReader(memoryStream); string json = streamReader.ReadToEnd(); memoryStream.Close(); return string.Format("CDATA[{0}]", json); } Now, let’s add code to receive incoming geometry messages. Firstly we only want to process DataMessages and ignore other messages types (eg connection, disconnection and text). The snippet below extracts the geometry from the message as well as the name of the sender. private void ChatEnvironment_NoteReceived(object sender, NoteEventArgs e) { if (e.Note.Payload.GetType() == typeof(DataMessage)) { // Get DataMessage DataMessage dataMessage = (DataMessage)e.Note.Payload; // Get Geometry Geometry geometry = this.JsonToGeometry(dataMessage.Text, dataMessage.Type); // Who sent this message? string from = e.Note.From.FriendlyName; } } Here is the code for the JsonToGeometry method referenced above. The code assumes that the incoming message is some sort of ESRI Silverlight geometry and that the JSON string is enclosed in a CDATA block. private Geometry JsonToGeometry(string json, string type) { Type t = null; if (type == typeof(MapPoint).ToString()) { t = typeof(MapPoint); } else if (type == typeof(Polyline).ToString()) { t = typeof(Polyline); } else if (type == typeof(Envelope).ToString()) { t = typeof(Envelope); } else if (type == typeof(Polygon).ToString()) { t = typeof(Polygon); } else { return null; } // JSON to Geometry string json2 = json.Substring(6, json.Length - 7); Byte[] bytes = Encoding.Unicode.GetBytes(json2); MemoryStream memoryStream = new MemoryStream(bytes); DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(t); Geometry geometry = dataContractJsonSerializer.ReadObject(memoryStream) as Geometry; memoryStream.Close(); return geometry; } That concludes the introduction to the geochat user control for Silverlight. Enjoy! 4月2日 Police Dispatcher Demo – ArcGIS API for Microsoft SilverlightThis is a quick sample thrown together that demonstrates some of the capabilities of the ArcGIS API for Microsoft Silverlight. Video in Map TooltipsOne intriguing feature is the ability to extend ESRI’s map tips with multimedia content. In the police sample, video hosted by the server is streamed into the map tip. The following XAML shows how this is achieved. <esri:Map> <esri:Map.Layers> <ve:TileLayer Opacity="0" LayerStyle="AerialWithLabels"/> <ve:TileLayer Opacity="1" LayerStyle="Road"/> <esri:GraphicsLayer> <esri:GraphicsLayer.MapTip> <StackPanel Orientation="Vertical" Background="Transparent"> <TextBlock Text="..."/> <Border Width="200" Height="150" BorderBrush="SkyBlue" BorderThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" > <Border.Background> <VideoBrush SourceName="video" Stretch="UniformToFill" /> </Border.Background> </Border> </StackPanel> </esri:GraphicsLayer.MapTip> </esri:GraphicsLayer> </esri:Map.Layers> </esri:Map> Where “video” is defined as: <MediaElement x:Name="video" AutoPlay="True" Source="police-video-large.wmv" IsMuted="True" Opacity="0" IsHitTestVisible="False" MediaEnded="Video_MediaEnded" /> Animated GraphicsThe Silverlight animation environment is very powerful. This power can be leveraged by the ArcGIS API for Silverlight. For example, the incident graphics are displayed as a red icons with a rotating swirl. There are three animations in action here:
This behavior can be achieved by subclassing the ESRI MarkerSymbol and overloading the common and mouseover view states. IncidentSymbol.cs using System.IO; using System.Windows.Controls; using System.Windows.Markup; using ESRI.ArcGIS.Symbols; namespace ESRI.PrototypeLab.PoliceDispatcher { public class IncidentSymbol : MarkerSymbol { public IncidentSymbol() : base() { string key = "<your namespace>.IncidentSymbol.xaml"; Stream stream = typeof(IncidentSymbol).Assembly.GetManifestResourceStream(key); string template = new StreamReader(stream).ReadToEnd(); this.ControlTemplate = XamlReader.Load(template) as ControlTemplate; } } } IncidentSymbol.xaml <ControlTemplate xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" > <Grid Cursor="Hand" RenderTransformOrigin="0.5,0.5" Height="50" Width="50" > <Grid.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scale" ScaleX="1" ScaleY="1" /> <TranslateTransform X="-25" Y="-25"/> </TransformGroup> </Grid.RenderTransform> <vsm:VisualStateManager.VisualStateGroups> <vsm:VisualStateGroup x:Name="CommonStates"> <vsm:VisualState x:Name="Normal"> <Storyboard> <DoubleAnimation Storyboard.TargetName="rotateTransform" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:3" RepeatBehavior="Forever" /> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name="MouseOver"> <Storyboard> <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="path" Storyboard.TargetProperty="Visibility" > <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/> </ObjectAnimationUsingKeyFrames> <DoubleAnimation BeginTime="0:0:0" Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" To="2" Duration="0:0:0.2" /> <DoubleAnimation BeginTime="0:0:0" Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" To="2" Duration="0:0:0.2" /> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> <vsm:VisualStateGroup x:Name="SelectionStates"> <vsm:VisualState x:Name="Selected" /> <vsm:VisualState x:Name="Unselected" /> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> <Image HorizontalAlignment="Center" VerticalAlignment="Center" Height="32" Width="32" Source="ESRI.PrototypeLab.PoliceDispatcher;component/Images/incident.png" /> <Path x:Name="path" Opacity="1" > <Path.Data> <PathGeometry> <PathGeometry.Figures> <PathFigureCollection> <PathFigure StartPoint="25,0" IsClosed="True"> <PathFigure.Segments> <PathSegmentCollection> <ArcSegment Point="50,25" Size="25,25" SweepDirection="Clockwise" IsLargeArc="False" RotationAngle="0" /> <LineSegment Point="45,25"/> <ArcSegment Point="25,5" Size="20,20" SweepDirection="Counterclockwise" IsLargeArc="False" RotationAngle="0" /> </PathSegmentCollection> </PathFigure.Segments> </PathFigure> </PathFigureCollection> </PathGeometry.Figures> </PathGeometry> </Path.Data> <Path.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop x:Name="color1" Color="#00FF0000" Offset="0"/> <GradientStop x:Name="color2" Color="#FFFF0000" Offset="1"/> </LinearGradientBrush> </Path.Fill> <Path.RenderTransform> <TransformGroup> <RotateTransform x:Name="rotateTransform" Angle="0" CenterX="25" CenterY="25" /> </TransformGroup> </Path.RenderTransform> </Path> </Grid> </ControlTemplate> 4月1日 Silverlight Serialization to JSONThis post will walkthrough the process of serializing and de-serializing an object to/from a JSON using Silverlight. Starting from a new Silverlight Application, add references to the System.Runtime.Serialization and System.ServiceModel.Web assemblies. At the top of the Page.xaml.cs code page, add the highlighted using statements. Still in the Page.xaml.cs code page, add a definition of a Person class that we will ultimately serialize to JSON. The class must be attributed with DataContract, a flag that denotes that the class (and all public members) are serializable. In the screenshot below, I have explicitly added DataMember attributes to shorten the property names in the JSON string.
Add a Button to the XAML and add an event handler for the click event, so that the code in Page.xaml.cs looks like the following.
Within the Button_Click method, let’s start by creating a new instance of the Person class.
Using DataContractJsonSerializer the person object can be converted to a JSON string.
Let’s add a message box to display the JSON string.
Now let’s convert the JSON string (denoted by the “json” variable) back into a Person object (denoted by “person2”).
Lastly, just to confirm that de-serialized object is correct, display the property values of “person2”.
The final step is to run this code and see if it works! Run the application in debug and click on the button you defined above to execute the serialization code. The first popup displays the serialized Person as a JSON string. The JSON is using the shorter member names defined using the DataMember attribute.
The second popup displays properties from the de-serialized person.
Presentation Extension for ArcGIS DesktopToday the ESRI Prototype Lab published a new sample entitled Presentation Extension for ArcGIS Desktop on the ArcGIS Desktop Code Gallery. This sample allows ArcMap users to give presentations directly from ArcMap without Microsoft PowerPoint. Below is a screenshot of the presentation manager, a simple-to-use window that allows the ArcMap user to create and manipulate “slides”. A slide can be consider similar to a traditional bookmark except that it also includes a title, notes, a thumbnail and most important, layer visibility. The second tab on the presentation manager defines the behavior of the presentation window. By default, the presentation window will occupy the entire extent of the primary display. When exiting a presentation you can optionally force ArcMap to display the last viewed slide and copy any ink added to the current map. To activate the presentation, click the green play button on the presentation toolbar or presentation manager window. The blue resume button will activate the presentation starting from the currently selected slide. The presentation window consists of a map, title, navigation controls and a small expander button in the lower right hand corner. Clicking the expander will display a set of somewhat familiar mapping tools. Use these buttons to interact with the map:
To exit the presentation click the “x” button or press the escape key. How was it implemented?Both the Presentation Manager and Presentation Window are built using the Windows Presentation Framework (or WPF). This is very exciting technology with virtually unlimited flexibility. The Presentation Window however is actually two WPF windows. The first is a simple window hosting the ESRI map control inside a WindowsFormsHost. A second window containing the title and buttons is overlaid on top. We used some messy Win32 calls to parent the map window to the overlay window. The dual window implementation is due to a draw order issue associated with hybrid GDI/WPF windows. Namely, it is not possible to overlay a WPF control on top of a GDI control (e.g. ESRI map control). Prerequisites
Known IssuesMicrosoft Virtual Earth layers cause the presentation window to take a long time to start. |
|
|