' ------------------------------------------------------------------------- ' GIS Laboratory ' Geological & Planetary Sciences Division ' Caltech ' ------------------------------------------------------------------------- ' Program : GPS.Xsection ' Purpose : Generate a table of coordinates and attributes extracted from ' selected points in an active theme along a cross section line ' ------------------------------------------------------------------------- ' Calls : none ' Called by: GPS extension ' ------------------------------------------------------------------------- ' Arguments: none ' Globals : none ' ------------------------------------------------------------------------- ' Notes : theFTab is the table associated with the point theme, whereas ' theVTab is the table associated with the new x-section points ' ------------------------------------------------------------------------- ' History : 09/23/97 - Tony Soeller; script created ' ------------------------------------------------------------------------- '. ' ' Identify theView document and ' allow user to generate a graphical line theView = av.GetActiveDoc userLine = theView.ReturnUserLine if (userLine.IsNull) then return nil else grLine = GraphicShape.Make(userLine) theView.GetGraphics.UnselectAll grLine.SetSelected(FALSE) theView.GetGraphics.Add(grLine) av.GetProject.SetModified(true) end ' Extract the end points of the userline startPoint = userLine.ReturnStart endPoint = userLine.ReturnEnd x_start = startPoint.GetX y_start = startPoint.GetY x_end = endPoint.GetX y_end = endPoint.GetY ' Calculate angle from the starting point to the ' ending point of the cross section line ' (First handle the rare cases for a vertical cross section line) theXSide = x_end - x_start theYSide = y_end - y_start if (theXSide = 0) then baseAngle = 90 if (theYSide < 0) then baseAngle = 270 end else baseAngle = (theYSide / theXSide).ATan.AsDegrees if ((x_end < x_start) and (y_end >= y_start)) then baseAngle = 180 - baseAngle.Abs elseif ((x_end < x_start) and (y_end < y_start)) then baseAngle = 180 + baseAngle elseif ((x_end > x_start) and (y_end < y_start)) then baseAngle = 360 - baseAngle.Abs end end baseAngle = baseAngle * -1 ' Get the theme, FTab and shape class and make sure it's a point theme theThemeList = theView.GetActiveThemes theTheme = theThemeList.Get(0) theFTab = theTheme.GetFTab ' Get the bitmap and make sure something is selected for processing theBitMap = theFTab.GetSelection if (theBitMap.Count < 1 ) then MsgBox.Warning("There must be at least one selected point"+NL+ "before you can generate a new table of points.","") theView.GetGraphics.RemoveGraphic(grLine) return nil end ' Construct those cute little tic marks on the end of the X-sec line ' The length of the tic is relative to the view extent theExtent = theView.GetDisplay.ReturnExtent theMax = theExtent.GetHeight.Max(theExtent.GetWidth) theRatio = 25 ' fraction of the max of view width or height ticLength = theMax / theRatio ticX = ticLength * (90 - baseAngle).AsRadians.Cos ticY = ticLength * (90 - baseAngle).AsRadians.Sin ticX1 = ticX + x_start ticY1 = ticY + y_start ticX2 = ticX + x_end ticY2 = ticY + y_end tic1 = GraphicShape.Make(Line.Make(x_start@y_start,ticX1@ticY1)) theView.GetGraphics.Add(tic1) tic2 = GraphicShape.Make(Line.Make(x_end@y_end,ticX2@ticY2)) theView.GetGraphics.Add(tic2) ' Assign the user's .dbf file theFileName = FileDialog.Put("xsection.dbf".AsFileName,"*.dbf", "Enter table name") if (theFileName = nil) then theView.GetGraphics.RemoveGraphic(grLine) theView.GetGraphics.RemoveGraphic(tic1) theView.GetGraphics.RemoveGraphic(tic2) return nil end ' Add the "A" and "A'" to the user's line textLength = 2 * (theMax / theRatio) textX = textLength * (90 - baseAngle).AsRadians.Cos textY = textLength * (90 - baseAngle).AsRadians.Sin textX1 = textX + x_start - (ticLength / 2) textY1 = textY + y_start - (ticLength / 2) textX2 = textX + x_end - (ticLength / 2) textY2 = textY + y_end - (ticLength / 2) textAngle = baseAngle * -1 if ((textAngle > 90) and (textAngle < 270)) then textAngle = textAngle - 180 end textLeft = GraphicText.Make("A",textX1@textY1) textLeft.SetAngle(textAngle) textLeft.SetDisplay(theView.GetDisplay) theView.GetGraphics.Add(textLeft) textRight = GraphicText.Make("A'",textX2@textY2) textRight.SetAngle(textangle) textRight.SetDisplay(theView.GetDisplay) theView.GetGraphics.Add(textRight) ' Group the line, tics and text into a single GraphicGroup grLine.SetSelected(true) tic1.SetSelected(true) tic2.SetSelected(true) textLeft.SetSelected(true) textRight.SetSelected(true) theView.GetGraphics.GroupSelected ' Attach the new cross section line to the point theme theTheme.GetGraphics.Merge(theView.GetGraphics.GetSelected) theTheme.GetGraphics.RemoveDuplicates theTheme.GetGraphics.Invalidate theView.GetGraphics.UnselectAll ' Extract the attribute names from the currently selected point theme ' (Drop the "Shape" attribute) theFields = theTheme.GetFTab.GetFields.DeepClone theFields.Remove(0) ' Construct the new VTab theVTab = VTab.MakeNew(theFileName,dBase) fields = List.Make fields.Add(Field.Make("X",#FIELD_DOUBLE,16,6)) fields.Add(Field.Make("Y",#FIELD_DOUBLE,16,6)) for each aField in theFields fields.Add(aField) end theVTab.AddFields(fields) XField = theVTab.FindField("X") YField = theVTab.FindField("Y") ' Visit each selected point in the FTab, extract the coordinates, remove ' the offset to the cross section origin, and determine ' the new coordinate of the point along the cross section line, and ' write the coordinates and attributes out to the new table x_right = ((x_end - x_start) * baseAngle.AsRadians.Cos) - ((y_end - y_start) * baseAngle.AsRadians.Sin) shpField = theFTab.FindField("Shape") for each rec in theFTab if (theBitMap.Get(rec)) then thePoint = theFTab.ReturnValue(shpField,rec) x_pt = thePoint.GetX - x_start y_pt = thePoint.GetY - y_start x_new = (x_pt * baseAngle.AsRadians.Cos) - (y_pt * baseAngle.AsRadians.Sin) if ((x_new < 0) or (x_new > x_right)) then continue end y_new = (x_pt * baseAngle.AsRadians.Sin) + (y_pt * baseAngle.AsRadians.Cos) newRec = theVTab.AddRecord theVTab.SetValue(XField,newRec,x_new) theVTab.SetValue(YField,newRec,y_new) for each aField in theFields fieldName = theFTab.FindField(aField.AsString) theValue = theFTab.ReturnValue(fieldName,rec) theVTab.SetValue( aField,newRec, theValue ) end end end theVTab.Refresh theVTab.SetEditable(false) ' Get the resulting number of record in the new VTab. ' If there are none then cancel the table construction totalRecs = theVTab.GetNumRecords if (totalRecs < 1 ) then MsgBox.Warning("None of the selected points are perpendicular"+NL+ "to the cross section line along its extent."+NL+ "The table will not be generated.","") return nil end ' Finally, write the start and end points of the cross section line ' to the new table and include the name of the original point theme theTable = Table.Make(theVTab) theDict = Dictionary.Make(30) theDict.Add("x_start",x_start) theDict.Add("y_start",y_start) theDict.Add("x_end",x_end) theDict.Add("y_end",y_end) theDict.Add("source theme",theTheme.AsString) theTable.SetObjectTag(theDict) theComments = "Generated from"++theTheme.AsString++"using"++ x_start.AsString+","+y_start.AsString++"to"++ x_end.AsString+","+y_end.AsString theTable.SetComments(theComments) theTable.SetName(theFileName.GetBaseName.AsString)