How to create Shapefile and Add Features to it?

Topics: General Topics, SharpMap v2.0, WinForms Controls
Oct 23, 2008 at 5:08 PM
Hi,
  I just want to know th e procedure to create an empty shapefile and add Point features to it and save it.Basically my requirement(s) are:
-I am displaying a shapefile  on Windows C# Form control.
-I read GPS coordinates from a device and want to track the movement of a person on my map.
-As I understand ,I need to create a shapefile,add the GPS points dynamically to it,save it to disk for further analysis.

How do I go about that using Sharpmap ?
Coordinator
Oct 25, 2008 at 12:37 AM

Hi dgp -

The SharpMapWinFormsDemo (http://sharpmapv2.googlecode.com/svn/trunk/Demos/SharpMapWinFormsDemo) is a good starting place to see how to display shapefiles in SharpMap.

You can use http://www.codeplex.com/SharpGPS to get GPS data. (Make sure to grab the source, not the release: http://www.codeplex.com/SharpGPS/SourceControl/ListDownloadableCommits.aspx)

You can write to a Shapefile like this (not sure if this is exact):

ICoordinateSequenceFactory<BufferedCoordinate> sequenceFactory = new BufferedCoordinateSequenceFactory();
IGeometryFactory<BufferedCoordinate> geoFactory = new GeometryFactory<BufferedCoordinate>(sequenceFactory);

FeatureDataTable<UInt32> schema = new FeatureDataTable<UInt32>("OID", geoFactory);
schema.Columns.AddRange(new DataColumn[]
       {
        new DataColumn("Name", typeof (String)),
        new DataColumn("DateCreated", typeof (DateTime)),
        new DataColumn("Visits", typeof (Int64)),
        new DataColumn("Weight", typeof (Double))
       });

FeatureDataRow<UInt32> feature = schema.NewRow(1);    
feature["Name"] = "ABCD";
feature["DateCreated"] = DateTime.Now;
feature["Visits"] = 1000;
feature["Temperature"] = 23.456;
feature.Geometry = geoFactory.CreatePoint2D(0, 0);

ShapeFileProvider shapeFile = ShapeFileProvider.Create("C:\MovementData", "DataSet1", ShapeType.Point, schema, geoFactory);
shapeFile.Open();    
shapeFile.Insert(feature);
shapeFile.Close();

Oct 27, 2008 at 10:24 AM
Hi  Codekaizen,
              I tried to use the tip given by you.But ,I get the following errors when compile it in VS2005

The type or namespace name 'BufferedCoordinate' could not be found (are you missing a using directive or an assembly reference?)
The non-generic type 'GeoAPI.Geometries.ICoordinateSequenceFactory' cannot be used with type arguments
The type or namespace name 'BufferedCoordinateSequenceFactory' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'BufferedCoordinate' could not be found (are you missing a using directive or an assembly reference?)
The non-generic type 'GeoAPI.Geometries.IGeometryFactory' cannot be used with type arguments
The type or namespace name 'BufferedCoordinate' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'GeometryFactory' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'FeatureDataTable' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'FeatureDataTable' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'FeatureDataRow' could not be found (are you missing a using directive or an assembly reference?)
Cannot apply indexing with [] to an expression of type 'FeatureDataRow<uint>'
Cannot apply indexing with [] to an expression of type 'FeatureDataRow<uint>'
Cannot apply indexing with [] to an expression of type 'FeatureDataRow<uint>'
Cannot apply indexing with [] to an expression of type 'FeatureDataRow<uint>'
The type or namespace name 'ShapeFileProvider' could not be found (are you missing a using directive or an assembly reference?)
The name 'ShapeFileProvider' does not exist in the current context
Coordinator
Oct 30, 2008 at 5:27 PM
I updated the VS 2005 solution and made a slight name change. If you do an update on the v2.0 source, you should get it.
Nov 6, 2008 at 2:16 PM
Hi,

When i load a shapefile with SharpMapWinFormsDemo and press "Fixed Zoom In" i get the following errors

SharpMap.Data.Providers.ShapeFile.ShapeFileInvalidOperationException: An attempt was made to access a closed data source.
   bei SharpMap.Data.Providers.AsyncResult.EndInvoke() in D:\Projekte\Test\v2\SharpMap\Data\Providers\AsyncResult.cs:Zeile 104.
   bei SharpMap.Data.Providers.AsyncResult`1.EndInvoke() in D:\Projekte\Test\v2\SharpMap\Data\Providers\AsyncResult`1.cs:Zeile 38.
   bei SharpMap.Data.Providers.AsyncFeatureProviderAdapter.EndExecuteQuery(IAsyncResult asyncResult) in D:\Projekte\Test\v2\SharpMap\Data\Providers\AsyncFeatureProviderAdapter.cs:Zeile 69.
   bei SharpMap.Layers.Layer.LoadLayerData(QueryExpression query) in D:\Projekte\Test\v2\SharpMap\Layers\Layer.cs:Zeile 583.
   bei SharpMap.Layers.FeatureLayer.handleFeaturesSelectRequested(Object sender, SelectRequestedEventArgs e) in D:\Projekte\Test\v2\SharpMap\Layers\FeatureLayer.cs:Zeile 343.
   bei SharpMap.Data.FeatureDataTable.OnSelectRequested(FeatureQueryExpression query) in D:\Projekte\Test\v2\SharpMap\Data\FeatureDataTable.cs:Zeile 814.
   bei SharpMap.Data.FeatureDataTable.<Select>d__f.MoveNext() in D:\Projekte\Test\v2\SharpMap\Data\FeatureDataTable.cs:Zeile 721.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.RenderFeatureLayer(IFeatureLayer layer, RenderPhase phase) in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 933.
   bei SharpMap.Presentation.WinForms.MapPresenter.RenderFeatureLayer(IFeatureLayer layer, RenderPhase phase) in D:\Projekte\Test\v2\SharpMap.Presentation\WinForms\MapPresenter.cs:Zeile 103.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.RenderLayer(ILayer layer, RenderPhase phase) in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 879.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.RenderAllLayers(RenderPhase phase) in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 846.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.RenderAllLayers() in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 823.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.setViewMetricsInternal(Size2D newViewSize, ICoordinate newCenter, Double newWorldWidth) in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 1390.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.setViewEnvelopeInternal(IExtents2D newEnvelope) in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 1307.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.ZoomToWorldBoundsInternal(IExtents2D zoomBox) in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 610.
   bei SharpMap.Presentation.Presenters.MapPresenter2D.handleViewZoomToWorldBoundsRequested(Object sender, MapViewPropertyChangeEventArgs`1 e) in D:\Projekte\Test\v2\SharpMap\Presentation\Presenters\MapPresenter2D.cs:Zeile 1153.
   bei SharpMap.Presentation.WinForms.MapViewControl.onRequestZoomToWorldBounds(IExtents2D zoomBox) in D:\Projekte\Test\v2\SharpMap.Presentation\WinForms\MapViewControl.cs:Zeile 1042.
   bei SharpMap.Presentation.WinForms.MapViewControl.ZoomToWorldBounds(IExtents2D zoomBox) in D:\Projekte\Test\v2\SharpMap.Presentation\WinForms\MapViewControl.cs:Zeile 403.
   bei MapViewer.MapViewerForm.Zoom(Double amount) in D:\Projekte\Test\v2\Demos\SharpMapWinFormsDemo\MapViewerForm.cs:Zeile 465.
   bei MapViewer.MapViewerForm.FixedZoomIn() in D:\Projekte\Test\v2\Demos\SharpMapWinFormsDemo\MapViewerForm.cs:Zeile 454.
   bei MapViewer.ActionCommandHandler.HandleCommand() in D:\Projekte\Test\v2\Demos\SharpMapWinFormsDemo\ActionCommandHandler.cs:Zeile 50.
   bei MapViewer.Commands.CommandHandlerBase.CommandFired(Object sender, EventArgs e) in D:\Projekte\Test\v2\Demos\SharpMapWinFormsDemo\Commands\CommandHandlerBase.cs:Zeile 43.
   bei MapViewer.Commands.Command.FireCommand() in D:\Projekte\Test\v2\Demos\SharpMapWinFormsDemo\Commands\Command.cs:Zeile 50.
   bei MapViewer.Commands.ToolStripItemCommandSource`1.component_Click(Object sender, EventArgs e) in D:\Projekte\Test\v2\Demos\SharpMapWinFormsDemo\Commands\ToolStripMenuItemCommandSource.cs:Zeile 57.
   bei System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   bei System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
   bei System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   bei System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   bei System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
   bei System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
   bei System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   bei System.Windows.Forms.Control.WndProc(Message& m)
   bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   bei System.Windows.Forms.ToolStrip.WndProc(Message& m)
   bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


i use latest  svn checkout. With Postgis works fine.

What can i do?

Thanks in advance
Christian


Coordinator
Nov 9, 2008 at 4:14 PM
Hi Christian -

If I can get this project I'm working on done on Monday, I'll look at this then, unless you figured it out already?
Coordinator
Nov 9, 2008 at 5:25 PM
Hi Christian, that issue should be fixed now.. cheers jd
Nov 21, 2008 at 3:06 PM
Hi,

I've implemented the method you posted codekaizen but it's terribly slow :s
i have to insert about 300000 point features and it seems to take ages... (more than 5 minutes for the first 50K features... stopped it there)
<code>
            ICoordinateSequenceFactory<BufferedCoordinate> sequencefactory = new BufferedCoordinateSequenceFactory();
            IGeometryFactory<BufferedCoordinate> geoFactory = new GeometryFactory<BufferedCoordinate>(sequencefactory);
            FeatureDataTable<UInt32> schema = new FeatureDataTable<UInt32>("OID", geoFactory);
            schema.Columns.Add(new DataColumn("tpc", typeof(Int32)));
            Dictionary<IPoint, tpc>.Enumerator num = dictionarry.GetEnumerator();
            num.MoveNext();
            FeatureDataRow<UInt32>feature = schema.NewRow(1);
            feature["tpc"] = num.Current.Value.val;
            feature.Geometry = (IGeometry)num.Current.Key;
            shpprov = ShapeFileProvider.Create(@"D:\", newshapefilepath, ShapeType.Point, schema, geoFactory);
            shpprov.Open();
            shpprov.Insert(feature);
            while (num.MoveNext())
            {
                feature = schema.NewRow(1);
                feature["tpc"] = num.Current.Value.val;
                feature.Geometry = (IGeometry)num.Current.Key;
                shpprov.Insert(feature);
            }
            shpprov.Close();
</code>
Nov 24, 2008 at 8:50 AM
1. i have tried turning indexing off... didn't change
2. that .Create() method throws me an exception:
shpprov = ShapeFileProvider.Create(@"D:\", newshapefilepath, ShapeType.Point, schema, geoFactory);
results in:

<exception>
System.IO.EndOfStreamException was unhandled
  Message="Unable to read beyond the end of the stream."
  Source="mscorlib"
  StackTrace:
       at System.IO.BinaryReader.ReadByte()
       at SharpMap.Data.Providers.ShapeFile.DbaseHeader.ParseDbfHeader(Stream dataStream) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\DbaseHeader.cs:line 163
       at SharpMap.Data.Providers.ShapeFile.DbaseFile.parseHeader(Stream dbfStream) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\DbaseFile.cs:line 491
       at SharpMap.Data.Providers.ShapeFile.DbaseFile.syncReadHeader(Stream dbfStream) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\DbaseFile.cs:line 484
       at SharpMap.Data.Providers.ShapeFile.DbaseFile.get_Header() in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\DbaseFile.cs:line 388
       at SharpMap.Data.Providers.ShapeFile.DbaseFile.CreateDbaseFile(String fileName, DataTable schema, CultureInfo culture, Encoding encoding, IGeometryFactory geoFactory) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\DbaseFile.cs:line 216
       at SharpMap.Data.Providers.ShapeFile.ShapeFileProvider.Create(DirectoryInfo directory, String layerName, ShapeType type, FeatureDataTable model, CultureInfo culture, Encoding encoding, IGeometryFactory geoFactory) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\ShapeFileProvider.cs:line 465
       at SharpMap.Data.Providers.ShapeFile.ShapeFileProvider.Create(DirectoryInfo directory, String layerName, ShapeType type, FeatureDataTable model, IGeometryFactory geoFactory) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\ShapeFileProvider.cs:line 377
       at SharpMap.Data.Providers.ShapeFile.ShapeFileProvider.Create(String directory, String layerName, ShapeType type, FeatureDataTable schema, IGeometryFactory geoFactory) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\ShapeFileProvider.cs:line 352
       at WindowsFormsApplication1.Form1.button1_Click(Object sender, EventArgs e) in d:\vs\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 105
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(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(Int32 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 WindowsFormsApplication1.Program.Main() in d:\vs\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:
</Exception>


3. If i use a .Create without a schema, i get an exception on .Insert() an IENumerable of featuredatarows:
List<FeatureDataRow<UInt32>> features = new List<FeatureDataRow<uint>>();
shpprov.Open();
shpprov.Insert(features); 

<Exception>
System.Collections.Generic.KeyNotFoundException was unhandled
  Message="The given key was not present in the dictionary."
  Source="System"
  StackTrace:
       at System.Collections.Generic.SortedList`2.get_Item(TKey key)
       at SharpMap.Data.Providers.ShapeFile.ShapeFileIndex.get_Item(UInt32 key) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\ShapeFileIndex.cs:line 183
       at SharpMap.Data.Providers.ShapeFile.ShapeFileProvider.Insert(IEnumerable`1 features) in D:\vs\sharpmapv2-read-only\SharpMap.Data.Providers\ShapeFileProvider\ShapeFileProvider.cs:line 1198
       at WindowsFormsApplication1.Form1.button1_Click(Object sender, EventArgs e) in d:\vs\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 133
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(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(Int32 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 WindowsFormsApplication1.Program.Main() in d:\vs\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:
</Exception>

Nov 24, 2008 at 1:27 PM
See my solution to this problem on IssueTracker
http://www.codeplex.com/SharpMap/WorkItem/View.aspx?WorkItemId=19720

Best
Coordinator
Nov 24, 2008 at 4:01 PM
Edited Nov 24, 2008 at 4:08 PM
Thanks slaks, gave me a head start.. the issue should be fixed now in the trunk cheers jd

ALSO - back to the topic: see the new SharpMap.Demo.FeatureExporter project which exports feature by feature the contents of one shapefile into many shapefiles