This project is read-only.

Creating Shapefile Columns And Populating

Nov 15, 2010 at 4:50 PM

I am trying to create a shapefile from scratch, add some coulmns, and fill them with values.

Any help on how to go about this?

Thanks,

Terry

Nov 15, 2010 at 4:53 PM

P.S. - This all needs to be done programetrically.

Nov 15, 2010 at 4:57 PM

Some starter sample code here: http://dotspatial.codeplex.com/wikipage?title=Desktop_SampleCode&referringTitle=System.Spatial.Data

Nov 15, 2010 at 6:50 PM

I did start there but there is no reference to creating shapefile fields in these examples.

Nov 15, 2010 at 10:51 PM

I added a sample of how to do this

 

http://dotspatial.codeplex.com/wikipage?title=CreateAttributes&referringTitle=Desktop_SampleCode

Nov 16, 2010 at 4:19 PM
Edited Nov 16, 2010 at 4:42 PM

Hi,

Thanks for the code example! After changing it for my potential need, I can get as far as the SAVEAS line and then an error is generated. I have included the error and my code.

I also notice that you make reference to the shapefile but never actually use it. Is this correct?

Shapefile s = new Shapefile();

The error shows up in the Shapefileheader.cs module at the SetExtent routine, specifically where the _xMin = extent.MinX is being set. Any Ideas on what I am doing wrong?

The error is:

System.NullReferenceException was unhandled
  Message=Object reference not set to an instance of an object.
  Source=DotSpatial.Data
  StackTrace:
       at DotSpatial.Data.ShapefileHeader.SetExtent(IExtent extent) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\ShapefileHeader.cs:line 331
       at DotSpatial.Data.PointShapefile.SaveAs(String fileName, Boolean overwrite) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\PointShapefile.cs:line 251
       at DotSpatial.Data.FeatureSet.Save() in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\FeatureSet.cs:line 1064
       at DotSpatial.Data.FeatureSet.SaveAs(String fileName, Boolean overwrite) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\FeatureSet.cs:line 1112
       at DotSpatial_Demo.Form1.Button1_Click(Object sender, EventArgs e) in C:\Documents and Settings\osheate\My Documents\My Programming\Visual Studio 2010 Projects\DotSpatial_Demo\DotSpatial_Demo\Form1.vb:line 72
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.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.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(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at DotSpatial_Demo.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       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()
  InnerException:

 My code is:

 

Dim myIF As IFeature

        Dim mySF As New Shapefile

        Dim myFS As New FeatureSet(FeatureType.Point)

        Dim myGeometry As New DotSpatial.Topology.Point

        Dim myCoordinate As New DotSpatial.Topology.Coordinate

        Dim myProjection As New DotSpatial.Projections.ProjectionInfo

        myProjection.ReadProj4String("+proj=longlat +ellps=GRS80 +datum=NAD83 +units=m  no_defs")

        myFS.Projection = myProjection

        myFS.DataTable.Columns.Add(New DataColumn("ID", GetType(Integer)))

        myFS.DataTable.Columns.Add(New DataColumn("DVMS_ID", GetType(Integer)))

        myFS.DataTable.Columns.Add(New DataColumn("ImageName", GetType(String)))

        myFS.DataTable.Columns.Add(New DataColumn("ImagePath", GetType(String)))

        'Dim myCoordinates As IList(Of Coordinate) = New Coordinate(0) {}
        'myCoordinates.Item(0) = New Coordinate(1000, 1000, 100)
        'myGeometry.X = 1000
        'myGeometry.Y = 1000
        'myGeometry.Z = 100

        myCoordinate.X = 10000
        myCoordinate.Y = 10000
        myCoordinate.Z = 100

        myGeometry.Factory.CreatePoint(myCoordinate)

        myIF = myFS.AddFeature(myGeometry)

        myIF.DataRow.BeginEdit()

        myIF.DataRow("ID") = 1

        myIF.DataRow("DVMS_ID") = 1

        myIF.DataRow("ImageName") = "Image 1.jpg"

        myIF.DataRow("ImagePath") = "C:\Temp"

        myIF.DataRow.EndEdit()

        myFS.SaveAs("C:\test.shp", True)
Nov 16, 2010 at 4:27 PM
Edited Nov 16, 2010 at 4:28 PM

One more thing I notice in playing around. If I use the command

 

I get an error "A column named 'FID' already belongs to this DataTable."

Should this return a boolean true/false instead of the error?

 myFS.AddFid()



 

 

Nov 16, 2010 at 4:54 PM
Shapefile is an abstract class and cannot save to files itself. You should use FeatureSet fs = new FeatureSet() etc and not the Shapefile class. Featureset internally will use a PolygonShapefile, PointShapefile, or LineShapefile, or MultiPointShapefile depending on what you need, but when opening a shapefile it is helpful to be able to open it without knowing its data type ahead of time, and so we wrap it in FeatureSet.

Ted



Nov 16, 2010 at 5:15 PM

Yes, that first line in the sample - regarding the Shapefile - was completely unnecessary, not involved in the code snippet at all.

However, there is still a problem in the Pointshapefile class that is causing the exception.  I suspect it it is a side  effect of the recent change from "Envelope" to "Extent".

Anyway, in PointShape.cs you may find

public override void SaveAs(string fileName, bool overwrite)

{

    ...

    InvalidateEnvelope();

    ...

}

 

This line is also found in LineShapefile.SaveAs but is not found in PolygonShapefile.SaveAs

Invalidate envelope simple sets

MyExtent = null;

 which forces an error at 

Header.SetExtent(MyExtent);

 

 

 

This error exists in PointShape file and LineShapefile but not PolygonShapeFile.

If you comment out the call to InvalidateEnvelope then all three cases "appear" to work correctly.

 

I'll commit this but, Ted, I really you'll take a close look at this to confirm that we do not need the call to InvalididateEnvelope to be Update to "UpdateExtent" or something similar.

 

 

 

Nov 16, 2010 at 8:18 PM

Reverting back to

DotSpatial 11-7-2010

myFS.SaveAs("C:\test.shp", True)

Now produces the error:

  System.ArgumentNullException was unhandled
  Message=Path cannot be null.
Parameter name: path
  ParamName=path
  Source=mscorlib
  StackTrace:
       at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
       at DotSpatial.Data.AttributeTable.GetRowOffsets() in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\AttributeTable.cs:line 164
       at DotSpatial.Data.AttributeTable.Fill(Int32 numRows) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\AttributeTable.cs:line 212
       at DotSpatial.Data.Shapefile.FillAttributes() in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\Shapefile.cs:line 467
       at DotSpatial.Data.FeatureSet.Save() in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\FeatureSet.cs:line 1045
       at DotSpatial.Data.FeatureSet.SaveAs(String fileName, Boolean overwrite) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\FeatureSet.cs:line 1093
       at DotSpatial_Demo.Form1.Button1_Click(Object sender, EventArgs e) in C:\Documents and Settings\osheate\My Documents\My Programming\Visual Studio 2010 Projects\DotSpatial_Demo\DotSpatial_Demo\Form1.vb:line 98
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.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.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(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at DotSpatial_Demo.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       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()
  InnerException:

Nov 17, 2010 at 1:12 AM

Try 2010-11-14.  I fixed that problem on saturday in change set  e2cb87c0818b

 
Nov 25, 2010 at 3:45 AM

I had the same problem when saving my FeatureSet to a shapefile.

When I go to save the Line FeatureSet it spits a NullReferenceException at:

Header.SetExtent(MyExtent);

This is as keenedge said; because the call to InvalidateEnvelope() sets the extent to null.