'DLGShape -- 8/4/98 'AV3.x DLG to Shapefile Script 'Version 2.1a: Individual version 'Revisions: supports unCHOPPED files 'This Avenue script converts Optional Format DLG-3 lines, points '(degenerate lines), or polys to a shapefile, with attributes. 'Sorry, nodes are not supported. 'DLGShape assumes that the DLG file is uncompressed. Optionally, the 'file may be preprocessed to 80 character lines of text. Public domain 'processing software (GZIP and CHOP) may be obtained via the Internet: ' http://edcwww.cr.usgs.gov/doc/edchome/ndcdb/public.html 'Mark Cederholm 'plp@pierssen.com '======================================================================= 'Home brew software, home brew beer -- Yahoo!!!! '======================================================================= '**** get input file dlg_name = FileDialog.Show("*.dlg", "DLG Optional Format", "Import DLG") if (dlg_name = nil) then exit end '**** get feature type to convert OptionList = {"Line","Polygon","Point"} GetFeature = MsgBox.ChoiceAsString(Optionlist,"Feature:","Import DLG") if (GetFeature = nil) then exit elseif (GetFeature = "Polygon") then skipfirst = MsgBox.MiniYesNo("Skip first polygon?",true) end '**** get output file out_name = dlg_name.clone out_name.SetExtension("shp") out_name = FileDialog.Put(out_name, "*.shp", "Output Shapefile") if (out_name = nil) then exit end '*** ask if file has been CHOPped isChopped = MsgBox.MiniYesNo("Has the file been CHOPped?",true) '**** 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 MsgBox.Info("Done.","DLGShape") '=======================================================================