2012 Developer Summit must watch videos

by Shawn 25. April 2012 01:56

If you haven’t heard, the videos for the 2012 ArcGIS Developer Summit are now finally available. The day one plenary was available the very next day so I have no idea why it took a month to get the session videos out. The videos I’m going to recommend are from the perspective of someone who has worked with ArcGIS Server for more than 4 years. My team built the very first custom Server Object Extension (SOE). I helped redesign the Telvent Silverlight SDK, and and I see a strong need for more mobile apps. These videos are ordered.

Sesions I attended

Building Web Editing Applications with ArcGIS 10.1 for Server-by Gary MacDougall and Ismael Chivite
Hands down the best session in terms of content. I was floored to see all of the new editing functionality within ArcGIS Server. I had been working with ArcGIS Server 10.1 the first week that Beta 1 went out, but I had never been able to test or investigate the new editing.

ArcGIS Server for Administrators-by Ismael Chivite and Jay Theodore
I must say that the best part of this session was that Ismael created his power point presentations during the presentation. He would design each slide to show how ArcGIS Server works at each tier.

Supporting High-Quality Printing in Web Applications with ArcGIS 10.1 for Server-by Craig Williams and Tanu Hoque
Just about every shop out there has built their own server side printing so I like everyone am very happy to see this functionality. Esri did a great job with this. I was amazed with what they are supporting with their serer side printing. Printing supports client side graphics. It supports the new dynamic layer rendering. It does it all.

What’s new in ArcGIS API for Silverlight-by Rex Hansen and Morten Nielsen
I’m a Silverlight guy so I had to throw this in. Auto projection of graphics, IdentityManager, Dynamic Layer Rendering… The list goes on.

Killer Apps: HTML5 and Flex-by Sajit Thomasand Mansour Raad
I did not learn anything from this session other than the fact that Sajit and Mansour give a good presentation. Well worth the watch.

Sessions I did not attend

Building Applications with ArcGIS Runtime SDK for WPF – Part 1-by Euan Cameron and Mike Branscomb
Building Applications with ArcGIS Runtime SDK for WPK – Part 2-by Euan Cameron and Mike Branscomb
While I did not attend these sessions, I would recommend them. I had been working with the ArcGIS Runtime for about five months prior to the DevSummit and I see this as the the next best way to build mobile apps. If you are familiar with Esri’s .Net SDKs (Silverlight/WPF/Windows Phone) you already know how to use the Runtime SDK. There are some new things to learn if you are working in a disconnected environment so give these videos a watch.

Creating Geoprocessing Services-by Kevin Hibma and Scott Murray
If you have not heard yet, Geoprocessing Tools are the new black. This is the way to build new functionality. Connect up a few GP tools that already exist and BANG, you now have a new tool. Publish this as a GP Service and you have that same functionality in your web apps. All of the client SDKs are built to understand any GP tool that you throw at it.

ArcGIS for Server Performance and Scalability – Testing Methodologies-by Andrew Sakowicz and Frank Pizzi
Always best to make sure your server can stand up properly!

Tags: ,

ArcGIS

Using extension methods to iterate ArcGIS COM collections

by Shawn 9. March 2012 18:30

I’m a big fan of .Net and all the glory that it offers. So when I’m developing against ArcGIS COM objects I cry a little inside. Working with COM objects in .Net is not fun. C# 4.0 made this a little better by improving the code generated by interop.

Example code to get an indexed property within .Net from a COM object with VS2008

int fieldIndex = 2;
IRow row = cursor.NextRow();
object value = row.get_Value(fieldIndex);

Example code to get an indexed property within .Net from a COM object with VS2010

int fieldIndex = 2;
IRow row = cursor.NextRow();
object value = row.Value[fieldIndex];

Notice the difference? It’s in the last line where we get the value for the field. Not only do you not need the get_XXX prefix, but you use square brackets. It’s actually an indexed property now! Small things like this make working with ArcObjects a little better, but there is still a lot more that can be done. One area that always just plain sucks is iterating over COM collections. Here is a simple example of iterating over an ICursor

ICursor cursor = table.Search(null, true);
IRow row = cursor.NextRow();
while(row != null)
{
    // Do some stuff
    row = cursor.NextRow();
}

This is one of the easier COM collections to work with. This one at least does not have a Reset() method. Without a doubt, you are bound to forget that setter at the end of the while loop and your be looking at the same row for a very long time. This is very error prone.

Luckily we can add new functionality to any object by using extension methods. I hope you’re familiar with extension methods. I’m always surprised when I find active developers that have never heard of them. By creating an extension method, I can change the code above to:

ICursor cursor = table.Search(null, true);
foreach(var row in cursor.ToEnumerable())
{
    // do some stuff
}

Ahhh… So much better! No need to worry about setting the row object again at the end of the while loop. I can work with this a lot easier than before, and it just looks a ton better!

Let’s take a look at what it would take to write this extension method.

public static class Extensions
{
    public static IEnumerable<IRow> ToEnumerable(this ICursor source)
    {
        if (source != null)
        {
            IRow row = source.NextRow();
            while (row != null)
            {
                yield return row;
                row = source.NextRow();
            }
        }
    }
}

I have this code written once and I can now forget all about it! From now on it’s .Net goodness baby!

But wait! There’s more! I went ahead an created a NuGet package that contains many of these extension methods!

PM> Install-Package ArcGISExtensions

This package contains 15 ToEnumerable methods to help out with iterating over the ArcGIS COM collections. I picked the ones that are used the most. I plan to add some more Enumerable extensions as well as others to help out with your ArcGIS development.

Enjoy!

Tags:

ArcGIS

Managing Extents within the ArcGIS WPF/Silverlight/etc. APIs

by Shawn 23. November 2011 17:25

Managing extents within the ArcGIS .Net client API’s is pretty simple. Esri has an example on the resources page. I implemented one for the ArcFM Silverlight SDK sample. Oddly enough, they are quite similar. I don’t remember copying theirs, but you never know. Like most things we as developers do, after a couple of years you look back and wonder “What was I thinking?” I look back at my original code and wonder why did I implement the Extents class the way that I did. I originally used one List to hold all of the Extents. This made some of the code pretty ugly. I’ve created a different implementation that utilizes two stacks. I have one class that manages all of the extents:

   1: public class Extents
   2: {
   3:     private readonly Stack<Envelope> _backStack = new Stack<Envelope>();
   4:     private readonly Stack<Envelope> _forwardStack = new Stack<Envelope>();
   5:  
   6:     public bool HasPreviousExtent
   7:     {
   8:         get { return _backStack.Count > 0; }
   9:     }
  10:  
  11:     public bool HasNextExtent
  12:     {
  13:         get { return _forwardStack.Count > 0; }
  14:     }
  15:  
  16:     public Envelope CurrentExtent { get; set; }
  17:  
  18:     public Envelope PreviousExtent
  19:     {
  20:         get
  21:         {
  22:             if (HasPreviousExtent)
  23:             {
  24:                 _forwardStack.Push(CurrentExtent);
  25:                 CurrentExtent = _backStack.Pop();
  26:                 return CurrentExtent;
  27:             }
  28:             return null;
  29:         }
  30:     }
  31:  
  32:     public Envelope NextExtent
  33:     {
  34:         get
  35:         {
  36:             if (HasNextExtent)
  37:             {
  38:                 _backStack.Push(CurrentExtent);
  39:                 CurrentExtent = _forwardStack.Pop();
  40:                 return CurrentExtent;
  41:             }
  42:             return null;
  43:         }
  44:     }
  45:  
  46:     public void Add(Envelope extent)
  47:     {
  48:         if (extent == null) return;
  49:  
  50:         if (CurrentExtent != null)
  51:         {
  52:             _backStack.Push(CurrentExtent);
  53:         }
  54:         CurrentExtent = extent;
  55:  
  56:         // If a new extent is added, then anything in our forward stack needs to be removed
  57:         _forwardStack.Clear();
  58:     }
  59: }

I’m a big fan of MVVM, so I’ll use a ViewModel to access the Extents. I’ll also be using the DelegateCommand from Microsoft.

   1: public class ViewModel
   2: {
   3:     public ViewModel()
   4:     {
   5:         Extents = new Extents();
   6:         PreviousExtent = new DelegateCommand(MovePreviousExtent, extent => Extents.HasPreviousExtent);
   7:         NextExtent = new DelegateCommand(MoveNextExtent, extent => Extents.HasNextExtent);
   8:         IsNewExtent = true;
   9:     }
  10:  
  11:     private Map _map;
  12:  
  13:     public Map Map
  14:     {
  15:         get { return _map; }
  16:         set
  17:         {
  18:             UnsubscribeMapEvents(_map);
  19:             SubscribeMapEvents(value);
  20:             _map = value; 
  21:         }
  22:     }
  23:  
  24:     public DelegateCommand PreviousExtent { get; private set; }
  25:     public DelegateCommand NextExtent { get; private set; }
  26:  
  27:     private bool IsNewExtent { get; set; }
  28:     private Extents Extents { get; set; }
  29:  
  30:     private void MovePreviousExtent(object obj)
  31:     {
  32:         // This extent should not be put onto the Extents stack.
  33:         IsNewExtent = false;
  34:         Map.ZoomTo(Extents.PreviousExtent);
  35:     }
  36:     
  37:     private void MoveNextExtent(object obj)
  38:     {
  39:         // This extent should not be put onto the Extents stack.
  40:         IsNewExtent = false;
  41:         Map.ZoomTo(Extents.NextExtent);
  42:     }
  43:  
  44:     private void UnsubscribeMapEvents(Map map)
  45:     {
  46:         if (map == null) return;
  47:         map.ExtentChanged -= Map_ExtentChanged;
  48:     }
  49:  
  50:     private void SubscribeMapEvents(Map map)
  51:     {
  52:         if (map == null) return;
  53:         map.ExtentChanged += Map_ExtentChanged;
  54:     }
  55:  
  56:     private void Map_ExtentChanged(object sender, ExtentEventArgs e)
  57:     {
  58:         // Only add the extent if it is "new" ie: Not a Previous or Next extent
  59:         if (IsNewExtent)
  60:         {
  61:             Extents.Add(e.NewExtent);
  62:         }
  63:         IsNewExtent = true;
  64:         PreviousExtent.RaiseCanExecuteChanged();
  65:         NextExtent.RaiseCanExecuteChanged();
  66:     }
  67: }

The joy of these classes is that they can be used within all of the .Net Client API’s! This can even be used within the new ArcGIS Runtime (currently in Beta). Using these within our application is now a breeze! Here is the xaml for a WPF Window

   1: <Window x:Class="ExtentNavigationApp.MainWindow"
   2:         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:         xmlns:esri="http://schemas.esri.com/arcgis/client/2009"
   5:         Title="MainWindow" Height="350" Width="525">
   6:     <Grid x:Name="LayoutRoot" Background="White">
   7:         <esri:Map x:Name="Map" >
   8:             <esri:ArcGISTiledMapServiceLayer Url="http://server.arcfmsolution.com/ArcGIS/rest/services/Landbase/MapServer"/>
   9:             <esri:ArcGISTiledMapServiceLayer Url="http://server.arcfmsolution.com/ArcGIS/rest/services/Electric/MapServer"/>
  10:         </esri:Map>
  11:         <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
  12:             <Button Content="Previous Extent" Command="{Binding PreviousExtent}" Height="25" Width="100"/>
  13:             <Button Content="Next Extent" Command="{Binding NextExtent}" Height="25" Width="100"/>
  14:         </StackPanel>
  15:     </Grid>
  16: </Window>

And the code behind:

   1: public partial class MainWindow : Window
   2: {
   3:     public MainWindow()
   4:     {
   5:         InitializeComponent();
   6:         DataContext = new ViewModel() { Map = Map };
   7:     }
   8: }

Tags: , , , ,

ArcGIS WPF/Silverlight/Phone SDK

Using the Silverlight 5 PivotViewer with ArcGIS Silverlight

by Shawn 3. November 2011 15:16

Pivot was originally released as a demonstration project that was a separate download from Silverlight itself. At version 5, Pivot becomes part of the Silverlight family. Pivot allows users the ability to visualize their data. Puts the power of filtering and grouping their data without the need to learn complex SQL statements. The original version of Pivot required you to have an XML representation of the data, and images that it would display. This required extra work for the developer, or web administrator to create this data from their data store. With Silverlight 5, you now have the ability to bind to any property that your class has. It also allows you the ability to create what’s known as trading cards with XAML. These cards replace the images you previously needed. You can even define at what stage you want a trading card to display. By defining different trading cards at different levels, you can give the user more information the more they filter down their data.

When I first started looking into whether I’d be able to get PivotViewer results from ArcGIS Server, I figured I would have to create a Silverlight class with properties for all of the fields that I wanted to use within Pivot. It turns out that Pivot works great with the data you get straight from the ArcGIS or ArcFM Silverlight SDK. It easily binds to the Attributes Dictionary that is on the Graphics objects.

To get started using Pivot, you need to download the latest Silverlight 5 Tools. Create a new Silverlight Application. Make sure to pick Silverlight 5 as the version

image

You’ll need to add a reference to ESRI.ArcGIS.Client and System.Windows.Controls.Pivot. To add the ArcGIS Silverlight SDK, open the Add Reference dialog, and click the Browse tab. Browse to the location of ESRI.ArcGIS.Client assembly. The default location is C:\Program Files (x86)\ESRI SDKs\Silverlight.

Open MainPage.xaml.cs. We’re going to need to create a query to the ArcGIS Server. For my example, I’m going to use the Telvent ArcGIS Server at http://server.arcfmsolution.com/arcgis/rest/services. First, we need to query for the electrical switches that we’ll use within Pivot

public MainPage()
{
    InitializeComponent();

    QueryForSwitches();
}

private void QueryForSwitches()
{
    // Query for switches. Switches have LayerID of 3 
QueryTask task = new QueryTask("http://server.arcfmsolution.com/ArcGIS/rest/services/Electric/MapServer/3"); Query query = new Query(); // Return all of the fields, we want use them all, but good to have 'em anyways! query.OutFields.Add("*"); // Get as many of the switches as we can
query.Where = "ObjectID > 0"; task.ExecuteCompleted += QueryTask_ExecuteCompleted; task.ExecuteAsync(query); }

Add a call to this method within the constructor of the MainPage. When the task completes, all we need to do is set the DataContext to the Features that are returned.

void QueryTask_ExecuteCompleted(object sender, QueryEventArgs e)
{
    DataContext = e.FeatureSet.Features;
}

The XAML is where all of the magic happens. We are able to pick which fields the user will be able to filter/sort by, and define the trading cards. I want to give the user the ability to sort and filter switches by Installation Date, the Phase Designation, which Feeder it belongs to, and the Operating Voltage. So the fields I need from the Attributes dictionary are INSTALLATIONDATE, PHASEDESIGNATION, FEEDERID, and OPERATINGVOLTAGE. To do this, you add PivotViewerProperties.

<UserControl x:Class="PivotViewer.MainPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
             xmlns:ViewModels="clr-namespace:PivotViewer.ValueConverters">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.Resources>
            <ViewModels:PhaseDesignationValueConverter x:Key="PhaseConverter"/>
            <ViewModels:VoltageToStringValueConverter x:Key="VoltageConverter"/>            
        </Grid.Resources>
        <sdk:PivotViewer x:Name="MyPivot" ItemsSource="{Binding}">
            <!-- Setting PivotProperties -->
            <sdk:PivotViewer.PivotProperties>
                <sdk:PivotViewerDateTimeProperty Id="InstallDate" Options="CanFilter" DisplayName="Date Installed" 
Binding="{Binding Attributes[INSTALLATIONDATE], StringFormat=\{0:MM/dd/yyyy\}}" /> <sdk:PivotViewerStringProperty Id="Phase" Options="CanFilter" DisplayName="Phase"
Binding="{Binding Attributes[PHASEDESIGNATION], Converter={StaticResource PhaseConverter}}" /> <sdk:PivotViewerStringProperty Id="Feeder" Options="CanFilter" DisplayName="Feeder"
Binding="{Binding Attributes[FEEDERID]}" /> <sdk:PivotViewerStringProperty Id="OpVoltage" Options="CanFilter" DisplayName="Operating Voltage"
Binding="{Binding Attributes[OPERATINGVOLTAGE], Converter={StaticResource VoltageConverter}}" /> </sdk:PivotViewer.PivotProperties> </sdk:PivotViewer> </Grid> </UserControl>

I’m using fields that have domain values, so I need a few value converters, I won’t bore you with the conversion of the domains here. If you need to sort/filter by date values, like the Installation Date, use a PivotViewerDateTimeProperty This gives you cool date filtering capabilities. I don’t have any integer values that I’m sorting by, but if I did I would use the PivotViewerNumericProperty. To create a trading card, add a PivotViewerItemTemplate to the ItemTemplates collection.

<sdk:PivotViewer.ItemTemplates>
    <sdk:PivotViewerItemTemplate>
        <Border Width="200" Height="200" Background="Gray" BorderBrush="Black" BorderThickness="1">
            <StackPanel Orientation="Vertical">
                <TextBlock Text="{Binding Attributes[FACILITYID]}" FontSize="24" Foreground="White" />
                <StackPanel Margin="10,0">
                    <TextBlock Text="Feeder" Foreground="White" FontSize="18" Margin="0,10,0,0"/>
                    <TextBlock Text="{Binding Attributes[FEEDERID]}" FontSize="14" Foreground="White" />

                    <TextBlock Text="Voltage" Foreground="White" FontSize="18" Margin="0,10,0,0"/>
                    <TextBlock Text="{Binding Attributes[OPERATINGVOLTAGE], 
Converter={StaticResource VoltageConverter}}"
FontSize="14" Foreground="White" /> <TextBlock Text="Installed" Foreground="White" FontSize="18" Margin="0,10,0,0"/> <TextBlock Text="{Binding Attributes[INSTALLATIONDATE], StringFormat=\{0:MM/dd/yyyy\}}"
FontSize="14" Foreground="White" /> </StackPanel> </StackPanel> </Border> </sdk:PivotViewerItemTemplate> </sdk:PivotViewer.ItemTemplates>

This gives our trading card a Metro feel. But there isn’t much data here, as the user drills further into their data, I want to show them more. We can add more trading cards if we want to add more detail when users start filtering their data, or using the zoom capability of Pivot. To do this you set the MaxWidth property of the PivotViewerItemTemplate, and add another template.

<sdk:PivotViewerItemTemplate MaxWidth="250">

To see more, download the complete sample here. Give your users the power to SEE their data.

Tags: , ,

ArcGIS Silverlight SDK | Silverlight

About the author

Shawn KendrotShawn Kendrot is a Technical Lead at Telvent, specializing in GIS (ArcGIS) Desktop and Silverlight.

Month List

Page List

DISCLAIMER

The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.