private static void CachePoints(string InPointsPath, int InValueFieldIndex, out KDTreeDLL.KDTree PointsTree, out double[][] Points, out double[] PointVals, out string Projection, out string ProjectionUnits, out MapWinGIS.Extents PointsExtents, MapWinGIS.ICallback callback)
        {
            int newperc = 0, oldperc = 0;

            MapWinGIS.Shapefile pointsf = new MapWinGIS.Shapefile();
            pointsf.Open(InPointsPath, null);

            PointsExtents = pointsf.Extents;
            Projection    = pointsf.Projection;
            if (Projection != null)
            {
                ProjectionUnits = Projection.Substring(Projection.IndexOf("units=") + 6);
                ProjectionUnits = ProjectionUnits.Substring(0, ProjectionUnits.IndexOf("+")).Trim();
            }
            else
            {
                double tmpX   = pointsf.Extents.xMax;
                string tmpstr = Math.Floor(tmpX).ToString();

                if (tmpstr.Length > 4)
                {
                    ProjectionUnits = "";
                }
                else
                {
                    ProjectionUnits = "lat/long";
                }
            }

            PointsTree = new KDTreeDLL.KDTree(2);

            MapWinGIS.Point currpt;
            int             ns          = pointsf.NumShapes;

            Points    = new double[ns][];
            PointVals = new double[ns];
            int duplicates = 0;

            for (int i = 0; i < ns; i++)
            {
                Points[i] = new double[2];

                newperc = Convert.ToInt32((Convert.ToDouble(i) / Convert.ToDouble(ns)) * 100);
                if ((newperc > oldperc))
                {
                    if (callback != null)
                    {
                        callback.Progress("Status", newperc, "IDW Caching " + i.ToString());
                    }
                    oldperc = newperc;
                }

                currpt       = pointsf.get_Shape(i).get_Point(0);
                Points[i][0] = currpt.x;
                Points[i][1] = currpt.y;
                PointVals[i] = double.Parse(pointsf.get_CellValue(InValueFieldIndex, i).ToString());

                try
                {
                    if (PointsTree.search(Points[i]) == null)
                    {
                        PointsTree.insert(Points[i], i);
                    }
                }
                catch (KDTreeDLL.KeyDuplicateException)
                {
                    duplicates++;
                }
            }
            pointsf.Close();
        }
Example #2
0
        private void MapResult_Load(object sender, EventArgs e)
        {
            idleTimer = DateTime.Now;
            timer1.Start();
            timer1.Interval = 5000;

            int intHandler1;

            MapWinGIS.Shapefile shapefile1 = new MapWinGIS.Shapefile();
            shapefile1.Open("..\\..\\shapefiles\\Form.shp");
            intHandler1 = axMap1.AddLayer(shapefile1, true);

            int intHandler2;

            MapWinGIS.Shapefile shapefile2 = new MapWinGIS.Shapefile();
            shapefile2.Open("..\\..\\shapefiles\\gang.shp");
            intHandler2 = axMap1.AddLayer(shapefile2, true);

            int intHandler7;

            MapWinGIS.Shapefile shapefile7 = new MapWinGIS.Shapefile();
            shapefile7.Open("..\\..\\shapefiles\\Stairs.shp");
            intHandler7 = axMap1.AddLayer(shapefile7, true);

            int intHandler6;

            MapWinGIS.Shapefile shapefile6 = new MapWinGIS.Shapefile();
            shapefile6.Open("..\\..\\shapefiles\\Shape .shp");
            string myLabel;
            //define two double variables to use as a coordinates for label position
            double x, y;

            for (int i = 0; i < shapefile6.NumShapes - 1; i++)
            {
                //assign the value of the cells of the field number zero to the label
                myLabel = System.Convert.ToString(
                    shapefile6.get_CellValue(1, i));
                //Calculate the x position for the label
                x = shapefile6.get_Shape(i).Extents.xMin +
                    (shapefile6.get_Shape(i).Extents.xMax -
                     shapefile6.get_Shape(i).Extents.xMin) / 2;
                //Calculate the y position for the label
                y = shapefile6.get_Shape(i).Extents.yMin +
                    (shapefile6.get_Shape(i).Extents.yMax -
                     shapefile6.get_Shape(i).Extents.yMin) / 2;

                shapefile6.Labels.AddLabel(myLabel, x, y, 0, -1);
            }
            intHandler6 = axMap1.AddLayer(shapefile6, true);

            int intHandler3;

            MapWinGIS.Shapefile shapefile3 = new MapWinGIS.Shapefile();
            shapefile3.Open("..\\..\\shapefiles\\Indgang.shp");
            intHandler3 = axMap1.AddLayer(shapefile3, true);

            int intHandler8;

            MapWinGIS.Shapefile shapefile8 = new MapWinGIS.Shapefile();
            shapefile8.Open("..\\..\\shapefiles\\WC.shp");
            intHandler8 = axMap1.AddLayer(shapefile8, true);

            int intHandler9;

            MapWinGIS.Shapefile shapefile4 = new MapWinGIS.Shapefile();
            shapefile4.Open("..\\..\\shapefiles\\navlines.shp");
            shapefile4.DefaultDrawingOptions.LineWidth = 4;
            intHandler9 = axMap1.AddLayer(shapefile4, true);

            int intHandler5;

            MapWinGIS.Shapefile shapefile5 = new MapWinGIS.Shapefile();
            shapefile5.Open("..\\..\\shapefiles\\navnodes.shp");
            intHandler5 = axMap1.AddLayer(shapefile5, false);

            //Calls the Dijkstra algorithm
            Dijkstra.dijkstra(SetLocationMap.Loc, Destinations.Dest);

            //Makes all lines initially hidden.
            for (int i = 0; i < shapefile4.NumShapes; i++)
            {
                shapefile4.set_ShapeIsHidden(i, true);
            }

            routelength = 0;

            foreach (int line in Dijkstra.Route.eroute)
            {
                //Sets included lines from  the route to be shown rather than hidden.
                shapefile4.set_ShapeIsHidden(line, false);
                //Sums up the lengths of included lines.
                routelength += Convert.ToDouble(shapefile4.get_CellValue(3, line));
            }
            //Sets the label to show travel time. It is the sum of line lengths (so total route length) divided by 1.4 meters per second (average walking speed) divided by 60 seconds (to get minutes).
            timeest.Text = String.Format("Estimated time to reach destination: {0} minutes", Math.Round((routelength / 1.4) / 60, 1));
            Dijkstra.Route.eroute.Clear();
        }
        private void btnOK_Click(object sender, EventArgs e)
        {
            double tolerance = 0;

            if (!double.TryParse(txtTolerance.Text, out tolerance))
            {
                MapWinUtility.Logger.Message("Please enter only numbers in the distance field.", "Enter Only Numbers", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, DialogResult.OK);
                return;
            }

            this.Cursor = Cursors.WaitCursor;

            prgShape.Visible = true;
            prgPoint.Visible = true;

            sf.StartEditingShapes(true, null);
            long totalRemoved = 0;
            long fromShapes   = 0;
            int  numPts;

            System.Collections.ArrayList removeList = new System.Collections.ArrayList();

            if (sf.NumShapes > 0)
            {
                prgShape.Maximum = sf.NumShapes;

                for (int z = 0; z < sf.NumShapes; z++)
                {
                    MapWinGIS.Shape shp = sf.get_Shape(z);
                    if (z < 100 || z % 5 == 0)
                    {
                        prgShape.Value = z;
                        this.Refresh();
                    }
                    Application.DoEvents();

                    numPts = shp.numPoints;
                    if (numPts > 0)
                    {
                        prgPoint.Maximum = numPts;

                        for (int i = numPts - 1; i > 0; i--) // 0 never needs to actually be hit, inner loop will compare against all zeros
                        {
                            if (i % 5 == 0)
                            {
                                prgPoint.Value = numPts - i;
                                this.Refresh();
                            }

                            for (int j = i - 1; j >= 0; j--)
                            {
                                if (Math.Sqrt(Math.Pow(shp.get_Point(i).x - shp.get_Point(j).x, 2) + Math.Pow(shp.get_Point(i).y - shp.get_Point(j).y, 2)) < tolerance)
                                {
                                    // Make sure that !(i == numPts - 1 && j == 0) -- polygon completion point
                                    if (!removeList.Contains(i) && !(i == numPts - 1 && j == 0))
                                    {
                                        removeList.Add(i);
                                    }
                                }
                            }
                        }
                    }

                    if (removeList.Count > 0)
                    {
                        if (removeList.Count >= shp.numPoints - 1)
                        {
                            // Probably not a good thing.....
                            MapWinUtility.Logger.Message("Aborting: Proceeding will remove all points from one or more shapes. The distance may need to be smaller, particularly for unprojected (latitute and longitude) coordinate systems.", "Aborting -- All Points Would Be Removed", MessageBoxButtons.OK, MessageBoxIcon.Error, DialogResult.OK);
                            sf.StopEditingShapes(false, true, null);
                            this.Cursor      = Cursors.Default;
                            prgPoint.Value   = 0;
                            prgShape.Value   = 0;
                            prgPoint.Visible = false;
                            prgShape.Visible = false;
                            this.Cursor      = Cursors.Default;
                            return;
                        }

                        totalRemoved += removeList.Count;
                        fromShapes++;

                        while (removeList.Count > 0)
                        {
                            for (int part = 0; part < shp.NumParts; part++)
                            {
                                if (shp.get_Part(part) >= (int)removeList[0])
                                {
                                    shp.set_Part(part, shp.get_Part(part) - 1);
                                }
                            }
                            shp.DeletePoint((int)removeList[0]);
                            removeList.RemoveAt(0);
                        }

                        // If this is a polygon and there are now less than 3 shapes, panic
                        if ((shp.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGON || shp.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGONZ || shp.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGONM) && shp.numPoints < 3)
                        {
                            // Probably not a good thing.....
                            MapWinUtility.Logger.Message("Aborting: Proceeding will leave less than 3 points in a polygon. The distance may need to be smaller, particularly for unprojected (latitute and longitude) coordinate systems.", "Aborting -- Polygons Would Be Destroyed", MessageBoxButtons.OK, MessageBoxIcon.Error, DialogResult.OK);
                            sf.StopEditingShapes(false, true, null);
                            this.Cursor      = Cursors.Default;
                            prgPoint.Value   = 0;
                            prgShape.Value   = 0;
                            prgPoint.Visible = false;
                            prgShape.Visible = false;
                            this.Cursor      = Cursors.Default;
                            return;
                        }

                        // If the first and last points are not the same now, reclose it
                        if (shp.get_Point(0).x != shp.get_Point(shp.numPoints - 1).x || shp.get_Point(0).y != shp.get_Point(shp.numPoints - 1).y)
                        {
                            MapWinGIS.Point pnt = new MapWinGIS.Point();
                            pnt.x = shp.get_Point(0).x;
                            pnt.y = shp.get_Point(0).y;
                            pnt.Z = shp.get_Point(0).Z;
                            int ptidx = shp.numPoints;
                            shp.InsertPoint(pnt, ref ptidx);
                        }
                    }
                }
            }

            prgPoint.Value = prgPoint.Maximum;
            prgShape.Value = prgShape.Maximum;

            g.CreateUndoPoint();

            sf.StopEditingShapes(true, true, null);

            this.Cursor = Cursors.Default;

            if (totalRemoved > 0)
            {
                MapWinUtility.Logger.Message("There were " + totalRemoved.ToString() + " points removed from " + fromShapes.ToString() + " shapes.", "Finished", MessageBoxButtons.OK, MessageBoxIcon.Information, DialogResult.OK);
            }
            else
            {
                MapWinUtility.Logger.Message("Finished -- no extra points needed to be removed.", "Finished", MessageBoxButtons.OK, MessageBoxIcon.Information, DialogResult.OK);
            }

            this.DialogResult = DialogResult.OK;
            this.Close();
        }
Example #4
0
        private void RemoveSelectedVertex(System.Collections.ArrayList snapPoints, MapWinGIS.Shapefile shpFile)
        {
            try
            {
                //start editing shapes
                shpFile.StartEditingShapes(true, null);

                ShapefileEditor.SnapData snapData;
                int count;

                if (snapPoints.Count == 0)
                {
                    return;
                }

                if (m_globals.AllowSnapingToVertices)
                {
                    count = snapPoints.Count;
                }
                else
                {
                    count = 1;
                }

                //delete all snapPoints
                for (int i = count - 1; i >= 0; i--)
                {
                    snapData = (ShapefileEditor.SnapData)snapPoints[i];

                    MapWinGIS.Shape shp = shpFile.get_Shape(snapData.shpIndex);

                    if (shpFile.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYLINE)
                    {
                        if (shpFile.get_Shape(snapData.shpIndex).numPoints > 2)
                        {
                            if (shp.DeletePoint(snapData.pointIndex))
                            {
                                ShiftDownVertices(ref shp, snapData.pointIndex);
                            }
                        }
                        else
                        {
                            MapWinUtility.Logger.Message("You can not delete this point from this shape. Line shapes must have at least two points. If you want to delete this shape then use remove shape.", "Error in remove vertex", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information, DialogResult.OK);
                        }
                    }
                    else if (shpFile.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYGON)
                    {
                        if (shpFile.get_Shape(snapData.shpIndex).numPoints > 4)
                        {
                            if (shp.DeletePoint(snapData.pointIndex))
                            {
                                ShiftDownVertices(ref shp, snapData.pointIndex);
                            }
                        }
                        else
                        {
                            MapWinUtility.Logger.Message("You can not delete this point from this shape. Polygon shapes must have at least three points. If you want to delete this shape then use remove shape.", "Error in remove vertex", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information, DialogResult.OK);
                        }
                    }
                    else if (shpFile.ShapefileType == MapWinGIS.ShpfileType.SHP_POINT)
                    {
                        MapWinUtility.Logger.Message("You can not delete this point from this shape. Point shapes must have at least one point. If you want to delete this shape then use remove shape.", "Error in remove vertex", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information, DialogResult.OK);
                    }
                }

                m_globals.CreateUndoPoint();

                //stop editing and save changes
                shpFile.StopEditingShapes(true, true, null);
            }
            catch (System.Exception ex)
            {
                m_MapWin.ShowErrorDialog(ex);
            }
        }
        private void MovePolygons(int ScreenX, int ScreenY)
        {
            try
            {
                if (m_objShapefile != null && m_selectInfo != null)
                {
                    m_globals.LogWrite("num selected shapes: " + m_selectInfo.NumSelected.ToString());
                    m_dblDestinyX = ScreenX;
                    m_dblDestinyY = ScreenY;
                    double dblProjInitX = 0;
                    double dblProjInitY = 0;
                    double dblDestProjX = 0;
                    double dblDestProjY = 0;
                    m_globals.MapWin.View.PixelToProj(m_dblInitX, m_dblInitY, ref dblProjInitX, ref dblProjInitY);
                    m_globals.MapWin.View.PixelToProj(m_dblDestinyX, m_dblDestinyY, ref dblDestProjX, ref dblDestProjY);

                    double dblDistanceX = Math.Abs(dblProjInitX - dblDestProjX);
                    double dblDistanceY = Math.Abs(dblProjInitY - dblDestProjY);


                    if (m_intSelectedShapes != null)
                    {
                        //double dblxMin, dblyMin, dblzMin, dblxMax, dblyMax, dblzMax;
                        //m_selectInfo.SelectBounds.GetBounds(out dblxMin, out dblyMin, out dblzMin, out dblxMax, out dblyMax, out dblzMax);

                        m_objShapefile.StartEditingShapes(true, null);
                        // Chris M 12/21/2006 - no longer necessary, using an integer array now

                        /* int[] intShapes = null;
                         * intShapes = (int[])m_objShapes; */

                        MapWinGIS.Shape objShape = null;

                        if (m_intSelectedShapes.Length > 0)
                        {
                            //http://www.mapwindow.org/wiki/index.php/MapWinGIS:SampleCode-VB_Net:SelectShapes
                            int intUpperBound = m_intSelectedShapes.Length;
                            m_globals.LogWrite("Upperbound" + intUpperBound);
                            for (int ixShape = 0; ixShape < intUpperBound; ixShape++)
                            {
                                // Move each next selected shape.
                                objShape = m_objShapefile.get_Shape(m_intSelectedShapes[ixShape]);
                                Moveshape(dblDistanceX, dblDistanceY, objShape);
                                m_globals.LogWrite(">1");
                            }
                        }

                        if (!m_objShapefile.StopEditingShapes(true, true, null))//true, true, ICallback))
                        {
                            //ToDo: Stopediting failed.
                            throw new Exception("referencing intShapes failed.");
                        }
                        ;
                        m_globals.MapWin.View.Redraw();
                    }
                    else
                    {
                        throw new Exception("Selectshapes failed.");
                    };
                }
                else
                {
                    //ToDo: Handling shapefile not opened.
                    throw new Exception("shapefile opened failed.");
                }
            }
            catch (Exception ex)
            {
                m_globals.LogWrite(ex.Message);
                m_globals.LogWrite(ex.StackTrace);;
            }
        }
        /// <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));
            }
        }
        public void MapMouseUp(int Button, int Shift, int x, int y, ref bool Handled)
        {
            try
            {
                if (m_globals.CurrentMode == GlobalFunctions.Modes.MoveVertex)
                {
                    if (m_MapDraging == true)
                    {
                        double projX = 0, projY = 0;
                        m_MapWin.View.PixelToProj((double)x, (double)y, ref projX, ref projY);

                        //get the working shapefile
                        if (m_globals.CurrentLayer == null)
                        {
                            return;
                        }
                        MapWinGIS.Shapefile shpFile = m_globals.CurrentLayer;

                        //start editing the vertex postion
                        shpFile.StartEditingShapes(true, null);

                        //get all the vertex points that are within tolerance
                        System.Collections.ArrayList snapPoints = new System.Collections.ArrayList();
                        if (m_snapClass.CanSnap(m_globals.CurrentTolerance, projX, projY, ref snapPoints))
                        {
                            DrawAllSnapPoints(snapPoints);
                        }

                        ShapefileEditor.SnapData snapPoint;
                        MapWinGIS.Shape          shp;
                        MapWinGIS.Point          p;

                        //if allow snaping then change all vertex in the snaping tolerance
                        int count;
                        if (m_globals.AllowSnapingToVertices)
                        {
                            count = m_snapPoints.Count;
                        }
                        else
                        {
                            count = Math.Min(m_snapPoints.Count, 1);
                        }

                        for (int i = 0; i < count; i++)
                        {
                            snapPoint = (ShapefileEditor.SnapData)m_snapPoints[i];
                            shp       = shpFile.get_Shape(snapPoint.shpIndex);
                            p         = shp.get_Point(snapPoint.pointIndex);

                            //check to see if were going to snap to a point
                            if (snapPoints.Count > 0 && m_globals.AllowSnapingToVertices)
                            {
                                p.x = ((ShapefileEditor.SnapData)snapPoints[0]).point.x;
                                p.y = ((ShapefileEditor.SnapData)snapPoints[0]).point.y;
                            }
                            else
                            {
                                p.x = projX;
                                p.y = projY;
                            }
                        }

                        m_globals.CreateUndoPoint();

                        //stop editing and save changes
                        shpFile.StopEditingShapes(true, true, null);

                        //set the cursor to move cur
                        m_MapWin.View.UserCursorHandle = (int)m_cursor.Handle;

                        // update snap class
                        m_snapClass = new SnapClass(m_MapWin);
                    }

                    ClearDrawings();
                    m_MapDraging = false;
                    Handled      = true;
                }
            }
            catch (System.Exception ex)
            {
                m_MapWin.ShowErrorDialog(ex);
            }
        }
Example #8
0
        private void cmdIdentify_Click(object sender, EventArgs e)
        {
            if (m_MapWin.View.SelectedShapes.NumSelected == 0)
            {
                MapWinUtility.Logger.Msg(resMan.GetString("msgZeroShapesSelected.Text"), resMan.GetString("titleSelectShapes.Text"));
                return;
            }

            if (cmbIdentFrom.SelectedIndex == -1)
            {
                MapWinUtility.Logger.Msg(resMan.GetString("msgIdentFromNotSelected.Text"), resMan.GetString("titleSpecifyLayer.Text"));
                return;
            }

            if (cmbIdentWith.SelectedIndex == -1)
            {
                MapWinUtility.Logger.Msg(resMan.GetString("msgIdentWithNotSelected.Text"), resMan.GetString("titleSpecifyLayer.Text"));
                return;
            }
            if (m_MapWin.View.SelectedShapes.NumSelected == 0)
            {
                return;
            }

            // If it's a polygon layer we're identifying, call SelectByPolygon
            // If it's a grid, extract by mask
            // ...then, open that temporary file (not Add to Map, just "Open"), and summarize all data within that
            // file.
            int fromLayerHandle = -1;
            int maskLayerHandle = -1;

            if (cmbIdentFrom.SelectedIndex != -1)
            {
                string s = cmbIdentFrom.Items[cmbIdentFrom.SelectedIndex].ToString();
                if (s.Contains(")"))
                {
                    s = s.Substring(0, s.IndexOf(")"));
                }
                s = s.Replace("(", "");
                if (!int.TryParse(s, out fromLayerHandle))
                {
                    return;
                }

                if (fromLayerHandle == -1)
                {
                    return;
                }
            }
            if (cmbIdentWith.SelectedIndex != -1)
            {
                string s = cmbIdentWith.Items[cmbIdentWith.SelectedIndex].ToString();
                if (s.Contains(")"))
                {
                    s = s.Substring(0, s.IndexOf(")"));
                }
                s = s.Replace("(", "");
                if (!int.TryParse(s, out maskLayerHandle))
                {
                    return;
                }

                if (maskLayerHandle == -1)
                {
                    return;
                }
            }

            string TempPath = System.IO.Path.GetTempFileName();

            System.IO.File.Delete(TempPath);

            MapWinGIS.Shape     IdentifyBy;
            MapWinGIS.Shapefile sf = (MapWinGIS.Shapefile)m_MapWin.Layers[m_MapWin.Layers.CurrentLayer].GetObject();

            if (m_MapWin.View.SelectedShapes.NumSelected > 1)
            {
                // Get 0 and 1 first to initialize IdentifyBy
                MapWinGIS.Shape shp1 = sf.get_Shape(m_MapWin.View.SelectedShapes[0].ShapeIndex);
                MapWinGIS.Shape shp2 = sf.get_Shape(m_MapWin.View.SelectedShapes[1].ShapeIndex);
                MapWinGeoProc.SpatialOperations.MergeShapes(ref shp1, ref shp2, out IdentifyBy);
                // ...now, the rest
                if (m_MapWin.View.SelectedShapes.NumSelected > 2)
                {
                    for (int i = 2; i < m_MapWin.View.SelectedShapes.NumSelected; i++)
                    {
                        MapWinGIS.Shape tmpResultShp;
                        MapWinGIS.Shape shp3 = sf.get_Shape(m_MapWin.View.SelectedShapes[i].ShapeIndex);
                        MapWinGeoProc.SpatialOperations.MergeShapes(ref IdentifyBy, ref shp3, out tmpResultShp);
                        IdentifyBy   = tmpResultShp;
                        tmpResultShp = null;
                    }
                }
                // Ready to identify based on a single shape now regardless of multiple selected
            }
            else
            {
                IdentifyBy = sf.get_Shape(m_MapWin.View.SelectedShapes[0].ShapeIndex);
            }

            MapWindow.Interfaces.eLayerType layerType = m_MapWin.Layers[fromLayerHandle].LayerType;
            if (layerType == MapWindow.Interfaces.eLayerType.Grid)
            {
                // Grid
                TempPath = System.IO.Path.ChangeExtension(TempPath, ".bgd");
                string fn = m_MapWin.Layers[fromLayerHandle].FileName;
                MapWinGeoProc.SpatialOperations.ClipGridWithPolygon(ref fn, ref IdentifyBy, ref TempPath, chbJustToExtents.Checked);
                MapWinGIS.Grid grd = new MapWinGIS.Grid();
                grd.Open(TempPath, MapWinGIS.GridDataType.UnknownDataType, true, MapWinGIS.GridFileType.UseExtension, null);
                if (grd == null || grd.Header == null)
                {
                    MapWinUtility.Logger.Msg(resMan.GetString("msgNoGridValues.Text"), resMan.GetString("titleNoGridValues.Text"));
                    return;
                }
                m_Plugin.ActivateNoLoad();
                m_Plugin.LoadLayerAlternate(layerType, m_MapWin.Layers[fromLayerHandle].Name);

                MapWinGIS.Extents exts = new MapWinGIS.Extents();
                exts.SetBounds(grd.Header.XllCenter, grd.Header.YllCenter + grd.Header.NumberRows * grd.Header.dY, 0, grd.Header.XllCenter + grd.Header.NumberCols * grd.Header.dX, grd.Header.YllCenter, 0);
                m_MapWin.Layers.CurrentLayer = fromLayerHandle;

                m_Plugin.m_GridPropfrm.PopulateForm(!m_Plugin.m_HavePanel, grd, m_MapWin.Layers[fromLayerHandle].Name, exts, fromLayerHandle);
                this.Close();
            }
            else
            {
                // SF
                if (!chbJustToExtents.Checked)
                {
                    string fn = m_MapWin.Layers[fromLayerHandle].FileName;

                    // 2/14/2008 jk the results ArrayList cannot be null,
                    // when it was null it caused an exception in SpatialOperations.SelectWithPolygon method
                    //System.Collections.ArrayList results = null;
                    System.Collections.ArrayList results = new System.Collections.ArrayList();

                    MapWinGeoProc.SpatialOperations.SelectWithPolygon(ref fn, ref IdentifyBy, ref results);

                    // Switch current layer over to the one we're identifying so that the shapes
                    // can be reselected for visual effect
                    m_MapWin.Layers.CurrentLayer = fromLayerHandle;
                    m_Plugin.ActivateNoLoad();
                    m_Plugin.LoadLayerAlternate(layerType, m_MapWin.Layers[fromLayerHandle].Name);

                    int[] iresults = new int[results.Count];
                    for (int i = 0; i < results.Count; i++)
                    {
                        iresults[i] = (int)results[i];
                        m_MapWin.View.SelectedShapes.AddByIndex((int)results[i], m_MapWin.View.SelectColor);
                    }

                    m_Plugin.m_shpFilePropfrm.PopulateForm(!m_Plugin.m_HavePanel, (MapWinGIS.Shapefile)m_MapWin.Layers[fromLayerHandle].GetObject(), iresults, m_MapWin.Layers[fromLayerHandle].Name, false);

                    this.Close();
                }
                else
                {
                    object rslt = null;
                    m_MapWin.Layers.CurrentLayer = fromLayerHandle;
                    MapWinGIS.Shapefile DestSF = (MapWinGIS.Shapefile)m_MapWin.Layers[fromLayerHandle].GetObject();

                    DestSF.SelectShapes(IdentifyBy.Extents, 0.1, MapWinGIS.SelectMode.INTERSECTION, ref rslt);

                    m_Plugin.ActivateNoLoad();
                    m_Plugin.LoadLayerAlternate(layerType, m_MapWin.Layers[fromLayerHandle].Name);

                    int[] results = (int[])rslt;
                    for (int i = 0; i < results.Length; i++)
                    {
                        m_MapWin.View.SelectedShapes.AddByIndex((int)results[i], m_MapWin.View.SelectColor);
                    }

                    m_Plugin.m_shpFilePropfrm.PopulateForm(!m_Plugin.m_HavePanel, DestSF, results, m_MapWin.Layers[fromLayerHandle].Name, false);

                    this.Close();
                }
            }
        }
        /// <summary>
        /// Inserts shapes with the given indices in the specified table.
        /// </summary>
        /// <returns>Number of inserted shapes. -1 if the table doesn't exist.</returns>
        public int InsertShapes(MapWinGIS.Shapefile sf, string tableName, int[] indices)
        {
            this.CheckConnection();

            int count = 0;

            using (DbTransaction dbTrans = m_connection.BeginTransaction())
            {
                using (DbCommand cmd = this.CreateCommand())
                {
                    DbParameter param = this.CreateBinaryParameter();
                    param.SourceColumn  = "Geometry";
                    param.ParameterName = "@Geometry";
                    cmd.Parameters.Add(param);

                    // generating sql and parameters
                    int    fieldCount = sf.NumFields;
                    string sql        = "INSERT INTO [" + tableName + "] ([Geometry], ";
                    string values     = "VALUES (?, ";

                    for (int j = 0; j < fieldCount; j++)
                    {
                        param = this.CreateParameter();

                        MapWinGIS.Field fld = sf.get_Field(j);
                        switch (fld.Type)
                        {
                        case MapWinGIS.FieldType.STRING_FIELD:

                            param.DbType = DbType.StringFixedLength;
                            param.Size   = fld.Width;
                            break;

                        case MapWinGIS.FieldType.INTEGER_FIELD:
                            param.DbType = DbType.Int32;
                            break;

                        case MapWinGIS.FieldType.DOUBLE_FIELD:
                            param.DbType = DbType.Double;
                            break;
                        }

                        param.ParameterName = "@p" + j.ToString();
                        param.SourceColumn  = fld.Name;
                        cmd.Parameters.Add(param);

                        sql    += "[" + fld.Name + "]";
                        sql    += (j == fieldCount - 1) ? ") " : ", ";
                        values += (j == fieldCount - 1) ? "?)" : "?, ";
                    }
                    cmd.CommandText = sql + values;
                    cmd.Transaction = dbTrans;
                    cmd.Connection  = m_connection;
                    System.Diagnostics.Debug.Print(cmd.CommandText);

                    // adding new records
                    DbParameterCollection paramters = cmd.Parameters;
                    MapWinGIS.Table       table     = sf.Table;
                    int maxSize = 0;
                    int percent = 0;

                    for (int i = 0; i < sf.NumShapes; i++)
                    {
                        if (m_callback != null && m_showCallback)
                        {
                            int newPercent = (int)((double)i / (double)(sf.NumShapes - 1) * 100.0);
                            if (newPercent != percent)
                            {
                                m_callback.Progress("", newPercent, "Exporting shapes...");
                                percent = newPercent;
                            }
                        }

                        object          data  = null;
                        MapWinGIS.Shape shape = sf.get_Shape(i);

                        if (shape.ExportToBinary(ref data))
                        {
                            if ((data as byte[]).Length > maxSize)
                            {
                                maxSize = (data as byte[]).Length;
                            }

                            paramters[0].Value = data as byte[];
                            for (int j = 0; j < fieldCount; j++)
                            {
                                paramters[j + 1].Value = table.get_CellValue(j, i);
                            }
                            if (cmd.ExecuteNonQuery() != 0)
                            {
                                count++;
                            }
                        }
                    }

                    if (m_callback != null && m_showCallback)
                    {
                        m_callback.Progress("", 100, "");
                    }
                }
                dbTrans.Commit();
            }
            return(count);
        }
        private void RotateShapes()
        {
            try
            {
                System.Collections.SortedList arr = new System.Collections.SortedList();
                for (int i = 0; i < g.MapWin.View.SelectedShapes.NumSelected; i++)
                {
                    arr.Add(g.MapWin.View.SelectedShapes[i].ShapeIndex, g.MapWin.View.SelectedShapes[i].ShapeIndex);
                }

                if (arr.Count > 0)
                {
                    MapWinGIS.Shapefile sf = g.CurrentLayer;
                    if (sf.StartEditingShapes(true, null))
                    {
                        System.Diagnostics.Debug.WriteLine(sf.get_ErrorMsg(sf.LastErrorCode));
                        bool allCancelled = false;
                        for (int j = arr.Count - 1; j >= 0; j--)
                        {
                            // Show the dialog to get input -- rotation amount,
                            // rotate about point, etc. Note that dialog defaults
                            // to rotate about the centroid, which is calculated
                            // when the shape is set.
                            // Actual rotation will be done here as well.
                            dlg = new Forms.RotateShapeForm(g);

                            dlg.sf    = sf;
                            dlg.Shape = sf.get_Shape((int)arr.GetByIndex(j));

                            // Note -- don't show modally; we want the user
                            // to be able to click the map to choose a point if needed
                            dlg.Show(g.MapWindowForm);
                            // However, execution should not proceed until the user has finished...
                            // So we use a really old-style waiting scheme
                            while (dlg.Visible)
                            {
                                System.Windows.Forms.Application.DoEvents();
                            }

                            if (dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel)
                            {
                                allCancelled = true;
                                break;
                            }
                        }

                        if (!allCancelled)
                        {
                            g.CreateUndoPoint();
                            if (sf.StopEditingShapes(true, true, null) == false)
                            {
                                MapWinUtility.Logger.Message("Failed to save the changes that were made.", "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.DialogResult.OK);
                            }
                        }
                        else
                        {
                            sf.StopEditingShapes(false, true, null);
                            MapWinUtility.Logger.Message("Shape resizing has been cancelled - no changes were saved.", "Cancelled", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information, System.Windows.Forms.DialogResult.OK);
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
            }
        }
Example #11
0
        /// <summary>
        /// Generalization of polyline
        /// shapefiles using the Douglas-Peucker line simplification
        /// algorithm. This method will output a line shapefile.
        /// </summary>
        /// <param name="inFileName">Input shapefile</param>
        /// <param name="outFileName">Output shapefile</param>
        /// <param name="tolerance">tolerance parameter -
        /// specfies the maximum allowed distance between original polyline
        /// and simplified polyline</param>
        /// <param name="cback">Use this parameter for reporting progress. Set to null if not needed</param>
        public static void Generalize(string inFileName, string outFileName, double tolerance, MapWinGIS.ICallback cback)
        {
            MapWinGIS.Shapefile oldSF = new MapWinGIS.Shapefile();
            if (!oldSF.Open(inFileName, null))
            {
                throw new ArgumentException(string.Format("Shapefile {0} could not be opened. Error: {1}",
                                                          inFileName, oldSF.get_ErrorMsg(oldSF.LastErrorCode)));
            }

            //Check if it's a line shapefile
            if (!(oldSF.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYLINE ||
                  oldSF.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYLINEM ||
                  oldSF.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYLINEZ))
            {
                throw new ArgumentException(string.Format("Shapefile {0} must be a polyline shapefile.", inFileName));
            }

            int numShapes = oldSF.NumShapes;
            int numFields = oldSF.NumFields;

            //create a new output shapefile
            MapWinGIS.Shapefile   newSF  = new MapWinGIS.Shapefile();
            MapWinGIS.ShpfileType sftype = MapWinGIS.ShpfileType.SHP_POLYLINE;

            // if shapefile exists - open it and clear all shapes
            if (System.IO.File.Exists(outFileName))
            {
                try
                {
                    //TODO: ask for overwriting..
                    bool deleted = MapWinGeoProc.DataManagement.DeleteShapefile(ref outFileName);
                }
                finally
                {
                }
            }

            if (!newSF.CreateNew(outFileName, sftype))
            {
                throw new InvalidOperationException
                          ("Error creating shapefile " + outFileName + " " + newSF.get_ErrorMsg(newSF.LastErrorCode));
            }
            newSF.StartEditingShapes(true, cback);

            //Copy all fields
            if (!Globals.CopyFields(ref oldSF, ref newSF))
            {
                throw new InvalidOperationException(string.Format("Error copying fields from {0} to {1}",
                                                                  oldSF.Filename, newSF.Filename));
            }

            int newShapeIndex = 0;

            for (int shpIdx = 0; shpIdx < numShapes; ++shpIdx)
            {
                MapWinGIS.Shape shp = oldSF.get_Shape(shpIdx);

                // convert each part of the polyline shape to a 'geometry' object
                Geometry geom = MapWinGeoProc.NTS_Adapter.ShapeToGeometry(shp);
                for (int partIdx = 0; partIdx < geom.NumGeometries; ++partIdx)
                {
                    Geometry geomPart = (Geometry)geom.GetGeometryN(partIdx);

                    //do the simplification
                    ICoordinate[] oldCoords = geomPart.Coordinates;
                    DouglasPeuckerLineSimplifier simplifier = new DouglasPeuckerLineSimplifier(oldCoords);
                    simplifier.DistanceTolerance = tolerance;
                    ICoordinate[] newCoords = simplifier.Simplify();

                    //convert the coordinates back to a geometry
                    Geometry newGeom = new LineString(newCoords);

                    //convert the geometry back to a shape
                    MapWinGIS.Shape newShape = MapWinGeoProc.NTS_Adapter.GeometryToShape(newGeom);

                    //add the shape to the new shapefile
                    newShapeIndex = newSF.NumShapes;
                    if (newSF.EditInsertShape(newShape, ref newShapeIndex) == false)
                    {
                        throw new InvalidOperationException("Error inserting shape: " +
                                                            newSF.get_ErrorMsg(newSF.LastErrorCode));
                    }
                    //add attribute values
                    for (int fldIdx = 0; fldIdx < numFields; ++fldIdx)
                    {
                        object val = oldSF.get_CellValue(fldIdx, shpIdx);
                        if (newSF.EditCellValue(fldIdx, newSF.NumShapes - 1, val) == false)
                        {
                            throw new InvalidOperationException("Error editing cell value: " +
                                                                newSF.get_ErrorMsg(newSF.LastErrorCode));
                        }
                    }
                }
            }
            //close the old shapefile
            oldSF.Close();

            //stop editing and close the new shapefile
            newSF.StopEditingShapes(true, true, cback);
            newSF.Close();
        }