2013-02-21 9 views
5

Ho uno Shapefile che contiene diverse migliaia di poligoni.Come esportare WKT da uno Shapefile in C#?

Ho bisogno di leggere da questo file in C# e di stampare un elenco di stringhe WKT formatted.

Ho guardato a DotSpatial e allo "CatFood" ESRI Shapefile Reader. Posso ottenere sia per caricare lo shapefile bene, ma non riesco a capire come poi esportare come WKT.

In DotSpatial, gli unici esempi che ho trovato utilizzano uno WktWriter che accetta uno Geometry. Non riuscivo a capire come ottenere un Geometry da un Shape.

C'è una libreria più appropriata per questo?

Aggiornamento

Grazie alla risposta di mdm20, sono stato in grado di scrivere il seguente:

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); 
    } 
} 

La ragione per cui ho perso in origine è perché stavo seguendo this sample, che utilizza fs.ShapeIndices invece di fs.GetShape() . Questo non restituisce uno Shape, ma uno ShapeRange, che non è stato possibile convertire in una geometria.

Nuove domande

  1. dovrei essere fissando fs.IndexMode = true? Perché o perché no? Non sembra avere alcun impatto sulle prestazioni o sui risultati.
  2. fs.GetShape() prende un booleano chiamato getAttributes. Ho degli attributi sulle mie forme e sembrano capire se questo è vero o falso. Anche in questo caso, non vi è alcun impatto notevole sulle prestazioni in entrambi i casi. È previsto?
  3. Ottenendo in questo modo, il WKT rappresenta i valori effettivi memorizzati nello shapefile? O si sono trasformati in qualche modo? Sta prendendo in considerazione le impostazioni predefinite di dotSpatial e dovrei preoccuparmi di modificarle?
  4. Lo shapefile che sto importando è lo world timezone map. Contiene un file .prj. DotSpatial tiene conto di ciò e, in caso contrario, devo fare qualcosa in più?

Grazie mille!

risposta

4

In DotSpatial, la classe Shape ha un metodo ToGeometry.

/// <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); 
} 

Modifica

ho usato solo la roba dotspatial per proiezioni, quindi non può davvero aiutare troppo.

1-2: Non sono sicuro. Il codice è open source se si desidera vedere e vedere cosa fanno

3: WKT è una rappresentazione di testo leggibile dall'uomo della geometria. Suppongo che sia lo stesso valore del file, ma non lo so. Ancora..controllare il codice sorgente dotspatial

4: Il file prj indica quale proiezione è la geometria. A seconda di cosa si vuole fare con esso, potrebbe essere necessario riprogettarlo. Cose come Bing Maps e Google Earth usano una proiezione mercator, per esempio. La libreria di proiezioni dotspatial è buona e semplifica la trasformazione della geometria da una proiezione all'altra.

Ho fatto un bel po 'di lavoro con gli shapefile .. fammi sapere se hai altre domande.

+0

Grazie! Si prega di vedere la mia domanda aggiornata ... con più domande. :) –

1

provare questo:

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); 


    } 
1

Prima aprire lo shapefile e quindi ottenere le sue caratteristiche geometria di base .......

 IFeatureSet fb = FeatureSet.Open("F:\\Test_value\\test.shp"); 
     List<string> str = new List<string>(); 
     foreach (IFeature ff in fb.Features) 
     { 
      Geometry geometry = ff.BasicGeometry as Geometry; 
      WktWriter wktWriter = new WktWriter(); 
      str.Add(wktWriter.Write(geometry));   
     } 
+0

Questa è davvero una bella risposta :) Stavo cercando questa soluzione per un po '. In alcuni casi l'uso di DotSpatial è così utile, ma a volte è un po 'complicato. Conosci siti Web con buoni tutorial DotSpatial diversi dalla pagina principale? – Losbaltica