### FlightPlan74.sml
### SML Tool Script
### Requires TNT version 2008:74 or later.
### 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 GUI_GADGET_SEGMENT LineTool; # class for a 2-point line tool
class GUI_GADGET_POLYLINE PolyLineTool; # class for polyline/polygon tool.
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;
class GUI_CTRL_EDIT_STRING promptFld;
# 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 ()
{
promptFld.SetValueStr("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);
promptFld.SetValueStr("Create or load a boundary for the flight area.");
}
# 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
promptFld.SetValueStr("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
promptFld.SetValueStr("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
promptFld.SetValueStr("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);
promptFld.SetValueStr("Flight lines completed.");
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();
promptFld.SetValueStr("Reset line or right-click to accept.");
}
# 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);
promptFld.SetValueStr("Press Compute Flight Lines button to create flight lines.");
}
# Procedure called when boundary polygon is drawn in the View.
proc OnPolyLineToolSet()
{
promptFld.SetValueStr("Adjust polygon or 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);
PolyLineTool.Managed = 0;
orientationBtn.SetEnabled(1);
promptFld.SetValueStr("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;
promptFld.SetValueStr("Draw polygon in view outlining area boundary.");
}
# Procedure called when Orientation Line button on dialog is pressed; activates line tool.
proc LineActivate()
{
LineTool.Managed = 1;
LineTool.HasPosition = 0;
promptFld.SetValueStr("Drag line in view in desired flight line direction.");
}
# 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);
promptFld.SetValueStr("Press Orientation Line button to set flight line direction.")
}
# 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, "<?xml version=\"1.0\"?>\n");
fwritestring(fOut, "<gpx\n");
fwritestring(fOut, " version=\"1.0\"\n");
fwritestring(fOut, " creator=\"MicroImages - https://www.microimages.com\"\n");
fwritestring(fOut, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
fwritestring(fOut, " xmlns=\"http://www.topografix.com/GPX/1/0\"\n");
fwritestring(fOut, " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\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("<bounds minlat=\"%.6f\" minlon=\"%.6f\" maxlat=\"%.6f\" maxlon=\"%.6f\"/>\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("<wpt lat=\"%.6f\" lon=\"%.6f\">\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(" <name>LINE%i #%i</name>\n", i, k);
fwritestring(fOut, name$);
fwritestring(fOut, "</wpt>\n");
}
pointlist.Clear();
}
fwritestring(fOut, "</gpx>\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);
} # end OnSaveVector()
# 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);
} # end OnSaveCAD()
# 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$ = '<?xml version="1.0"?>
<root>
<dialog id= "flightplan" Title="Flight Plan" Buttons="">
<pane Orientation="horizontal">
<label>Line Spacing (m)</label>
<editnumber id="spacingEN" MinVal="0" HorizResize="expand" Default="0" Precision="1" OnUserEdit="OnSpacing()" />
<label id="bufflabel" Enabled="false">Buffer Distance (m)</label>
<editnumber id="buffdistanceEN" MinVal="0" HorizResize="expand" Enabled="false" Default="0" Precision="1" OnChanged="OnBuffDistance()"/>
</pane>
<pane Orientation="horizontal">
<pushbutton id="boundaryBtn" Name="Create Boundary" WidthGroup="1" HorizResize="expand" Enabled="false" OnPressed="PolyLineActivate()"/>
<pushbutton id="loadboundaryBtn" Name="Load Boundary" WidthGroup="2" HorizResize="expand" Enabled="false" OnPressed="OnPolyLineLoad()"/>
</pane>
<pane Orientation="horizontal">
<pushbutton id="orientationBtn" Name="Orientation Line" WidthGroup="1" HorizResize="expand" Enabled="false" OnPressed="LineActivate()"/>
<pushbutton id="computeBtn" Name="Compute Flight Lines" WidthGroup="2" HorizResize="expand" Enabled="false" OnPressed="ComputeLines()"/>
</pane>
<pane Orientation="horizontal">
<pushbutton id="saveBtnV" Name="Save Vector" WidthGroup="1" HorizResize="expand" Enabled="false" OnPressed="OnSaveVector()"/>
<pushbutton id="saveBtnC" Name="Save CAD" WidthGroup="2" HorizResize="expand" Enabled="false" OnPressed="OnSaveCAD()"/>
</pane>
<pane Orientation="horizontal">
<pushbutton id="exportBtn" Name="Export to GPX" WidthGroup="1" HorizResize="expand" Enabled="false" OnPressed="OnExport()"/>
<pushbutton id="closeBtn" Name="Close" WidthGroup="2" HorizResize="expand" OnPressed="OnClose()"/>
</pane>
<edittext id="promptFld" HorizResize="expand" ReadOnly="true" />
</dialog>
</root>';
################################################################
### 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(); ### create as modeless dialog
################################################################################
### 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");
promptFld = dlgwin.GetCtrlByID("promptFld");
##### 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");
LineTool = ViewCreateLineGadget(View);
ToolAddCallback(LineTool.ApplyCallback,OnLineToolApply);
ToolAddCallback(LineTool.PositionSetCallback,OnLineToolSet);
LineTool.DialogPosition = "RightCenter";
#PolyLineTool = ViewCreatePolyLineTool(View, "Region Tool", "add_polygon", "TNTedit");
PolyLineTool = ViewCreatePolyLineGadget(View);
ToolAddCallback(PolyLineTool.ApplyCallback, OnPolyLineToolApply);
ToolAddCallback(PolyLineTool.PositionSetCallback, OnPolyLineToolSet);
View.ShowDataTips = 0;
} # end of OnInitialize()
# function called whenever the tool is activated (initially and after switching tools).
func OnActivate ()
{
PolyLineTool.Managed = 0;
LineTool.Managed = 0;
dlgwin.Open();
spacingEN.SetFocus();
promptFld.SetValueStr("Enter flight line spacing in meters.");
}
# 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.