Imports System.Windows
Imports ESRI.ArcGIS.Client
Imports ESRI.ArcGIS.Client.Local
Imports System.IO
Imports System
Imports Microsoft.Win32
Imports ESRI.ArcGIS.Client.Symbols
Imports System.Windows.Media
Imports ESRI.ArcGIS.Client.Toolkit
Imports System.Collections.Generic
Imports System.Windows.Controls
Imports System.Linq
Namespace ArcGISWPFSDK
Public Class DynamicLayersFeatureDataGrid
Inherits UserControl
' Get the path of the "empty" MPK from the application folder
Private _emptyMpkPath As String = "..\Data\DynamicLayers\EmptyMPK_WGS84.mpk"
''' <summary>
''' Initializes a new instance of the <see cref="MainWindow"/> class.
''' </summary>
Public Sub New()
InitializeComponent()
' Bring the graphics forwards if they are selected or reset to 0 if unselected.
AddHandler MyDataGrid.SelectionChanged,
Function(s3, e3)
For Each graphic As Graphic In e3.RemovedItems
graphic.SetZIndex(0)
Next
For Each graphic As Graphic In e3.AddedItems
graphic.SetZIndex(1)
Next
End Function
End Sub
''' <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 Sub AddShapefileButton_Click(sender As Object, e As RoutedEventArgs)
' Setup the OpenFiledialog.
Dim openFileDialog As 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 Then
Try
' Remove any existing FeatureLayers in the Map
Dim featureLayers As List(Of FeatureLayer) = MyMap.Layers.OfType(Of FeatureLayer)().ToList()
For Each fl As FeatureLayer In featureLayers
MyMap.Layers.Remove(fl)
Next
' 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 ex As Exception
MessageBox.Show("Error: Could not read file from disk. Original error: " & ex.Message)
End Try
End If
End Sub
''' <summary>
''' Adds a file dataset (Shapefile) to a new local dynamic map service layer.
''' </summary>
''' <param name="workspaceType">The workspace type (Shapefile only in this example).<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 Sub AddFileDatasetToDynamicMapServiceLayer(workspaceType As WorkspaceFactoryType, directoryPath As String, fileName As String)
Try
' Generate a unique workspace ID (any unique string).
Dim uniqueId As String = Guid.NewGuid().ToString()
' Create a new WorkspaceInfo object with a unique ID.
Dim workspaceInfo As New WorkspaceInfo(uniqueId, workspaceType, "DATABASE=" & directoryPath)
' Create a new LocalMapService instance, set the path property, and enable the dynamic layers capability.
Dim localMapService As New LocalMapService() With { _
.Path = _emptyMpkPath, _
.EnableDynamicLayers = True, _
.MaxRecords = 1000000}
' Register the workspace to be used with this service.
localMapService.DynamicWorkspaces.Add(workspaceInfo)
' Asynchronously start the local map service.
localMapService.StartAsync( _
Sub(x)
' Create a new FeatureLayer instance passing in the local service.
' Construct the URL to include the /dynamicLayer resource, Assign ID, request all fields and set a selection color
Dim featureLayer As New FeatureLayer() With { _
.Url = localMapService.UrlMapService + "/dynamicLayer", _
.ID = fileName, _
.OutFields = New ESRI.ArcGIS.Client.Tasks.OutFields() From {"*"}, _
.SelectionColor = New SolidColorBrush(Colors.Yellow)}
' The workspace is a feature class so create a new TableDataSource
' Match the DataSourceName to the physical filename on disk (excluding extension).
' Provide the WorkspaceID (the unique workspace identifier created earlier).
Dim dataSource As DataSource = New TableDataSource() With { _
.DataSourceName = fileName, _
.WorkspaceID = workspaceInfo.Id}
' Set the Source property of the DynamicLayerInfo object.
Dim layerDataSource As New LayerDataSource() With { _
.DataSource = dataSource}
' Assign the LayerDataSource
featureLayer.Source = layerDataSource
AddHandler featureLayer.Initialized,
Sub(s, e)
' Check the InitializationFailure property.
If featureLayer.InitializationFailure IsNot Nothing Then
MessageBox.Show("Error: " + featureLayer.InitializationFailure.Message)
Exit Sub
End If
' Set the FeatureDataGrid's Map property
MyDataGrid.Map = MyMap
' Set the new FeatureLayer as the FeatureDataGrid's GraphicsLayer property
MyDataGrid.GraphicsLayer = TryCast(featureLayer, GraphicsLayer)
' Assign default rendering based on the geometry type (i.e. SimpleMarkerSymbol, SimpleLineSymbol or SimpleFillSymbol.
Dim renderer As SimpleRenderer = Nothing
Select Case featureLayer.LayerInfo.GeometryType
Case ESRI.ArcGIS.Client.Tasks.GeometryType.MultiPoint
renderer = New SimpleRenderer() With { _
.Symbol = New SimpleMarkerSymbol() With { _
.Color = New SolidColorBrush(GetRandomColor()), _
.Size = 8}}
Exit Select
Case ESRI.ArcGIS.Client.Tasks.GeometryType.Point
renderer = New SimpleRenderer() With { _
.Symbol = New SimpleMarkerSymbol() With { _
.Color = New SolidColorBrush(GetRandomColor()), _
.Size = 8}}
Exit Select
Case ESRI.ArcGIS.Client.Tasks.GeometryType.Polygon
renderer = New SimpleRenderer() With { _
.Symbol = New SimpleFillSymbol() With { _
.Fill = New SolidColorBrush(GetRandomColor()), _
.BorderBrush = New SolidColorBrush(GetRandomColor())}}
Exit Select
Case ESRI.ArcGIS.Client.Tasks.GeometryType.Polyline
renderer = New SimpleRenderer() With { _
.Symbol = New SimpleLineSymbol() With { _
.Color = New SolidColorBrush(GetRandomColor())}}
Exit Select
Case Else
Exit Select
End Select
' Apply the new renderer to the FeatureLayer (Renderer will take precedence be default unless you set RendererTakesPrecendence=False)
featureLayer.Renderer = renderer
End Sub
' Handle the InitializationFailed event, just in case...
AddHandler featureLayer.InitializationFailed,
Sub(s, e)
' Check the InitializationFailure property and display message if available
If featureLayer.InitializationFailure IsNot Nothing Then
MessageBox.Show("Error: " + featureLayer.InitializationFailure.Message)
End If
' Exit
Return
End Sub
' Add the FeatureLayer to the Map. This will trigger the FeatureLayer initialization. Initialization completion will be handled in the event handler above.
MyMap.Layers.Add(featureLayer)
End Sub)
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.[Error])
End Try
End Sub
' Utility function: Generate a random System.Windows.Media.Color
Private _random As New Random()
Private Function GetRandomColor() As Color
Dim colorBytes = New Byte(2) {}
_random.NextBytes(colorBytes)
Dim randomColor As Color = Color.FromRgb(colorBytes(0), colorBytes(1), colorBytes(2))
Return randomColor
End Function
Private Sub Legend_Refreshed(sender As Object, e As Legend.RefreshedEventArgs)
' Clear the sub items from the basemap layer.
If e.LayerItem.Layer Is _worldTopographicBasemap Then
e.LayerItem.LayerItems.Clear()
End If
End Sub
End Class
End Namespace