Saving an edited layer in GeoObjects

So we’ve extended the GeoObjects library, and seen how to edit an existing feature.  Next we’ll need to save those changes.  The GeoObjects SaveOverlayLayer() method does just what it says – it saves the Overlay Layer along with the two attributes that it carries – Id and Name.  Not so good if you are editing a feature with more attributes.

The Extension library I wrote includes a new method – SaveOverlayLayer2() .

How it works

GeoObjects saves the Overlay into a MapInfo TAB file.  SaveOverlayLayer2() builds on that as the TAB format has a very simple format.  Our first step is to do a standard SaveOverlayLayer call.  This will give us the geographic data in a MapInfo .map file.

Next, we create a temp file to hold the .tab file.  This is a simple text file that looks somthing like this very simple example:

!table
!version 300
!charset Neutral
Definition Table
 Type NATIVE Charset "Neutral"
 Fields 4
 ID Char (35) ;
 Column0 Char (35) ;
 Column1 Char (35) ;
 Column2 Char (35) ;

The column definitions will come from our extended attributes and will be written using a .Net StreamWriter object. At the same time we’ll be building our .dat file, which is nothing more than a standard .dbf:

dbfWriter annoAttrib = new dbfWriter();
annoAttrib.SetConnection(fileInfo.DirectoryName);

Dictionary<string, string>.KeyCollection featAttrs = attrDict[firstKey].Keys;
int firstKey = attrDict.Keys.First();

using (TextWriter streamWriter = new StreamWriter(s))
{
  streamWriter.WriteLine("!table");
  streamWriter.WriteLine("!version 300");
  streamWriter.WriteLine("!charset Neutral");
  streamWriter.WriteLine("");
  streamWriter.WriteLine("Definition Table");
  streamWriter.WriteLine("  Type NATIVE Charset \"Neutral\"");
  streamWriter.WriteLine("  Fields " + attrDict[firstKey].Keys.Count.ToString());

  foreach (string key in featAttrs)
  {
    annoAttrib.AddField(key, "VARCHAR", 35);
    streamWriter.WriteLine("    " + key + " Char (35) ;");
  }
}

Once that is done, we’ll close the stream and write the .dat/dbf file.

string shortFileName = "_attemp";
string baseFileName = Path.GetFileNameWithoutExtension(fileInfo.FullName);

annoAttrib.CreateDBF(shortFileName, true);

OverlayLayer overlay = (OverlayLayer)m.GetOverlayLayer(0);
int feat2Count = ((Features)overlay.Features).Count;

for (int i = 1; i <= feat2Count; i++)
{
    Feature2 copyFeat = (Feature2)((Features)overlay.Features).get_Item(i);
    Dictionary<string, string> featAttrs = new Dictionary<string, string>();
    try
    {
        featAttrs = attrDict[copyFeat.Id];

        foreach (KeyValuePair<string, string> kvp2 in featAttrs)
        {
            annoAttrib.SetFieldValues(kvp2.Key, kvp2.Value);
        }
        annoAttrib.WriteRecord();
    }
    catch { }
}

annoAttrib.EndConnection();

Once that is done, I rename the .dbf to a .dat, and we’re done with the MapInfo file.  If we want to create a Shapefile, we use GeoConvert on the saved MapInfo TAB.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.

Up ↑