Exception when using Shapefile.Table.Query()

Sep 9, 2013 at 7:56 PM
Hi,

I am using MapWinGis OCX 4.8.8 in a VS2010 C# project to evaluate the control for use in our c#app. Up until now I have been really impressed and I am hoping this is an easy one:

The app has a textbox where the end user can input some text. This 'text' is then used in a query against one of the shapefiles loaded into the control.

Today, the code began throwing an exception on my development machine and I do not know why. I have attempted:
-reinstalling the 'MapWinGIS-only-v4.8.8SR-32bit-installer.exe'
-restarting the machine.
-uninstalling the newly installed TortoiseSVN after attempting and failing to compile the OCX source.


Any ideas how I can get back to the state where this app succeeds in its call to .Table.Query()?

TIA

Here is the code:
        string error = "";
        object result = null;

        // the text values must be placed in quotes; we need to shield them with \ sign in C#
        // fields are must be placed in square brackets
        string query = "[PID] = \"" + textBoxParcelID.Text + "\"";
        fParcels.SelectNone();
        try
        {
            if (fParcels.Table.Query(query, ref result, ref error))
            {
                int[] shapes = result as int[];
                if (shapes != null)
                {

                    for (int i = 0; i < shapes.Length; i++)
                    {
                        fParcels.set_ShapeSelected(shapes[i], true);

                        MapWinGIS.Shape shp = fParcels.get_Shape(shapes[i]);
                        string text = fParcels.get_CellValue(8, shapes[i]).ToString();
                        MapWinGIS.Point pnt = shp.Centroid;
                        fParcels.Labels.AddLabel(text, pnt.x, pnt.y, 0.0, -1);
                    }
                    axMap1.ZoomToSelected(layerHandleParcels);
                    MapWinGIS.Extents extentCurrent = (MapWinGIS.Extents)axMap1.Extents;
                    axMap1.ZoomOut(0.5);

                }

                //MessageBox.Show("Objects selected: " + fParcels.NumSelected);
            }
            else
            {
                //MessageBox.Show("No shapes agree with the condition.");
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Exception:" + ex.Message);
        }
The Exception is: "System.Runtime.InteropServices.SEHException" "External component has thrown an exception"
Sep 9, 2013 at 8:18 PM
Edited Sep 9, 2013 at 9:06 PM
More info:

Last week I made an installer for this test app for internal testing.

I just ran this installer on my development machine and I am able to successfully run a Table.Query using the aforementioned textbox.

But if I try to run the app from within VS2010, I get the aforementioned Exception.

And I am getting an System.OutOfMemoryException as well!

Any Ideas?
Coordinator
Sep 10, 2013 at 11:40 AM
Did you set your configuration setting in VS2010 to x86?
Sep 10, 2013 at 12:19 PM
Hi,

Yes the VS2010 Configuration setting is for x86. The App builds and runs. The problem is when I call the Shapefile.Table.Query() method to retrieve a record from the tabular data (which I subsequently zoom to on the map).

This morning I re-installed the MapWinGIS 4.8.8.1 components and tried again - same problem.

So I built a new VS2010 app and placed a MapWinGIS Map Control on the form. Copied the necessary code from the old project to the new project and it works fine!

So now I am thinking of just moving everything to the new project and forgetting about the old project, but I certainly would like to know how the old project got into the state that it is in where a call to Query the shapefile table throws a 'System.Runtime.InteropServices.SEHException' and chews through memory, thereby leading to an OutOfMemoryException.

Charlie
Sep 10, 2013 at 12:55 PM
More Information on this issue:

so now I have 2 projects using the same MapWinGIS components.

I have been transferring code blocks between the 2, from the old project to the new project, and re-testing each time to see which code blocks might be causing this exception to be thrown. As I test, I am monitoring (Via Task Manager) the amount of memory being used.

The 9 shapefiles that I am using comprise about 2GB (including .mwd and .mwx index files) on disk.

When I include the largest of the shapefiles (850000 features) the map loads OK. I can Pan and Zoom with performance looking ok. But when the call to Table.Query() method runs (on a different layer), the memeory working set ramps up to about 1.8 GB and then the SEHException is thrown, followed by an OutOfMemoryException.

So, I am wondering if there is a better strategy for loading all of these shapefiles and being able to query one of them using the Shapefile.Table.Query() method.


TIA
Coordinator
Sep 11, 2013 at 7:39 AM
It might you are needing more memory than your hardware can deliver.
You can try to use the quad-tree index: http://www.mapwindow.org/documentation/mapwingis4.8/group__shapefile__spatial__index.html#ga95bd6801ec7a37b9b860e91c109916ca

And you can also try to set the FastMode property to True: http://www.mapwindow.org/documentation/mapwingis4.8/group__shapefile__optimizations.html#ga2d6959aee84a49fc901f3ab05e100180

If you are going to do a lot of querying and you keep having these problems you might consider importing your dbf-file into a SQLite database and use that database to query.
Sep 11, 2013 at 12:13 PM
Thanks for the idea.

My development machine has 8GB of memory. Most of the client machines that this app is to be installed on will have about half of that.

After I found that the size of the shape data was contributing to this issue, I modified some of the .dbf files to remove extraneous columns. This has helped limit the amount of memory that gets consumed by the call to .Table.Query(). It still surprises me that the entire .dbf file seems to be loaded in order to query it. This places a limit on us that I was not expecting.

I looked at the QuadTree index. The documentation states that this index is used for editing. I'll try it out to see if it helps.

I am currently using the FastMode property. I have assumed that it is helping with the drawing of the shapes, though I believe that the scale-dependent rendering logic helps a lot with that as well.

I had considered using SQLite with the dbf file. I did some testing with Spatialite (SQLite extended with spatial) and was encouraged, though I did find that the feature ID returned from a Spatialite tabular query was not the same featureID returned by the Shapefile.Table.Query() method. They differed by 1. The Spatialite tabular query was much faster, BTW.

Again, Thanks for the good ideas.