Hi,
I had a revelation that actually I'd probably confused the issue by keeping the ArcGISDynamicMapServiceLayer in my example whilst introducing a FeatureLayer as well. So I've simplified it to just use a FeatureLayer (below). So it now assumes that you actually want to add the FeatureLayer to the map and display that instead of the ArcGISDynamicMapServiceLayer. I'd recommend you definitely use the accelerated display mode if the feature layer may contain many thousands of graphics, or graphics with complex polygons.
Code:/// <summary> /// Interaction logic for DynamicLayersFeatureDataGrid.xaml /// </summary> public partial class DynamicLayersFeatureDataGrid : UserControl { // Get the path of the "empty" MPK from the application folder string _emptyMpkPath = @"..\Data\DynamicLayers\EmptyMPK_WGS84.mpk"; public DynamicLayersFeatureDataGrid() { InitializeComponent(); MyDataGrid.SelectionChanged += (s3, e3) => { foreach (Graphic graphic in e3.RemovedItems) { graphic.SetZIndex(0); } foreach (Graphic graphic in e3.AddedItems) { graphic.SetZIndex(1); } }; } /// <summary> /// Handles the Click event of the AddShapefileButton control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> private void AddShapefileButton_Click(object sender, RoutedEventArgs e) { // Setup the OpenFiledialog. OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Shapefiles (*.shp)|*.shp"; openFileDialog.RestoreDirectory = true; openFileDialog.Multiselect = false; // This sample assumes a single file is selected if (openFileDialog.ShowDialog() == true) { try { // Remove any existing FeatureLayers in the Map List<FeatureLayer> featureLayers = MyMap.Layers.OfType<FeatureLayer>().ToList(); foreach (var fl in featureLayers) { MyMap.Layers.Remove(fl); } // Call the add dataset method with workspace type, parent directory path, file names (without extensions) and delegate. AddFileDatasetToDynamicMapServiceLayer(WorkspaceFactoryType.Shapefile, Path.GetDirectoryName(openFileDialog.FileName), Path.GetFileNameWithoutExtension(openFileDialog.SafeFileName)); } catch (Exception ex) { MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); } } } /// <summary> /// Adds a file dataset (Shapefile) to a new feature layer. /// </summary> /// <param name="workspaceType">The workspace type (FileGDB, Raster, SDE, Shapefile) <see cref="http://resources.arcgis.com/en/help/runtime-wpf/apiref/index.html?ESRI.ArcGIS.Client.Local~ESRI.ArcGIS.Client.Local.WorkspaceFactoryType.html"/>.</param> /// <param name="directoryPath">A <see cref="System.String"/> representing the directory path.</param> /// <param name="fileNames">A <see cref="System.Collections.Generic.List{System.String}"/> representing the name of the file.</param> public void AddFileDatasetToDynamicMapServiceLayer(WorkspaceFactoryType workspaceType, string directoryPath, string fileName) { try { // Generate a unique workspace ID (any unique string). string uniqueId = Guid.NewGuid().ToString(); // Create a new WorkspaceInfo object with a unique ID. WorkspaceInfo workspaceInfo = new WorkspaceInfo(uniqueId, workspaceType, "DATABASE=" + directoryPath); // Create a new LocalMapService instance. LocalMapService localMapService = new LocalMapService { Path = _emptyMpkPath, // Set the path property. EnableDynamicLayers = true, // Enable the dynamic layers capability. MaxRecords = 1000000, // Set the maximum number of records }; // Register the workspace to be used with this service. localMapService.DynamicWorkspaces.Add(workspaceInfo); // Asynchronously start the local map service. localMapService.StartAsync(x => { // Create a new ArcGISLocalDynamicMapServiceLayer passing in the newly started local service. FeatureLayer featureLayer = new FeatureLayer() { Url = localMapService.UrlMapService + "/dynamicLayer", // Construct the URL to include the /dynamicLayer resource. ID = fileName, // Assign ID OutFields = new ESRI.ArcGIS.Client.Tasks.OutFields() { "*" }, // Display all fields SelectionColor = new SolidColorBrush(Colors.Yellow), // Yellow is generally a nice selection color }; // The workspace is a feature class so create a new TableDataSource DataSource dataSource = new TableDataSource { DataSourceName = fileName, // Match the DataSourceName to the physical filename on disk (excluding extension). WorkspaceID = workspaceInfo.Id // Provide the WorkspaceID (the unique workspace identifier created earlier). }; // Set the Source property of the DynamicLayerInfo object. LayerDataSource layerDataSource = new LayerDataSource { DataSource = dataSource }; // Assign the LayerDataSource featureLayer.Source = layerDataSource; featureLayer.Initialized += (s, e) => { // Set the FeatureDataGrid's Map property MyDataGrid.Map = MyMap; // Set the new FeatureLayer as the FeatureDataGrid's GraphicsLayer property MyDataGrid.GraphicsLayer = featureLayer as GraphicsLayer; SimpleRenderer renderer = null; switch (featureLayer.LayerInfo.GeometryType) { case ESRI.ArcGIS.Client.Tasks.GeometryType.MultiPoint: renderer = new SimpleRenderer() { Symbol = new SimpleMarkerSymbol() { Color = new SolidColorBrush(GetRandomColor()), Size = 8 } }; break; case ESRI.ArcGIS.Client.Tasks.GeometryType.Point: renderer = new SimpleRenderer() { Symbol = new SimpleMarkerSymbol() { Color = new SolidColorBrush(GetRandomColor()), Size = 8 } }; break; case ESRI.ArcGIS.Client.Tasks.GeometryType.Polygon: renderer = new SimpleRenderer() { Symbol = new SimpleFillSymbol() { Fill = new SolidColorBrush(GetRandomColor()), BorderBrush = new SolidColorBrush(GetRandomColor()) } }; break; case ESRI.ArcGIS.Client.Tasks.GeometryType.Polyline: renderer = new SimpleRenderer() { Symbol = new SimpleLineSymbol() { Color = new SolidColorBrush(GetRandomColor()) } }; break; default: break; } featureLayer.Renderer = renderer; }; MyMap.Layers.Add(featureLayer); }); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } // Utility function: Generate a random System.Windows.Media.Color Random _random = new Random(); private Color GetRandomColor() { var colorBytes = new byte[3]; _random.NextBytes(colorBytes); Color randomColor = Color.FromRgb(colorBytes[0], colorBytes[1], colorBytes[2]); return randomColor; } private void Legend_Refreshed(object sender, Legend.RefreshedEventArgs e) { // Clear the sub items from the basemap layer. if (e.LayerItem.Layer == _worldTopographicBasemap) e.LayerItem.LayerItems.Clear(); } }
Sorry - I haven't had time to look at the code in your previous yet... it's the end of the week here...
Cheers
Mike
The only thing I haven't been able to do with shapefiles is use the Editor toolkit control to select features on it. If anyone has any suggestions, please let me know.
ESRI.ArcGIS.Client.Editor myEditor = LayoutRoot.Resources["MyEditor"] as ESRI.ArcGIS.Client.Editor; myEditor.Map = MyMap;
Editor editor = LayoutRoot.Resources["MyEditor"] as Editor; editor.LayerIDs = new List<String>() { featureLayer.ID };
What do you mean by 'symbols'?
private void AddFeatureLayerFromShapeFile(UserMapLayer userMapLayer, ArcGISLocalDynamicMapServiceLayer dynamicLayer) { var featureLayer = new FeatureLayer(); featureLayer.ID = Guid.NewGuid().ToString(); featureLayer.DisplayName = dynamicLayer.DisplayName; featureLayer.OutFields.Add("*"); featureLayer.Mode = FeatureLayer.QueryMode.OnDemand; featureLayer.OnDemandCacheSize = 500; featureLayer.MaximumResolution = 15; featureLayer.Url = dynamicLayer.Service.UrlMapService + "/dynamicLayer"; featureLayer.Source = dynamicLayer.DynamicLayerInfos[0].Source; //featureLayer.SelectionColor = System.Windows.Media.Brushes.Yellow; //featureLayer.Renderer = dynamicLayer.LayerDrawingOptions[0].Renderer; featureLayer.Initialized += (s1, e1) => { featureLayer.SelectionColor = System.Windows.Media.Brushes.Yellow; featureLayer.Renderer = dynamicLayer.LayerDrawingOptions[0].Renderer; if (featureLayer.DisplayName == "parcels") // TEMP { context.Selection.OnParcelLayerLoaded(); } }; AddLayer(featureLayer, true, userMapLayer); }
Renderer = GetRandomSimpleRenderer()
public static SimpleRenderer GetRandomSimpleRenderer() { return new SimpleRenderer() { Symbol = GetRandomSimpleFillSymbol() }; } public static SimpleFillSymbol GetRandomSimpleFillSymbol() { return new SimpleFillSymbol() { Fill = GetRandomSolidBrush() }; } public static SolidColorBrush GetRandomSolidBrush() { return new SolidColorBrush(GetRandomColor()); } public static Color GetRandomColor() { var colorBytes = new byte[3]; random.NextBytes(colorBytes); return Color.FromRgb(colorBytes[0], colorBytes[1], colorBytes[2]); }
public static SimpleFillSymbol GetRandomSimpleFillSymbol()
{
return new SimpleFillSymbol() { Fill = GetRandomSolidBrush() };
}