### FlightPlan.sml ### SML Tool Script ### Requires TNT version 2007:73 ### Tool script for laying out a set of parallel flight lines for aerial imaging ### operations over a target area. Script provides and manages tools for drawing ### the target area polygon in the View and for drawing a straight line to ### indicate the flight line direction. The target area can also be loaded from ### a vector, CAD, or region object. Flight lines are created to fully cover ### the target polygon and are clipped at a buffer polygon surrounding the target ### area at the specified buffer distance. A custom dialog window provides controls ### for inputing parameters and for activating the drawing actions and other ### procedures. Flight lines, area boundary, and buffer can be saved as either ### vector or CAD objects, and flight line can be exported to a GPX file. ### Brett Colombe and Randy Smith, MicroImages, March 2007. ### Revised 26 April 2007 to add boundary from vector, CAD, or region and save as CAD. ### Revised 24 June 2007 to change the callback behavior for the Spacing and Buffer distance ### fields in the control dialog to streamline entry of values. class GRE_GROUP group; class GRE_VIEW View; class XmForm form; # parent form for dialog window. class LINETOOL LineTool; # class for tool used to return a 3D point. class MDISPPOLYLINETOOL PolyLineTool; class POINT2D coordstart; class POINT2D coordend; class VECTOR vectorLine, vectorPoly, vectorBuffer, vectorPoint, vectorInitLine, temp; class SR_COORDREFSYS crs; # coordinate reference system class class GRE_LAYER_VECTOR vectorLineLayer; class GRE_LAYER_VECTOR vectorPolyLayer; class GRE_LAYER_VECTOR vectorBufferLayer; class GRE_LAYER_VECTOR vectorPointLayer; # class PROMPTNUM spacingdist, bufferdist; class GUI_DLG dlgwin; # class instance for the GUI dialog ## handles for dialog controls class GUI_CTRL_LABEL bufflabel; class GUI_CTRL_EDIT_NUMBER spacingEN, buffdistanceEN; class GUI_CTRL_PUSHBUTTON orientationBtn, boundaryBtn, loadboundaryBtn, computeBtn; class GUI_CTRL_PUSHBUTTON saveBtnV, saveBtnC, exportBtn, closeBtn; # Clear all elements in the vector proc ClearVector (var class VECTOR vectorvar) { numeric i; for i = 1 to NumVectorLines(vectorvar) VectorDeleteLine(vectorvar, 1); for i = 1 to NumVectorPoints(vectorvar) VectorDeletePoint(vectorvar, 1); } # Procedure called when spacing distance is entered. proc OnSpacing () { View.SetMessage("Enter distance for buffer zone around boundary."); bufflabel.SetEnabled(1); buffdistanceEN.SetEnabled(1); } # Procedure called when buffer distance is entered. proc OnBuffDistance () { boundaryBtn.SetEnabled(1); loadboundaryBtn.SetEnabled(1); View.SetMessage("Press the Boundary button to draw the field boundary or press Load Boundary to load an existing one."); } # Compute offset distance in degrees # A given distance in meters will be different degrees based on location # Thus, recompute distance for each line proc ComputeDistance (var numeric value, numeric dist, var class POLYLINE baseline) { numeric distoffset = 0; # compute arbitrary offset line if .01 degrees class POLYLINE offset; baseline.ComputeOffset(.01, offset); # determine meters equivalent to .01 degrees offset distoffset = ProjDistanceToMeters(crs, baseline.GetVertex(0).x, baseline.GetVertex(0).y, offset.GetVertex(0).x, offset.GetVertex(0).y); # determine degrees equivalent to offset meters value = .01 * (dist / distoffset); } # Procedure called when Compute Flight Lines button is pressed. proc ComputeLines() { clear(); class VECTOR tempLines, tempPoints; class POLYLINE baseline = GetVectorLine(vectorLine, 1); class POLYLINE original; class POLYLINE offsetline; class RECT extents; numeric spacingdist = spacingEN.GetValueNum(); numeric computedist, i, j, count; extents = vectorPolyLayer.Extents; VectorToBufferZoneExt(vectorPoly, vectorBuffer, "polygon", buffdistanceEN.GetValueNum(), "meters", "outside"); ClearVector(temp); ClearVector(vectorLine); ClearVector(vectorPoint); ClearVector(vectorInitLine); # Fix orientation line to extend outside polygon. # The orientation line needs only to specify directions of lines, but for using as a baseline it needs to intersect with the boundary - increase size of line for this purpose class POINT2D pt1, pt2; # Determine size to increase line based on polygon extents numeric maxdist = round(ProjDistanceToMeters(crs, extents.x1, extents.y1, extents.x2, extents.y2) / ProjDistanceToMeters(crs, baseline.GetVertex(0).x, baseline.GetVertex(0).y, baseline.GetVertex(1).x, baseline.GetVertex(1).y)); pt1.x = baseline.GetVertex(0).x + maxdist*(baseline.GetVertex(0).x - baseline.GetVertex(1).x); pt1.y = baseline.GetVertex(0).y + maxdist*(baseline.GetVertex(0).y - baseline.GetVertex(1).y); pt2.x = baseline.GetVertex(1).x + maxdist*(baseline.GetVertex(1).x - baseline.GetVertex(0).x); pt2.y = baseline.GetVertex(1).y + maxdist*(baseline.GetVertex(1).y - baseline.GetVertex(0).y); baseline.SetVertex(0, pt1); baseline.SetVertex(1, pt2); original = baseline; # Add baseline as first line VectorAddPolyLine(temp, baseline); # Start computing offset lines: # Do for positive offset direction # loop a number of times based on extents of polygon to ensure lines reach end of polygon View.SetMessage("Creating flight lines..."); for i = 1 to ( round(ProjDistanceToMeters(crs, extents.x1, extents.y1, extents.x2, extents.y2) / spacingdist) + 5) { # Convert the distance in meters to degrees ComputeDistance(computedist, spacingdist, baseline); # Offset the line baseline.ComputeOffset(computedist, offsetline); # Add the line VectorAddPolyLine(temp, offsetline); # Next line used is now the new line added baseline = offsetline; } # Reset baseline baseline = original; # Do for negative offset direction for i = 1 to ( round(ProjDistanceToMeters(crs, extents.x1, extents.y1, extents.x2, extents.y2) / spacingdist) + 5) { # Convert the distance in meters to degrees ComputeDistance(computedist, spacingdist, baseline); # Offset the line baseline.ComputeOffset(computedist*-1, offsetline); # Add the line VectorAddPolyLine(temp, offsetline); # Next line used is now the new line added baseline = offsetline; } CreateTempVector(tempLines); # Get Lines that intersect with buffer for exporting vectorInitLine = VectorExtract(vectorBuffer, temp, "PartInside"); # Clip the Lines to buffer View.SetMessage("Clipping lines to buffer..."); tempLines = VectorExtract(vectorBuffer, temp, "InsideClip"); # Add these lines to the vector for i = 1 to NumVectorLines(tempLines) { class POLYLINE line = GetVectorLine(tempLines, i); VectorAddPolyLine(vectorLine, line); VectorAddPoint(vectorPoint, line.GetVertex(0).x, line.GetVertex(0).y); VectorAddPoint(vectorPoint, line.GetVertex(1).x, line.GetVertex(1).y); } # Clip the Lines to the Polygon View.SetMessage("Clipping lines to polygon"); CreateTempVector(tempPoints) tempPoints = VectorExtract(vectorPoly, tempLines, "InsideClip"); for i = 1 to NumVectorLines(tempPoints) { class POLYLINE line = GetVectorLine(tempPoints, i); VectorAddPoint(vectorPoint, line.GetVertex(0).x, line.GetVertex(0).y); VectorAddPoint(vectorPoint, line.GetVertex(1).x, line.GetVertex(1).y); } CloseVector(tempLines); CloseVector(tempPoints); LayerDestroy(vectorPointLayer); LayerDestroy(vectorLineLayer); LayerDestroy(vectorPolyLayer); LayerDestroy(vectorBufferLayer); vectorPointLayer = GroupQuickAddVectorVar(group, vectorPoint); vectorLineLayer = GroupQuickAddVectorVar(group, vectorLine); vectorPolyLayer = GroupQuickAddVectorVar(group, vectorPoly); vectorBufferLayer = GroupQuickAddVectorVar(group, vectorBuffer); ViewRedraw(View); saveBtnV.SetEnabled(1); saveBtnC.SetEnabled(1); exportBtn.SetEnabled(1); } # Procedure called when the orientation line is drawn. proc OnLineToolSet () { class TRANSPARM ScreenToView = ViewGetTransViewToScreen(View, 1); class TRANSPARM ViewToMap = ViewGetTransMapToView(View, crs, 1); coordstart = TransPoint2D(TransPoint2D(LineTool.start, ScreenToView, 0), ViewToMap, 0); coordend = TransPoint2D(TransPoint2D(LineTool.end, ScreenToView, 0), ViewToMap, 0); # determine degrees for tooltip of orientation line numeric degrees = atand((coordend.x - coordstart.x) / (coordend.y - coordstart.y)) if (coordend.y < coordstart.y) degrees = 180 + degrees; else if (coordend.x < coordstart.x) degrees = 360 + degrees; class STRING displaystr = NumToStr(degrees) + " deg"; class TOOLTIP tooltip; tooltip = CreateToolTip(View.DrawingArea, displaystr); tooltip.Show(); } # Procedure called when user right-clicks to accept the orientation line. proc OnLineToolApply () { array numeric xpoints[5]; array numeric ypoints[5]; # clear everything but boundary polygon and buffer polygon ClearVector(vectorLine); ClearVector(vectorPoint); class TRANSPARM ScreenToView = ViewGetTransViewToScreen(View, 1); class TRANSPARM ViewToMap = ViewGetTransMapToView(View, crs, 1); coordstart = TransPoint2D(TransPoint2D(LineTool.start, ScreenToView, 0), ViewToMap, 0); coordend = TransPoint2D(TransPoint2D(LineTool.end, ScreenToView, 0), ViewToMap, 0); xpoints[1] = coordstart.x; xpoints[2] = coordend.x; ypoints[1] = coordstart.y; ypoints[2] = coordend.y; # add line VectorAddLine(vectorLine, 2, xpoints, ypoints); LineTool.HasPosition = 0; VectorAddPoint(vectorPoint, coordstart.x, coordstart.y); VectorAddPoint(vectorPoint, coordend.x, coordend.y); # add line to view LayerDestroy(vectorLineLayer); LayerDestroy(vectorPointLayer); vectorLineLayer = GroupQuickAddVectorVar(group, vectorLine); vectorPointLayer = GroupQuickAddVectorVar(group, vectorPoint); ViewRedraw(View); computeBtn.SetEnabled(1); View.SetMessage("Press the Compute Flight Lines button to create flight lines."); } # Procedure called when boundary polygon is drawn in the View. proc OnPolyLineToolSet() { View.SetMessage("Adjust the polygon if necessary, then right-click to accept."); } # Procedure called when user right-clicks to accept the field boundary polygon. proc OnPolyLineToolApply() { class POLYLINE polyline; polyline = PolyLineTool.GetPolygon(); polyline.AppendVertex(polyline.GetVertex(0)); class TRANSPARM ScreenToView = ViewGetTransViewToScreen(View, 1); class TRANSPARM ViewToMap = ViewGetTransMapToView(View, crs, 1); polyline.ConvertForward(ScreenToView); polyline.ConvertForward(ViewToMap); VectorAddPolyLine(vectorPoly, polyline); PolyLineTool.HasPosition = 0; LayerDestroy(vectorPolyLayer); vectorPolyLayer = GroupQuickAddVectorVar(group, vectorPoly); ViewRedraw(View); orientationBtn.SetEnabled(1); View.SetMessage("Press Orientation Line button to set direction of flight lines."); } # Procedure called when Create Boundary button on dialog is pressed; activates polyline tool. proc PolyLineActivate() { LineTool.Managed = 0; PolyLineTool.Managed = 1; PolyLineTool.HasPosition = 0; View.SetMessage("Draw polygon in view outlining the area boundary."); } # Procedure called when Orientation Line button on dialog is pressed; activates line tool. proc LineActivate() { PolyLineTool.Managed = 0; LineTool.Managed = 1; LineTool.HasPosition = 0; View.SetMessage("Drag a line in the view in the desired flight line direction; right-click to accept."); } # Procedure called when Load Boundary button on dialog is pressed to open a pre-existing # object for field boundary polygon. proc OnPolyLineLoad() { class RVC_OBJITEM objitem; DlgGetObject("Select Object", "Vector,CAD,Region", objitem, "ExistingOnly"); class TRANS2D_MAPGEN trans; trans.OutputCoordRefSys = group.ActiveLayer.MapRegion.CoordRefSys; numeric i = 0; switch (objitem.GetObjectType()) { case "VECTOR" : class RVC_VECTOR loadedVector; loadedVector.Open(objitem); class GEOREF georef = GetLastUsedGeorefObject(loadedVector); trans.InputCoordRefSys = georef.CoordRefSys; for i = 1 to NumVectorLines(loadedVector) { class POLYLINE line = GetVectorLine(loadedVector, i); line.ConvertForward(trans); VectorAddPolyLine(vectorPoly, line); } CloseVector(loadedVector); break; case "CAD" : class RVC_CAD loadedCAD; loadedCAD.Open(objitem); class GEOREF georef = GetLastUsedGeorefObject(loadedCAD); trans.InputCoordRefSys = georef.CoordRefSys; array numeric lineelemlist[100]; array numeric polyelemlist[100] array numeric xPoints[1000]; array numeric yPoints[1000]; numeric elem; numeric numPoints; numeric numLines = CADGetElementList(loadedCAD, 1, "Line", lineelemlist); numeric numPolys = CADGetElementList(loadedCAD, 1, "Polygon", polyelemlist); for elem = 1 to numLines { class POLYLINE line; numPoints = CADReadLine(loadedCAD, 1, lineelemlist[elem], xPoints, yPoints); for i = 1 to numPoints { class POINT2D point; point.x = xPoints[i]; point.y = yPoints[i]; line.AppendVertex(point); } line.ConvertForward(trans); VectorAddPolyLine(vectorPoly, line); } for elem = 1 to numPolys { class POLYLINE line; numPoints = CADReadPoly(loadedCAD, 1, polyelemlist[elem], xPoints, yPoints); for i = 1 to numPoints { class POINT2D point; point.x = xPoints[i]; point.y = yPoints[i]; line.AppendVertex(point); } line.ConvertForward(trans); VectorAddPolyLine(vectorPoly, line); } CloseCAD(loadedCAD); break; case "REGION": class RVC_VECTOR vectorRegion; CreateTempVector(vectorRegion); class REGION2D loadedRegion; ReadRegion(loadedRegion, objitem.GetFilePath(), objitem.GetObjectPath()); vectorRegion = ConvertRegionToVect(loadedRegion); class GEOREF georef = GetLastUsedGeorefObject(vectorRegion); trans.InputCoordRefSys = georef.CoordRefSys; for i = 1 to NumVectorLines(vectorRegion) { class POLYLINE line = GetVectorLine(vectorRegion, i); line.ConvertForward(trans); VectorAddPolyLine(vectorPoly, line); } CloseVector(vectorRegion); break; } LayerDestroy(vectorPolyLayer); vectorPolyLayer = GroupQuickAddVectorVar(group, vectorPoly); ViewRedraw(View); orientationBtn.SetEnabled(1); View.SetMessage("Press Orientation Line button to set direction of flight lines.") } # Procedure called when Export to GPX button on dialog is pressed. proc OnExport() { # Exporting points to GPX log class SR_COORDREFSYS latloncrs; # coordinate reference system class latloncrs.Assign("Geographic2D_WGS84_Deg"); # set crs for vector class REGION2D layerregion = group.ActiveLayer.MapRegion; layerregion.ConvertTo(latloncrs); class RECT extents = layerregion.Extents; class TRANSPARM MapToGeog; MapToGeog.InputCoordRefSys = group.ActiveLayer.MapRegion.CoordRefSys; MapToGeog.OutputCoordRefSys = latloncrs; class FILE fOut; fOut = GetOutputTextFile("c:/default.txt", "Select Text file", "gpx"); # write GPX header fwritestring(fOut, "\n"); fwritestring(fOut, "\n"); # determine bounding lat/lon numeric minlat, minlon, maxlat, maxlon; if (extents.x1 < extents.x2) { minlon = extents.x1; maxlon = extents.x2; } else { minlon = extents.x2; maxlon = extents.x1; } if (extents.y1 < extents.y2) { minlat = extents.y1; maxlat = extents.y2; } else { minlat = extents.y2; maxlat = extents.y1; } class STRING bounds$ = sprintf("\n", minlat, minlon, maxlat, maxlon); fwritestring(fOut, bounds$); numeric i, j, k; class STRINGLIST pointlist; class STRING point$, name$; class POINT2D pt; class GEOREF georef = GetGeorefObject(vectorInitLine); for i = 1 to NumVectorLines(vectorInitLine) { # step through each line for j = 1 to NumVectorPoints(vectorPoint) { # for all points pt.x = vectorPoint.point[j].Internal.x; pt.y = vectorPoint.point[j].Internal.y; # find points that lie on current line and add these points if (FindClosestLine(vectorInitLine, pt.x, pt.y, georef, 0.0001) == i) { point$ = sprintf("\n", MapToGeog.ConvertPoint2DFwd(pt).y, MapToGeog.ConvertPoint2DFwd(pt).x); pointlist.AddToEnd(point$); } } # output points in pointlist pointlist.Sort(); for k = 1 to (pointlist.GetNumItems()) { fwritestring(fOut, pointlist[k-1]); name$ = sprintf(" LINE%i #%i\n", i, k); fwritestring(fOut, name$); fwritestring(fOut, "\n"); } pointlist.Clear(); } fwritestring(fOut, "\n"); fclose(fOut); } # Procedure called when Save Vector button is pressed. proc OnSaveVector() { class RVC_VECTOR VectorOutPoints, VectorOutLines, VectorOutBuffer, VectorOutBoundary; class REGION2D layerregion = group.ActiveLayer.MapRegion; class RECT layerextents = layerregion.Extents; numeric i = 0; class STRINGLIST labels; labels.AddToEnd("Points Vector"); labels.AddToEnd("Lines Vector"); labels.AddToEnd("Buffer Vector"); labels.AddToEnd("Boundary Vector"); class RVC_OBJITEM objitemlist[]; class RVC_DESCRIPTOR descriptor; descriptor.SetName("Points"); objitemlist[1].SetDescriptor(descriptor); descriptor.SetName("Lines"); objitemlist[2].SetDescriptor(descriptor); descriptor.SetName("Buffer Polygon"); objitemlist[3].SetDescriptor(descriptor); descriptor.SetName("Boundary Polygon"); descriptor.SetDescription("Boundary Polygon"); objitemlist[4].SetDescriptor(descriptor); DlgGetObjectSet("Select Vector Object", "Vector", labels, objitemlist, "NewOrExisting"); # Points if (ObjectExists(objitemlist[1].GetFilePath(), objitemlist[1].GetDescriptor().GetShortName(), "Vector") == 0) # check if vector exists { CreateVector(VectorOutPoints, objitemlist[1].GetFilePath(), objitemlist[1].GetDescriptor().GetShortName(), objitemlist[1].GetDescriptor().GetDescription(), "VectorToolkit", "", layerextents); # create vector CreateImpliedGeoref(VectorOutPoints, crs); } else OpenVector(VectorOutPoints, objitemlist[1].GetFilePath(), objitemlist[1].GetDescriptor().GetShortName()); # open vector VectorCopyElements(vectorPoint, VectorOutPoints); # Lines if (ObjectExists(objitemlist[2].GetFilePath(), objitemlist[2].GetDescriptor().GetShortName(), "Vector") == 0) # check if vector exists { CreateVector(VectorOutLines, objitemlist[2].GetFilePath(), objitemlist[2].GetDescriptor().GetShortName(), objitemlist[2].GetDescriptor().GetDescription(), "VectorToolkit", "", layerextents); # create vector CreateImpliedGeoref(VectorOutLines, crs); } else OpenVector(VectorOutLines, objitemlist[2].GetFilePath(), objitemlist[2].GetDescriptor().GetShortName()); # open vector VectorCopyElements(vectorLine, VectorOutLines); # Polygons if (ObjectExists(objitemlist[3].GetFilePath(), objitemlist[3].GetDescriptor().GetShortName(), "Vector") == 0) # check if vector exists { CreateVector(VectorOutBuffer, objitemlist[3].GetFilePath(), objitemlist[3].GetDescriptor().GetShortName(), objitemlist[3].GetDescriptor().GetDescription(), "VectorToolkit", "", layerextents); # create vector CreateImpliedGeoref(VectorOutBuffer, crs); } else OpenVector(VectorOutBuffer, objitemlist[3].GetFilePath(), objitemlist[3].GetDescriptor().GetShortName()); # open vector for i = 1 to NumVectorLines(vectorBuffer) { class POLYLINE line = GetVectorLine(vectorBuffer, i); VectorAddPolyLine(VectorOutBuffer, line); } if (ObjectExists(objitemlist[4].GetFilePath(), objitemlist[4].GetDescriptor().GetShortName(), "Vector") == 0) # check if vector exists { CreateVector(VectorOutBoundary, objitemlist[4].GetFilePath(), objitemlist[4].GetDescriptor().GetShortName(), objitemlist[4].GetDescriptor().GetDescription(), "VectorToolkit", "", layerextents); # create vector CreateImpliedGeoref(VectorOutBoundary, crs); } else OpenVector(VectorOutBoundary, objitemlist[4].GetFilePath(), objitemlist[4].GetDescriptor().GetShortName()); # open vector for i = 1 to NumVectorLines(vectorPoly) { class POLYLINE line = GetVectorLine(vectorPoly, i); VectorAddPolyLine(VectorOutBoundary, line); } CloseVector(VectorOutPoints); CloseVector(VectorOutLines); CloseVector(VectorOutBuffer); CloseVector(VectorOutBoundary); } # Procedure called when Save CAD button is pressed. proc OnSaveCAD() { class RVC_CAD CADOutPoints, CADOutLines, CADOutBuffer, CADOutBoundary; numeric i = 0; class STRINGLIST labels; labels.AddToEnd("Points CAD"); labels.AddToEnd("Lines CAD"); labels.AddToEnd("Buffer CAD"); labels.AddToEnd("Boundary CAD"); class RVC_OBJITEM objitemlistCAD[]; class RVC_DESCRIPTOR descriptor; descriptor.SetName("Points"); objitemlistCAD[1].SetDescriptor(descriptor); descriptor.SetName("Lines"); objitemlistCAD[2].SetDescriptor(descriptor); descriptor.SetName("Buffer Polygon"); objitemlistCAD[3].SetDescriptor(descriptor); descriptor.SetName("Boundary Polygon"); descriptor.SetDescription("Boundary Polygon"); objitemlistCAD[4].SetDescriptor(descriptor); DlgGetObjectSet("Select CAD Object", "CAD", labels, objitemlistCAD, "NewOrExisting"); # Points if (ObjectExists(objitemlistCAD[1].GetFilePath(), objitemlistCAD[1].GetDescriptor().GetShortName(), "CAD") == 0) # check if vector exists { CreateCAD(CADOutPoints, objitemlistCAD[1].GetFilePath(), objitemlistCAD[1].GetDescriptor().GetShortName(), objitemlistCAD[1].GetDescriptor().GetDescription()); # create vector CreateImpliedGeoref(CADOutPoints, crs); CADCreateBlock(CADOutPoints, "Points", "PointsBlock"); } else OpenCAD(CADOutPoints, objitemlistCAD[1].GetFilePath(), objitemlistCAD[1].GetDescriptor().GetShortName()); # open vector numeric i = 1; numeric j = 1; for i = 1 to NumVectorPoints(vectorPoint) CADWritePoint(CADOutPoints, 1, vectorPoint.point[i].Internal.x, vectorPoint.point[i].Internal.y); # Lines if (ObjectExists(objitemlistCAD[2].GetFilePath(), objitemlistCAD[2].GetDescriptor().GetShortName(), "CAD") == 0) # check if vector exists { CreateCAD(CADOutLines, objitemlistCAD[2].GetFilePath(), objitemlistCAD[2].GetDescriptor().GetShortName(), objitemlistCAD[2].GetDescriptor().GetDescription()); # create vector CreateImpliedGeoref(CADOutLines, crs); CADCreateBlock(CADOutLines, "Lines", "LinesBlock"); } else OpenCAD(CADOutLines, objitemlistCAD[2].GetFilePath(), objitemlistCAD[2].GetDescriptor().GetShortName()); # open vector for i = 1 to NumVectorLines(vectorLine) { class POLYLINE vline = GetVectorLine(vectorLine, i); array xpoints[vline.GetNumPoints()]; array ypoints[vline.GetNumPoints()]; for j = 1 to vline.GetNumPoints() { xpoints[j] = vline.GetVertex(j-1).x; ypoints[j]= vline.GetVertex(j-1).y } CADWriteLine(CADOutLines, 1, vline.GetNumPoints(), xpoints, ypoints); } # Polygons if (ObjectExists(objitemlistCAD[3].GetFilePath(), objitemlistCAD[3].GetDescriptor().GetShortName(), "CAD") == 0) # check if vector exists { CreateCAD(CADOutBuffer, objitemlistCAD[3].GetFilePath(), objitemlistCAD[3].GetDescriptor().GetShortName(), objitemlistCAD[3].GetDescriptor().GetDescription()); # create vector CreateImpliedGeoref(CADOutBuffer, crs); CADCreateBlock(CADOutBuffer, "Polygons", "PolygonBlock"); } else OpenCAD(CADOutBuffer, objitemlistCAD[3].GetFilePath(), objitemlistCAD[3].GetDescriptor().GetShortName()); # open vector for i = 1 to NumVectorLines(vectorBuffer) { class POLYLINE vline = GetVectorLine(vectorBuffer, i); array xpoints[vline.GetNumPoints()]; array ypoints[vline.GetNumPoints()]; for j = 1 to vline.GetNumPoints() { xpoints[j] = vline.GetVertex(j-1).x; ypoints[j]= vline.GetVertex(j-1).y; } CADWriteLine(CADOutBuffer, 1, vline.GetNumPoints(), xpoints, ypoints); } if (ObjectExists(objitemlistCAD[4].GetFilePath(), objitemlistCAD[4].GetDescriptor().GetShortName(), "CAD") == 0) # check if vector exists { CreateCAD(CADOutBoundary, objitemlistCAD[4].GetFilePath(), objitemlistCAD[4].GetDescriptor().GetShortName(), objitemlistCAD[4].GetDescriptor().GetDescription()); # create vector CreateImpliedGeoref(CADOutBoundary, crs); CADCreateBlock(CADOutBoundary, "Polygons", "PolygonBlock"); } else OpenCAD(CADOutBoundary, objitemlistCAD[4].GetFilePath(), objitemlistCAD[4].GetDescriptor().GetShortName()); # open vector for i = 1 to NumVectorLines(vectorPoly) { class POLYLINE vline = GetVectorLine(vectorPoly, i); array xpoints[vline.GetNumPoints()]; array ypoints[vline.GetNumPoints()]; for j = 1 to vline.GetNumPoints() { xpoints[j] = vline.GetVertex(j-1).x; ypoints[j]= vline.GetVertex(j-1).y; } CADWriteLine(CADOutBoundary, 1, vline.GetNumPoints(), xpoints, ypoints); } CloseCAD(CADOutPoints); CloseCAD(CADOutLines); CloseCAD(CADOutBuffer); CloseCAD(CADOutBoundary); } # procedure called when Close button is pressed proc OnClose() { PolyLineTool.Managed = 0; LineTool.Managed = 0; CloseVector(vectorInitLine); CloseVector(temp); dlgwin.Close(1); View.SetDefaultTool(); } # function called when script is initialized. Use to set up custom dialog window. func OnInitialize () { if (Layout) { group = Layout.ActiveGroup; } else group = Group; local numeric errXML; local class XMLDOC dlgdoc; local class XMLNODE dlgnode; local string xml$ = ' '; ################################################################ ### parse XML text for main search dialog into memory; ### return an error code (number < 0) if there are syntax errors ################################################################ errXML = dlgdoc.Parse(xml$); if (errXML < 0) { PopupError(errXML); Exit(); } ########################################################## # get the dialog element from the parsed XML document and # show error message if the dialog element can't be found ########################################################## dlgnode = dlgdoc.GetElementByID("flightplan"); if (dlgnode == 0) { PopupMessage("Could not find dialog node in XML document"); Exit(); } ########################################################## # Set the XML dialog element as the source for the GUI_DLG # class instance we are using for the dialog window. ########################################################## dlgwin.SetXMLNode(dlgnode); dlgwin.CreateModeless(View.InfoForm); ### create as modeless dialog with ### View window status line as parent ################################################################################ ### get handles for dialog controls using their ID's in the dialog specification ################################################################################ spacingEN = dlgwin.GetCtrlByID("spacingEN"); bufflabel = dlgwin.GetCtrlByID("bufflabel"); buffdistanceEN = dlgwin.GetCtrlByID("buffdistanceEN"); orientationBtn = dlgwin.GetCtrlByID("orientationBtn"); boundaryBtn = dlgwin.GetCtrlByID("boundaryBtn"); loadboundaryBtn = dlgwin.GetCtrlByID("loadboundaryBtn"); computeBtn = dlgwin.GetCtrlByID("computeBtn"); saveBtnV = dlgwin.GetCtrlByID("saveBtnV"); saveBtnC = dlgwin.GetCtrlByID("saveBtnC"); exportBtn = dlgwin.GetCtrlByID("exportBtn"); closeBtn = dlgwin.GetCtrlByID("closeBtn"); ##### Setup Vectors crs = group.ActiveLayer.MapRegion.CoordRefSys; class REGION2D layerregion; layerregion = group.ActiveLayer.MapRegion; class RECT layerextents = layerregion.Extents; CreateTempVector(vectorPoint, "VectorToolkit", "", layerextents); CreateImpliedGeoref(vectorPoint, crs); CreateTempVector(vectorLine, "VectorToolkit", "", layerextents); CreateImpliedGeoref(vectorLine, crs); CreateTempVector(vectorInitLine, "VectorToolkit", "", layerextents); CreateImpliedGeoref(vectorInitLine, crs); CreateTempVector(vectorPoly, "", "", layerextents); CreateImpliedGeoref(vectorPoly, crs); CreateTempVector(vectorBuffer, "VectorToolkit", "", layerextents); CreateImpliedGeoref(vectorBuffer, crs); CreateTempVector(temp, "", "", layerextents); CreateImpliedGeoref(temp, crs); ##### # Add point tool to view. LineTool = ViewCreateLineTool(View,"Line Tool","add_line","TNTedit"); ToolAddCallback(LineTool.ApplyCallback,OnLineToolApply); ToolAddCallback(LineTool.PositionSetCallback,OnLineToolSet); LineTool.DialogPosition = "RightCenter"; PolyLineTool = ViewCreatePolyLineTool(View, "Region Tool", "add_polygon", "TNTedit"); ToolAddCallback(PolyLineTool.ApplyCallback, OnPolyLineToolApply); ToolAddCallback(PolyLineTool.PositionSetCallback, OnPolyLineToolSet); View.ShowDataTips = 0; } # procedure called to write initial prompt to View status line after tool is activated. proc OnMyTimerActivate ( class GUI_TIMER this ) { View.SetMessage("Enter flight line spacing in meters."); } class GUI_TIMER msgTimer; # function called whenever the tool is activated (initially and after switching tools). func OnActivate () { PolyLineTool.Managed = 0; LineTool.Managed = 0; dlgwin.Open(); spacingEN.SetFocus(); # View status line is automatically cleared when tool is acivated, so use # timer class to call procedure to set an initial user prompt there. msgTimer.SetOnTimer(OnMyTimerActivate); msgTimer.Activate(0.5, false); } # function called whenever the tool is deactivated (as by switching tools). func OnDeactivate () { PolyLineTool.Managed = 0; LineTool.Managed = 0; dlgwin.Close(0); # close dialog without notifying, so OnClose() callback is not } # called. Allows user to switch tools and come back to script dialog.