Exemplo n.º 1
0
        /// <summary>
        /// Not Implemented
        /// This function will calculate the length of every line shape in the shapefile and save the results to the corresponding .dbf table.
        /// </summary>
        /// <param name="sf">The shapefile of lines whose lengths are to be computed.</param>
        /// <param name="fieldIndex">The field index of the field to update with values.</param>
        /// <param name="Units">The units of the dataset (e.g., Meters, Lat/Long).</param>
        /// <returns>False if an error was encountered, true otherwise.</returns>
        public static bool ComputeLengths(MapWinGIS.Shapefile sf, int fieldIndex, string Units)
        {
            try
            {
                //Loop trough all shapes
                for (int i = 0; i <= sf.NumShapes - 1; i++)
                {
                    double          length = 0f;
                    MapWinGIS.Shape line   = new MapWinGIS.Shape();
                    //Measure length of each line part
                    line = sf.get_Shape(i);
                    //-2 else out of bounds!!
                    for (int j = 0; j <= line.numPoints - 2; j++)
                    {
                        length += DistancePointToPoint(line.get_Point(j).x, line.get_Point(j).y, line.get_Point(j + 1).x, line.get_Point(j + 1).y, Units);
                    }

                    //Add length as attribute:
                    if (!sf.EditCellValue(fieldIndex, i, length))
                    {
                        Error.SetErrorMsg(sf.get_ErrorMsg(sf.LastErrorCode));
                    }
                }

                return(false);
            }
            catch (Exception lEx)
            {
                Error.SetErrorMsg(lEx.ToString());
                return(false);
            }
        }
Exemplo n.º 2
0
        private void ShrinkOrGrowPoly(ref MapWinGIS.Shape shp, double distance)
        {
            MapWinGIS.Point centroid = MapWinGeoProc.Statistics.Centroid(ref shp);
            // Avoid OLE calls; cache centroid point in local variable
            double cx = centroid.x;
            double cy = centroid.y;

            for (int i = 0; i < shp.numPoints; i++)
            {
                double ox = shp.get_Point(i).x;
                double oy = shp.get_Point(i).y;
                // Find the adjusted "real" distance (rdistance)
                double rdistance = Math.Sqrt(Math.Pow(cy - oy, 2) + Math.Pow(cx - ox, 2)) + distance;
                // Find the full distance of point to centroid (fdistance)
                double fdistance = Math.Sqrt(Math.Pow(cy - oy, 2) + Math.Pow(cx - ox, 2));

                if (rdistance < 0.00001)
                {
                    MapWinUtility.Logger.Message("Shrinking the shape by this amount will result in losing some shape geometry; aborting.", "Aborting - Loss of Geometry", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, DialogResult.OK);
                    return;
                }

                // Find the new point (project the old point along the line from point to midpoint)
                shp.get_Point(i).x = cx + (rdistance / fdistance) * (ox - cx);
                shp.get_Point(i).y = cy + (rdistance / fdistance) * (oy - cy);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// If a Shape has multiple parts, this will create a separate polyline for each part.
        /// </summary>
        /// <param name="mwShape">A MapWinGIS.Shape that should be a LineString shape type</param>
        /// <returns>A List of Polylines derived from the various shapes</returns>
        public static List <LineString> mwShape_To_LineStrings(MapWinGIS.Shape mwShape)
        {
            if (Adapter.GetCategory(mwShape) != ShapeCategories.Line)
            {
                throw new ArgumentException("The Split method only takes Polyline shape types.");
            }
            List <LineString> newLines = new List <LineString>();

            if (mwShape.NumParts <= 1)
            {
                LineString Part = new LineString();
                for (int I = 0; I < mwShape.numPoints; I++)
                {
                    Part.Add_Point(mwShape.get_Point(I));
                }
                newLines.Add(Part);
                return(newLines);
            }
            int PartIndex = 0;

            for (int P = 0; P < mwShape.NumParts; P++)
            {
                LineString Part  = new LineString();
                int        Pnext = mwShape.get_Part(P);
                for (int I = PartIndex; I < Pnext; I++)
                {
                    Part.Add_Point(mwShape.get_Point(I));
                }
                newLines.Add(Part);
            }
            return(newLines);
        }
        private void DrawMoveLine(double x, double y, System.Collections.ArrayList snapPoints)
        {
            try
            {
                if (snapPoints.Count == 0)
                {
                    return;
                }

                double projX = 0, projY = 0;
                m_MapWin.View.PixelToProj(x, y, ref projX, ref projY);

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

                //get the current vertex index
                ShapefileEditor.SnapData snapData = (ShapefileEditor.SnapData)snapPoints[0];
                int vertexIndex                   = snapData.pointIndex;

                //get the current shape
                MapWinGIS.Shape shp = shpFile.get_Shape(snapData.shpIndex);

                if (shpFile.ShapefileType == MapWinGIS.ShpfileType.SHP_POINT)
                {
                    m_MapWin.View.Draw.DrawPoint(projX, projY, m_globals.VertexSize, System.Drawing.Color.Red);
                }
                else
                {
                    if (vertexIndex > 0 && vertexIndex < shp.numPoints - 1)
                    {
                        //draw a line from the prev to current to next vertex
                        MapWinGIS.Point prevPoint = shp.get_Point(vertexIndex - 1);
                        MapWinGIS.Point nextPoint = shp.get_Point(vertexIndex + 1);

                        m_MapWin.View.Draw.DrawLine(prevPoint.x, prevPoint.y, projX, projY, 2, System.Drawing.Color.Red);
                        m_MapWin.View.Draw.DrawLine(projX, projY, nextPoint.x, nextPoint.y, 2, System.Drawing.Color.Red);
                    }
                    else if (vertexIndex == 0)
                    {
                        MapWinGIS.Point nextPoint = shp.get_Point(vertexIndex + 1);
                        m_MapWin.View.Draw.DrawLine(projX, projY, nextPoint.x, nextPoint.y, 2, System.Drawing.Color.Red);
                    }
                    else if (vertexIndex == shp.numPoints - 1)
                    {
                        MapWinGIS.Point prevPoint = shp.get_Point(vertexIndex - 1);
                        m_MapWin.View.Draw.DrawLine(prevPoint.x, prevPoint.y, projX, projY, 2, System.Drawing.Color.Red);
                    }
                }
            }
            catch (System.Exception ex)
            {
                m_MapWin.ShowErrorDialog(ex);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns a MultiLineString geometry collection derived from the mwShape
        /// </summary>
        /// <param name="mwShape">The shape to convert into a multi-line string</param>
        public static MultiLineString CreateMultiLineString(MapWinGIS.Shape mwShape)
        {
            MultiLineString MLS = new MultiLineString();
            // Variables
            int        numParts;  // The number of parts in the shape
            int        numPoints; // The number of points in the shape
            LineString LS;

            // Parameter checking
            if (mwShape == null)
            {
                throw new ArgumentException("mwShape should either not be null, or not be specified.");
            }
            if (mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPATCH ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPOINT ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPOINTM ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPOINTZ ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_NULLSHAPE ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POINT ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POINTM ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POINTZ)
            {
                throw new ArgumentException("Argument mwShape shapetype must be a polyline or polygon.");
            }

            MLS.GeometryN = new List <Geometry>();
            numParts      = mwShape.NumParts;
            numPoints     = mwShape.numPoints;
            // if NumParts = 0, treat as though the whole shape was a single part
            int prt = 0;                 // prt is the part index
            int pt  = 0;                 // pt is the point index

            while (prt < numParts - 1)
            {
                int maxpt = mwShape.get_Part(prt + 1);
                LS = new LineString();
                while (pt < maxpt)
                {
                    Coordinate Coord = GeometryFactory.CreateCoordinate(mwShape.get_Point(pt));
                    LS.Coordinates.Add(Coord);
                    pt++;
                }
                MLS.GeometryN.Add(LS);
                prt++;
            }
            LS = new LineString();
            while (pt < numPoints)
            {
                Coordinate Coord = GeometryFactory.CreateCoordinate(mwShape.get_Point(pt));
                LS.Coordinates.Add(Coord);
                pt++;
            }
            MLS.GeometryN.Add(LS);
            return(MLS);
        }
Exemplo n.º 6
0
        // Returns only the point index values of the shapes in the interesection of the shape extents
        private static void PointsOfInterest(MapWinGIS.Shape Shape1, MapWinGIS.Shape Shape2, ref List <int> Points1, ref List <int> Points2)
        {
            Envelope Rect1, Rect2, rectIntersect;

            Rect1         = new Envelope(Shape1.Extents);
            Rect2         = new Envelope(Shape2.Extents);
            rectIntersect = (Envelope)Rect1.Intersection(Rect2);
            MapWinGIS.Point pt = new MapWinGIS.Point();
            // reduce our points to points of interrest
            int numPoints1 = Shape1.numPoints;

            for (int I = 0; I < numPoints1; I++)
            {
                pt = Shape1.get_Point(I);
                if (rectIntersect.Intersects(pt))
                {
                    Points1.Add(I);
                }
            }

            int numPoints2 = Shape2.numPoints;

            for (int I = 0; I < numPoints2; I++)
            {
                pt = Shape2.get_Point(I);
                if (rectIntersect.Intersects(pt))
                {
                    Points2.Add(I);
                }
            }
        }
        private void MarkAllVertices()
        {
            try
            {
                MapWinGIS.Shape           shp = null;
                MapWinGIS.Shapefile       sf  = m_globals.CurrentLayer;
                MapWindow.Interfaces.View v   = m_globals.MapWin.View;

                //clear the drawings
                v.Draw.ClearDrawing(m_HDraw);
                m_HDraw = v.Draw.NewDrawing(MapWinGIS.tkDrawReferenceList.dlSpatiallyReferencedList);

                //display all the vertices for each shape
                for (int i = 0; i < v.SelectedShapes.NumSelected; i++)
                {
                    shp = sf.get_Shape(v.SelectedShapes[i].ShapeIndex);

                    for (int j = 0; j < shp.numPoints; j++)
                    {
                        MapWinGIS.Point shpPoint = shp.get_Point(j);
                        m_globals.MapWin.View.Draw.DrawPoint(shpPoint.x, shpPoint.y, m_globals.VertexSize, System.Drawing.Color.Red);
                    }
                }
            }
            catch (System.Exception ex)
            {
                m_globals.MapWin.ShowErrorDialog(ex);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Creates a new instance of the polyline class
        /// </summary>
        /// <param name="mwShape">A MapWinGIS.Shape to derive the polyline from</param>
        /// <remarks>Assumes shape is one part.  To Split Multipart shapes, use Split.</remarks>
        public LineString(MapWinGIS.Shape mwShape)
        {
            if (Adapter.GetCategory(mwShape) != ShapeCategories.Line)
            {
                throw new ArgumentException("The Split method only takes Polyline shape types.");
            }

            m_Envelope   = new Envelope(mwShape.Extents);
            extentsValid = true; // When adding all the points at once, we have no problem.

            m_Length    = 0;
            lengthValid = false; // Calculate this only if it is needed

            m_Center    = new Point((m_Envelope.xMin + m_Envelope.xMax) / 2, (m_Envelope.yMin + m_Envelope.yMax) / 2, (m_Envelope.zMin + m_Envelope.zMax) / 2);
            centerValid = true; // since extents were ok already, we can quickly find the center

            m_MaxRadius    = 0;
            maxradiusValid = false; // Calculate this only if it is needed

            m_Points = new List <Point>();
            for (int I = 0; I < mwShape.NumParts; I++)
            {
                Add_Point(mwShape.get_Point(I));
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Creates a new instance of the Polygon class
        /// The shape is closed, but the first and last point will be the same.
        /// This way, algorithms don't have to loop back to the 0 point in order to evaluate
        /// the final segment.
        /// </summary>
        /// <param name="mwShape">A MapWinGIS.Shape to derive the Polygon from</param>
        /// <remarks>Assumes shape is one part.  To Split Multipart shapes, use Split.</remarks>
        public Polygon(MapWinGIS.Shape mwShape)
        {
            if (Adapter.GetCategory(mwShape) != ShapeCategories.Polygon)
            {
                throw new ArgumentException("The Split method only takes Polygon shape types.");
            }

            m_Area    = 0;
            areaValid = false; // Calculate this when needed and then cache it.

            m_Envelope   = new Envelope(mwShape.Extents);
            extentsValid = true; // When adding all the points at once, we have no problem.

            m_Center    = new Point((m_Envelope.xMin + m_Envelope.xMax) / 2, (m_Envelope.yMin + m_Envelope.yMax) / 2, (m_Envelope.zMin + m_Envelope.zMax) / 2);
            centerValid = true; // since extents were ok already, we can quickly find the center

            m_Perimeter    = 0.0;
            perimeterValid = false; // Calculate this only if it is needed


            m_MaxRadius    = 0.0;
            maxradiusValid = false;        // Calculate this only if it is needed

            m_Points = new List <Point>(); // skip the last duplicate point
            for (int I = 0; I < mwShape.NumParts - 1; I++)
            {
                Add_Point(mwShape.get_Point(I));
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// This function scans a Polygon/PolygonM/PolygonZ to determine if any of the
        /// existing polygons are counter-clockwise.  If they are, then it creates a linear ring
        /// from the shape.
        /// </summary>
        /// <param name="mwShape">A MapWinGIS.Shape Polygon/PolygonM/PolygonZ that might have holes.</param>
        /// <returns>A List of Linear Rings, each item representing one of the holes from the polygon.</returns>
        public static List <ILinearRing> GetHoles(MapWinGIS.Shape mwShape)
        {
            List <ILinearRing> Holes = new List <ILinearRing>();

            MapWinGIS.Point mwPoint = new MapWinGIS.Point();
            int             pt      = 0;
            int             prt     = 0;

            do
            {
                int Start = mwShape.get_Part(prt);
                int End;
                if (prt >= mwShape.NumParts - 1)
                {
                    End = mwShape.numPoints;
                }
                else
                {
                    End = mwShape.get_Part(prt + 1);
                }
                int          Count  = End - Start + 1;
                Coordinate[] Coords = new Coordinate[Count];
                double       area   = 0;
                for (int PrtPoint = 0; PrtPoint < Count - 1; PrtPoint++)
                {
                    // PrtPoint will be tracking the index for the specific linestring
                    mwPoint          = mwShape.get_Point(pt);
                    Coords[PrtPoint] = new Coordinate(mwPoint.x, mwPoint.y);
                    if (PrtPoint > 0)
                    {
                        area += Coords[PrtPoint].X * Coords[PrtPoint - 1].Y - Coords[PrtPoint - 1].X * Coords[PrtPoint].Y;
                    }
                    pt++;
                }
                mwPoint           = mwShape.get_Point(Start); // close the loop
                Coords[Count - 1] = new Coordinate(mwPoint.x, mwPoint.y);
                area += Coords[Count - 2].X * Coords[Count - 1].Y - Coords[Count - 1].X * Coords[Count - 2].Y;

                // if the area is negative, then the shape is counter-clockwise and therefore a hole
                if (area < 0)
                {
                    Holes.Add(new LinearRing(Coords));
                }
                prt++;
            }while (prt < mwShape.NumParts);
            return(Holes);
        }
Exemplo n.º 11
0
 private void RotateShape(MapWinGIS.Shape shape, double Angle, double aboutX, double aboutY)
 {
     for (int i = 0; i < shape.numPoints; i++)
     {
         MapWinGIS.Point pt = shape.get_Point(i);
         double          Nx = 0, Ny = 0;
         Rotate(Angle, pt.x, pt.y, aboutX, aboutY, ref Nx, ref Ny);
         pt.x = Nx;
         pt.y = Ny;
     }
 }
Exemplo n.º 12
0
        /// <summary>
        /// Finds the points within extents for polygons and polylines and automatically creates a list
        /// of appropriate line segments representing all the segments found within the extents.
        /// </summary>
        /// <param name="LineOrPolygon">A MapWinGIS.Shape that is a line or polygon shape</param>
        /// <param name="Rect">A Envelope defining the region of interrest</param>
        /// <returns>A list of all segments that have at least one point within or on the extents</returns>
        public static List <LineSegment> LineSegmentsWithinRect(MapWinGIS.Shape LineOrPolygon, Envelope Rect)
        {
            List <LineSegment> ContainedLineSegments = new List <LineSegment>();
            ShapeCategories    Category = GetCategory(LineOrPolygon);

            if (LineOrPolygon == null)
            {
                throw new ArgumentException("Argument for Line or Polygon cannot be null");
            }
            if (Category != ShapeCategories.Polygon && Category != ShapeCategories.Line)
            {
                throw new ArgumentException("The input argument must be a line or polygon or else it doesn't have segments.");
            }
            Envelope rectShape, rectIntersect;

            rectShape     = new Envelope(LineOrPolygon.Extents);
            rectIntersect = (Envelope)rectShape.Intersection(Rect);
            int  numPoints             = LineOrPolygon.numPoints;
            bool PreviousPointIncluded = true; // the first and last points are the same, so don't look backwards from point 1

            for (int I = 0; I < numPoints - 1; I++)
            {
                MapWinGIS.Point pt = LineOrPolygon.get_Point(I);
                if (rectIntersect.Intersects(pt))
                {
                    if (PreviousPointIncluded == false)
                    {
                        ContainedLineSegments.Add(new LineSegment(LineOrPolygon.get_Point(I - 1), pt));
                    }
                    // since this point is contained, we know for sure that we need the next segment
                    ContainedLineSegments.Add(new LineSegment(LineOrPolygon.get_Point(I), LineOrPolygon.get_Point(I + 1)));
                    PreviousPointIncluded = true;
                }
                else
                {
                    PreviousPointIncluded = false;
                }
            }
            return(ContainedLineSegments);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Creates a new instance of the polyline class
        /// </summary>
        /// <param name="MapWinGIS_Shape">A MapWinGIS.Shape to derive the polyline from</param>
        /// <remarks>Assumes shape is one part.  To Split Multipart shapes, use Split.</remarks>
        public static LineString CreateLineString(object MapWinGIS_Shape)
        {
            if (MapWinGIS_Shape.GetType() != typeof(MapWinGIS.ShapeClass))
            {
                return(null);
            }
            MapWinGIS.Shape mwShape = MapWinGIS_Shape as MapWinGIS.Shape;

            LineString LS = new LineString();

            LS.Envelope = new Envelope(mwShape.Extents);

            LS.Coordinates = new List <Coordinate>();
            for (int I = 0; I < mwShape.numPoints; I++)
            {
                MapWinGIS.Point mwPoint = mwShape.get_Point(I);
                LS.Coordinates.Add(new Coordinate(mwPoint.x, mwPoint.y));
            }
            return(LS);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Finds a list of point indecies from a MapWinGIS.Shape that are within the rectangle specified
        /// </summary>
        /// <param name="Shape">A mapWinGIS.Shape object to select points from</param>
        /// <param name="Rect">A Envelope structure representing a rectangle to search</param>
        /// <returns>A List of integer values representing the index values of the points within the rectangle</returns>
        public static List <int> PointsWithinRect(MapWinGIS.Shape Shape, Envelope Rect)
        {
            List <int> ContainedPoints = new List <int>();
            Envelope   RectShape, rectIntersect;

            RectShape     = new Envelope(Shape.Extents);
            rectIntersect = (Envelope)RectShape.Intersection(Rect);
            MapWinGIS.Point pt        = new MapWinGIS.Point();
            int             numPoints = Shape.numPoints;

            for (int I = 0; I < numPoints; I++)
            {
                pt = Shape.get_Point(I);
                if (rectIntersect.Intersects(pt))
                {
                    ContainedPoints.Add(I);
                }
            }
            return(ContainedPoints);
        }
Exemplo n.º 15
0
        // Only returns true if a point from shape1 is the same location as shape2
        private static bool MultiPoints_TouchTheBoundaryOf(MapWinGIS.Shape Shape1, MapWinGIS.Shape Shape2)
        {
            List <int> Points1 = new List <int>(); // Points from Shape1 where the rectangular shape extents overlap
            List <int> Points2 = new List <int>(); // Points from Shape2 where the rectangular shape extents overlap

            MapWinGIS.Point pt1, pt2;
            PointsOfInterest(Shape1, Shape2, ref Points1, ref Points2);
            for (int I = 0; I < Points1.Count; I++)
            {
                for (int J = 0; J < Points2.Count; J++)
                {
                    pt1 = Shape1.get_Point(Points1[I]);
                    pt2 = Shape2.get_Point(Points2[J]);
                    if (pt1.x == pt2.x && pt1.y == pt2.y)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 16
0
 private void MoveYOverDistance(MapWinGIS.Shape objShape, int ixPoint, double dblDistance, double dblSgn)
 {
     objShape.get_Point(ixPoint).y = objShape.get_Point(ixPoint).y + dblSgn * dblDistance;
 }
Exemplo n.º 17
0
        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();
        }
Exemplo n.º 18
0
        /// <summary>
        /// Creates one multi-part polygon out of two input polygons.
        /// </summary>
        /// <param name="poly1">The first polygon to be combined.</param>
        /// <param name="poly2">The second polygon to be combined.</param>
        /// <param name="resultShp">The resulting multi-part polygon.</param>
        /// <returns>True if combining was successful, false otherwise.</returns>
        private static bool CombinePolygons(ref MapWinGIS.Shape poly1, ref MapWinGIS.Shape poly2, out MapWinGIS.Shape resultShp)
        {
            int p1NumParts = poly1.NumParts;

            if (p1NumParts == 0)
            {
                p1NumParts = 1;
            }
            int p2NumParts = poly2.NumParts;

            if (p2NumParts == 0)
            {
                p2NumParts = 1;
            }

            MapWinGIS.Shape multiShp = new MapWinGIS.ShapeClass();
            multiShp.Create(poly1.ShapeType);
            int partIndex  = 0;
            int pointIndex = 0;
            int numPoints  = poly1.numPoints;
            int begPart    = 0;
            int endPart    = numPoints;

            //deal with the first shape and all of its parts
            //			Globals.Vertex[][] p1VertArray = new Globals.Vertex[p1NumParts][];
            //			Globals.ConvertPolyToVertexArray(ref poly1, out p1VertArray);
            //bool firstIsClockwise = Globals.IsClockwise(ref p1VertArray[0]);

            for (int i = 0; i <= p1NumParts - 1; i++)
            {
                partIndex  = i;
                pointIndex = multiShp.numPoints;
                multiShp.InsertPart(pointIndex, ref partIndex);

                begPart = poly1.get_Part(i);
                if (i < p1NumParts - 1)
                {
                    endPart = poly1.get_Part(i + 1);
                }
                else
                {
                    endPart = poly1.numPoints;
                }
                //				if(firstIsClockwise)
                //				{
                //add part
                for (int j = begPart; j <= endPart - 1; j++)
                {
                    pointIndex = multiShp.numPoints;
                    multiShp.InsertPoint(poly1.get_Point(j), ref pointIndex);
                }
                //				}
                //				else
                //				{
                //					//add part in reverse order
                //					for(int j = endPart-1; j >= begPart; j--)
                //					{
                //						pointIndex = multiShp.numPoints;
                //						multiShp.InsertPoint(poly1.get_Point(j), ref pointIndex);
                //					}
                //				}
            }            //end of adding poly1 and all of its parts to the result shape

            //deal with the second shape and all of its parts
            //			Globals.Vertex[][] p2VertArray = new Globals.Vertex[p2NumParts][];
            //			Globals.ConvertPolyToVertexArray(ref poly2, out p2VertArray);
            //			bool secondIsClockwise = Globals.IsClockwise(ref p2VertArray[0]);
            partIndex++;
            numPoints = poly2.numPoints;
            begPart   = 0;
            endPart   = numPoints;

            for (int i = 0; i <= p2NumParts - 1; i++)
            {
                partIndex += i;
                pointIndex = multiShp.numPoints;
                multiShp.InsertPart(pointIndex, ref partIndex);

                begPart = poly2.get_Part(i);
                if (i < p2NumParts - 1)
                {
                    endPart = poly2.get_Part(i + 1);
                }
                else
                {
                    endPart = poly2.numPoints;
                }

                //				if(secondIsClockwise)
                //				{
                for (int j = begPart; j <= endPart - 1; j++)
                {
                    pointIndex = multiShp.numPoints;
                    multiShp.InsertPoint(poly2.get_Point(j), ref pointIndex);
                }
                //				}
                //				else
                //				{
                //					for(int j = endPart-1; j >= begPart; j--)
                //					{
                //						pointIndex = multiShp.numPoints;
                //						multiShp.InsertPoint(poly2.get_Point(j), ref pointIndex);
                //					}
                //				}
            }            //end of inserting parts from the second shape

            resultShp = multiShp;
            if (resultShp.numPoints > 0)
            {
                return(true);
            }
            else
            {
                gErrorMsg = "Error occured while trying to combine parts. No points in result shape.";
                Debug.WriteLine(gErrorMsg);
                Error.SetErrorMsg(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
        }
Exemplo n.º 19
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);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Checks whether the borders of a polygon shape, lines of line shapes, or points of point shapes touch.
        /// </summary>
        /// <param name="Shape1">A MapWinGIS.Shape object to test</param>
        /// <param name="Shape2">A MapWinGIS.Shape object to test</param>
        /// <returns>True if the boundaries touch</returns>
        public static bool ShapeBoundariesTouch(MapWinGIS.Shape Shape1, MapWinGIS.Shape Shape2)
        {
            if (Shape1 == null || Shape1.ShapeType == MapWinGIS.ShpfileType.SHP_NULLSHAPE)
            {
                throw new ArgumentException("Argument Shape1 cannot be null");
            }
            if (Shape2 == null || Shape2.ShapeType == MapWinGIS.ShpfileType.SHP_NULLSHAPE)
            {
                throw new ArgumentException("Argument Shape2 cannot be null");
            }
            if (Shape1.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPATCH)
            {
                throw new ArgumentException("Multipatch is not supported");
            }
            if (Shape2.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPATCH)
            {
                throw new ArgumentException("Multipatch is not supported");
            }

            ShapeCategories Typ1, Typ2;

            Typ1 = GetCategory(Shape1);
            Typ2 = GetCategory(Shape2);

            // for single points, simply show if these specific points overlap
            if (Typ1 == ShapeCategories.Point &&
                Typ2 == ShapeCategories.Point)
            {
                Point p1 = new Point(Shape1.get_Point(0));
                Point p2 = new Point(Shape2.get_Point(0));
                if (p1.Intersects(p2))
                {
                    return(true);
                }
                return(false);
            }

            // Point to Non-point
            if (Typ1 == ShapeCategories.Point)
            {
                Point p1 = new Point(Shape1.get_Point(0));

                if (Typ2 == ShapeCategories.MultiPoint)
                {
                    for (int I = 0; I < Shape2.numPoints; I++)
                    {
                        Point p2 = new Point(Shape2.get_Point(I));
                        if (p1.Intersects(p2))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
                else
                {
                    for (int I = 0; I < Shape2.numPoints - 1; I++)
                    {
                        LineSegment seg = new LineSegment(Shape2.get_Point(I), Shape2.get_Point(I + 1));
                        if (seg.Intersects(p1))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
            }

            // Point2 to non-point
            if (Typ2 == ShapeCategories.Point)
            {
                Point p2 = new Point(Shape2.get_Point(0));

                if (Typ1 == ShapeCategories.MultiPoint)
                {
                    for (int I = 0; I < Shape1.numPoints; I++)
                    {
                        Point p1 = new Point(Shape1.get_Point(I));
                        if (p2.Intersects(p1))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
                else
                {
                    for (int I = 0; I < Shape1.numPoints - 1; I++)
                    {
                        LineSegment seg = new LineSegment(Shape1.get_Point(I), Shape1.get_Point(I + 1));
                        if (seg.Intersects(p2))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
            }

            // for multipoint, test every point for intersection.
            if (Typ1 == ShapeCategories.MultiPoint &&
                Typ2 == ShapeCategories.MultiPoint)
            {
                List <int> Points1 = PointsWithinEnvelope(Shape1, Shape2.Extents);
                List <int> Points2 = PointsWithinEnvelope(Shape2, Shape1.Extents);
                for (int I = 0; I < Points1.Count; I++)
                {
                    for (int J = 0; J < Points2.Count; J++)
                    {
                        Point p1 = new Point(Shape1.get_Point(I));
                        Point p2 = new Point(Shape2.get_Point(J));
                        if (p1.Intersects(p2))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }
            // For lines and polygons simply test line segments in the area of interrest to see if they touch
            // (touching in this case just equates to having a minimum distance of 0.
            if ((Typ1 == ShapeCategories.Line || Typ1 == ShapeCategories.Polygon) &&
                (Typ2 == ShapeCategories.Line || Typ2 == ShapeCategories.Polygon))
            {
                List <LineSegment> Segs1 = LineSegmentsWithinEnvelope(Shape1, Shape2.Extents);
                List <LineSegment> Segs2 = LineSegmentsWithinEnvelope(Shape2, Shape1.Extents);
                for (int I = 0; I < Segs1.Count; I++)
                {
                    for (int J = 0; J < Segs2.Count; J++)
                    {
                        if (Segs1[I].Intersects(Segs2[J]))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }

            // multi-point to polygon
            if (Typ1 == ShapeCategories.MultiPoint)
            {
                List <int>         Points1 = PointsWithinEnvelope(Shape1, Shape2.Extents);
                List <LineSegment> Segs2   = LineSegmentsWithinEnvelope(Shape2, Shape1.Extents);
                for (int I = 0; I < Points1.Count; I++)
                {
                    for (int J = 0; J < Segs2.Count; J++)
                    {
                        if (Segs2[J].Intersects(Shape1.get_Point(Points1[I])))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }

            if (Typ2 == ShapeCategories.MultiPoint)
            {
                List <int>         Points2 = PointsWithinEnvelope(Shape2, Shape1.Extents);
                List <LineSegment> Segs1   = LineSegmentsWithinEnvelope(Shape1, Shape2.Extents);
                for (int I = 0; I < Points2.Count; I++)
                {
                    for (int J = 0; J < Segs1.Count; J++)
                    {
                        if (Segs1[J].Intersects(Shape2.get_Point(Points2[I])))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }



            return(false);
        }
Exemplo n.º 21
0
        // Returns only the point index values of the shapes in the interesection of the shape extents
        private static void LineSegmentsOfInterest(MapWinGIS.Shape Shape1, MapWinGIS.Shape Shape2, ref List <LineSegment> LineSegments1, ref List <LineSegment> LineSegments2)
        {
            Envelope Rect1, Rect2, rectIntersect;

            Rect1         = new Envelope(Shape1.Extents);
            Rect2         = new Envelope(Shape2.Extents);
            rectIntersect = (Envelope)Rect1.Intersection(Rect2);
            MapWinGIS.Point pt = new MapWinGIS.Point();
            // reduce our points to points of interrest
            int  numPoints1            = Shape1.numPoints;
            bool PreviousPointIncluded = true; // we will get the first point by wrapping from the last point

            for (int I = 0; I < numPoints1; I++)
            {
                pt = Shape1.get_Point(I);
                if (rectIntersect.Intersects(pt))
                {
                    if (PreviousPointIncluded == false)
                    {
                        // Add a segment back to the point
                        LineSegments1.Add(new LineSegment(Shape1.get_Point(I - 1), pt));
                    }
                    if (I == numPoints1 - 1)
                    {
                        LineSegments1.Add(new LineSegment(pt, Shape1.get_Point(0)));
                    }
                    else
                    {
                        LineSegments1.Add(new LineSegment(pt, Shape1.get_Point(I + 1)));
                    }
                    PreviousPointIncluded = true;
                }
                else
                {
                    PreviousPointIncluded = false;
                }
            }

            int numPoints2 = Shape2.numPoints;

            PreviousPointIncluded = true;

            for (int I = 0; I < numPoints2; I++)
            {
                pt = Shape2.get_Point(I);
                if (rectIntersect.Intersects(pt))
                {
                    if (PreviousPointIncluded == false)
                    {
                        // Add a segment back to the point
                        LineSegments2.Add(new LineSegment(Shape2.get_Point(I - 1), pt));
                    }
                    if (I == numPoints2 - 1)
                    {
                        LineSegments2.Add(new LineSegment(pt, Shape2.get_Point(0)));
                    }
                    else
                    {
                        LineSegments2.Add(new LineSegment(pt, Shape2.get_Point(I + 1)));
                    }
                    PreviousPointIncluded = true;
                }
                else
                {
                    PreviousPointIncluded = false;
                }
            }
        }
Exemplo n.º 22
0
        //see: http://astronomy.swin.edu.au/~pbourke/geometry/polyarea/
        //for a simple explanation on how to calculate the area of a polygon.
        // 16. Mar 2008 modified by Jiri Kadlec for shapes in lat/long coordinates.
        /// <summary>
        /// Computes the area of a polygon. For multi-part polygons, assume holes are counter-clockwise.
        /// To calculate the area correctly, the shape must have an equal-area projection. For shapes
        /// in Lat/Long coordinates use the LLArea() function.
        /// </summary>
        /// <param name="shape">The polygon shape.</param>
        /// <returns>The area in square units, or 0.0 if it could not be found.</returns>
        public static double Area(ref MapWinGIS.Shape shape)
        {
            Error.ClearErrorLog();
            double area;

            if (shape == null)
            {
                area      = 0.0;
                gErrorMsg = "Unexpected null paramter: shape.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                return(area);
            }

            MapWinGIS.ShpfileType shpType;
            shpType = shape.ShapeType;

            if (shpType != MapWinGIS.ShpfileType.SHP_POLYGON && shpType != MapWinGIS.ShpfileType.SHP_POLYGONM && shpType != MapWinGIS.ShpfileType.SHP_POLYGONZ)
            {
                area      = 0.0;
                gErrorMsg = "Incompatible shape type: must be of type polygon in order to calculate area.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                return(area);
            }

            double totalArea = 0.0;
            double indivArea = 0.0;

            int numParts  = shape.NumParts;
            int numPoints = shape.numPoints;

            if (numParts > 1)            //dealing with a multi-part polygon, hole areas must be subtracted from total
            {
                MapWinGIS.Shape[] allPolygons = new MapWinGIS.Shape[numParts];
                int begPart;
                int endPart;
                for (int i = 0; i <= numParts - 1; i++)
                {
                    allPolygons[i]           = new MapWinGIS.ShapeClass();
                    allPolygons[i].ShapeType = shpType;

                    begPart = shape.get_Part(i);
                    if (i < numParts - 1)
                    {
                        endPart = shape.get_Part(i + 1);
                    }
                    else
                    {
                        endPart = numPoints;
                    }

                    int ptIndex = 0;
                    for (int j = begPart; j <= endPart - 1; j++)
                    {
                        allPolygons[i].InsertPoint(shape.get_Point(j), ref ptIndex);
                        ptIndex++;
                    }                    //end of creating separate polygons out of each part

                    //calculate the area for each polygon part
                    int numPolyPts = allPolygons[i].numPoints;
                    indivArea = 0.0;
                    for (int j = 0; j <= numPolyPts - 2; j++)
                    {
                        double oneX = allPolygons[i].get_Point(j).x;
                        double oneY = allPolygons[i].get_Point(j).y;
                        double twoX = allPolygons[i].get_Point(j + 1).x;
                        double twoY = allPolygons[i].get_Point(j + 1).y;

                        double trapArea = ((oneX * twoY) - (twoX * oneY));
                        indivArea += trapArea;
                    }    //end of calculating individual area for the current part
                    totalArea += indivArea;
                }        //end of looping through parts
                totalArea = 0.5 * Math.Abs(totalArea);
            }            //end of dealing with multi-part polygons
            else
            {
                for (int i = 0; i <= numPoints - 2; i++)
                {
                    double oneX = shape.get_Point(i).x;
                    double oneY = shape.get_Point(i).y;
                    double twoX = shape.get_Point(i + 1).x;
                    double twoY = shape.get_Point(i + 1).y;

                    double trapArea = ((oneX * twoY) - (twoX * oneY));
                    totalArea += trapArea;
                }
                totalArea = 0.5 * Math.Abs(totalArea);
            }

            return(totalArea);
        }
Exemplo n.º 23
0
        /// <summary>
        /// calculate the area of large shapes in lat/long coordinates.
        /// The coordinates must be in decimal degrees
        /// the return value is in square kilometres
        /// </summary>
        /// <param name="shape">Polygon shape (decimal degree coordinates)</param>
        /// <returns>Area of the shape in square kilometres</returns>
        private static double SphericPolygonArea(ref MapWinGIS.Shape shape)
        {
            // added by Jiri Kadlec 3/16/2008
            //
            // for each part of shape:
            // convert ellipsoid latitude to a latitude on equal-area unit sphere
            // convert the sphere coordinates from long/lat to x/y of sinusoidal equal-area projection
            // (x, y is in radians)
            // calculate area of the part
            // if it's a normal polygon, add it and if it's a hole, subtract it from total
            // area of shape
            //
            //note: this function uses the sphere approximation. It should be
            //used for large shapes with |max.latitude - min.latitude| > 1 degree.
            //please refer to: http://www.ucl.ac.uk/~ucessan/news/bob-aag2007.ppt
            // and: http://www.gmat.unsw.edu.au/wang/jgps/v5n12/v5n12p02.pdf

            //radius of equal-area sphere corresponding to WGS 84 ellipsoid
            double EARTH_RADIUS_SQUARED = Math.Pow(EqualAreaSphereRadius(), 2);

            //calculation modified from MapWinGeoProc.Statistics.Area
            double totalArea = 0.0;
            double indivArea = 0.0;

            int numParts  = shape.NumParts;
            int numPoints = shape.numPoints;

            if (numParts > 1) //dealing with a multi-part polygon, hole areas must be subtracted from total
            {
                MapWinGIS.Shape[] allPolygons = new MapWinGIS.Shape[numParts];
                int begPart;
                int endPart;
                for (int i = 0; i <= numParts - 1; i++)
                {
                    allPolygons[i]           = new MapWinGIS.ShapeClass();
                    allPolygons[i].ShapeType = shape.ShapeType;

                    begPart = shape.get_Part(i);
                    if (i < numParts - 1)
                    {
                        endPart = shape.get_Part(i + 1);
                    }
                    else
                    {
                        endPart = numPoints;
                    }

                    int ptIndex = 0;
                    for (int j = begPart; j <= endPart - 1; j++)
                    {
                        allPolygons[i].InsertPoint(shape.get_Point(j), ref ptIndex);
                        ptIndex++;
                    }//end of creating separate polygons out of each part

                    //calculate the area for each polygon part
                    int numPolyPts = allPolygons[i].numPoints;
                    indivArea = 0.0;
                    for (int j = 0; j <= numPolyPts - 2; j++)
                    {
                        double oneY = EqualAreaSphereLat(Utils.deg2rad(allPolygons[i].get_Point(j).y));
                        double oneX = Utils.deg2rad(allPolygons[i].get_Point(j).x) * Math.Cos(oneY);
                        double twoY = EqualAreaSphereLat(Utils.deg2rad(allPolygons[i].get_Point(j + 1).y));
                        double twoX = Utils.deg2rad(allPolygons[i].get_Point(j + 1).x) * Math.Cos(twoY);

                        double trapArea = ((oneX * twoY) - (twoX * oneY));
                        indivArea += trapArea;
                    } //end of calculating individual area for the current part
                    totalArea += indivArea;
                }     //end of looping through parts
                totalArea = 0.5 * Math.Abs(totalArea) * EARTH_RADIUS_SQUARED;
            }         //end of dealing with multi-part polygons
            else
            {
                for (int j = 0; j <= numPoints - 2; j++)
                {
                    double oneY = EqualAreaSphereLat(Utils.deg2rad(shape.get_Point(j).y));
                    double oneX = Utils.deg2rad(shape.get_Point(j).x) * Math.Cos(oneY);
                    double twoY = EqualAreaSphereLat(Utils.deg2rad(shape.get_Point(j + 1).y));
                    double twoX = Utils.deg2rad(shape.get_Point(j + 1).x) * Math.Cos(twoY);

                    double trapArea = ((oneX * twoY) - (twoX * oneY));
                    totalArea += trapArea;
                }
                totalArea = 0.5 * Math.Abs(totalArea) * EARTH_RADIUS_SQUARED;
            }

            return(totalArea);
        }
Exemplo n.º 24
0
        /// <summary>
        /// Converts a MapWinGIS.Shape of any type to the associated geometry.
        /// Clockwise/Counter clockwise arrangements are important for polygons.
        /// Any hole that isn't correctly counter-clockwise will be treated as a polygon.
        /// Any clockwise "hole" that is not contained by at least one polygon will be
        /// reversed to clockwise and returned as a polygon.
        /// NULLSHAPE || MULTIPATCH --> throws exception.
        /// POINT || POINTM || POINTZ --> Geometries.Point
        /// MULTIPOINT || MULTIPOINTM || MULTIPOINTZ --> Geometries.MultiPoint
        /// {1 part} POLYLINE || POLYLINEM || POLYLINEZ --> Geometires.LineString
        /// {n parts} POLYLINE || POLYLINEM || POLYLINEZ --> Geometires.MultiLineString
        /// {1 shell} POLYGON || POLYGONM || POLYGONZ --> Geometires.Polygon
        /// {n shells} POLYGON || POLYGONM || POLYGONZ --> Geometries.MultiPolygon
        /// </summary>
        /// <param name="mwShape">A MapWinGIS.Shape to convert to a Geometry</param>
        /// <returns>Geometry representing the shape specified by mwShape.</returns>
        ///
        public static Geometry ShapeToGeometry(MapWinGIS.Shape mwShape)
        {
            #region -------------------------- UNSUPPORTED -------------------------------------

            MapWinGIS.Point mwPoint; // a generic MapWinGIS style point

            // ------------ NOT SUPPORTED
            if (mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_NULLSHAPE ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPATCH)
            {
                throw new ArgumentException("Shape type is not supported.");
            }
            #endregion

            #region -------------------------- POINT -------------------------------------------

            // ------------- POINT
            if (mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POINT ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POINTM ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POINTZ)
            {
                // The shape represents a single point, so return a single point
                Coordinate Coord = new Coordinate(mwShape.get_Point(0).x, mwShape.get_Point(0).y);
                return(new Point(Coord));
            }

            #endregion

            #region -------------------------- MULTI POINT -------------------------------------

            if (mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPOINT ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPOINTM ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPOINTZ)
            {
                Point[] Coords = new Point[mwShape.numPoints];
                for (int pt = 0; pt < mwShape.numPoints; pt++)
                {
                    mwPoint    = mwShape.get_Point(pt);
                    Coords[pt] = new Point(mwPoint.x, mwPoint.y);
                }
                return(new MultiPoint(Coords));
            }
            #endregion

            #region -------------------------- LINE STRINGS ------------------------------------


            if (mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POLYLINE ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POLYLINEM ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POLYLINEZ)
            {
                // ------------- LINE STRING
                if (mwShape.NumParts < 2)
                {
                    Coordinate[] Coords = new Coordinate[mwShape.numPoints];
                    for (int pt = 0; pt < mwShape.numPoints; pt++)
                    {
                        mwPoint    = mwShape.get_Point(pt);
                        Coords[pt] = new Coordinate(mwPoint.x, mwPoint.y);
                    }
                    return(new LineString(Coords));
                }

                // ------------- MULTI LINE STRING
                else
                {
                    int          pt    = 0;
                    LineString[] Lines = new LineString[mwShape.NumParts];
                    for (int prt = 0; prt < mwShape.NumParts; prt++)
                    {
                        int Start = mwShape.get_Part(prt);
                        int End;
                        if (prt == mwShape.NumParts - 1)
                        {
                            End = mwShape.numPoints;
                        }
                        else
                        {
                            End = mwShape.get_Part(prt + 1);
                        }
                        Coordinate[] Coords = new Coordinate[End - Start];
                        for (int PrtPoint = 0; PrtPoint < End - Start; PrtPoint++)
                        {
                            // PrtPoint will be tracking the index for the specific linestring
                            mwPoint          = mwShape.get_Point(pt);
                            Coords[PrtPoint] = new Coordinate(mwPoint.x, mwPoint.y);
                            pt++;
                        }
                        // Create a new linestring using only the coordinates for a specific part
                        Lines[prt] = new LineString(Coords);
                    }
                    return(new MultiLineString(Lines));
                }
            }
            #endregion

            #region -------------------------- POLYGONS ----------------------------------------

            if (mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGON ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGONM ||
                mwShape.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGONZ)
            {
                // Polygons are complex and not as straight forward as linear rings.
                // A multi-part shape might just be a single polygon with a hole.

                List <NRings>     Rings = new List <NRings>();
                List <LinearRing> Holes = new List <LinearRing>();
                int pt  = 0;
                int prt = 0;
                List <LinearRing> RawRings = new List <LinearRing>();
                do
                {
                    int Start = mwShape.get_Part(prt);
                    int End;
                    if (prt >= mwShape.NumParts - 1)
                    {
                        End = mwShape.numPoints;
                    }
                    else
                    {
                        End = mwShape.get_Part(prt + 1);
                    }
                    int          Count  = End - Start + 1;
                    Coordinate[] Coords = new Coordinate[Count];
                    double       area   = 0;
                    for (int PrtPoint = 0; PrtPoint < Count - 1; PrtPoint++)
                    {
                        // PrtPoint will be tracking the index for the specific linestring
                        mwPoint          = mwShape.get_Point(pt);
                        Coords[PrtPoint] = new Coordinate(mwPoint.x, mwPoint.y);
                        if (PrtPoint > 0)
                        {
                            area += Coords[PrtPoint].X * Coords[PrtPoint - 1].Y - Coords[PrtPoint - 1].X * Coords[PrtPoint].Y;
                        }
                        pt++;
                    }
                    mwPoint           = mwShape.get_Point(Start); // close the loop
                    Coords[Count - 1] = new Coordinate(mwPoint.x, mwPoint.y);
                    area += Coords[Count - 2].X * Coords[Count - 1].Y - Coords[Count - 1].X * Coords[Count - 2].Y;

                    // if the area is negative, then the shape is counter-clockwise and therefore a hole
                    if (area < 0)
                    {
                        Holes.Add(new LinearRing(Coords));
                    }
                    else
                    {
                        Rings.Add(new NRings(Coords));
                    }

                    prt++;
                } while (prt < mwShape.NumParts);
                // Add the holes to every ring that can hold it.
                for (int iHole = 0; iHole < Holes.Count; iHole++)
                {
                    bool HolePunched = false;
                    for (int iRing = 0; iRing < Rings.Count; iRing++)
                    {
                        if (Rings[iRing].Ring.Contains(Holes[iHole]))
                        {
                            Rings[iRing].Holes.Add(Holes[iHole]);
                            HolePunched = true;
                        }
                    }
                    // If we couldn't punch the hole anywhere, then we will turn it into a polygon
                    if (HolePunched == false)
                    {
                        ILineString LS = Holes[iHole].Reverse(); //Switch to clockwise
                        Rings.Add(new NRings(LS.Coordinates));
                    }
                }

                // Create polygons from each of the rings and add them to a multipolygon
                if (Rings.Count == 1)
                {
                    if (Rings[0].Holes.Count > 0)
                    {
                        LinearRing[] HoleArray = new LinearRing[Rings[0].Holes.Count];
                        for (int iHole = 0; iHole < Rings[0].Holes.Count; iHole++)
                        {
                            HoleArray[iHole] = Rings[0].Holes[iHole];
                        }
                        return(new Polygon(Rings[0].Ring, HoleArray));
                    }
                    else
                    {
                        return(new Polygon(Rings[0].Ring));
                    }
                }
                Polygon[] Polygons = new Polygon[Rings.Count];
                for (int iRing = 0; iRing < Rings.Count; iRing++)
                {
                    if (Rings[iRing].Holes.Count > 0)
                    {
                        LinearRing[] HoleArray = new LinearRing[Rings[iRing].Holes.Count];
                        for (int iHole = 0; iHole < Rings[iRing].Holes.Count; iHole++)
                        {
                            HoleArray[iHole] = Rings[0].Holes[iHole];
                        }
                        Polygons[iRing] = new Polygon(Rings[iRing].Ring, HoleArray);
                    }
                    else
                    {
                        Polygons[iRing] = new Polygon(Rings[iRing].Ring);
                    }
                }
                return(new MultiPolygon(Polygons));
            }
            #endregion

            // There shouldn't be any way to get here.
            throw new ApplicationException("The shapetype specified is invalid, or new and not handled yet.");
        }
Exemplo n.º 25
0
        /// <summary>
        /// Finds the point that represents the "center of mass" for a polygon shape.
        /// </summary>
        /// <param name="polygon">The polygon shape.</param>
        /// <returns>The centroid: a point representing the center of mass of the polygon.</returns>
        public static MapWinGIS.Point Centroid(ref MapWinGIS.Shape polygon)
        {
            MapWinGIS.Point centroid = new MapWinGIS.PointClass();

            // Centroid function only works for polygons - return something useful instead of causing
            // crashes in client apps
            if (!(polygon.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGON || polygon.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGONZ || polygon.ShapeType == MapWinGIS.ShpfileType.SHP_POLYGONM))
            {
                centroid.x = (polygon.Extents.xMax + polygon.Extents.xMin) / 2.0F;
                centroid.y = (polygon.Extents.yMax + polygon.Extents.yMin) / 2.0F;
                return(centroid);
            }

            Error.ClearErrorLog();
            double area      = Area(ref polygon);
            int    numPoints = polygon.numPoints;
            int    numParts  = polygon.NumParts;
            double xSum      = 0;
            double ySum      = 0;

            if (numParts > 1)
            {
                //TO DO: determine how to handle this case
                //use the outermost part for finding the center????
                //what about island chains? mulitple centroids exist.
                gErrorMsg = "Sorry, centroid cannot be computed for a multi-part polygon.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                return(centroid);
            }
            else
            {
                for (int i = 0; i <= numPoints - 2; i++)
                {
                    MapWinGIS.Point currPt = new MapWinGIS.PointClass();
                    currPt = polygon.get_Point(i);
                    MapWinGIS.Point nextPt = new MapWinGIS.PointClass();
                    nextPt = polygon.get_Point(i + 1);
                    double cProduct = (currPt.x * nextPt.y) - (nextPt.x * currPt.y);

                    xSum += (currPt.x + nextPt.x) * cProduct;
                    ySum += (currPt.y + nextPt.y) * cProduct;
                }
            }
            centroid.x = xSum / (6 * area);
            centroid.y = ySum / (6 * area);

            if (centroid.x < 0 && centroid.y < 0)
            {
                if (polygon.get_Point(0).x > 0)
                {
                    //translation incorrect, flip
                    centroid.x = -1 * centroid.x;
                }
                if (polygon.get_Point(0).y > 0)
                {
                    centroid.y = -1 * centroid.y;
                }
            }

            return(centroid);
        }