11

I am looking for a well documented, Open Source Library that can create and write to a shapefile from .NET. I need lower lever access i.e. I should be able to write feature by feature.

I have investigated and found the following:

Is there a library that can be used to write a new shapefile?

0
9

I feel your pain. I went through the same sort of thing with NetTopologySuite (v1.13) and had some success looking at the unit tests.

First off, you might check out the DotSpatial library which was referenced in a similar question specific to DS shapefile operations

I am personally happy with the NTS library. Once you figure out the object model it's not too much fuss to put something together. Since this topic will likely be referenced more than once here is a quick code dump for writing shapefiles from NTS.

1) Download the NTS (1.13.0) Binaries

2) Reference the following assemblies:

-GeoAPI, NetTopologySuite, NetTopologySuite.IO, NetTopologySuite.IO.GeoTools (guess how long it took to figure out this last one was required)

3) Write some code (this is a 10 minute hack job)

add using statements for NetTopologySuite, NetTopologySuite.IO, NetTopologySuite.Features, GeoAPI, GeoAPI.Geometries (sorry I can't figure out how to get SO to format these)

        string path = @"C:\data\atreides";
        string firstNameAttribute = "firstname";
        string lastNameAttribute = "lastname";

        //create geometry factory
        IGeometryFactory geomFactory = NtsGeometryServices.Instance.CreateGeometryFactory();

        //create the default table with fields - alternately use DBaseField classes
        AttributesTable t1 = new AttributesTable();
        t1.AddAttribute(firstNameAttribute, "Paul");
        t1.AddAttribute(lastNameAttribute, "Atreides");

        AttributesTable t2 = new AttributesTable();
        t2.AddAttribute(firstNameAttribute, "Duncan");
        t2.AddAttribute(lastNameAttribute, "Idaho");

        //create geometries and features
        IGeometry g1 = geomFactory.CreatePoint(new Coordinate(300000, 5000000));
        IGeometry g2 = geomFactory.CreatePoint(new Coordinate(300200, 5000300));

        Feature feat1 = new Feature(g1, t1);
        Feature feat2 = new Feature(g2, t2);

        //create attribute list
        IList<Feature> features = new List<Feature>() { feat1, feat2 };
        ShapefileDataWriter writer = new ShapefileDataWriter(path) { Header = ShapefileDataWriter.GetHeader(features[0], features.Count) };

        System.Collections.IList featList = (System.Collections.IList)features;
        writer.Write(featList);

So, not well documented but it is fairly point & shoot once you get going.

0
6

I haven't used it myself but quickly looking at the documentation for DotSpatial, it looks like it should be able to do what you want.

It has individual assemblies up on NuGet if you know which ones you need (which I don't).

Here is a sample that at least demonstrates the possibility. It would be nice if there was a WKT reader/converter to make for a more readable sample, but that seems to be missing.

1
  • The link you've provided is dead.
    – hansmei
    Oct 9 '20 at 10:30
2

There is also shapelib: http://shapelib.maptools.org/

A .NET wrapper is listed on the webpage.

1

You could also consider MapWinGIS.

MapWinGIS.ocx is used to provide GIS and mapping functionality to any Windows Forms based application. MapWinGIS.ocx is a FREE and OPEN SOURCE C++ based geographic information system programming ActiveX Control and application programmer interface (API) that can be added to a Windows Form in Visual Basic, C#, Delphi, or other languages that support ActiveX, providing your app with a map.

0
1

Feature Data Objects (FDO) does SHP read/write through its SHP provider and has an API for C++ and .net

1

Maybe a stretch but...

PyShp gives you feature-level shapefile control or more in pure Python: http://code.google.com/p/pyshp/

IronPython let's you run pure Pythin scripts on the .NET CLR: http://ironpython.net/

Turn the IronPython script into a .Net library such as this thread: https://stackoverflow.com/questions/1578010/ironpython-2-6-py-exe/9609120#9609120

1

Although this has already been answered, a suggestion for anyone viewing this at a later date is also EGIS (Easy GIS) which allows for shapefiles to be written feature by feature.

ShapeFileWriter sfw = ShapeFileWriter.CreateWriter(dir,fileName,shapeType,dataFieldHeadings);
sfw.AddRecord(pointArray, pointCount, fieldData);

This adds one feature to the shapefile of choice and the AddRecord method has 7 overloads.

1
  • Could you post a code Snippet which shows how this can be done? The answer in its current state cannot stand on it's own, in case the link goes dead. Sep 8 '15 at 17:09
0

I can recommend EasyGIS. Download the latest version from https://www.easygisdotnet.com, include the EGIS.ShapeFileLib and with a few lines you create your first shapefile. The code below creates a Polygon shapefile with one attribute char field "Name" and one shape (a rectangle with name "FirstRecord").

DbfFieldDesc[] lFields = new DbfFieldDesc[1];
DbfFieldDesc fld1 = new DbfFieldDesc();
fld1.FieldName = "Name";
fld1.FieldType = DbfFieldType.Character;
fld1.FieldLength = 16;
lFields[0] = fld1;
ShapeFileWriter sfw = ShapeFileWriter.CreateWriter(sExportDir, "testShapeFile", ShapeType.Polygon, lFields);
PointD[] lPoints = new PointD[4];
lPoints[0] = new PointD(1, 1);
lPoints[1] = new PointD(1, 2);
lPoints[2] = new PointD(2, 2);
lPoints[3] = new PointD(2, 1);
String[] lFieldValues = new String[1];
lFieldValues[0] = "FirstRecord";
sfw.AddRecord(lPoints, 4, lFieldValues);
sfw.Close();
0

I had no success with EasyGIS as it did not write a proper DBF (at least I couldn't make it work). Here is a working code for writing SHP-files with DotSpatial.

PS: I found that the automatic dependencies you'll get from downloading the Dotspation.Data-library through NuGet appear to link to old libraries of the other DotSpatial-references. I had to manually install the DotSpatial.Mono, DotSpatial.Projections and DotSpatial.Topology-libraries through NuGet in order to get the Data-library to work.

// You'll need this library. It will import dependencies it needs, 
// but you may need to reinstall these to get the proper versions
using DotSpatial.Data;

// Function for your class:
public void WriteShape(string savePath)
{
    string rootDir = Path.GetDirectoryName(savePath);
    string shapefileBaseName = Path.GetFileNameWithoutExtension(savePath);

    Shapefile shapefile = new Shapefile();

    Shape shape = new Shape(new Vertex(0,0)); // Set coordinates
    shapefile.AddShape(shape);

    DataTable data = new DataTable();
    data.Columns.Add("PID");
    data.Columns.Add("Name");
    data.Columns.Add("Marks");

    DataRow dr = data.NewRow();
    dr["PID"] = 1;
    dr["Name"] = "Mark";
    dr["Marks"] = "13";
    data.Rows.Add(dr);

    shapefile.Attributes.Table = data;

    string file = Path.ChangeExtension(savePath, ".dbf");
    shapefile.Attributes.Filename = file; // This is important
    shapefile.AttributesPopulated = true; // This is important

    // This will automatically save all the files you need, (.shp, .shx, .dbf)
    shapefile.SaveAs(Path.ChangeExtension(savePath, ".shp"), true);

    // You may choose to save a projection file along with the SHP
    //shapefile.ProjectionString = "Some WKT string";
    //shapefile.SaveProjection()

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.