Open ShapeFile in SharpMap 2

Topics: SharpMap Project, SharpMap v2.0, WinForms Controls
Sep 8, 2007 at 12:53 PM
Hi,

I've downloaded latest source code of SharpMap v2 and I tried to create desktop windows application which can open shape file: I have this code:

SharpMap.Data.Providers.ShapeFile.ShapeFile sh = new SharpMap.Data.Providers.ShapeFile.ShapeFile(@"c:\pasport_mk.shp");
SharpMap.Layers.VectorLayer v = new SharpMap.Layers.VectorLayer("test", sh);

But the second line throws NullPointerException in class FreatureDataView, method createRowPredicateFilter. Do I have something wrong or the code is not ready yet?

Thanks, SharpMap is great project, I like it very much :-)

Smoke


Coordinator
Sep 9, 2007 at 3:23 AM
Ah, so.... you've found it, too. This escaped me until a coworker had the same problem.

The reason is due to how FeatureDataView is implemented to allow spatial filtering. It turns out that DataView is extremely resistant to subclass appropriately. Everything which makes a DataView filter the DataTable's DataRow collection is internal to System.Data. It is hard for me to understand why Microsoft made it so difficult to add functionality to the DataView (and even the DataTable).

At any rate, it turns out that I had to gain access to internals via reflection in order to do spatial filtering. One of the internal classes in DataView allows a System.Predicate<T> to be used to filter rows with. This class is System.Data.DataView+RowPredicateFilter. The catch, and the problem, is that this class only exists in the CLR version 2.0.50727.1378. The version that you have is probably 2.0.50727.832 (or even earlier). Revision 1378 is the version which ships with .Net 3.5 Beta 2. (More about the versions of v2.0 can be found here: http://blogs.msdn.com/dougste/archive/2007/07/31/summary-of-fixes-available-for-asp-net-2-0.aspx.)

This is all probably more info you wanted... but, if you haven't already figured it out, you currently need to have .Net v3.5 Beta 2 to run current revisions of SharpMap 2 (Download here). I'm not sure if this is ultimately a good dependency or not, since it would allow LINQ queries (which is a future plan), but it would force an upgrade, which would slow adoption. I've tried 2 alternative ways of spatially filtering the DataView rows, but they don't work on revision 832 of the runtime (short of rewriting the JIT compiler and replacing core .Net dlls). The only 2 reasonable alternatives appear to be using the CLR revision which ships with .Net 3.5 (unless MS releases it as a hotfix) or implement IBindingListView from scratch as FeatureDataView, which would require a large effort and would significantly delay v2.0.

Any thoughts on this issue would be greatly appreciated.
Sep 9, 2007 at 7:59 AM
Thanks for your replay.

I've upgraded .Net to version which you have recomended. Now I'm receiving "NotImplementedException" (class ShapeFile, function SetTableSchema). Probably, class ShapeFile is not finished yet.

Smoke
Coordinator
Sep 9, 2007 at 10:41 AM
I just implemented it now. It's in revision 171.
Sep 10, 2007 at 6:55 AM
Great, thanks!

Now I can open shape file (VectorLayer) and add it to Map object. However, when ZoomToExtents is called, I receive InvalidOperationException (class VectorLayer, function OnVisibleRegionChanging).
I don't want to disturb you, probably I should wait to Beta 1 release.

Thanks,

Smoke
Coordinator
Sep 10, 2007 at 7:56 AM
Try setting the AsyncQuery property to false. I still haven't really implemented it. I should really make it false by default until I do.
Sep 18, 2007 at 6:42 AM
I have this code:

SharpMap.Data.Providers.ShapeFile.ShapeFileProvider sh = new SharpMap.Data.Providers.ShapeFile.ShapeFileProvider(@"c:\pasport_mk.shp ");

SharpMap.Layers.GeometryLayer v = new SharpMap.Layers.GeometryLayer("test", sh);
SharpMap.Map map = new SharpMap.Map();

sh.Open();
map.AddLayer(v);
mpMain.Map = map;

mpMain.ZoomToExtents();

But ZoomToExtents() throws exception ArgumentException("Parameter 'table' must be of type FeatureDataTable<uint>.") - class ShapeFileProvider, function ExecuteIntersectionQuery. What I am doing wrong?

Thanks,

Smoke
Coordinator
Sep 19, 2007 at 2:55 AM
Hey Smoke -

That's an odd one. Could you get the latest code and try it again? I fixed a number of problems with rendering and presentation within the past few checkins. If you get it again, could you post the stack trace?
Sep 19, 2007 at 6:05 AM
Revision 197, stack trace:

Exception: "Parameter 'table' must be of type FeatureDataTable<uint>."
at SharpMap.Data.Providers.ShapeFile.ShapeFileProvider.ExecuteIntersectionQuery(BoundingBox bounds, FeatureDataTable table) in c:\SharpMap\src-google\src\SharpMap\Data\Providers\Shapefile\ShapeFileProvider.cs:line 924
at SharpMap.Layers.FeatureLayer.LoadLayerDataForRegion(BoundingBox region) in c:\SharpMap\src-google\src\SharpMap\Layers\FeatureLayer.cs:line 141
at SharpMap.Layers.Layer.set_VisibleRegion(BoundingBox value) in c:\SharpMap\src-google\src\SharpMap\Layers\Layer.cs:line 408
at SharpMap.Map.set_VisibleRegion(BoundingBox value) in c:\SharpMap\src-google\src\SharpMap\Map.cs:line 1157
at SharpMap.Presentation.MapPresenter2D.setViewMetricsInternal(Size2D newViewSize, Point newCenter, Double newWorldWidth) in c:\SharpMap\src-google\src\SharpMap\Presentation\Presenters\MapPresenter2D.cs:line 854
at SharpMap.Presentation.MapPresenter2D.setViewEnvelopeInternal(BoundingBox newEnvelope) in c:\SharpMap\src-google\src\SharpMap\Presentation\Presenters\MapPresenter2D.cs:line 808
at SharpMap.Presentation.MapPresenter2D.ZoomToWorldBoundsInternal(BoundingBox zoomBox) in c:\SharpMap\src-google\src\SharpMap\Presentation\Presenters\MapPresenter2D.cs:line 505
at SharpMap.Presentation.MapPresenter2D.ZoomToExtentsInternal() in c:\SharpMap\src-google\src\SharpMap\Presentation\Presenters\MapPresenter2D.cs:line 462
at SharpMap.Presentation.MapPresenter2D.view_ZoomToExtentsRequested(Object sender, EventArgs e) in c:\SharpMap\src-google\src\SharpMap\Presentation\Presenters\MapPresenter2D.cs:line 741
at SharpMap.Presentation.WinForms.MapViewControl.onRequestZoomToExtents() in c:\SharpMap\src-google\src\SharpMap.Presentation.WinForms\MapViewControl.cs:line 622
at SharpMap.Presentation.WinForms.MapViewControl.ZoomToExtents() in c:\SharpMap\src-google\src\SharpMap.Presentation.WinForms\MapViewControl.cs:line 315
at TestMM.Form1.Form1_Load(Object sender, EventArgs e) in c:\SharpMap\src-google\src\TestMM\Form1.cs:line 41
....