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