This project is read-only.

Delete Features problem

Feb 1, 2011 at 10:05 PM

Hey Guys,

I am trying to deleting features from a featureset using  "featureset.Features.Remove(featureToDelete);" and am getting a ArgumentOutOfRangeException.  Any idea what I might be doing wrong?

I have included the code and stack trace below:

 

Stack Trace:

   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at DotSpatial.Data.FeatureList.get_Item(Int32 index) in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\FeatureList.cs:line 771
   at DotSpatial.Data.Shapefile.SetupFeatureLookup() in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\Shapefile.cs:line 464
   at DotSpatial.Data.Shapefile.AttributeTableAttributesFilled(Object sender, EventArgs e) in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\Shapefile.cs:line 238
   at DotSpatial.Data.AttributeTable.OnAttributesFilled() in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\AttributeTable.cs:line 1106
   at DotSpatial.Data.AttributeTable.Fill(Int32 numRows) in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\AttributeTable.cs:line 268
   at DotSpatial.Data.AttributeTable.get_Table() in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\AttributeTable.cs:line 1083
   at DotSpatial.Data.Shapefile.get_DataTable() in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\Shapefile.cs:line 207
   at DotSpatial.Data.FeatureList.ExcludeFeature(IFeature item) in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\FeatureList.cs:line 115
   at DotSpatial.Data.FeatureList.Remove(IFeature item) in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Data\DotSpatial.Data\FeatureList.cs:line 531
   at Dustran.AddSite..ctor(String siteName, Int32 utmZone, Envelope siteEnvelope) in C:\Documents and Settings\d3y518\My Documents\Visual Studio 2010\Projects\Dustran\Dustran\AddSite.cs:line 99
   at Dustran.AddSite.CreateSite(Coordinate center) in C:\Documents and Settings\d3y518\My Documents\Visual Studio 2010\Projects\Dustran\Dustran\AddSite.cs:line 223
   at Dustran.frmMain.mainMap_MouseDown(Object sender, MouseEventArgs e) in C:\Documents and Settings\d3y518\My Documents\Visual Studio 2010\Projects\Dustran\Dustran\frmMain.cs:line 100
   at System.Windows.Forms.Control.OnMouseDown(MouseEventArgs e)
   at System.Windows.Forms.UserControl.OnMouseDown(MouseEventArgs e)
   at DotSpatial.Controls.Map.OnMouseDown(MouseEventArgs e) in C:\Documents and Settings\d3y518\My Documents\dotspatial_1-26-11\DotSpatial.Controls\DotSpatial.Controls\Map.cs:line 1437
   at System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.UserControl.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Dustran.Program.Main() in C:\Documents and Settings\d3y518\My Documents\Visual Studio 2010\Projects\Dustran\Dustran\Program.cs:line 18
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

 

Code Use:

public AddSite(string siteName, int utmZone, DotSpatial.Topology.Envelope siteEnvelope)
        {
            DotSpatial.Data.Extent clipExt;
            DotSpatial.Topology.Polygon clipPoly;
            DotSpatial.Data.FeatureSet fs;
            List<int> selectedFeatureIndices;
            List<DotSpatial.Data.IFeature> featureDeleteList = new List<DotSpatial.Data.IFeature>();
            List<string> layerPaths = new List<string>();
            DotSpatial.Topology.Coordinate minX_minY;
            DotSpatial.Topology.Coordinate minX_maxY;
            DotSpatial.Topology.Coordinate maxX_maxY;
            DotSpatial.Topology.Coordinate maxX_minY;
            List<DotSpatial.Topology.Coordinate> clipCoordinates;
            DotSpatial.Data.Feature clipFeature;
            m_siteName = siteName;
            m_utmZone = utmZone;
            m_siteEnvelope = siteEnvelope.Copy();
            m_siteExt = siteEnvelope.Copy();
            m_siteExt.Width = m_siteExt.Width * 2;
            m_siteExt.Height = m_siteExt.Height * 2;

            clipExt = new DotSpatial.Data.Extent(m_siteExt);
            double[] d_minX_minY = {clipExt.MinX, clipExt.MinY, 0};
            double[] d_minX_maxY = {clipExt.MinX, clipExt.MaxX, 0};
            double[] d_maxX_maxY = {clipExt.MaxX, clipExt.MaxY, 0};
            double[] d_maxX_minY = {clipExt.MaxX, clipExt.MinY, 0};
            minX_minY = new DotSpatial.Topology.Coordinate(d_minX_minY);
            minX_maxY = new DotSpatial.Topology.Coordinate(d_minX_maxY);
            maxX_maxY = new DotSpatial.Topology.Coordinate(d_maxX_maxY);
            maxX_minY = new DotSpatial.Topology.Coordinate(d_maxX_minY);
            clipCoordinates = new List<DotSpatial.Topology.Coordinate>()
            {
                minX_minY,
                minX_maxY,
                maxX_maxY,
                maxX_minY
            };
            clipPoly = new DotSpatial.Topology.Polygon(clipCoordinates);
            clipFeature = new DotSpatial.Data.Feature(clipPoly);

            System.IO.Directory.CreateDirectory(ProfileManager.ProfilePath + siteName);
            foreach (var layer in frmMain.self.Map.MapFrame.Layers)
            {
                if (layer.LegendText != "UTMzones")
                {
                    fs = (DotSpatial.Data.FeatureSet)layer.DataSet;
                    if (fs != null)
                    {
                        string path = ProfileManager.ProfilePath + siteName + "\\" + System.IO.Path.GetFileName(fs.Filename);
                        fs.SaveAs(path, true);
                        layerPaths.Add(path);
                        selectedFeatureIndices =  fs.SelectIndices(clipExt);

                        featureDeleteList.Clear();
                        for (int i = 0; i < fs.Features.Count; i++)
                        {
                            if (!selectedFeatureIndices.Contains(i))
                            {
                                featureDeleteList.Add(fs.Features[i]);
                            }
                        }


                        foreach (DotSpatial.Data.IFeature featureToDelete in featureDeleteList)
                        {
                            fs.Features.Remove(featureToDelete);
                        }

                        fs.Save();
                    }
                }
                else
                {
                    frmMain.self.Map.MapFrame.Layers.Remove(layer);
                }
            }
            frmMain.self.Map.MapFrame.Invalidate();
            frmMain.self.Map.Invalidate();
        }

Feb 2, 2011 at 12:02 AM
Edited Feb 2, 2011 at 12:05 AM

One more problem,

tried using featureset.RemoveShapesAt(...) and I am getting the same error.

I will also get an exception unless my list of int's have been sorted from largest to smallest:

 /// <summary>
        /// Attempts to remove a range of shapes by index.  This is optimized to
        /// work better for large numbers.  For one or two, using RemoveShapeAt might
        /// be faster.
        /// </summary>
        /// <param name="indices">
        /// The enumerable set of indices to remove.
        /// </param>
        public void RemoveShapesAt(IEnumerable<int> indices)
        {
            if (IndexMode == false)
            {
                foreach (int index in indices)
                {
                    if (index < 0 || index >= _shapeIndices.Count) continue;
                    Features.RemoveAt(index);
                }

...

 

-Sam

Jan 9, 2012 at 4:03 PM

I am getting this error on iterating over the FeatureList...

foreach(var feature in fs.Features)

...

 

- Barry

Jan 9, 2012 at 5:06 PM

When an item is deleted by index, the indexes of all later items change.

Deleting using a list of indexes will not work correctly unless the list is sorted from highest to lowest index.

Keep in mind that it is also not allowed to add or remove items from a collection while inside a foreach on that collection.