2013-02-21 12 views
5

Mam Shapefile, który zawiera kilka tysięcy wielokątów.Jak eksportować WKT z Shapefile wC#?

Potrzebuję przeczytać z tego pliku w C# i wyświetlić listę ciągów WKT formatted.

Spojrzałem na DotSpatial i "CatFood" ESRI Shapefile Reader. Mogę albo załadować plik kształtu w porządku, ale nie mogę wymyślić, jak następnie eksportować jako WKT.

W DotSpatial, jedyne przykłady, jakie mogłem znaleźć, to WktWriter, które pobierają Geometry. Nie mogłem wymyślić, jak uzyskać Geometry od Shape.

Czy istnieje biblioteka odpowiednia do tego?

Aktualizacja

Dzięki odpowiedź mdm20 jest, byłem w stanie napisać, co następuje:

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

Powodem brakowało mi go pierwotnie dlatego, że był po this sample, który wykorzystuje fs.ShapeIndices zamiast fs.GetShape() . To nie zwraca wartości Shape, ale ShapeRange, której nie można przekonwertować na geometrię.

Nowe pytania

  1. powinienem być ustawienie fs.IndexMode = true? Dlaczego lub dlaczego nie? Wygląda na to, że nie ma żadnego wpływu na wyniki ani wyniki.
  2. fs.GetShape() przyjmuje wartość logiczną o nazwie getAttributes. Mam swoje atrybuty na moich kształtach i wydaje się, że przechodzą przez to, czy jest to prawda czy fałsz. Ponownie, nie ma zauważalnego wpływu na wydajność w obu kierunkach. Czy to jest oczekiwane?
  3. Uzyskując je w ten sposób, czy WKT reprezentuje rzeczywiste wartości przechowywane w pliku shape? Czy są one w jakikolwiek sposób przekształcone? Czy bierze pod uwagę jakieś ustawienia domyślne z dotSpatial i czy powinienem się przejmować ich zmianą?
  4. Plik kształtu, który importuję, to world timezone map. Zawiera plik .prj. Czy dotSpatial bierze to pod uwagę, a jeśli nie - czy muszę zrobić coś ekstra?

Wielkie dzięki!

Odpowiedz

4

W DotSpatial klasa Shape ma metodę 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); 
} 

Edit

Użyłem tylko dotspatial rzeczy do projekcji, więc nie mogę pomóc zbyt dużo.

1-2: Nie jestem pewien. Kod jest open source, jeśli chcesz zobaczyć i zobaczyć, co one robią:

3: WKT to czytelna dla człowieka reprezentacja tekstowa geometrii. Zakładam, że ma tę samą wartość co plik, ale nie wiem. Jeszcze raz..sprawdź kod źródłowy dotspatial

4: Plik prj pokazuje, w jakiej projekcji znajduje się geometria. W zależności od tego, co chcesz z nią zrobić, być może będziesz musiał go ponownie zaprojektować. Rzeczy takie jak Bing Maps i Google Earth używają np. Projekcji mercator. Biblioteka przewidywań dotspatial jest dobra i ułatwia przekształcenie geometrii z jednej projekcji na drugą.

Zrobiłem sporo pracy z shapefile .. daj mi znać, jeśli masz więcej pytań.

+0

Dzięki! Zobacz moje zaktualizowane pytanie ... z dodatkowymi pytaniami. :) –

1

spróbuj tego:

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

Pierwszy otworzyć shapefile a następnie uzyskać produkt podstawowy geometria .......

 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

To naprawdę fajna odpowiedź :) Szukałem tego rozwiązania przez jakiś czas. W niektórych przypadkach używanie DotSpatial jest tak przydatne, ale czasami jest nieco trudne. Czy znasz jakieś strony internetowe z dobrymi samouczkami DotSpatial poza stroną główną? – Losbaltica