Example #1
0
        /// <summary>
        /// Exports the shapes from the inputSF which fall within the given polygon, saving to the resultSF provided.
        /// </summary>
        /// <returns>False if an error occurs, true otherwise.</returns>
        public static bool SelectPolygonsWithPolygon(ref MapWinGIS.Shapefile inputSF, ref MapWinGIS.Shape polygon, ref MapWinGIS.Shapefile resultSF, bool SkipMWShapeID)
        {
            MapWinUtility.Logger.Dbg("SelectPolygonsWithPolygon(inputSF: " + Macro.ParamName(inputSF) + ",\n" +
                                     "                          polygon: " + Macro.ParamName(polygon) + ",\n" +
                                     "                          resultSF: ref " + Macro.ParamName(resultSF) + ",\n" +
                                     "                          SkipMWShapeID: " + SkipMWShapeID.ToString() + ")");
            int numShapes = inputSF.NumShapes;
            int shpIndex  = 0;

            if (Globals.CopyFields(ref inputSF, ref resultSF) == false)
            {
                return(false);
            }

            for (int i = 0; i <= numShapes - 1; i++)
            {
                MapWinGIS.Shape currShape = new MapWinGIS.ShapeClass();
                currShape = inputSF.get_Shape(i);
                bool boundsIntersect = Globals.CheckBounds(ref currShape, ref polygon);
                if (boundsIntersect)
                {
                    //check that actual intersection occurs
                    MapWinGIS.Shape intersectShp = new MapWinGIS.ShapeClass();
                    intersectShp = SpatialOperations.Intersection(currShape, polygon);
                    if (intersectShp != null && intersectShp.numPoints > 0)
                    {
                        //shape has at least a small portion inside polygon
                        shpIndex = resultSF.NumShapes;
                        if (resultSF.EditInsertShape(currShape, ref shpIndex) == false)
                        {
                            gErrorMsg = "Problem inserting shape into result file: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                            Debug.WriteLine(gErrorMsg);
                            Error.SetErrorMsg(gErrorMsg);
                            MapWinUtility.Logger.Dbg(gErrorMsg);
                            return(false);
                        }
                        //add the table values
                        int numFields = resultSF.NumFields;
                        for (int j = 0; j <= numFields - 1; j++)
                        {
                            if (resultSF.EditCellValue(j, shpIndex, inputSF.get_CellValue(j, i)) == false)
                            {
                                gErrorMsg = "Problem inserting value into DBF table: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                                Debug.WriteLine(gErrorMsg);
                                Error.SetErrorMsg(gErrorMsg);
                                MapWinUtility.Logger.Dbg(gErrorMsg);
                                return(false);
                            }
                        } //end of looping through table
                    }     //end of checking for intersection
                }         //end of checking bounds
            }             //end of looping through shapes
            if (resultSF.NumShapes > 0)
            {
                if (resultSF.NumFields == 0 || !SkipMWShapeID)
                {
                    //add the ID field and values
                    if (Globals.DoInsertIDs(ref resultSF) == false)
                    {
                        return(false);
                    }
                }
                MapWinUtility.Logger.Dbg("Finished SelectPolygonsWithPolygon");
                return(true);
            }
            else
            {
                MapWinUtility.Logger.Dbg("Finished SelectPolygonsWithPolygon");
                return(false);
            }
        }
        /// <summary>
        /// Returns a shapefile of points from the input shapefile that fall within the polygon.
        /// </summary>
        /// <param name="pointSFPath">Full path to the point shapefile.</param>
        /// <param name="polygon">The polygon used for clipping the point shapefile.</param>
        /// <param name="resultSFPath">Full path to where the resulting point shapefile should be saved.</param>
        /// <param name="copyAttributes">True if copying attributes over</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ClipPointSFWithPolygon(ref string pointSFPath, ref MapWinGIS.Shape polygon, ref string resultSFPath, bool copyAttributes)
        {
            MapWinUtility.Logger.Dbg("ClipPointSFWithPolygon(pointSFPath: " + pointSFPath + ",\n" +
                                     "                       polygon: " + Macro.ParamName(polygon) + ",\n" +
                                     "                       resultSFPath: " + resultSFPath.ToString() + ",\n" +
                                     "                       copyAttributes: " + copyAttributes.ToString() + ")");

            MapWinGIS.Shapefile resultSF = new MapWinGIS.ShapefileClass();
            MapWinGIS.Shapefile pointSF  = new MapWinGIS.ShapefileClass();
            int    shpIndex = 0;          //all new shapes will be placed at the beginning of the shapefile
            string tmpName;

            if (pointSF.Open(pointSFPath, null) == false)
            {
                gErrorMsg = "Failure to open input shapefile: " + pointSF.get_ErrorMsg(pointSF.LastErrorCode);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
            MapWinGIS.ShpfileType sfType = pointSF.ShapefileType;

            //make sure we are dealing with a valid shapefile type
            if (sfType == MapWinGIS.ShpfileType.SHP_POINT || sfType == MapWinGIS.ShpfileType.SHP_POINTM || sfType == MapWinGIS.ShpfileType.SHP_POINTZ)
            {
                if (Globals.PrepareResultSF(ref resultSFPath, ref resultSF, sfType, copyAttributes) == false)
                {
                    return(false);
                }

                if (copyAttributes)
                {
                    MapWinGIS.Field tmpField, pointField;
                    for (int f = 0; f <= pointSF.NumFields - 1; f++)
                    {
                        tmpField   = new MapWinGIS.Field();
                        pointField = pointSF.get_Field(f);
                        tmpName    = pointField.Name;
                        if (tmpName.Contains("MWShapeID"))
                        {
                            tmpField.Name = "Last_" + tmpName;
                        }
                        else
                        {
                            tmpField.Name = tmpName;
                        }
                        tmpField.Width     = pointField.Width;
                        tmpField.Type      = pointField.Type;
                        tmpField.Precision = pointField.Precision;

                        tmpField.Key = pointField.Key;
                        if (!resultSF.EditInsertField(tmpField, ref f, null))
                        {
                            return(false);
                        }
                    }
                }

                int             numTargetPoints = pointSF.NumShapes;
                MapWinGIS.Point targetPoint     = new MapWinGIS.PointClass();
                //MapWinGIS.Utils utils = new MapWinGIS.UtilsClass();
                int numParts = polygon.NumParts;
                if (numParts == 0)
                {
                    numParts = 1;
                }
                Globals.Vertex[][] polyVertArray = new Globals.Vertex[numParts][];
                Globals.ConvertPolyToVertexArray(ref polygon, out polyVertArray);

                for (int i = 0; i <= numTargetPoints - 1; i++)
                {
                    targetPoint = pointSF.QuickPoint(i, 0);

                    if (Utils.PointInPoly(ref polyVertArray, ref targetPoint) == true)
                    {
                        resultSF.EditInsertShape(pointSF.get_Shape(i), ref shpIndex);
                        if (copyAttributes)
                        {
                            for (int f = 0; f <= pointSF.NumFields - 1; f++)
                            {
                                bool tmpbool = resultSF.EditCellValue(f, shpIndex, pointSF.get_CellValue(f, i));
                            }
                        }
                    }
                }

                MapWinGIS.Field ID = new MapWinGIS.FieldClass();
                ID.Name = "MWShapeID";
                ID.Type = MapWinGIS.FieldType.INTEGER_FIELD;
                int fieldIndex = 0;
                if (resultSF.EditInsertField(ID, ref fieldIndex, null) == false)
                {
                    gErrorMsg = "Problem inserting field into .dbf table: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                    Debug.WriteLine(gErrorMsg);
                    Error.SetErrorMsg(gErrorMsg);
                    MapWinUtility.Logger.Dbg(gErrorMsg);
                    return(false);
                }

                int numIDs = resultSF.NumShapes;
                for (int i = 0; i <= numIDs - 1; i++)
                {
                    if (resultSF.EditCellValue(fieldIndex, i, i) == false)
                    {
                        gErrorMsg = "Problem inserting value into .dbf table for shape " + i + ": " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                        Debug.WriteLine(gErrorMsg);
                        Error.SetErrorMsg(gErrorMsg);
                        MapWinUtility.Logger.Dbg(gErrorMsg);
                        return(false);
                    }
                }

                if (resultSF.StopEditingShapes(true, true, null) == false)
                {
                    gErrorMsg = "Problem with StopEditingShapes: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                    Debug.WriteLine(gErrorMsg);
                    Error.SetErrorMsg(gErrorMsg);
                    MapWinUtility.Logger.Dbg(gErrorMsg);
                    return(false);
                }

                resultSF.Close();
                pointSF.Close();
                MapWinUtility.Logger.Dbg("Finished ClipPointSFWithPolygon");
            }
            else
            {
                pointSF.Close();
                gErrorMsg = "Shapefile type is incorrect. Must be of type Point.";
                Debug.WriteLine(gErrorMsg);
                MapWinGeoProc.Error.SetErrorMsg(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
            return(true);
        }
Example #3
0
        /// <summary>
        /// Merges two lines (at matching end points) or two polygons
        /// (by dissolving the common border or by combining into a multi-part polygon)
        /// to make one result shape.
        /// This version requires that both shapes be located in the same shapefile.
        /// </summary>
        /// <param name="shapes">The shapefile containing the two shapes to be merged.</param>
        /// <param name="indexOne">The index of the first shape.</param>
        /// <param name="indexTwo">The index of the second shape.</param>
        /// <param name="resultShp">The result of merging the shapes at indexOne and indexTwo together.</param>
        /// <returns>True if the shapes were merged, false otherwise.</returns>
        public static bool MergeShapes(ref MapWinGIS.Shapefile shapes, int indexOne, int indexTwo, out MapWinGIS.Shape resultShp)
        {
            MapWinUtility.Logger.Dbg("MergeShapes(shapes: " + Macro.ParamName(shapes) + ",\n" +
                                     "            indexOne: " + indexOne.ToString() + ",\n" +
                                     "            indexTwo: " + indexTwo.ToString() + ",\n" +
                                     "            resultShp: resultShp)");
            Error.ClearErrorLog();
            MapWinGIS.ShpfileType sfType = shapes.ShapefileType;
            MapWinGIS.Shape       mShp   = new MapWinGIS.ShapeClass();
            mShp.Create(sfType);
            bool status = false;

            //having a point merge function is quite pointless...but, just in case it's needed!
            if (sfType == MapWinGIS.ShpfileType.SHP_POINT || sfType == MapWinGIS.ShpfileType.SHP_POLYGONM || sfType == MapWinGIS.ShpfileType.SHP_POLYGONZ)
            {
                MapWinGIS.Point pt1 = new MapWinGIS.PointClass();
                pt1 = shapes.QuickPoint(indexOne, 0);
                MapWinGIS.Point pt2 = new MapWinGIS.PointClass();
                pt2 = shapes.QuickPoint(indexTwo, 0);

                status = MergePoints(ref pt1, ref pt2, sfType, out mShp);

                while (Marshal.ReleaseComObject(pt1) != 0)
                {
                    ;
                }
                pt1 = null;
                while (Marshal.ReleaseComObject(pt2) != 0)
                {
                    ;
                }
                pt2 = null;

                resultShp = mShp;
                MapWinUtility.Logger.Dbg("Finished MergeShapes");
                return(status);
            }            //end of merging points

            //merge polygons
            else if (sfType == MapWinGIS.ShpfileType.SHP_POLYGON || sfType == MapWinGIS.ShpfileType.SHP_POLYGONM || sfType == MapWinGIS.ShpfileType.SHP_POLYGONZ)
            {
                MapWinGIS.Shape poly1 = new MapWinGIS.ShapeClass();
                poly1 = shapes.get_Shape(indexOne);
                MapWinGIS.Shape poly2 = new MapWinGIS.ShapeClass();
                poly2 = shapes.get_Shape(indexTwo);

                status = MergePolygons(ref poly1, ref poly2, sfType, out mShp);

                while (Marshal.ReleaseComObject(poly1) != 0)
                {
                    ;
                }
                poly1 = null;
                while (Marshal.ReleaseComObject(poly2) != 0)
                {
                    ;
                }
                poly2 = null;

                resultShp = mShp;
                MapWinUtility.Logger.Dbg("Finished MergeShapes");
                return(status);
            }            //end of merging polygons

            //Merge lines by joining them at common endpoints
            else if (sfType == MapWinGIS.ShpfileType.SHP_POLYLINE || sfType == MapWinGIS.ShpfileType.SHP_POLYLINEM || sfType == MapWinGIS.ShpfileType.SHP_POLYLINEZ)
            {
                MapWinGIS.Shape line1 = new MapWinGIS.ShapeClass();
                line1 = shapes.get_Shape(indexOne);
                MapWinGIS.Shape line2 = new MapWinGIS.ShapeClass();
                line2 = shapes.get_Shape(indexTwo);

                status = MergeLines(ref line1, ref line2, sfType, out mShp);
                if (line1 != null)
                {
                    while (Marshal.ReleaseComObject(line1) != 0)
                    {
                        ;
                    }
                }
                line1 = null;
                if (line2 != null)
                {
                    while (Marshal.ReleaseComObject(line2) != 0)
                    {
                        ;
                    }
                }
                line2 = null;

                resultShp = mShp;
                MapWinUtility.Logger.Dbg("Finished MergeShapes");
                return(status);
            }            //end of merging lines
            else
            {
                gErrorMsg = "Unknown shapefile type, aborting call to ShapeMerge.";
                Debug.WriteLine(gErrorMsg);
                Error.SetErrorMsg(gErrorMsg);
                resultShp = mShp;
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
        }
Example #4
0
        /// <summary>
        /// Removes portions of the lineSF that fall within the erase polygon
        /// </summary>
        /// <param name="lineSF">The shapefile of lines to be erased.</param>
        /// <param name="erasePoly">The polygon to be used for erasing portion of the line shapefile.</param>
        /// <param name="resultSF">The resulting line shapefile with portions removed.</param>
        /// <param name="CopyAttributes">Indicates whether to copy attributes</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool EraseLineSFWithPoly(ref MapWinGIS.Shapefile lineSF, ref MapWinGIS.Shape erasePoly, ref MapWinGIS.Shapefile resultSF, bool CopyAttributes)
        {
            MapWinUtility.Logger.Dbg("EraseLineSFWithPoly(lineSF: " + Macro.ParamName(lineSF) + ",\n" +
                                     "                    erasePoly: " + Macro.ParamName(erasePoly) + ",\n" +
                                     "                    resultSF: " + Macro.ParamName(resultSF) + ",\n" +
                                     "                    CopyAttributes: " + CopyAttributes.ToString() + ")");
            if (lineSF == null || erasePoly == null || resultSF == null)
            {
                gErrorMsg = "One of the input parameters is null.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }

            if (CopyAttributes)
            {
                string          tmpName;
                MapWinGIS.Field tmpField, currField;
                for (int f = 0; f <= lineSF.NumFields - 1; f++)
                {
                    tmpField      = new MapWinGIS.Field();
                    currField     = lineSF.get_Field(f);
                    tmpName       = currField.Name;
                    tmpField.Name = tmpName;

                    tmpField.Width     = currField.Width;
                    tmpField.Type      = currField.Type;
                    tmpField.Precision = currField.Precision;
                    tmpField.Key       = currField.Key;
                    resultSF.EditInsertField(tmpField, ref f, null);
                }
            }

            int shpIndex = 0;
            int numLines = lineSF.NumShapes;

            for (int i = 0; i <= numLines - 1; i++)
            {
                MapWinGIS.Shape currLine = new MapWinGIS.ShapeClass();
                currLine.Create(lineSF.ShapefileType);
                currLine = lineSF.get_Shape(i);

                MapWinGIS.Shape lineEnvelope = new MapWinGIS.ShapeClass();
                lineEnvelope.Create(MapWinGIS.ShpfileType.SHP_POLYGON);
                //create lineExtents' points out of the line extent points
                MapWinGIS.Point lTop, rTop, rBottom, lBottom;
                lTop      = new MapWinGIS.PointClass();
                lTop.x    = currLine.Extents.xMin;
                lTop.y    = currLine.Extents.yMax;
                rTop      = new MapWinGIS.PointClass();
                rTop.x    = currLine.Extents.xMax;
                rTop.y    = currLine.Extents.yMax;
                rBottom   = new MapWinGIS.PointClass();
                rBottom.x = currLine.Extents.xMax;
                rBottom.y = currLine.Extents.yMin;
                lBottom   = new MapWinGIS.PointClass();
                lBottom.x = currLine.Extents.xMin;
                lBottom.y = currLine.Extents.yMin;
                //now add the extent points to the new polygon shape: lineEnvelope
                int ptIndex = 0;
                lineEnvelope.InsertPoint(lTop, ref ptIndex);
                ptIndex++;
                lineEnvelope.InsertPoint(rTop, ref ptIndex);
                ptIndex++;
                lineEnvelope.InsertPoint(rBottom, ref ptIndex);
                ptIndex++;
                lineEnvelope.InsertPoint(lBottom, ref ptIndex);
                ptIndex++;
                lineEnvelope.InsertPoint(lTop, ref ptIndex);
                //remove COM points from memory
                while (Marshal.ReleaseComObject(lTop) != 0)
                {
                    ;
                }
                while (Marshal.ReleaseComObject(rTop) != 0)
                {
                    ;
                }
                while (Marshal.ReleaseComObject(rBottom) != 0)
                {
                    ;
                }
                while (Marshal.ReleaseComObject(lBottom) != 0)
                {
                    ;
                }

                //Check if line extents and polygon extents overlap
                if (Globals.CheckBounds(ref lineEnvelope, ref erasePoly))
                {
                    //make the envelope polygon slightly larger
                    MapWinGIS.Shape lgEnvelope = new MapWinGIS.ShapeClass();
                    lgEnvelope.Create(MapWinGIS.ShpfileType.SHP_POLYGON);
                    SpatialOperations.BufferPolygon(ref lineEnvelope, 0.5, Enumerations.Buffer_HoleTreatment.Ignore, Enumerations.Buffer_CapStyle.Pointed, out lgEnvelope);
                    //take the difference of the envelope polygon with the erase polygon.
                    MapWinGIS.Shape diff = new MapWinGIS.ShapeClass();
                    diff.Create(MapWinGIS.ShpfileType.SHP_POLYGON);
                    diff = SpatialOperations.Difference(lgEnvelope, erasePoly);
                    if (diff.numPoints > 0)
                    {
                        //the difference shape represents the line envelope
                        //minus the area of the erase polygon.
                        MapWinGIS.Shapefile inputLine = new MapWinGIS.ShapefileClass();
                        string tempPath = System.IO.Path.GetTempPath() + "tempInputLine.shp";
                        //CDM 8/4/2006 inputLine.CreateNew(tempPath, lineSF.ShapefileType);
                        Globals.PrepareResultSF(ref tempPath, ref inputLine, lineSF.ShapefileType);
                        shpIndex = 0;
                        inputLine.EditInsertShape(currLine, ref shpIndex);

                        int numParts = diff.NumParts;
                        if (numParts == 0)
                        {
                            numParts = 1;
                        }

                        if (numParts > 1)
                        {
                            //separate and test each part individually
                            MapWinGIS.Shape[] diffParts = new MapWinGIS.Shape[numParts];
                            Globals.SeparateParts(ref diff, out diffParts);
                            for (int j = 0; j <= numParts - 1; j++)
                            {
                                //don't check inside of holes
                                if (Globals.IsClockwise(ref diffParts[j]))
                                {
                                    MapWinGIS.Shapefile tempLineResult = new MapWinGIS.ShapefileClass();
                                    string tempLineFile = System.IO.Path.GetTempPath() + "tempLines.shp";
                                    DataManagement.DeleteShapefile(ref tempLineFile);
                                    //CDM 8/4/2006 tempLineResult.CreateNew(tempLineFile, lineSF.ShapefileType);
                                    Globals.PrepareResultSF(ref tempLineFile, ref tempLineResult, lineSF.ShapefileType);
                                    tempLineResult.StartEditingShapes(true, null);

                                    SpatialOperations.ClipShapesWithPolygon(ref inputLine, ref diffParts[j], out tempLineResult, false);

                                    int numResults = tempLineResult.NumShapes;
                                    if (numResults > 0)
                                    {
                                        //add results to the final result file.
                                        for (int k = 0; k <= numResults - 1; k++)
                                        {
                                            shpIndex = resultSF.NumShapes;
                                            resultSF.EditInsertShape(tempLineResult.get_Shape(k), ref shpIndex);
                                            if (CopyAttributes)
                                            {
                                                for (int f = 0; f <= lineSF.NumFields - 1; f++)
                                                {
                                                    bool tmpbool = resultSF.EditCellValue(f, shpIndex, lineSF.get_CellValue(f, i));
                                                }
                                            }
                                        }
                                    }                    //clipping successful
                                }                        //done checking islands
                            }                            //done looping through parts of the difference shape
                        }
                        else
                        {
                            MapWinGIS.Shapefile tempLineResult = new MapWinGIS.ShapefileClass();
                            string tempLineFile = System.IO.Path.GetTempPath() + "tempLines.shp";
                            DataManagement.DeleteShapefile(ref tempLineFile);
                            //CDM 8/4/2006 tempLineResult.CreateNew(tempLineFile, lineSF.ShapefileType);
                            Globals.PrepareResultSF(ref tempLineFile, ref tempLineResult, lineSF.ShapefileType);

                            tempLineResult.StartEditingShapes(true, null);

                            SpatialOperations.ClipShapesWithPolygon(ref inputLine, ref diff, out tempLineResult, false);

                            int numResults = tempLineResult.NumShapes;
                            if (numResults > 0)
                            {
                                //add results to the final result file.
                                for (int k = 0; k <= numResults - 1; k++)
                                {
                                    shpIndex = resultSF.NumShapes;
                                    resultSF.EditInsertShape(tempLineResult.get_Shape(k), ref shpIndex);
                                    if (CopyAttributes)
                                    {
                                        for (int f = 0; f <= lineSF.NumFields - 1; f++)
                                        {
                                            bool tmpbool = resultSF.EditCellValue(f, shpIndex, lineSF.get_CellValue(f, i));
                                        }
                                    }
                                }
                            }    //clipping successful
                        }
                    }            //difference operation successful
                }                //bounds overlapped
                else
                {
                    shpIndex = resultSF.NumShapes;
                    resultSF.EditInsertShape(currLine, ref shpIndex);
                    if (CopyAttributes)
                    {
                        for (int f = 0; f <= lineSF.NumFields - 1; f++)
                        {
                            bool tmpbool = resultSF.EditCellValue(f, shpIndex, lineSF.get_CellValue(f, i));
                        }
                    }
                }
            }            //end of looping through lines in the input shapefile
            MapWinUtility.Logger.Dbg("Finished EraseLineSFWithPoly");
            return(true);
        }
        /// <summary>
        /// Returns an in-memory shapefile of points from the input shapefile that fall within the polygon.
        /// </summary>
        /// <param name="pointSF">Full path to the point shapefile.</param>
        /// <param name="polygon">The polygon used for clipping the point shapefile.</param>
        /// <param name="result">Full path to where the resulting point shapefile should be saved.</param>
        /// <param name="copyAttributes">True if copying attributes over</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ClipPointSFWithPolygon(ref MapWinGIS.Shapefile pointSF, ref MapWinGIS.Shape polygon, out MapWinGIS.Shapefile result, bool copyAttributes)
        {
            MapWinUtility.Logger.Dbg("ClipPointSFWithPolygon(pointSF: " + Macro.ParamName(pointSF) + ",\n" +
                                     "                       polygon: " + Macro.ParamName(polygon) + ",\n" +
                                     "                       result: out, \n" +
                                     "                       copyAttributes: " + copyAttributes.ToString() + ",\n");
            MapWinGIS.Shapefile resultSF = new MapWinGIS.ShapefileClass();
            int shpIndex = 0;             //all new shapes will be placed at the beginning of the shapefile

            MapWinGIS.ShpfileType sfType = pointSF.ShapefileType;

            //make sure we are dealing with a valid shapefile type
            if (sfType == MapWinGIS.ShpfileType.SHP_POINT || sfType == MapWinGIS.ShpfileType.SHP_POINTM || sfType == MapWinGIS.ShpfileType.SHP_POINTZ)
            {
                string tempPath = System.IO.Path.GetTempPath() + "resultSF.shp";
                DataManagement.DeleteShapefile(ref tempPath);
                string tmpName;
                //create the result shapeFile if it does not already exist
                //if(resultSF.CreateNew(tempPath, sfType) == false)
                //{
                //    gErrorMsg = "Problem creating the result shapeFile: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                //    Debug.WriteLine(gErrorMsg);
                //    MapWinGeoProc.Error.SetErrorMsg(gErrorMsg);
                //    result = resultSF;
                //    return false;
                //}
                //CDM 8/4/2006 resultSF.CreateNew(resultSFPath, sfType);
                Globals.PrepareResultSF(ref tempPath, ref resultSF, sfType);

                if (copyAttributes)
                {
                    MapWinGIS.Field tmpField, pointField;
                    for (int f = 0; f <= pointSF.NumFields - 1; f++)
                    {
                        tmpField   = new MapWinGIS.Field();
                        pointField = pointSF.get_Field(f);
                        tmpName    = pointField.Name;
                        if (tmpName.Contains("MWShapeID"))
                        {
                            tmpField.Name = "Last_" + tmpName;
                        }
                        else
                        {
                            tmpField.Name = tmpName;
                        }
                        tmpField.Width     = pointField.Width;
                        tmpField.Type      = pointField.Type;
                        tmpField.Precision = pointField.Precision;
                        tmpField.Key       = pointField.Key;
                        resultSF.EditInsertField(tmpField, ref f, null);
                    }
                }

                int             numTargetPoints = pointSF.NumShapes;
                MapWinGIS.Point targetPoint     = new MapWinGIS.PointClass();
                //MapWinGIS.Utils utils = new MapWinGIS.UtilsClass();
                int numParts = polygon.NumParts;
                if (numParts == 0)
                {
                    numParts = 1;
                }
                Globals.Vertex[][] polyVertArray = new Globals.Vertex[numParts][];
                Globals.ConvertPolyToVertexArray(ref polygon, out polyVertArray);

                for (int i = 0; i <= numTargetPoints - 1; i++)
                {
                    targetPoint = pointSF.QuickPoint(i, 0);

                    if (Utils.PointInPoly(ref polyVertArray, ref targetPoint) == true)
                    {
                        resultSF.EditInsertShape(pointSF.get_Shape(i), ref shpIndex);
                        if (copyAttributes)
                        {
                            for (int f = 0; f <= pointSF.NumFields - 1; f++)
                            {
                                bool tmpbool = resultSF.EditCellValue(f, shpIndex, pointSF.get_CellValue(f, i));
                            }
                        }
                    }
                }
            }
            else
            {
                gErrorMsg = "The shapefile is of the wrong type. Should be of type Point.";
                Debug.WriteLine(gErrorMsg);
                MapWinGeoProc.Error.SetErrorMsg(gErrorMsg);
                result = resultSF;
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
            result = resultSF;
            MapWinUtility.Logger.Dbg("Finished ClipPointSFWithPolygon");
            return(true);
        }
Example #6
0
        /// <summary>
        /// Removes portions of the input polygon shapefile that are within the erase polygons.
        /// </summary>
        /// <param name="inputSF">The input polygon shapefile.</param>
        /// <param name="eraseSF">The erase polygon shapefile.</param>
        /// <param name="resultSF">The resulting shapefile, with portions removed.</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ErasePolySFWithPolySF(ref MapWinGIS.Shapefile inputSF, ref MapWinGIS.Shapefile eraseSF, ref MapWinGIS.Shapefile resultSF)
        {
            MapWinUtility.Logger.Dbg("ErasePolySFWithPolySF(inputSF: " + Macro.ParamName(inputSF) + ",\n" +
                                     "                      eraseSF: " + Macro.ParamName(eraseSF) + ",\n" +
                                     "                      resultSF: " + Macro.ParamName(resultSF) + ",\n");
            if (inputSF == null || eraseSF == null || resultSF == null)
            {
                gErrorMsg = "One of the input parameters is null.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
            int numInputs = inputSF.NumShapes;
            int shpIndex  = 0;

            //create the result shapefile out of the original inputSF
            for (int i = 0; i <= numInputs - 1; i++)
            {
                shpIndex = resultSF.NumShapes;
                resultSF.EditInsertShape(inputSF.get_Shape(i), ref shpIndex);
            }

            int numErase = eraseSF.NumShapes;

            for (int i = 0; i <= numErase - 1; i++)
            {
                MapWinGIS.Shape eraseShape = new MapWinGIS.ShapeClass();
                eraseShape = eraseSF.get_Shape(i);

                MapWinGIS.Shape resultShp = new MapWinGIS.ShapeClass();
                for (int j = 0; j <= numInputs - 1; j++)
                {
                    MapWinGIS.Shape currShape = new MapWinGIS.ShapeClass();
                    currShape = resultSF.get_Shape(j);

                    //if bounds intersect, then check if all polygon points are inside the currShape
                    if (Globals.CheckBounds(ref currShape, ref eraseShape))
                    {
                        int  numPts    = eraseShape.numPoints;
                        bool allInside = true;
                        int  numParts  = eraseShape.NumParts;
                        if (numParts == 0)
                        {
                            numParts = 1;
                        }
                        Globals.Vertex[][] vertArray = new Globals.Vertex[numParts][];
                        Globals.ConvertPolyToVertexArray(ref currShape, out vertArray);
                        for (int k = 0; k <= numPts - 1; k++)
                        {
                            double x = eraseShape.get_Point(k).x;
                            double y = eraseShape.get_Point(k).y;
                            if (Utils.PointInPoly(ref vertArray, x, y) == false)
                            {
                                allInside = false;
                                break;
                            }
                        }

                        if (allInside == true)
                        {
                            resultShp = new MapWinGIS.ShapeClass();
                            resultShp.Create(inputSF.ShapefileType);
                            //we want the symmetric difference of these two shapes
                            //which should leave us with a hole where the erase polygon was in the currShape
                            resultShp = SpatialOperations.SymmetricDifference(eraseShape, currShape);
                        }
                        else
                        {
                            //erase overlapping section and add result to the file.
                            MapWinGIS.Shape intersect = new MapWinGIS.ShapeClass();
                            intersect.ShapeType = inputSF.ShapefileType;
                            intersect           = SpatialOperations.Intersection(eraseShape, currShape);
                            if (intersect.numPoints > 0)
                            {
                                MapWinGIS.Shape diff = new MapWinGIS.ShapeClass();
                                diff.ShapeType = eraseShape.ShapeType;
                                diff           = SpatialOperations.Difference(currShape, eraseShape);
                                int numPoints = diff.numPoints;
                                if (numPoints > 0)
                                {
                                    resultShp = new MapWinGIS.ShapeClass();
                                    resultShp.Create(inputSF.ShapefileType);
                                    resultShp = diff;
                                }                        //difference operation successful
                            }                            //intersect operation successful
                            else
                            {
                                //no intersection, shapes do not collide
                                resultShp = currShape;
                            }
                        }                        //all points of erase polygon are not inside currShape

                        if (resultShp.numPoints > 0)
                        {
                            shpIndex = j;
                            resultSF.EditDeleteShape(shpIndex);
                            resultSF.EditInsertShape(resultShp, ref shpIndex);
                        }
                    }    //end of bounds intersect
                }        //end of looping through input polygons
            }            //end of looping through erase polygons
            MapWinUtility.Logger.Dbg("Finsihed ErasePolySFWithPolySF");
            return(true);
        }
Example #7
0
        /// <summary>
        /// Removes points from the point shapefile that lie within the polygon.
        /// </summary>
        /// <param name="pointSF">The point shapefile.</param>
        /// <param name="polygon">The erase polygon.</param>
        /// <param name="resultSF">The resulting file with points removed.</param>
        /// <param name="CopyAttributes">Indicates whether to copy attributes</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ErasePointSFWithPoly(ref MapWinGIS.Shapefile pointSF, ref MapWinGIS.Shape polygon, ref MapWinGIS.Shapefile resultSF, bool CopyAttributes)
        {
            MapWinUtility.Logger.Dbg("ErasePointSFWithPoly(pointSF: " + Macro.ParamName(pointSF) + "\n, " +
                                     "                     polygon: " + Macro.ParamName(polygon) + "\n, " +
                                     "                     resultSF: " + Macro.ParamName(resultSF) + "\n, " +
                                     "                     CopyAttributes: " + CopyAttributes.ToString() + ")");

            if (pointSF == null || polygon == null || resultSF == null)
            {
                gErrorMsg = "One of the input parameters is null.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }

            if (CopyAttributes)
            {
                string          tmpName;
                MapWinGIS.Field tmpField, currField;
                for (int f = 0; f <= pointSF.NumFields - 1; f++)
                {
                    tmpField      = new MapWinGIS.Field();
                    currField     = pointSF.get_Field(f);
                    tmpName       = currField.Name;
                    tmpField.Name = tmpName;

                    tmpField.Width     = currField.Width;
                    tmpField.Type      = currField.Type;
                    tmpField.Precision = currField.Precision;
                    tmpField.Key       = currField.Key;
                    resultSF.EditInsertField(tmpField, ref f, null);
                }
            }

            int numPts   = pointSF.NumShapes;
            int numParts = polygon.NumParts;

            if (numParts == 0)
            {
                numParts = 1;
            }
            int shpIndex = 0;

            Globals.Vertex[][] vertArray = new Globals.Vertex[numParts][];
            Globals.ConvertPolyToVertexArray(ref polygon, out vertArray);

            for (int i = 0; i <= numPts - 1; i++)
            {
                MapWinGIS.Point currPt = new MapWinGIS.PointClass();
                currPt = pointSF.QuickPoint(i, 0);
                double currX = currPt.x;
                double currY = currPt.y;
                if (Utils.PointInPoly(ref vertArray, currX, currY) == false)
                {
                    shpIndex = resultSF.NumShapes;
                    if (resultSF.EditInsertShape(pointSF.get_Shape(i), ref shpIndex) == false)
                    {
                        gErrorMsg = "ErasePointSF: problem inserting shape into result file: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                        Debug.WriteLine(gErrorMsg);
                        Error.SetErrorMsg(gErrorMsg);
                        MapWinUtility.Logger.Dbg(gErrorMsg);
                        return(false);
                    }
                    if (CopyAttributes)
                    {
                        for (int f = 0; f <= pointSF.NumFields - 1; f++)
                        {
                            bool tmpbool = resultSF.EditCellValue(f, shpIndex, pointSF.get_CellValue(f, i));
                        }
                    }
                }
            }
            MapWinUtility.Logger.Dbg("Finished ErasePointSFWithPoly");
            return(true);
        }
Example #8
0
        /// <summary>
        /// Erases the portions of the polygon shapefile that are within the polygon shape.
        /// </summary>
        /// <param name="polySF">The polygon shapefile.</param>
        /// <param name="polygon">The erase polygon.</param>
        /// <param name="resultSF">The resulting shapefile, with portions removed.</param>
        /// <param name="CopyAttributes">Indicates whether to copy attributes or not.</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ErasePolySFWithPoly(ref MapWinGIS.Shapefile polySF, ref MapWinGIS.Shape polygon, ref MapWinGIS.Shapefile resultSF, bool CopyAttributes)
        {
            MapWinUtility.Logger.Dbg("ErasePolySFWithPoly(polySF: " + Macro.ParamName(polySF) + ",\n" +
                                     "                    polygon: " + Macro.ParamName(polygon) + ",\n" +
                                     "                    resultSF: " + Macro.ParamName(resultSF) + "\n" +
                                     "                    CopyAttributes: " + CopyAttributes.ToString());
            if (polySF == null || polygon == null || resultSF == null)
            {
                gErrorMsg = "One of the input parameters is null.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }

            if (CopyAttributes)
            {
                string          tmpName;
                MapWinGIS.Field tmpField, currField;
                for (int f = 0; f <= polySF.NumFields - 1; f++)
                {
                    tmpField      = new MapWinGIS.Field();
                    currField     = polySF.get_Field(f);
                    tmpName       = currField.Name;
                    tmpField.Name = tmpName;

                    tmpField.Width     = currField.Width;
                    tmpField.Type      = currField.Type;
                    tmpField.Precision = currField.Precision;
                    tmpField.Key       = currField.Key;
                    resultSF.EditInsertField(tmpField, ref f, null);
                }
            }

            int numShapes = polySF.NumShapes;
            int shpIndex  = 0;

            for (int i = 0; i <= numShapes - 1; i++)
            {
                MapWinGIS.Shape currShape = new MapWinGIS.Shape();
                MapWinGIS.Shape resultShp = new MapWinGIS.Shape();

                currShape = polySF.get_Shape(i);

                //if bounds intersect, then check if all polygon points are inside the currShape
                if (Globals.CheckBounds(ref currShape, ref polygon))
                {
                    int  numPts    = polygon.numPoints;
                    bool allInside = true;
                    int  numParts  = currShape.NumParts;
                    if (numParts == 0)
                    {
                        numParts = 1;
                    }
                    Globals.Vertex[][] vertArray = new Globals.Vertex[numParts][];
                    Globals.ConvertPolyToVertexArray(ref currShape, out vertArray);
                    for (int j = 0; j <= numPts - 1; j++)
                    {
                        double x = polygon.get_Point(j).x;
                        double y = polygon.get_Point(j).y;
                        if (Utils.PointInPoly(ref vertArray, x, y) == false)
                        {
                            allInside = false;
                            break;
                        }
                    }

                    if (allInside == true)
                    {
                        resultShp = new MapWinGIS.ShapeClass();
                        resultShp.Create(polygon.ShapeType);
                        //we want the symmetric difference of these two shapes
                        //which should leave us with a hole where the erase polygon was in the currShape
                        resultShp = SpatialOperations.SymmetricDifference(polygon, currShape);
                    }
                    else
                    {
                        //erase overlapping section and add result to the file.
                        MapWinGIS.Shape intersect = new MapWinGIS.ShapeClass();
                        intersect.ShapeType = polygon.ShapeType;
                        intersect           = SpatialOperations.Intersection(polygon, currShape);
                        if (intersect.numPoints > 0)
                        {
                            //there might be parts in the difference result that do not belong,
                            //perform an intersection operation with currShape to remove them.
                            MapWinGIS.Shape diff = new MapWinGIS.ShapeClass();
                            diff.ShapeType = polygon.ShapeType;
                            //diff = SpatialOperations.SymmetricDifference(intersect, currShape);
                            diff = SpatialOperations.Difference(currShape, polygon);
                            int numPoints = diff.numPoints;
                            if (numPoints > 0)
                            {
                                resultShp = diff;
                            }                    //difference operation successful
                        }                        //intersect operation successful
                        else
                        {
                            //no intersection, shapes do not collide
                            resultShp = currShape;
                        }
                    }                    //all points of erase polygon are not inside currShape

                    if (resultShp.numPoints > 0)
                    {
                        shpIndex = resultSF.NumShapes;
                        if (resultSF.EditInsertShape(resultShp, ref shpIndex) == false)
                        {
                            gErrorMsg = "ErasePolySF: problem inserting shape into result file: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                            Debug.WriteLine(gErrorMsg);
                            Error.SetErrorMsg(gErrorMsg);
                            MapWinUtility.Logger.Dbg(gErrorMsg);
                            return(false);
                        }
                        if (CopyAttributes)
                        {
                            for (int f = 0; f <= polySF.NumFields - 1; f++)
                            {
                                bool tmpbool = resultSF.EditCellValue(f, shpIndex, polySF.get_CellValue(f, i));
                            }
                        }
                    }
                }                //end of if bounds intersect
                else
                {
                    //the erase object does not intersect with the current polygon,
                    //add current polygon to resultSF in unchanged form
                    shpIndex = resultSF.NumShapes;
                    if (resultSF.EditInsertShape(currShape, ref shpIndex) == false)
                    {
                        gErrorMsg = "ErasePolySF: problem inserting shape into result file: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                        Debug.WriteLine(gErrorMsg);
                        Error.SetErrorMsg(gErrorMsg);
                        MapWinUtility.Logger.Dbg(gErrorMsg);
                        return(false);
                    }
                    if (CopyAttributes)
                    {
                        for (int f = 0; f <= polySF.NumFields - 1; f++)
                        {
                            bool tmpbool = resultSF.EditCellValue(f, shpIndex, polySF.get_CellValue(f, i));
                        }
                    }
                }
            }            //end of looping through shapes in shapefile
            MapWinUtility.Logger.Dbg("Finished ErasePolySFWithPoly");
            return(true);
        }
        /// <summary>
        /// Returns all portions of the shapefile polygons that fall within the clipper polygon.
        /// </summary>
        /// <param name="polySFPath">The full path to the shapefile of polygons to be clipped.</param>
        /// <param name="polygon">The polygon used for clipping the shapefile.</param>
        /// <param name="resultSFPath">The full path to the result file for where the clipped polygons should be saved.</param>
        /// <param name="copyAttributes">True if copying attrs</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ClipPolygonSFWithPolygon(ref string polySFPath, ref MapWinGIS.Shape polygon, ref string resultSFPath, bool copyAttributes)
        {
            MapWinUtility.Logger.Dbg("ClipPolygonSFWithPolygon(polySFPath: " + polySFPath + ",\n " +
                                     "                         polygon: + " + Macro.ParamName(polygon) + ",\n" +
                                     "                         resultsSFPath: " + resultSFPath + ",\n" +
                                     "                         copyAttributes: " + copyAttributes + ",\n");

            MapWinGIS.Shapefile resultSF = new MapWinGIS.ShapefileClass();
            MapWinGIS.Shapefile polySF   = new MapWinGIS.ShapefileClass();
            polySF.Open(polySFPath, null);
            MapWinGIS.ShpfileType sfType = polySF.ShapefileType;
            int    shapeIndex            = 0;//insert new shapes at the beginning of the shapefile
            string tmpName;

            if (Globals.PrepareResultSF(ref resultSFPath, ref resultSF, sfType, copyAttributes) == false)
            {
                polySF.Close();
                return(false);
            }

            if (copyAttributes)
            {
                MapWinGIS.Field tmpField, currField;
                for (int f = 0; f <= polySF.NumFields - 1; f++)
                {
                    tmpField  = new MapWinGIS.Field();
                    currField = polySF.get_Field(f);
                    tmpName   = currField.Name;
                    if (tmpName.Contains("MWShapeID"))
                    {
                        tmpField.Name = "Last_" + tmpName;
                    }
                    else
                    {
                        tmpField.Name = tmpName;
                    }

                    tmpField.Width     = currField.Width;
                    tmpField.Type      = currField.Type;
                    tmpField.Precision = currField.Precision;
                    tmpField.Key       = currField.Key;
                    resultSF.EditInsertField(tmpField, ref f, null);
                }
            }

            if (sfType == MapWinGIS.ShpfileType.SHP_POLYGON || sfType == MapWinGIS.ShpfileType.SHP_POLYGONM || sfType == MapWinGIS.ShpfileType.SHP_POLYGONZ)
            {
                MapWinGIS.Shape   resultShape = new MapWinGIS.ShapeClass();
                MapWinGIS.Extents shpExtents  = new MapWinGIS.ExtentsClass();
                int  numShapes       = polySF.NumShapes;
                bool boundsIntersect = false;

                for (int i = 0; i <= numShapes - 1; i++)
                {
                    MapWinGIS.Shape currPoly = new MapWinGIS.ShapeClass();
                    currPoly = polySF.get_Shape(i);
                    //check to see if bounds intersect before sending shape to GPC clip function
                    boundsIntersect = Globals.CheckBounds(ref currPoly, ref polygon);

                    if (boundsIntersect == true)
                    {
                        //find the shape resulting from intersection
                        resultShape = SpatialOperations.Intersection(currPoly, polygon);
                        if (resultShape.numPoints != 0)
                        {
                            //save the new shape to the result shapefile
                            if (resultSF.EditInsertShape(resultShape, ref shapeIndex) == false)
                            {
                                gErrorMsg = "Problem inserting shape: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                                Debug.WriteLine(gErrorMsg);
                                Error.SetErrorMsg(gErrorMsg);
                                MapWinUtility.Logger.Dbg(gErrorMsg);
                                return(false);
                            }
                            if (copyAttributes)
                            {
                                for (int f = 0; f <= polySF.NumFields - 1; f++)
                                {
                                    bool tmpbool = resultSF.EditCellValue(f, shapeIndex, polySF.get_CellValue(f, i));
                                }
                            }
                        }
                    }
                }
            }
            if (copyAttributes)
            {
                MapWinGIS.Field ID = new MapWinGIS.FieldClass();
                ID.Name = "MWShapeID";
                ID.Type = MapWinGIS.FieldType.INTEGER_FIELD;
                int fieldIndex = 0;
                if (resultSF.EditInsertField(ID, ref fieldIndex, null) == false)
                {
                    gErrorMsg = "Problem inserting field into .dbf table: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                    Debug.WriteLine(gErrorMsg);
                    Error.SetErrorMsg(gErrorMsg);
                    MapWinUtility.Logger.Dbg(gErrorMsg);
                    return(false);
                }
            }
            int numIDs = resultSF.NumShapes;

            for (int i = 0; i <= numIDs - 1; i++)
            {
                if (resultSF.EditCellValue(0, i, i) == false)
                {
                    gErrorMsg = "Problem inserting value into .dbf table for shape " + i + ": " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                    Debug.WriteLine(gErrorMsg);
                    Error.SetErrorMsg(gErrorMsg);
                    MapWinUtility.Logger.Dbg(gErrorMsg);
                    return(false);
                }
            }
            if (resultSF.StopEditingShapes(true, true, null) == false)
            {
                gErrorMsg = "Problem with StopEditingShapes: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                Debug.WriteLine(gErrorMsg);
                Error.SetErrorMsg(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
            resultSF.Close();
            polySF.Close();
            MapWinUtility.Logger.Dbg("Finished ClipPolygonSFWithPolygon");
            return(true);
        }
        /// <summary>
        /// Returns the portions of the polygons in polySF that lie within polygon as a
        /// new shapefile of polygons: resultPolySF.
        /// </summary>
        /// <param name="polySF">The shapefile of polygons that are to be clipped.</param>
        /// <param name="polygon">The polygon used for clipping.</param>
        /// <param name="resultPolySF">The result shapefile for the resulting polygons to be saved (in-memory).</param>
        /// <param name="copyAttributes">True if copying attrs</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ClipPolygonSFWithPolygon(ref MapWinGIS.Shapefile polySF, ref MapWinGIS.Shape polygon, out MapWinGIS.Shapefile resultPolySF, bool copyAttributes)
        {
            MapWinUtility.Logger.Dbg("ClipPolygonSFWithPolygon(polySF: " + Macro.ParamName(polySF) + ",\n" +
                                     "                         polygon: " + Macro.ParamName(polygon) + ",\n" +
                                     "                         resultPolySF: out,\n" +
                                     "                         copyAttributes: " + copyAttributes.ToString() + "\n");

            MapWinGIS.Shapefile   resultSF = new MapWinGIS.ShapefileClass();
            MapWinGIS.ShpfileType sfType   = polySF.ShapefileType;
            string tempPath = System.IO.Path.GetTempPath() + "resultSF.shp";

            DataManagement.DeleteShapefile(ref tempPath);
            string tmpName;

            Globals.PrepareResultSF(ref tempPath, ref resultSF, sfType, copyAttributes);

            if (copyAttributes)
            {
                MapWinGIS.Field tmpField, currField;
                for (int f = 0; f <= polySF.NumFields - 1; f++)
                {
                    tmpField  = new MapWinGIS.Field();
                    currField = polySF.get_Field(f);
                    tmpName   = currField.Name;
                    if (tmpName.Contains("MWShapeID"))
                    {
                        tmpField.Name = "Last_" + tmpName;
                    }
                    else
                    {
                        tmpField.Name = tmpName;
                    }
                    tmpField.Width     = currField.Width;
                    tmpField.Type      = currField.Type;
                    tmpField.Precision = currField.Precision;
                    tmpField.Key       = currField.Key;
                    resultSF.EditInsertField(tmpField, ref f, null);
                }
            }

            int shapeIndex = 0;            //insert new shapes at the beginning of the shapefile

            if (polySF.NumShapes != 0 && polygon.numPoints != 0 && (sfType == MapWinGIS.ShpfileType.SHP_POLYGON || sfType == MapWinGIS.ShpfileType.SHP_POLYGONM || sfType == MapWinGIS.ShpfileType.SHP_POLYGONZ))
            {
                MapWinGIS.Shape resultShape     = new MapWinGIS.ShapeClass();
                int             numShapes       = polySF.NumShapes;
                bool            boundsIntersect = false;

                for (int i = 0; i <= numShapes - 1; i++)
                {
                    MapWinGIS.Shape currPoly = new MapWinGIS.ShapeClass();
                    currPoly = polySF.get_Shape(i);
                    //check to see if bounds intersect before sending shape to GPC clip function
                    boundsIntersect = Globals.CheckBounds(ref currPoly, ref polygon);

                    if (boundsIntersect == true)
                    {
                        //find the shape resulting intersection
                        resultShape = SpatialOperations.Intersection(polySF.get_Shape(i), polygon);
                        if (resultShape.numPoints != 0)
                        {
                            //save the new shape to the result shapefile
                            if (resultSF.EditInsertShape(resultShape, ref shapeIndex) == false)
                            {
                                gErrorMsg = "Problem inserting shape: " + resultSF.get_ErrorMsg(resultSF.LastErrorCode);
                                Debug.WriteLine(gErrorMsg);
                                MapWinGeoProc.Error.SetErrorMsg(gErrorMsg);
                                resultPolySF = resultSF;
                                return(false);
                            }
                            if (copyAttributes)
                            {
                                for (int f = 0; f <= polySF.NumFields - 1; f++)
                                {
                                    bool tmpbool = resultSF.EditCellValue(f, shapeIndex, polySF.get_CellValue(f, i));
                                }
                            }
                        }
                    }
                }
            }
            resultPolySF = resultSF;
            return(true);
        }
        /// <summary>
        /// Creates a new grid containing data from the input grid that
        /// falls within the polygon boundary.
        /// </summary>
        /// <param name="inputGF">Full path to the input grid file.</param>
        /// <param name="poly">The 2D polygon used for clipping the input grid.</param>
        /// <param name="resultGF">Full path to where the resulting grid will be saved.</param>
        /// <param name="clipToExtents">True if clipping to polygon extents rather than actual polygon shape.</param>
        /// <returns>True if clipping was successful, false if an error occurs.</returns>
        public static bool ClipGridWithPolygon(ref string inputGF, ref MapWinGIS.Shape poly, ref string resultGF, bool clipToExtents)
        {
            MapWinUtility.Logger.Dbg("ClipGridWithPolygon(inputGF: " + inputGF + ",\n" +
                                     "                    poly: " + Macro.ParamName(poly) + ",\n" +
                                     "                    resultGF: " + resultGF + ",\n" +
                                     "                    clipToExtents: " + clipToExtents.ToString());
            Error.ClearErrorLog();
            //			System.Diagnostics.PerformanceCounter ramCounter;
            //			ramCounter = new PerformanceCounter("Memory", "Available Bytes");
            //			float availableRAM = ramCounter.NextValue();
            bool inRAM = true;

            //open grid to get info and traverse through points
            MapWinGIS.Grid grid = new MapWinGIS.GridClass();

            //check memory availability
            //			availableRAM = ramCounter.NextValue();//amount of RAM in bytes
            //			Debug.WriteLine("available RAM: " + availableRAM.ToString() + " bytes");

            //			System.IO.FileInfo fileInfo = new FileInfo(inputGF);
            //			long fileSize = fileInfo.Length; //size of file in bytes
            //			Debug.WriteLine("file size: " + fileSize.ToString() + " bytes");
            //			if(fileSize*2 < availableRAM)
            //			{//go ahead and load grid into memory
            //				inRAM = true;
            //			}
            //			else
            //			{
            //				inRAM = false;
            //			}
            if (grid.Open(inputGF, MapWinGIS.GridDataType.UnknownDataType, inRAM, MapWinGIS.GridFileType.UseExtension, null) == false)
            {
                gErrorMsg = "Error occurred while trying to open grid: " + grid.get_ErrorMsg(grid.LastErrorCode);
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }

            int    numCols    = grid.Header.NumberCols;
            int    numRows    = grid.Header.NumberRows;
            double cellWidth  = grid.Header.dX;
            double cellHeight = grid.Header.dY;
            double xllCenter  = grid.Header.XllCenter;
            double yllCenter  = grid.Header.YllCenter;
            //now calculate the UNCOMPRESSED grid file size:
            long inputGFSize = numCols * numRows * 8;

            //find the grid extents
            double minX, maxX, minY, maxY;

            minX = xllCenter - (cellWidth / 2);
            maxX = xllCenter + (cellWidth * (numCols - 1)) + (cellWidth / 2);
            minY = yllCenter - (cellHeight / 2);
            maxY = yllCenter + (cellHeight * (numRows - 1)) + (cellHeight / 2);

            //see if grid and poly extents cross:
            double polyMinX = poly.Extents.xMin;
            double polyMaxX = poly.Extents.xMax;
            double polyMinY = poly.Extents.yMin;
            double polyMaxY = poly.Extents.yMax;

            bool boundsIntersect = Globals.CheckBounds(minX, maxX, minY, maxY, polyMinX, polyMaxX, polyMinY, polyMaxY);

            if (boundsIntersect == false)
            {
                grid.Close();
                gErrorMsg = "Polygon and Grid boundaries do not overlap.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }

            double newXll, newYll, firstXPt, firstYPt;
            int    newNumCols, newNumRows, firstCol, firstRow;

            //check if polygon extents are completely inside of grid extents
            if ((polyMinX >= minX && polyMinX <= maxX) && (polyMaxX >= minX && polyMaxX <= maxX) &&
                (polyMinY >= minY && polyMinY <= maxY) && (polyMaxY >= minY && polyMaxY <= maxY))
            {
                Debug.WriteLine("Poly extents are inside of grid extents.");
                minX = polyMinX;
                minY = polyMinY;
                maxX = polyMaxX;
                maxY = polyMaxY;

                //Find the new number of cols, rows, Xll and Yll values.
                int lastCol, lastRow;
                Globals.ProjToCell(minX, maxY, out firstCol, out firstRow, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
                Globals.ProjToCell(maxX, minY, out lastCol, out lastRow, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
                newNumCols = (lastCol - firstCol) + 1;
                newNumRows = (lastRow - firstRow) + 1;
                Debug.WriteLine("New numRows = " + newNumRows + " New numCols = " + newNumCols);
                Globals.CellToProj(firstCol, lastRow, out newXll, out newYll, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
                Globals.CellToProj(firstCol, firstRow, out firstXPt, out firstYPt, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
            }

            //check if grid extents are completely inside of polygon extents
            //note: there is really no purpose in this, as the new grid is the same
            //as the orgiginal grid....but we'll do it anyway.
            else if ((minX >= polyMinX && minX <= polyMaxX) && (maxX >= polyMinX && maxX <= polyMaxX) &&
                     (minY >= polyMinY && minY <= polyMaxY) && (maxY >= polyMinY && maxY <= polyMaxY))
            {
                Debug.WriteLine("Grid extents are inside of polygon extents.");
                //keep min and max values the same....no need to change them.
                newNumCols = numCols;
                newNumRows = numRows;
                newXll     = xllCenter;
                newYll     = yllCenter;
                firstCol   = 0;
                firstRow   = 0;
                Globals.CellToProj(0, 0, out firstXPt, out firstYPt, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
            }
            else             //part of polygon lies outside of the grid, find intersecting boundary shape
            {
                Debug.WriteLine("Grid extents and polygon extents overlap.");
                //create a new shape out of the grid extents
                MapWinGIS.Shape gridEnvelope = new MapWinGIS.ShapeClass();
                gridEnvelope.Create(MapWinGIS.ShpfileType.SHP_POLYGON);
                MapWinGIS.Point pt = new MapWinGIS.PointClass();
                pt.x = minX;
                pt.y = maxY;
                int ptIndex = 0;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = maxX;
                pt.y    = maxY;
                ptIndex = 1;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = maxX;
                pt.y    = minY;
                ptIndex = 2;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = minX;
                pt.y    = minY;
                ptIndex = 3;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = minX;
                pt.y    = maxY;
                ptIndex = 4;
                gridEnvelope.InsertPoint(pt, ref ptIndex);

                //create the final bounding envelope which is
                //the intersection of the polygon and grid envelope:
                MapWinGIS.Shape envelope = new MapWinGIS.ShapeClass();
                envelope.Create(MapWinGIS.ShpfileType.SHP_POLYGON);
                envelope = SpatialOperations.Intersection(gridEnvelope, poly);
                if (envelope.numPoints == 0)
                {
                    gErrorMsg = "Problem creating the bounding envelope. Aborting ClipGrid().";
                    Error.SetErrorMsg(gErrorMsg);
                    Debug.WriteLine(gErrorMsg);
                    MapWinUtility.Logger.Dbg(gErrorMsg);
                    return(false);
                }

                //calculate how many rows and columns will exist within the new grid
                //that is: how many rows/cols fit within the bounding envelope.
                minX = envelope.Extents.xMin;
                minY = envelope.Extents.yMin;
                maxX = envelope.Extents.xMax;
                maxY = envelope.Extents.yMax;

                newNumCols = (int)(((maxX - minX) / cellWidth) + 0.5);
                newNumRows = (int)(((maxY - minY) / cellHeight) + 0.5);
                newXll     = minX + (cellWidth / 2);
                newYll     = minY + (cellHeight / 2);
                firstXPt   = newXll;
                firstYPt   = newYll + (cellHeight * (newNumRows - 1));
                Globals.ProjToCell(firstXPt, firstYPt, out firstCol, out firstRow, xllCenter, yllCenter, cellWidth, cellHeight, numRows);

                //done using COM objects, release them
                while (Marshal.ReleaseComObject(pt) != 0)
                {
                    ;
                }
                pt = null;
                while (Marshal.ReleaseComObject(gridEnvelope) != 0)
                {
                    ;
                }
                gridEnvelope = null;
                while (Marshal.ReleaseComObject(envelope) != 0)
                {
                    ;
                }
                envelope = null;
            }

            // Chris M 12/13/2006 for BugZilla 377
            // Below code:
            // The grid header cannot be copied right across like that! The first line creates
            // a new grid header; the second line deletes the newly created grid header and
            // copies a reference to the original grid's header. Both grids then are using
            // the same header; and when the last lines set the XllCenter and YllCenter,
            // BOTH grids are updated with that information! A classic example of pointers gone wrong.
            //MapWinGIS.GridHeader resultHeader = new MapWinGIS.GridHeaderClass();
            //resultHeader = grid.Header;
            //resultHeader.NodataValue = grid.Header.NodataValue;
            //resultHeader.NumberCols = newNumCols;
            //resultHeader.NumberRows = newNumRows;
            //resultHeader.XllCenter = newXll;
            //resultHeader.YllCenter = newYll;
            // The right way to do it:
            MapWinGIS.GridHeader resultHeader = new MapWinGIS.GridHeaderClass();
            resultHeader.CopyFrom(grid.Header);
            // Not really needed due to CopyFrom: resultHeader.NodataValue = grid.Header.NodataValue;
            resultHeader.NumberCols = newNumCols;
            resultHeader.NumberRows = newNumRows;
            resultHeader.XllCenter  = newXll;
            resultHeader.YllCenter  = newYll;
            // Not really needed due to CopyFrom: resultHeader.dX = grid.Header.dX;
            // Not really needed due to CopyFrom: resultHeader.dY = grid.Header.dY;
            // Not really needed due to CopyFrom: resultHeader.Projection = grid.Header.Projection;

            //create the new grid object
            MapWinGIS.Grid resultGrid = new MapWinGIS.GridClass();
            DataManagement.DeleteGrid(ref resultGF);

            //check memory availability
            //			availableRAM = ramCounter.NextValue();//amount of RAM in bytes
            //			Debug.WriteLine("available RAM: " + availableRAM.ToString() + " bytes");

            long resultGFSize = newNumCols * newNumRows * 8;             //projected size of grid in bytes

            //			if(resultGFSize * 2 < availableRAM)
            //			{//go ahead and load grid into memory
            //				inRAM = true;
            //			}
            //			else
            //			{
            //				inRAM = false;
            //			}

            if (resultGrid.CreateNew(resultGF, resultHeader, grid.DataType, grid.Header.NodataValue, inRAM, MapWinGIS.GridFileType.UseExtension, null) == false)
            {
                gErrorMsg = "Problem creating the result grid: " + resultGrid.get_ErrorMsg(resultGrid.LastErrorCode);
                Debug.WriteLine(gErrorMsg);
                Error.SetErrorMsg(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
            //close the grids, we need to use the wrapper class now due to memory issues
            resultGrid.Save(resultGF, MapWinGIS.GridFileType.UseExtension, null);
            resultGrid.Close();
            while (Marshal.ReleaseComObject(resultGrid) != 0)
            {
                ;
            }
            resultGrid = null;
            grid.Close();
            while (Marshal.ReleaseComObject(grid) != 0)
            {
                ;
            }
            grid = null;

            //fill the result grid with values from the original grid
            try
            {
                Debug.WriteLine("newNumRows = " + newNumRows + " newNumCols = " + newNumCols);

                int rowClearCount = Globals.DetermineRowClearCount(newNumRows, newNumCols);

                Debug.WriteLine("Clearing COM resources every " + rowClearCount + " rows.");

                if (FillGrid(ref inputGF, ref resultGF, ref poly, newNumRows, newNumCols, rowClearCount, firstCol, firstRow, firstXPt, firstYPt, clipToExtents) == false)
                {
                    MapWinUtility.Logger.Dbg("Error running FillGrid\n");
                    return(false);
                }
            }            //end of try block
            catch (Exception e)
            {
                gErrorMsg = e.Message + e.ToString();
                Debug.WriteLine(gErrorMsg);
                Error.SetErrorMsg(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }


            //NOTE: The need for trimGrid has been removed from this function.
            //It will always return the smallest possible grid because we
            //build it based on the intersection boundary.

            DataManagement.CopyGridLegend(inputGF, resultGF);
            MapWinUtility.Logger.Dbg("Finished ClipGridWithPolygon");
            return(true);
        }
        /// <summary>
        /// This creates a new shapefile that has Z values and follows along the same line segments.
        /// The boundaries for grid cells are marked with vertices and the segment is given a Z value
        /// that corresponds to the grid elevation it intersects.
        /// </summary>
        /// <param name="mwElevGrid">A MapWinGIS Grid that contains the elevations.</param>
        /// <param name="mwPolyLine">A MapWinGIS Shapefile that shows the pathways of the cross sections in the X-Y direction.</param>
        /// <param name="OutFileName">A string containing the full path of the desired output shapefile.  The extension should be *.shp</param>
        /// <param name="CrossSectionType">Clarifies the type of output.  default = PolyLineWithZ</param>
        /// <param name="ICallBack">A MapWinGIS.ICallback for progress messages. [Optional]</param>
        /// <remarks>This function throws Argument or Application exceptions on errors, so it's recommended that coders enclose it in a try catch block.</remarks>
        public static void GetCrossSection(MapWinGIS.Grid mwElevGrid, MapWinGIS.Shapefile mwPolyLine, string OutFileName, CrossSectionTypes CrossSectionType, MapWinGIS.ICallback ICallBack)
        {
            MapWinUtility.Logger.Dbg("GetCrossSection(mwElevGrid: " + Macro.ParamName(mwElevGrid) + ",\n" +
                                     "                mwPolyLine: " + Macro.ParamName(mwPolyLine) + ",\n" +
                                     "                OutFileName: " + OutFileName + ",\n" +
                                     "                CrossSectionType: " + CrossSectionType.ToString() + ",\n" +
                                     "                ICallback)");
            bool   res;
            int    Prog = 0;
            int    OldProg = 0;
            double dS, dX, dY, XllCenter, YllCenter;
            int    NumRows, NumCols, ElevField, IDField;

            ElevField = 1;
            IDField   = 0;
            // Test to be sure that the elevation grid and shapefile are not null
            if (mwElevGrid == null)
            {
                MapWinUtility.Logger.Dbg("Argument Exception: Elevation grid mwElevGrid can't be null.");
                throw new ArgumentException("Elevation grid mwElevGrid can't be null.");
            }
            if (mwPolyLine == null)
            {
                MapWinUtility.Logger.Dbg("Argument Exception: The shapefile of input cross sections mwPolyLine can't be null.");
                throw new ArgumentException("The shapefile of input cross sections mwPolyLine can't be null.");
            }

            // Clear any existing shapefile output filenames that might cause problems if they exist.
            string fn;

            if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(OutFileName)) == false)
            {
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(OutFileName));
            }
            if (System.IO.File.Exists(OutFileName))
            {
                System.IO.File.Delete(OutFileName);
            }
            fn = System.IO.Path.ChangeExtension(OutFileName, ".dbf");
            if (System.IO.File.Exists(fn))
            {
                System.IO.File.Delete(fn);
            }
            fn = System.IO.Path.ChangeExtension(OutFileName, ".shx");
            if (System.IO.File.Exists(fn))
            {
                System.IO.File.Delete(fn);
            }
            fn = System.IO.Path.ChangeExtension(OutFileName, ".prj");
            if (System.IO.File.Exists(fn))
            {
                System.IO.File.Delete(fn);
            }
            // Since we are given the lower left coordinate, just make sure dX and dY are positive
            dX = Math.Abs(mwElevGrid.Header.dX);
            if (dX == 0)
            {
                throw new ApplicationException("mwElevGrid.Header.dX cannot be 0.");
            }
            dY = Math.Abs(mwElevGrid.Header.dY);
            if (dY == 0)
            {
                throw new ApplicationException("mwElevGrid.Header.dY cannot be 0.");
            }

            // Determine the stepping distance from the grid coordintes
            dS = dX / 2;
            if (dY < dX)
            {
                dS = dY / 2;
            }


            XllCenter = mwElevGrid.Header.XllCenter;
            YllCenter = mwElevGrid.Header.YllCenter;
            NumRows   = mwElevGrid.Header.NumberRows;
            NumCols   = mwElevGrid.Header.NumberCols;

            // Test for intersection between the entire shapefile and the grid
            double left, right, top, bottom;

            left   = XllCenter - dX / 2;
            right  = XllCenter + NumCols * dX - dX / 2;
            bottom = YllCenter - dY / 2;
            top    = YllCenter + NumRows * dY - dY / 2;
            MapWinGeoProc.Topology2D.Envelope gExt = new MapWinGeoProc.Topology2D.Envelope(left, right, bottom, top);
            MapWinGeoProc.Topology2D.Envelope pExt = new MapWinGeoProc.Topology2D.Envelope(mwPolyLine.Extents);
            if (gExt.Intersects(pExt) == false)
            {
                MapWinUtility.Logger.Dbg("Application Exception: The shapefile doesn't overlap the grid, so no cross sections were found.");
                throw new ApplicationException("The shapefile doesn't overlap the grid, so no cross sections were found.");
            }


            // Setup the output shapefile and the basic shape objects
            MapWinGIS.Shape     mwShape;
            MapWinGIS.Shapefile sfOut = new MapWinGIS.Shapefile();
            sfOut.Projection = mwPolyLine.Projection;

            if (CrossSectionType == CrossSectionTypes.PointsWithZAndElevField)
            {
                res = sfOut.CreateNew(OutFileName, MapWinGIS.ShpfileType.SHP_POINTZ);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                res = sfOut.StartEditingShapes(true, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                MapWinGIS.Field ID = new MapWinGIS.Field();
                ID.Name = "ID";
                ID.Type = MapWinGIS.FieldType.INTEGER_FIELD;
                res     = sfOut.EditInsertField(ID, ref IDField, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                MapWinGIS.Field Elev = new MapWinGIS.Field();
                Elev.Name = "Elevation";
                Elev.Type = MapWinGIS.FieldType.DOUBLE_FIELD;
                res       = sfOut.EditInsertField(Elev, ref ElevField, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
            }
            else
            {
                res = sfOut.CreateNew(OutFileName, MapWinGIS.ShpfileType.SHP_POLYLINEZ);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                res = sfOut.StartEditingShapes(true, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                MapWinGIS.Field ID = new MapWinGIS.Field();
                ID.Name = "ID";
                ID.Type = MapWinGIS.FieldType.INTEGER_FIELD;
                res     = sfOut.EditInsertField(ID, ref IDField, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
            }



            MapWinGIS.Shape mwOutShape;
            // Loop through all the shapes in the polyline shapefile
            int shIndx = -1;

            for (int shp = 0; shp < mwPolyLine.NumShapes; shp++)
            {
                mwShape = mwPolyLine.get_Shape(shp);

                // By turning multi-part polylines into multiple linestrings, we avoid the annoying multi-part logic
                MultiLineString MLS = GeometryFactory.CreateMultiLineString(mwShape);

                for (int ls = 0; ls < MLS.NumGeometries; ls++)
                {
                    LineString lsSource = MLS.GeometryN[ls] as LineString;
                    for (int pt = 0; pt < lsSource.Coordinates.Count - 1; pt++)
                    {
                        Coordinate start = lsSource.Coordinates[pt];
                        Coordinate end   = lsSource.Coordinates[pt + 1];

                        // Crop the parts of each segment that do not overlap with the grid.
                        if (start.X < left)
                        {
                            if (end.X < left)
                            {
                                // this segment is outside the grid
                                continue;
                            }
                            // crop this segment to only the portion on the grid
                            start.X = left;
                        }
                        if (end.X < left)
                        {
                            // crop this segment to only the portion on the grid
                            end.X = left;
                        }
                        if (start.X > right)
                        {
                            if (end.X > right)
                            {
                                // this segment is outside the grid
                                continue;
                            }
                            // crop to grid
                            start.X = right;
                        }
                        if (end.X > right)
                        {
                            // crop to the grid
                            end.X = right;
                        }


                        double length   = Math.Sqrt((end.X - start.X) * (end.X - start.X) + (end.Y - start.Y) * (end.Y - start.Y));
                        int    NumSteps = (int)Math.Floor(length / dS);
                        double segDx    = (end.X - start.X) / NumSteps;
                        double segDy    = (end.Y - start.Y) / NumSteps;
                        mwOutShape = new MapWinGIS.Shape();
                        if (CrossSectionType == CrossSectionTypes.PolyLineWithZ)
                        {
                            mwOutShape.Create(MapWinGIS.ShpfileType.SHP_POLYLINEZ);
                        }

                        // step by dS and get the grid value at that point at each step
                        int p = 0;
                        for (int I = 0; I < NumSteps; I++)
                        {
                            int    row, col;
                            object Elev;
                            double X = start.X + segDx * I;
                            double Y = start.Y + segDy * I;
                            mwElevGrid.ProjToCell(X, Y, out col, out row);
                            Elev = mwElevGrid.get_Value(col, row);
                            MapWinGIS.Point pnt = new MapWinGIS.Point();
                            pnt.x = X;
                            pnt.y = Y;
                            pnt.Z = (double)Elev;
                            if (CrossSectionType == CrossSectionTypes.PointsWithZAndElevField)
                            {
                                p          = 0;
                                mwOutShape = new MapWinGIS.Shape();
                                mwOutShape.Create(MapWinGIS.ShpfileType.SHP_POINTZ);
                                res = mwOutShape.InsertPoint(pnt, ref p);
                                if (res == false)
                                {
                                    throw new ApplicationException(mwOutShape.get_ErrorMsg(mwOutShape.LastErrorCode));
                                }
                                res = sfOut.EditInsertShape(mwOutShape, ref shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                res = sfOut.EditCellValue(IDField, shIndx, shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                res = sfOut.EditCellValue(ElevField, shIndx, Elev);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                shIndx++;
                            }
                            else
                            {
                                res = mwOutShape.InsertPoint(pnt, ref p);
                                p++;
                                if (res == false)
                                {
                                    throw new ApplicationException(mwOutShape.get_ErrorMsg(mwOutShape.LastErrorCode));
                                }
                            }
                        }
                        if (CrossSectionType == CrossSectionTypes.PolyLineWithZ)
                        {
                            if (mwOutShape.numPoints > 0)
                            {
                                res = sfOut.EditInsertShape(mwOutShape, ref shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                res = sfOut.EditCellValue(IDField, shIndx, shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                shIndx++;
                            }
                        }
                    }
                }
                Prog = Convert.ToInt32(shp * 100 / mwPolyLine.NumShapes);
                if (Prog > OldProg)
                {
                    MapWinUtility.Logger.Progress("Evaluating Cross Section..." + Prog.ToString() + "% Complete.", Prog, OldProg);
                    OldProg = Prog;
                }
            }
            res = sfOut.StopEditingShapes(true, true, ICallBack);
            if (res != true)
            {
                MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
            }
        }