problems with self-Projecting graphics layers and KML content. HELP!

Jump to solution
04-20-2012 12:43 PM
New Contributor III
Hello GIS gurus!

Fresh from the latest Dev Summit I saw some functionality that made me very excited: self projecting graphics layers.  I'm working on getting KML content onto maps and I'm having a great deal of trouble getting the graphics layer to project without errors.  The user will have access to different basemaps (with different coordinate systems) and I need the KML features to display correctly.  To test this functionality out, I downloaded the 2.4 SDK and created a simple silverlight map project.  Here is the xaml:

<UserControl x:Class="KMLFeedReader.MainPage"     xmlns=""      xmlns:x=""      xmlns:d=""      xmlns:esri=""     xmlns:mc=""   mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"   xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"     xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"     xmlns:toolkit="clr-namespace:System.Windows;assembly=System.Windows.Controls"     xmlns:userControls="clr-namespace:ESRI.ArcGIS.SilverlightMapApp"     xmlns:actions="clr-namespace:ESRI.ArcGIS.SilverlightMapApp.Actions"     xmlns:local="clr-namespace:KMLFeedReader;assembly=KMLFeedReader"     xmlns:esriLayers="clr-namespace:ESRI.ArcGIS.Client.Toolkit.DataSources;assembly=ESRI.ArcGIS.Client.Toolkit.DataSources"     xmlns:esriTasks="clr-namespace:ESRI.ArcGIS.Client.Tasks;assembly=ESRI.ArcGIS.Client">     <Grid x:Name="LayoutRoot" Background="Azure">         <Grid.Resources>             <local:BooleanVisibilityConverter x:Key="BoolToVisible" />             <esriTasks:GeometryService Url="http://MYGISServer/ArcGIS/rest/services/Geometry/GeometryServer" ProxyURL="http://localhost:52327/ProxyHandler.ashx" x:Key="ProjectionSvc" />         </Grid.Resources>         <Grid.RowDefinitions>             <RowDefinition Height="30" />             <RowDefinition Height="*" />         </Grid.RowDefinitions>         <Grid Grid.Row="0" x:Name="TopMenuGrid" Background="DarkGray">             <Rectangle x:Name="BackgroundGradient" Opacity=".5" Fill="DarkGray" />             <StackPanel HorizontalAlignment="Left" VerticalAlignment="Center" Orientation="Horizontal">                 <!-- Base layers -->                 <Button Content="Streets (Mercator)" ToolTipService.ToolTip="Worldwide Street Map" Tag="" Click="Button_Click" />                 <Button Content="Aerial (WGS-84)" ToolTipService.ToolTip="Worldwide Satellite Imagery Map" Tag="" Click="Button_Click" />                 <Button Content="Shaded Relief (Mercator)" ToolTipService.ToolTip="Worldwide Shaded Relief Map" Tag="" Click="Button_Click" />                 <Button Content="Topographic (Mercator)" ToolTipService.ToolTip="United States Topographic Map" Tag="" Click="Button_Click" />                 <Button Content="Physical World (Mercator)" ToolTipService.ToolTip="Natural Earth Physical Map" Tag="" Click="Button_Click" />             </StackPanel>         </Grid>         <esri:Map x:Name="MyMap" Grid.Row="1">             <esri:LayerCollection>                 <esri:ArcGISTiledMapServiceLayer ID="BaseLayer" Url="" Initialized="ArcGISTiledMapServiceLayer_Initialized" />                 <esriLayers:KmlLayer ID="kmlLyr" ProxyUrl="http://localhost:52327/ProxyHandler.ashx" ProjectionService="{StaticResource ProjectionSvc}" />             </esri:LayerCollection>         </esri:Map>         <Border x:Name="brdTrv" Width="300" BorderBrush="Black" BorderThickness="2" CornerRadius="5" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Row="1">             <controls:TreeView x:Name="trvContainers">                 <controls:TreeView.ItemTemplate>                     <toolkit:HierarchicalDataTemplate ItemsSource="{Binding Children}">                         <StackPanel Orientation="Horizontal">                             <CheckBox Width="20" IsChecked="{Binding IsVisible, Mode=TwoWay}" Checked="chkContainer_Checked" />                             <StackPanel Orientation="Vertical">                                 <TextBlock Height="22" Text="{Binding Path=Name}" VerticalAlignment="Center" TextWrapping="Wrap"/>                                 <TextBlock Text="{Binding Path=Description}" VerticalAlignment="Center" TextWrapping="Wrap" Foreground="Gray" />                             </StackPanel>                                                     </StackPanel>                     </toolkit:HierarchicalDataTemplate>                 </controls:TreeView.ItemTemplate>             </controls:TreeView>         </Border>     </Grid> </UserControl>

...and the codebehind

using System; using System.Windows; using System.Windows.Controls; using ESRI.ArcGIS.Client; using KMLFeedReader.DataModel; using ESRI.ArcGIS.Client.Tasks;  namespace KMLFeedReader {     public partial class MainPage : UserControl     {         public MainPage()         {             InitializeComponent();             //defining KML source URL in the back end because xaml doesn't like urls with query strings             (MyMap.Layers["kmlLyr"] as ESRI.ArcGIS.Client.Toolkit.DataSources.KmlLayer).Url = new Uri("", UriKind.Absolute);                      }          private void ArcGISTiledMapServiceLayer_Initialized(object sender, EventArgs e)         {                  }          private void Button_Click(object sender, RoutedEventArgs e)         {             string newBasemapURL = (sender as Button).Tag.ToString();              if (!string.IsNullOrEmpty(newBasemapURL) && (MyMap.Layers[0] as ArcGISTiledMapServiceLayer).Url != newBasemapURL)             {                 ESRI.ArcGIS.Client.Toolkit.DataSources.KmlLayer kml = (ESRI.ArcGIS.Client.Toolkit.DataSources.KmlLayer)MyMap.Layers["kmlLyr"];                  ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer() { Url = newBasemapURL, ID = "BaseLayer" };                 tiledLayer.Initialized += (s, args) =>                  {                     MyMap.Layers.Clear();                     MyMap.Extent = tiledLayer.FullExtent;                                         MyMap.Layers.Add(tiledLayer);                     MyMap.Layers.Add(kml);                                     };                 tiledLayer.Initialize();             }         }     } }

when I click on one of the buttons to change the basemap i get the following error:
Message: Unhandled Error in Silverlight Application
Code: 4004   
Category: ManagedRuntimeError      
Message: System.ArgumentException: Invalid geometry.
   at ESRI.ArcGIS.Client.Tasks.Utils.JSON.ArcGISJsonReader.GeometryServiceJsonToGraphics(String json, Nullable`1 geomType, SpatialReference sr, Int32[]& CutIndexes)
   at ESRI.ArcGIS.Client.Tasks.Utils.JSON.ArcGISJsonReader.GeometryServiceJsonToGraphics(String json, Nullable`1 geomType, SpatialReference sr)
   at ESRI.ArcGIS.Client.Tasks.GeometryService.project_Completed(Object sender, RequestEventArgs e)
   at ESRI.ArcGIS.Client.Tasks.TaskBase.request_Completed(Object sender, RequestEventArgs e)
   at ESRI.ArcGIS.Client.WebRequest.OnComplete(RequestEventArgs args)
   at ESRI.ArcGIS.Client.WebRequest.downloadStringCompleted(Object sender, DownloadStringCompletedEventArgs e)
   at System.Net.WebClient.OnDownloadStringCompleted(DownloadStringCompletedEventArgs e)
   at System.Net.WebClient.DownloadStringOperationCompleted(Object arg)    

Line: 56
Char: 13
Code: 0
URI: http://localhost:52327/KMLFeedReaderTestPage.aspx

I got a similar error using my home-grown KML parser, except the message was "Geometry type is not supported".  Is there something I'm missing?  The KML file has nothing but points and polygons in it.  I confirmed that my geometry service is working.  I'd like to upgrade my app from v2.0 to v2.4 but this has become a major stumbling block.  Any help anyone can provide is greatly appreciated.

0 Kudos
1 Solution

Accepted Solutions
Esri Regular Contributor
Yes, you are correct. Mixed geometry types are not supported. You can quickly check this by running Fiddler. When it makes a request to GeometryService, you can check "geometries" property if its mixed or if separate requests are made per type.

View solution in original post

0 Kudos
3 Replies
Esri Regular Contributor
Here's some blurb about Auto-Reprojection:

Auto-reprojection of graphics layers

GraphicsLayer and any layer that derives from it, such as GeoRssLayer and KmlLayer, can be reprojected on the fly. If the spatial reference of the Map is geographic World Geodetic System 1984 ([WGS84] WKID: 4326) or Web Mercator (WKID: 102100), reprojection will occur automatically on the client. If a graphics layer or map is in another spatial reference, you can use the ProjectionService property to reference a class that implements IProjectionService, such as the GeometryService task.

Graphic feature geometry in the underlying data remains untouched; only the display of graphics is affected.

Here's one sample: Notice that GeoRssLayer in this sample sets its ProjectionService property. ProjectionService="{StaticResource GeomSvc}". You probably need this on your KmlLayer.
0 Kudos
New Contributor III
Thanks Jennifer!

The code I posted in this thread references a geometry service task object which implements IProjectionService (i think) and I'm still experiencing difficulty.  The geometry service I'm using resides on an ArcGIS 10.0 server.  Will a 10.1 geometry service handle this better?

I vaguely remember at the dev summit that the projection service can only handle one geometry type at a time.  This might contribute to why I'm having problems because the KML layer features both point and polygon features.  Any ideas?

Also the link to that sample seems to not be working (  All I see is a splash screen.
0 Kudos
Esri Regular Contributor
Yes, you are correct. Mixed geometry types are not supported. You can quickly check this by running Fiddler. When it makes a request to GeometryService, you can check "geometries" property if its mixed or if separate requests are made per type.
0 Kudos