Why was the DynamicWorkspaceShapefile sample removed?

402
3
02-05-2024 10:29 PM
Labels (2)
MarkReyes11
New Contributor

I am looking into loading a local shape file (as well as file geodatabase) using a local server. Initially, I just used the ArcGISRuntime.ShapefileFeatureTable to display a shapefile and I was successful in doing that. However, file geodatabase is not supported and I need to use the local server.

I saw a post regardingthat makes use of ShapefileWorkspace but I wasn't able to make it work. I noticed that the DynamicWorkspaceShapefile  was removed in the latest code in the sample git repository. Is there a reason that it was removed?

0 Kudos
3 Replies
HamishDuff
Esri Contributor

Hi @MarkReyes11 thank you for your question. 

Could you give me a little more information on the problem you are seeing? 

What did you find prevented ShapefileWorkspace working?


0 Kudos
MarkReyes11
New Contributor

Hi @HamishDuff , thank you for answering. Basically, I'm unable to display the shapefile when I use Local Server and ShapeFileWorkspace though I was able to display it using ShapefileFeatureTable . Here's an screenshot of my test app after selecting the subdivision.shp file. I actually copied the code from the DynamicWOrkspaceShapeFile sample. I'm also wondering why this sample was removed from the main branch of the git repo.

MarkReyes11_0-1707226470057.png

Here is my code.

// Copyright 2017 Esri.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
// language governing permissions and limitations under the License.


using Esri.ArcGISRuntime.LocalServices;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Symbology;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Drawing;
using Esri.ArcGISRuntime.Data;

namespace ArcGisLocal
{
    public partial class DynamicWorkspaceShapefile
    {
        // Hold a reference to the local map service
        private LocalMapService _localMapService;

        // Hold a reference to the layer that will display the shapefile data
        private ArcGISMapImageSublayer _shapefileSublayer;

        public DynamicWorkspaceShapefile()
        {
            InitializeComponent();
            
            Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "MY_API_KEY";

            // Create the UI, setup the control references and execute initialization
            Initialize();
        }

        private async void Initialize()
        {
            // Create a map and add it to the view
            MyMapView.Map = new Map(BasemapStyle.ArcGISStreets);

            try
            {
                // LocalServer must not be running when setting the data path.
                if (LocalServer.Instance.Status == LocalServerStatus.Started)
                {
                    await LocalServer.Instance.StopAsync();
                }

                // Set the local data path - must be done before starting. On most systems, this will be C:\EsriSamples\AppData.
                // This path should be kept short to avoid Windows path length limitations.
                string tempDataPathRoot = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.Windows)).FullName;
                string tempDataPath = Path.Combine(tempDataPathRoot, "EsriSamples", "AppData");
                Directory.CreateDirectory(tempDataPath); // CreateDirectory won't overwrite if it already exists.
                LocalServer.Instance.AppDataPath = tempDataPath;

                // Start the local server instance
                await LocalServer.Instance.StartAsync();

                // Load the sample data
                LoadShapefilePaths();

                // Enable the 'choose shapefile' button
                MyChooseButton.IsEnabled = true;
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show(String.Format("Please ensure that local server is installed prior to using the sample. See instructions in readme.md. Message: {0}", ex.Message), "Local Server failed to start");
            }
        }

        private async void StartLocalMapService(string filename, string path)
        {

            #region Using ShapefileFeatureTable
            // Open the shapefile
            //ShapefileFeatureTable myShapefile = await ShapefileFeatureTable.OpenAsync(Path.Combine(path, filename));

            //// Create a feature layer to display the shapefile
            //FeatureLayer newFeatureLayer = new FeatureLayer(myShapefile);
            //await newFeatureLayer.LoadAsync();

            //MyMapView.Map.OperationalLayers.Clear();

            //// Zoom the map to the extent of the shapefile
            //MyMapView.SetViewpoint(new Viewpoint(newFeatureLayer.FullExtent));

            //// Add the layer to the map
            //MyMapView.Map.OperationalLayers.Add(newFeatureLayer);

            #endregion

            #region Using Local Server
            // Start a service from the blank MPK
            string mapServiceUrl = GetMpkPath();

            // Create the local map service
            _localMapService = new LocalMapService(mapServiceUrl);

            // Create the shapefile workspace
             ShapefileWorkspace shapefileWorkspace = new ShapefileWorkspace("shp_wkspc", path);
            // Create the layer source that represents the shapefile on disk
            TableSublayerSource source = new TableSublayerSource(shapefileWorkspace.Id, filename);

            // Create a sublayer instance from the table source
            _shapefileSublayer = new ArcGISMapImageSublayer(0, source);

            // Add the dynamic workspace to the map service
            _localMapService.SetDynamicWorkspaces(new List<DynamicWorkspace>() { shapefileWorkspace });

            // Subscribe to notifications about service status changes
            _localMapService.StatusChanged += _localMapService_StatusChanged;

            try
            {
                // Start the map service
                await _localMapService.StartAsync();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(), "Error");
            }
            #endregion
        }

        private async void _localMapService_StatusChanged(object sender, StatusChangedEventArgs e)
        {
            // Add the shapefile layer to the map once the service finishes starting
            if (e.Status == LocalServerStatus.Started)
            {
                // Create the imagery layer
                ArcGISMapImageLayer imageryLayer = new ArcGISMapImageLayer(_localMapService.Url);

                // Subscribe to image layer load status change events
                // Only set up the sublayer renderer for the shapefile after the parent layer has finished loading
                imageryLayer.LoadStatusChanged += (q, ex) =>
                {
                    // Add the layer to the map once loaded
                    if (ex.Status == Esri.ArcGISRuntime.LoadStatus.Loaded)
                    {
                        // Create a default symbol style
                        SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Red, 3);

                        // Apply the symbol style with a renderer
                        _shapefileSublayer.Renderer = new SimpleRenderer(lineSymbol);

                        // Add the shapefile sublayer to the imagery layer
                        imageryLayer.Sublayers.Add(_shapefileSublayer);
                    }
                };

                try
                {
                    // Load the layer
                    await imageryLayer.LoadAsync();

                    // Clear any existing layers
                    MyMapView.Map.OperationalLayers.Clear();

                    // Add the image layer to the map
                    MyMapView.Map.OperationalLayers.Add(imageryLayer);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Error");
                }
            }
        }

        private static string GetMpkPath()
        {
            // Gets the path to the blank map package
            return @"D:\Repos\playground\wpfapp1\ArcGisLocal\mpks\blankMap.mpkx";
        }

        private static string LoadShapefilePaths()
        {
            // Gets the path to the shapefile package
            return @"D:\Repos\playground\wpfapp1\ArcGisLocal\shapefiles";
        }

        private void MyChooseButton_Click(object sender, RoutedEventArgs e)
        {
            // Allow the user to specify a file path - create the dialog
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog()
            {
                DefaultExt = ".shp",
                Filter = "Shapefiles|*.shp",
                InitialDirectory = Path.GetDirectoryName(LoadShapefilePaths())
            };

            // Show the dialog and get the results
            bool? result = dlg.ShowDialog();

            // Take action if the user selected a file
            if (result == true)
            {
                string filename = Path.GetFileName(dlg.FileName);
                string path = Path.GetDirectoryName(dlg.FileName);
                StartLocalMapService(filename, path);
            }
        }
    }
}

 

0 Kudos
MichaelBranscomb
Esri Frequent Contributor

Hi,

Displaying Shapefiles should work fine using Local Server and the API type Class ShapefileWorkspace (arcgis.com) although the reason the sample for that type was removed is because it's no longer the promoted workflow. Instead, best practice is to use the API directly via the Class ShapefileFeatureTable (arcgis.com) type as shown by sample Symbolize shapefile | ArcGIS Maps SDK for .NET | ArcGIS Developers

 

Thanks

0 Kudos