Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export WKT from a Shapefile in c#?

I have a Shapefile that contains several thousand polygons.

I need to read from this file in C# and output a list of WKT formatted strings.

I looked at DotSpatial and the "CatFood" ESRI Shapefile Reader. I can get either to load the shapefile just fine, but I cannot figure out how to then export as WKT.

In DotSpatial, the only examples I could find use a WktWriter which takes a Geometry. I couldn't figure out how to get a Geometry from a Shape.

Is there a library that's more appropriate for this?

Update

Thanks to mdm20's answer, I was able to write the following:

using (var fs = FeatureSet.Open(path))
{
    var writer = new WktWriter();
    var numRows = fs.NumRows();
    for (int i = 0; i < numRows; i++)
    {
        var shape = fs.GetShape(i, true);                    
        var geometry = shape.ToGeometry();
        var wkt = writer.Write((Geometry) geometry);
        Debug.WriteLine(wkt);
    }
}

The reason I missed it originally is because I was following this sample, which uses fs.ShapeIndices instead of fs.GetShape(). That returns not a Shape, but a ShapeRange, which I couldn't convert to a geometry.

New Questions

  1. Should I be setting fs.IndexMode = true? Why or why not? It doesn't seem to have any performance or results impact.
  2. fs.GetShape() takes a boolean called getAttributes. I do have attributes on my shapes, and they seem to come through whether this is set true or false. Again, there is no noticeable performance impact either way. Is that expected?
  3. By getting them in this way, does the WKT represent the actual values stored in the shapefile? Or are they transformed in any way? Is it taking any default settings from dotSpatial into account, and should I be concerned about changing them?
  4. The shapefile I am importing is the world timezone map. It does contain a .prj file. Does dotSpatial take this into account, and if not - do I need to do anything extra?

Many Thanks!

like image 781
Matt Johnson-Pint Avatar asked Feb 21 '13 00:02

Matt Johnson-Pint


2 Answers

In DotSpatial, the Shape class has a ToGeometry method.

/// <summary>
/// Converts this shape into a Geometry using the default factory.
/// </summary>
/// <returns>The geometry version of this shape.</returns>
public IGeometry ToGeometry()
{
    return ToGeometry(Geometry.DefaultFactory);
}

Edit

I've only used the dotspatial stuff for projections, so I can't really help you too much.

1-2: Not sure. The code is open source if you want to look and see what they do

3: WKT is a human readable text representation of the geometry. I would assume that it's the same value as the file, but I don't know. Again.. check out the dotspatial source code

4: The prj file tells you what projection the geometry is in. Depending on what you want to do with it, you might have to re-project it. Things like Bing Maps and Google Earth use a mercator projection, for instance. The dotspatial projections library is good and makes it easy to transform the geometry from one projection to another.

I've done quite a bit of work with shapefiles.. let me know if you have more questions.

like image 177
mdm20 Avatar answered Oct 17 '22 21:10

mdm20


try this:

private void button1_Click(object sender, EventArgs e)
    {            
        String result = "";

        OpenFileDialog openfile = new OpenFileDialog();
        openfile.Filter = "Shapefile (*.shp)|*.shp|All files (*.*)|*.*";
        openfile.ShowDialog();
        String filePath = openfile.FileName.Replace(".shp", "").Replace(@"\", @"\\");
        String[] a = filePath.Split('\\');

        String shpName = a[a.Length-1];

        try
        {

            SQLiteConnection.CreateFile(openfile.FileName.Replace(".shp", "")+".sqlite");

            System.Data.SQLite.SQLiteConnection connection = new SQLiteConnection(@"Data Source=" + openfile.FileName.Replace(".shp", "") + ".sqlite");



            connection.Open();
            object returnvalue = new SQLiteCommand("SELECT load_extension('libspatialite-2.dll')", connection).ExecuteScalar();

            System.Data.SQLite.SQLiteCommand commande = new SQLiteCommand(connection);
            commande.CommandText = "CREATE virtual TABLE "+shpName+"VT USING VirtualShape('" + filePath + "', 'CP1252', 4326);";

            commande.ExecuteScalar();

            commande.CommandText = "CREATE TABLE geom AS SELECT * FROM " + shpName + "VT;";
            commande.ExecuteScalar();

            commande.CommandText = "drop table " + shpName + "VT";
            commande.ExecuteScalar();


            commande.CommandText = "ALTER TABLE geom ADD COLUMN WKT TEXT;";
            commande.ExecuteScalar();

            commande.CommandText = " UPDATE  geom set WKT= ST_AsText(Geometry);";
            commande.ExecuteScalar();


           // the test commande

            commande.CommandText = "SELECT WKT FROM geom;";

            result = (string)commande.ExecuteScalar();





        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);

        }
        MessageBox.Show(result);


    }
like image 41
Chakib SAFAR Avatar answered Oct 17 '22 23:10

Chakib SAFAR