'DLGShape -- 8/4/98 'AV3.x DLG to Shapefile Script 'Version 2.1b: Batch version 'Revisions: supports unCHOPPED files, plus improved object cleanup 'What you need to do is create an input file with each line in the 'following format: '[inputname] [outputname] [option] {YES/NO} 'YES/NO only applies to the POLYGON option, specifying whether you wish 'to skip the first polygon (default is YES). For example: 'hydro.dlg hydro_pt.shp POINT 'hydro.dlg hydro_ln.shp LINE 'hydro.dlg hydro.shp POLYGON 'land.dlg land.shp POLYGON NO 'Note that the script assumes the DLG files to reside in the same 'directory as the input file. 'Mark Cederholm 'plp@pierssen.com '======================================================================= 'Home brew software, home brew beer -- Yahoo!!!! '======================================================================= '**** get input file input_name = FileDialog.Show("*.*", "All Files", "Import DLG - Batch Input File") if (input_name = nil) then exit end '*** ask if files have been CHOPped isChopped = MsgBox.MiniYesNo("Have the files been CHOPped?",true) '**** set current directory to that of input file input_name.SetCWD temp = Filename.GetCWD av.GetProject.SetWorkDIR(temp) '**** read and process input file records input_file = LineFile.Make(input_name, #FILE_PERM_READ) while (not (input_file.IsAtEnd)) input_rec = input_file.ReadELT '**** get DLG file dlg_name = input_rec.Extract(0).AsFilename '**** get output file out_name = input_rec.Extract(1).AsFilename '**** get feature type to convert GetFeature = input_rec.Extract(2).Proper if (GetFeature = "Polygon") then temp = input_rec.Extract(3) if (temp = nil) then skipfirst = true elseif (temp.Ucase = "NO") then skipfirst = false else skipfirst = true end end '**** skip to first record to process if (isChopped) then dlg_file = LineFile.Make(dlg_name, #FILE_PERM_READ) FileLines = dlg_file.GetSize rblank = nil else dlg_file = TextFile.Make(dlg_name, #FILE_PERM_READ) FileLines = dlg_file.GetSize / 80 rblank = "" end if (GetFeature = "Polygon") then HeaderID = "A" else HeaderID = "L" end av.ClearMsg av.ClearStatus av.ShowMsg("Reading File Data...") if (isChopped) then record = dlg_file.ReadElt else record = dlg_file.Read(80) end InputLine = 1 av.SetStatus(100*Inputline/Filelines) while (record.Extract(0) <> HeaderID) if (isChopped) then record = dlg_file.ReadElt else record = dlg_file.Read(80) end InputLine = InputLine + 1 av.SetStatus(100*InputLine/FileLines) end '**** process area records '**** in this approach, the Shapefile is created minus the Shape value '**** a list of lists of line IDs is created which will be used later '**** in assembling the polygons if (GetFeature = "Polygon") then PShape = FTab.MakeNew(out_name, Polygon) fields = List.Make fields.Add(Field.Make("id",#FIELD_LONG,11,0)) PShape.AddFields(fields) PLineList = List.Make numpairs = 0 numpolys = 0 PolyRead = true while (PolyRead) '**** get poly ID and number of lines PolyID = record.Middle(1,5).AsNumber numlines = record.Middle(36,6).AsNumber '**** read remainder of poly record polyrec = List.make NotDone = true while (NotDone) if (isChopped) then record = dlg_file.ReadElt else record = dlg_file.Read(80) end InputLine = InputLine + 1 av.SetStatus(100*InputLine/FileLines) if (record.Extract(0) = "L") then NotDone = false PolyRead = false elseif (record.Extract(0) = "A") then NotDone = false else polyrec.Merge(record.AsTokens(" ")) end end if ((PolyID = 1) and (skipfirst)) then '**** skip first poly continue end rlist = List.Make j = 1 while (j <= numlines) lineID = polyrec.Get(j - 1).AsNumber rlist.Add(lineID) j = j + 1 end PLineList.Add(rlist) recno = PShape.AddRecord PShape.SetValue(PShape.FindField("id"),recno,PolyID) numpolys = numpolys + 1 '**** add code pairs, if any, to feature table CodePairs = (polyrec.Count - numlines) / 2 fields = List.Make while (CodePairs > numpairs) numpairs = numpairs + 1 fields = List.Make fields.Add(Field.Make("major"+numpairs.AsString,#FIELD_LONG,6,0)) fields.Add(Field.Make("minor"+numpairs.AsString,#FIELD_LONG,6,0)) PShape.AddFields(fields) end k = 1 while (k <= CodePairs) l = numlines + ((k - 1) * 2) major = polyrec.Get(l).AsNumber minor = polyrec.Get(l + 1).AsNumber PShape.SetValue(PShape.FindField("major"+k.AsString),recno,major) PShape.SetValue(PShape.FindField("minor"+k.AsString),recno,minor) k = k + 1 end end end '**** process line records '**** if the final product is to consist of polygons, '**** the line records will be processed into a list of point lists '**** otherwise the final shape file will be built on the fly if (GetFeature = "Polygon") then LineList = List.Make else if (GetFeature = "Line") then LShape = FTab.MakeNew(out_name, Polyline) else LShape = FTab.MakeNew(out_name, Point) end fields = List.Make fields.Add(Field.Make("id",#FIELD_LONG,11,0)) LShape.AddFields(fields) numpairs = 0 end while (record <> rblank) '**** get line ID and number of points lineID = record.Middle(1,5).AsNumber numpoints = record.Middle(42,6).AsNumber '**** read remainder of line record linerec = List.make NotDone = true while (NotDone) if (isChopped) then record = dlg_file.ReadElt else record = dlg_file.Read(80) end InputLine = InputLine + 1 av.SetStatus(100*InputLine/FileLines) if (record = rblank) then NotDone = false else if (record.Extract(0).IsNumber) then linerec.Merge(record.AsTokens(" ")) else NotDone = false end end end '**** create point list plist = list.make i = 1 while (i <= numpoints) j = (i - 1) * 2 x = linerec.Get(j).AsNumber y = linerec.Get(j + 1).AsNumber p1 = Point.Make(x,y) plist.Add(p1) i = i + 1 end '**** check for degenerate line NotDegenerate = true if (plist.count = 2) then p1 = plist.Get(0) p2 = plist.Get(1) if (p1 = p2) then NotDegenerate = false end end if (NotDegenerate) then if (GetFeature = "Point") then DoShape = false DoAttributes = false elseif (GetFeature = "Line") then DoShape = true DoAttributes = true else DoShape = true DoAttributes = false end else if (GetFeature = "Point") then DoShape = true DoAttributes = true elseif (GetFeature = "Line") then DoShape = false DoAttributes = false else DoShape = false DoAttributes = false end end '**** update line/point shapefile or dictionary if (DoShape) then if (GetFeature = "Line") then plistl = List.Make pline = PolyLine.Make(plistl.Add(plist)) recno = LShape.AddRecord LShape.SetValue(LShape.FindField("shape"),recno,pline) LShape.SetValue(LShape.FindField("id"),recno,lineID) elseif (GetFeature = "Point") then recno = LShape.AddRecord LShape.SetValue(LShape.FindField("shape"),recno,plist.Get(0)) LShape.SetValue(LShape.FindField("id"),recno,lineID) else while (Linelist.Count < lineID) LineList.Add(nil) end LineList.Add(plist) end end '**** add code pairs, if any, to feature table if (DoAttributes) then CodePairs = (linerec.Count / 2) - numpoints fields = List.Make while (CodePairs > numpairs) numpairs = numpairs + 1 fields = List.Make fields.Add(Field.Make("major"+numpairs.AsString,#FIELD_LONG,6,0)) fields.Add(Field.Make("minor"+numpairs.AsString,#FIELD_LONG,6,0)) LShape.AddFields(fields) end i = 1 while (i <= CodePairs) j = (numpoints * 2) + ((i - 1) * 2) major = linerec.Get(j).AsNumber minor = linerec.Get(j + 1).AsNumber LShape.SetValue(LShape.FindField("major"+i.AsString),recno,major) LShape.SetValue(LShape.FindField("minor"+i.AsString),recno,minor) i = i + 1 end end end dlg_file.close '**** assemble polygons if (GetFeature = "Polygon") then av.ClearMsg av.ClearStatus av.ShowMsg("Assembling Polygons...") item = 1 for each recno in PShape av.SetStatus(100*item/numpolys) polyrec = PLineList.Get(item-1) numlines = polyrec.Count rlistl = List.Make rlist = List.Make j = 1 while (j <= numlines) lineID = polyrec.Get(j - 1) if (lineID > 0) then '*** get pointlist entry and drop endpoint rlist.Merge(LineList.Get(lineID)) rlist.Remove(rlist.Count - 1) elseif (lineID < 0) then '**** get pointlist entry, reverse order, and drop endpoint temp1list = LineList.Get(lineID.Abs) temp2list = List.Make k = temp1list.Count while (k >= 1) temp2list.Add(temp1list.Get(k - 1)) k = k - 1 end rlist.Merge(temp2list) rlist.Remove(rlist.Count - 1) else '**** add ring and prepare for the next rlistl.Add(rlist) rlist = List.Make end j = j + 1 end rlistl.Add(rlist) poly = Polygon.Make(rlistl) PShape.SetValue(PShape.FindField("shape"),recno,poly) item = item + 1 end end av.ClearMsg av.ClearStatus if (GetFeature = "Polygon") then PShape.Flush PShape = nil LineList = nil Linerec = nil PlineList = nil else LShape.Flush LShape = nil end av.PurgeObjects end input_file.close MsgBox.Info("Done.","DLGShape") '=======================================================================