/// <summary>
 /// Generates an empty featureset that has the combined fields from this featureset
 /// and the specified featureset.
 /// </summary>
 /// <param name="self">This featureset</param>
 /// <param name="other">The other featureset to combine fields with.</param>
 /// <returns></returns>
 public static IFeatureSet CombinedFields(this IFeatureSet self, IFeatureSet other)
 {
     IFeatureSet result = new FeatureSet(self.FeatureType);
     Dictionary<string, DataColumn> resultColumns = new Dictionary<string, DataColumn>();
     foreach (DataColumn dc in self.DataTable.Columns)
     {
         string name = dc.ColumnName;
         int i = 1;
         while (resultColumns.ContainsKey(name))
         {
             name = dc.ColumnName + i;
             i++;
         }
         resultColumns.Add(name, dc);
     }
     foreach (DataColumn dc in other.DataTable.Columns)
     {
         string name = dc.ColumnName;
         int i = 1;
         while (resultColumns.ContainsKey(name))
         {
             name = dc.ColumnName + i;
             i++;
         }
         resultColumns.Add(name, dc);
     }
     foreach (KeyValuePair<string, DataColumn> pair in resultColumns)
     {
         result.DataTable.Columns.Add(new DataColumn(pair.Key, pair.Value.DataType));
     }
     return result;
 }
        /// <summary>
        /// Creates a new polygon featureset that is created by buffering each of the individual shapes.
        /// </summary>
        /// <param name="self">The IFeatureSet to buffer</param>
        /// <param name="distance">The double distance to buffer</param>
        /// <param name="copyAttributes">Boolean, if this is true, then the new featureset will have 
        /// the same attributes as the original.</param>
        /// <returns>The newly created IFeatureSet</returns>
        public static IFeatureSet Buffer(this IFeatureSet self, double distance, bool copyAttributes)
        {
            // Dimension the new, output featureset.  Buffered shapes are polygons, even if the 
            // original geometry is a point or a line.
            IFeatureSet result = new FeatureSet(FeatureTypes.Polygon);


            // Cycle through the features, and buffer each one separately.
            foreach (IFeature original in self.Features)
            {
                // Actually calculate the buffer geometry.
                IFeature buffer = original.Buffer(distance);

                // If copyAttributes is true, then this will copy those attributes from the original.
                if(copyAttributes)
                {
                    // Accessing the attributes should automatically load them from the datasource if
                    // they haven't been loaded already.
                    buffer.CopyAttributes(original);
                }

                // Add the resulting polygon to the featureset
                result.Features.Add(buffer);
            }
            return result;
        }
 private void OpenLayer()
 {
     OpenFileDialog ofd = new OpenFileDialog();
     ofd.Filter = "Shapefiles|*.shp";
     if (ofd.ShowDialog() != DialogResult.OK) return;
     FeatureSet fs = new FeatureSet();
     fs.Open(ofd.FileName);
     geoMap1.Layers.Add(fs);
     FeatureSet newFeature = new FeatureSet();
     newFeature.CopyTableSchema(fs);
     foreach(Feature f in fs.Features)
     {
         newFeature.Features.Add(f);   
     }
     bool stop = true;
 }
Beispiel #4
0
        /// <summary>
        /// The Voronoi Graph calculation creates a delaunay tesselation where 
        /// each point is effectively converted into triangles.
        /// </summary>
        /// <param name="points">The points to use for creating the tesselation</param>
        /// <returns></returns>
        public static IFeatureSet DelaunayLines(IFeatureSet points)
        {
            double[] vertices = points.Vertex;
            VoronoiGraph gp = Fortune.ComputeVoronoiGraph(vertices);
          
            FeatureSet result = new FeatureSet();
            foreach (VoronoiEdge edge in gp.Edges)
            {
                Coordinate c1 = edge.RightData.ToCoordinate();
                Coordinate c2 = edge.LeftData.ToCoordinate();
                LineString ls = new LineString(new List<Coordinate>{c1, c2});
                Feature f = new Feature(ls);
                result.AddFeature(f);
            }
            return result;

        }
Beispiel #5
0
        /// <summary>
        /// The Voronoi Graph calculation creates the lines that form a voronoi diagram
        /// </summary>
        /// <param name="points">The points to use for creating the tesselation</param>
        /// <returns></returns>
        public static IFeatureSet VoronoiLines(IFeatureSet points)
        {
            double[] vertices = points.Vertex;
            VoronoiGraph gp = Fortune.ComputeVoronoiGraph(vertices);

            HandleBoundaries(gp, points.Envelope);

            FeatureSet result = new FeatureSet();
            foreach (VoronoiEdge edge in gp.Edges)
            {
                Coordinate c1 = edge.VVertexA.ToCoordinate();
                Coordinate c2 = edge.VVertexB.ToCoordinate();
                LineString ls = new LineString(new List<Coordinate> { c1, c2 });
                Feature f = new Feature(ls);
                result.AddFeature(f);
            }
            return result;

        }
 private void RemoveAndInsert()
 {
     FeatureSet cities = new FeatureSet();
     FeatureSet states = new FeatureSet();
     cities.Open(@"C:\dev\SampleData\HIS_Desktop\cities.shp");
     states.Open(@"C:\dev\SampleData\HIS_Desktop\states.shp");
     IMapFeatureLayer cityLayer = geoMap1.Layers.Add(cities);
     IMapFeatureLayer stateLayer = geoMap1.Layers.Add(states);
     geoMap1.Layers.Remove(stateLayer);
     geoMap1.Layers.Insert(0, stateLayer);
 }
        /// <summary>
        /// Executes the ClipPolygonWithLine Operation tool programaticaly.
        /// Ping deleted static for external testing 01/2010
        /// </summary>
        /// <param name="input1">The input Polygon FeatureSet.</param>
        /// <param name="input2">The input Polyline FeatureSet.</param>
        /// <param name="output">The output Polygon FeatureSet.</param>
        /// <param name="cancelProgressHandler">The progress handler.</param>
        /// <returns></returns>
        public bool Execute(IFeatureSet input1, IFeatureSet input2, IFeatureSet output, ICancelProgressHandler cancelProgressHandler)
        {
            //Validates the input and output data
            if (input1 == null || input2 == null || output == null)
            {
                return false;
            }
            if (cancelProgressHandler.Cancel)
                return false;
            IFeature polygon = input1.Features[0];
            IFeature line = input2.Features[0];
            IFeatureSet resultFS = new FeatureSet(FeatureTypes.Polygon);
            int previous = 0;
            if (DoClipPolygonWithLine(ref polygon, ref line, ref output) == false)
            {
                throw new SystemException(TextStrings.Exceptioninclipin);
            }
            int intFeature = output.Features.Count;
            for (int i = 0; i < intFeature; i++)
            {
                Polygon poly = new Polygon(output.Features[i].Coordinates);
                resultFS.AddFeature(poly);

                int current = Convert.ToInt32(Math.Round(i * 100D / intFeature));
                //only update when increment in percentage
                if (current > previous)
                    cancelProgressHandler.Progress("", current, current + TextStrings.progresscompleted);
                previous = current;
            }
            cancelProgressHandler.Progress("", 100, 100 + TextStrings.progresscompleted);
            resultFS.SaveAs(output.Filename, true);
            return true;
        }
        /// <summary>
        /// Given a line that contains portion both inside and outside of the polygon, this
        /// function will split the polygon based only on the segments that completely bisect
        /// the polygon. It assumes: out->out, and in->in 2pt segments do not intersect the
        /// polygon, and out->in, in->out 2pt segments have only one point of intersection.
        /// </summary>
        /// <param name="insidePts">A boolean array indicating if a point is inside the polygon or not.</param>
        /// <param name="line">The line that intersects the polygon.</param>
        /// <param name="polygon">The polygon that will be split by the intersecting line.</param>
        /// <param name="resultSF">The shapefile that the polygon sections will be saved to.</param>
        /// <returns>False if errors were encountered or an assumption violated, true otherwise.</returns>
        private static bool Fast_ProcessPartInAndOut(ref bool[] insidePts, ref IFeature line, ref IFeature polygon, ref IFeatureSet resultSF)
        {
            int numLinePts = line.NumPoints;
            int numLineSegs = numLinePts - 1;
            int numPolyPts = polygon.NumPoints;
            int[] intersectsPerSeg = new int[numLineSegs];
            Point[][] intersectPts = new Point[numLineSegs][];
            int[][] polyIntLocs = new int[numLineSegs][]; //intersection occurs between polygon point indexed by polyIntLoc[][] and the previous point.

            //cut line into 2pt segments and put in new shapefile.
            IFeatureSet lineSegSF = new FeatureSet();

            IFeature lineSegment;
            IList<Coordinate> coordi = line.Coordinates;
            Coordinate[] secCoordinate = new Coordinate[2];
            for (int i = 0; i <= numLineSegs - 1; i++)
            {
                secCoordinate[0] = coordi[i];
                secCoordinate[1] = coordi[i + 1];
                lineSegment = new Feature(FeatureTypes.Line, secCoordinate);
                lineSegSF.Features.Add(lineSegment);
                lineSegment.Coordinates.Clear();

                intersectPts[i] = new Point[numPolyPts];
                polyIntLocs[i] = new int[numPolyPts];

            }
            //find number of intersections, intersection pts, and locations for each 2pt segment
            int numIntersects = CalcSiDeterm(ref lineSegSF, ref polygon, ref intersectsPerSeg, ref intersectPts, ref polyIntLocs);

            if (numIntersects == 0)
            {
                return false;
            }

            IFeature insideLine = new Feature();
            List<Coordinate> insideLineList = new List<Coordinate>();

            List<Coordinate> intersectSegList;
            Point startIntersect = new Point();
            bool startIntExists = false;
            bool validInsideLine = false;
            int insideStart = 0;
            int startIntPolyLoc = 0;

            //loop through each 2pt segment
            for (int i = 0; i <= numLinePts - 2; i++)
            {
                lineSegment = lineSegSF.Features[i];
                int numSegIntersects = intersectsPerSeg[i];
                //****************** case: inside->inside **************************************//
                int ptIndex;
                if (insidePts[i] && insidePts[i + 1])
                {
                    if (numSegIntersects == 0 && i != numLinePts - 2 && i != 0)
                    {
                        //add points to an inside line segment
                        if (startIntExists)
                        {
                            ptIndex = 0;
                            insideLineList.Insert(ptIndex, startIntersect.Coordinate);
                            startIntExists = false;
                            validInsideLine = true;
                            insideStart = startIntPolyLoc;
                        }
                        if (validInsideLine)
                        {
                            ptIndex = insideLine.NumPoints;
                            insideLineList.Insert(ptIndex, lineSegment.Coordinates[0]);
                        }
                    }
                    else
                    {
                        //we do not handle multiple intersections in the fast version
                        return false;
                    }

                }//end of inside->inside
                //********************** case: inside->outside ****************************************
                else if (insidePts[i] && insidePts[i + 1] == false)
                {
                    if (numSegIntersects == 0)
                    {
                        return false;
                    }
                    if (numSegIntersects == 1)
                    {
                        if (startIntExists)
                        {
                            intersectSegList = new List<Coordinate>();
                            ptIndex = 0;
                            intersectSegList.Insert(ptIndex, startIntersect.Coordinate);
                            ptIndex = 1;
                            intersectSegList.Insert(ptIndex, lineSegment.Coordinates[0]);
                            ptIndex = 2;
                            intersectSegList.Insert(ptIndex, intersectPts[i][0].Coordinate);
                            IFeature intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                            int firstPolyLoc = startIntPolyLoc;
                            int lastPolyLoc = polyIntLocs[i][0] - 1;
                            if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                            {
                                return false;
                            }

                            startIntExists = false; //we just used it up!
                        }
                        else if (insideLine.NumPoints != 0 && validInsideLine)
                        {
                            ptIndex = insideLineList.Count;
                            insideLineList.Insert(ptIndex, lineSegment.Coordinates[0]);
                            ptIndex++;
                            insideLineList.Insert(ptIndex, intersectPts[i][0].Coordinate);
                            insideLine = new Feature(FeatureTypes.Line, insideLineList);

                            int firstPolyLoc = insideStart;
                            int lastPolyLoc = polyIntLocs[i][0] - 1;
                            if (SectionPolygonWithLine(ref insideLine, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                            {
                                return false;
                            }

                            validInsideLine = false;
                            insideLine.Coordinates.Clear();
                        }
                    }
                    else
                    {
                        //we do not handle multiple intersections in the fast version
                        return false;
                    }
                } //end of inside->outside
                //********************** case: outside->inside ***************************************
                else if (insidePts[i] == false && insidePts[i + 1])
                {
                    validInsideLine = false;


                    if (numSegIntersects == 0)
                    {
                        return false;
                    }
                    if (numSegIntersects == 1)
                    {
                        startIntExists = true;
                        startIntersect = intersectPts[i][0];
                        startIntPolyLoc = polyIntLocs[i][0] - 1;
                    }
                    else
                    {
                        //we do not handle multiple intersections in the fast version
                        return false;
                    }
                }
                //************************ case: outside->outside ***********************************
                else if (insidePts[i] == false && insidePts[i + 1] == false)
                {
                    startIntExists = false;
                    validInsideLine = false;

                    if (numSegIntersects == 0)
                    {
                        //do nothing
                    }
                    else
                    {
                        //we do not handle multiple intersections in the fast version
                        return false;
                    }
                }//end of outside->outside	
            }//end of looping through 2pt segments
            return true;
        }
        /// <summary>
        /// This will clip MultiPart Polygon with line.
        /// </summary>
        /// <param name="polygon">Input Polygon.</param>
        /// <param name="line">Input Line.</param>
        /// <param name="resultFile">Output Featureset.</param>
        /// <param name="speedOptimized">The speed optimizer.</param>
        /// <returns></returns>
        public static bool ClipMultiPartPolyWithLine(ref IFeature polygon, ref IFeature line, ref IFeatureSet resultFile, bool speedOptimized)
        {
            int numParts = polygon.NumGeometries;
            if (numParts == 0)
                numParts = 1;
            if (numParts > 1)
            {
                //multiple parts
                FixMultiPartPoly(ref polygon);
                IFeature[] polyParts = new IFeature[numParts];
                SeparateParts(ref polygon, ref polyParts);
                IFeatureSet holeSF = new FeatureSet(FeatureTypes.Polygon);
                IFeatureSet tempResult = new FeatureSet(FeatureTypes.Polygon);
                IFeatureSet modPolySF = new FeatureSet(FeatureTypes.Polygon);
                IFeatureSet resultSF = new FeatureSet(FeatureTypes.Polygon);

                for (int i = 0; i <= numParts - 1; i++)
                {
                    IFeature currPart = polyParts[i];
                    if (MapWindow.Analysis.Topology.Algorithm.CGAlgorithms.IsCounterClockwise(currPart.Coordinates) == false)
                    {
                        if (speedOptimized)
                        {
                            Fast_ClipPolygonWithLine(ref currPart, ref line, ref tempResult);
                        }
                        else
                        {
                            Accurate_ClipPolygonWithLine(ref currPart, ref line, ref tempResult);
                        }
                        int numResults = tempResult.Features.Count;
                        if (numResults > 0)
                        {
                            for (int j = 0; j <= numResults - 1; j++)
                            {
                                modPolySF.Features.Add(tempResult.Features[j]);
                            }
                        }
                    }
                    else
                    {
                        holeSF.Features.Add(currPart);
                    }
                }
                if (holeSF.Features.Count > 0)
                {
                    ErasePolySFWithPolySF(ref modPolySF, ref holeSF, ref resultSF);
                }
                if (resultSF.Features.Count > 0)
                {
                    resultFile = resultSF;
                    return true;
                }
                resultFile = resultSF;
                return false;
            }
            if (speedOptimized)
                return Fast_ClipPolygonWithLine(ref polygon, ref line, ref resultFile);
            return Accurate_ClipPolygonWithLine(ref polygon, ref line, ref resultFile);
        }
        /// <summary>
        /// For lines where every point lies outside the polygon, this function will
        /// find if any 2pt segment crosses through the polygon. If so, it will split
        /// the polygon into mutliple parts using the intersecting line segments.
        /// </summary>
        /// <param name="line">The line whose points are all inside the polygon.</param>
        /// <param name="polygon">The polygon being checked for intersection.</param>
        /// <param name="resultSF">The file where new polygon sections should be saved to.</param>
        /// <returns>False if errors were encountered, true otherwise.</returns>
        private static bool ProcessAllOutside(ref IFeature line, ref IFeature polygon, ref IFeatureSet resultSF)
        {
            int numLinePts = line.NumPoints;
            int numLineSegs = numLinePts - 1;
            int numPolyPts = polygon.NumPoints;
            int[] intersectsPerSeg = new int[numLineSegs];
            Point[][] intersectPts = new Point[numLineSegs][];
            int[][] polyIntLocs = new int[numLineSegs][]; //intersection occurs between polygon point indexed by polyIntLoc[][] and the previous point.

            //cut line into 2pt segments and put in new shapefile.
            //string tempPath = System.IO.Path.GetTempPath() + "tempLineSF.shp";
            IFeatureSet lineSegSF = new FeatureSet(FeatureTypes.Line);
            //  Globals.PrepareResultSF(ref tempPath, ref lineSegSF, line.ShapeType);
            IList<Coordinate> coordi = line.Coordinates;
            Coordinate[] secCoordinate = new Coordinate[2];

            for (int i = 0; i <= numLineSegs - 1; i++)
            {
                secCoordinate[0] = coordi[i];
                secCoordinate[1] = coordi[i + 1];
                IFeature lineSegment = new Feature(FeatureTypes.Line, secCoordinate);
                lineSegSF.Features.Add(lineSegment);

                intersectPts[i] = new Point[numPolyPts];
                polyIntLocs[i] = new int[numPolyPts];
            }
            int numIntersects = CalcSiDeterm(ref lineSegSF, ref polygon, ref intersectsPerSeg, ref intersectPts, ref polyIntLocs);
            if (numIntersects == 0)
            {
                //entire line is outside the polygon, no splitting occurs
            }
            else
            {
                //intersections exist! Find out where.
                List<Coordinate> intersectSegList = new List<Coordinate>();
                for (int i = 0; i <= numLineSegs - 1; i++)
                {
                    int numSegIntersects = intersectsPerSeg[i];
                    //if there are less than 4 intersects, the line will not cross the 
                    //polygon in such a way that a new polygon section can be created.
                    if (numSegIntersects == 0)
                    {
                        //do not add the segment to the result file,
                        //this portion is not inside the polygon
                        int c = i + 1;
                        while (intersectsPerSeg[c] == 0 && c <= numLineSegs - 1)
                        {
                            c++;
                            if (c == numLineSegs)
                            {
                                break;
                            }
                        }
                        i = c - 1;
                    }
                    else
                    {
                        //there should always be an even # of intersects for a line of all outside pts
                        //find the valid intersect points from our array

                        Point[] intPts = new Point[numSegIntersects];
                        Point startPt = new Point(lineSegSF.Features[i].Coordinates[0]);

                        FindAndSortValidIntersects(numSegIntersects, ref intersectPts[i], ref intPts, ref startPt, ref polyIntLocs[i]);
                        for (int j = 0; j <= numSegIntersects - 1; j++)
                        {
                            int ptIndex = 0;
                            intersectSegList.Insert(ptIndex, intPts[j].Coordinate);
                            ptIndex = 1;
                            intersectSegList.Insert(ptIndex, intPts[j + 1].Coordinate);
                            IFeature intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);
                            int polyStartIndex = polyIntLocs[i][j] - 1;
                            int polyEndIndex = polyIntLocs[i][j + 1] - 1;
                            if (SectionPolygonWithLine(ref intersectSeg, ref polygon, polyStartIndex, polyEndIndex, ref resultSF) == false)
                            {
                                return false;
                            }
                            intersectSeg.Coordinates.Clear();
                            j++;
                        }//end of looping through segment intersect points

                    }//end of else intersects exist for 2pt segment	
                }//end of looping through 2pt line segments
            }//end of else intersects exist
            return true;
        }
 private IFeatureSet CreatePointFeatureset()
 {
     Random rnd = new Random(DateTime.Now.Millisecond);
     FeatureSet fs = new FeatureSet(FeatureTypes.Point);
     fs.DataTable.Columns.Add("Number", typeof(int));
     fs.DataTable.Columns.Add("Letter", typeof(string));
     fs.Name = "Test";
     for(int i = 0; i < 10; i++)
     {
         Feature f = new Feature(new Point(NextCoordinate(rnd)));
         fs.Features.Add(f);
         f.DataRow["Number"] = i;
         f.DataRow["Letter"] = "Shape " + i;
     }
     return fs;
 }
 private static IFeatureSet CreateLineFeatureSet()
 {
     Random rnd = new Random(DateTime.Now.Millisecond);
     FeatureSet fs = new FeatureSet(FeatureTypes.Point);
     fs.DataTable.Columns.Add("Number", typeof(int));
     fs.DataTable.Columns.Add("Letter", typeof(string));
     fs.Name = "Test";
     for (int i = 0; i < 10; i++)
     {
         List<Coordinate> coords = new List<Coordinate>();
         for(int j = 0; j < 10; j++)
         {
             coords.Add(NextCoordinate(rnd));
         }
         Feature f = new Feature(new LineString(coords));
         fs.Features.Add(f);
         f.DataRow["Number"] = i;
         f.DataRow["Letter"] = "Shape " + i;
     }
     return fs;
     
 }
 private static IFeatureSet CreatePolygonFeatureSet()
 {
     Random rnd = new Random(DateTime.Now.Millisecond);
     FeatureSet fs = new FeatureSet(FeatureTypes.Point);
     fs.DataTable.Columns.Add("Number", typeof(int));
     fs.DataTable.Columns.Add("Letter", typeof(string));
     fs.Name = "Test";
     for (int i = 0; i < 10; i++)
     {
         Coordinate center = NextCoordinate(rnd);
         List<Coordinate> shell = new List<Coordinate>();
         for (int j = 0; j < 10; j++)
         {
             Coordinate c = new Coordinate();
             double dx = 5*Math.Sin(Math.PI*(double) j/(double) 5);
             double dy = 5*Math.Cos(Math.PI*(double) j/(double) 5);
             c.X = center.X + dx;
             c.Y = center.Y + dy;
             shell.Add(c);
         }
         Polygon p = new Polygon(shell);
         Feature f = new Feature(p);
         fs.Features.Add(f);
         f.DataRow["Number"] = i;
         f.DataRow["Letter"] = "Shape " + i;
     }
     return fs;
 }
 private void CreateLayers()
 {
     FeatureSet cities = new FeatureSet();
     FeatureSet states = new FeatureSet();
     cities.Open(@"C:\dev\SampleData\HIS_Desktop\cities.shp");
     states.Open(@"C:\dev\SampleData\HIS_Desktop\states.shp");
     IMapFeatureLayer cityLayer = new MapPointLayer(cities);
     IMapFeatureLayer stateLayer = new MapPolygonLayer(states);
     geoMap1.Layers.Insert(0, cityLayer);
     geoMap1.Layers.Insert(0, stateLayer);
 }
        /// <summary>
        /// Allows for new behavior during deactivation.
        /// </summary>
        protected override void OnDeactivate()
        {
            if (_standBy) return;
            // Don't completely deactivate, but rather go into standby mode
            // where we draw only the content that we have actually locked in.
            _standBy = true;
            // base.OnDeactivate();
            if(_coordinateDialog != null)_coordinateDialog.Hide();
            if (_coordinates != null && _coordinates.Count > 1)
            {
                LineString ls = new LineString(_coordinates);
                FeatureSet fs = new FeatureSet(FeatureTypes.Line);
                fs.Features.Add(new Feature(ls));
                MapLineLayer gll = new MapLineLayer(fs);
                //gll.Symbolizer.FillColor = Color.Blue;
                gll.Symbolizer.ScaleMode = ScaleModes.Symbolic;
                gll.Symbolizer.Smoothing = true;
                gll.MapFrame = Map.MapFrame;
               
                _tempLayer = gll;
                Map.MapFrame.DrawingLayers.Add(gll);
               // Map.MapFrame.Initialize(_tempLayer);
                Map.MapFrame.Invalidate();
                Map.Invalidate();
            }

        }
Beispiel #16
0
 /// <summary>
 /// The Voronoi Graph calculation creates the lines that form a voronoi diagram
 /// </summary>
 /// <param name="points">The points to use for creating the tesselation</param>
 /// <param name="cropToExtent">The normal polygons have sharp angles that extend like stars.
 /// Cropping will ensure that the original featureset extent plus a small extra buffer amount
 /// is the outer extent of the polygons.  Errors seem to occur if the exact extent is used.</param>
 /// <param name="progHandler">A progress handler for updating progress information</param>
 /// <returns></returns>
 public static IFeatureSet VoronoiPolygons(IFeatureSet points, bool cropToExtent, IProgressHandler progHandler)
 {
     IFeatureSet fs = new FeatureSet();
     VoronoiPolygons(points, fs, cropToExtent, progHandler);
     return fs;
 }
        /// <summary>
        /// Sections a polygon into multiple parts depending on where line crosses it and if previous sectioning has occured.
        /// </summary>
        /// <param name="line">The line that splits the polygon. First and last points are intersect points.</param>
        /// <param name="polygon">The polygon that is to be split by the line.</param>
        /// <param name="polyStart">Index to polygon segment where the first intersect point is found.</param>
        /// <param name="polyEnd">Index to polygon segment where last intersect point is found.</param>
        /// <param name="resultSF">Reference to result shapefile where new polygon sections will be saved.</param>
        /// <returns>False if an error occurs, true otherwise.</returns>
        private static bool SectionPolygonWithLine(ref IFeature line, ref IFeature polygon, int polyStart, int polyEnd, ref IFeatureSet resultSF)
        {
            int numResults = resultSF.Features.Count;
            bool previousSplits = false;
            if (numResults != 0)
            {
                previousSplits = true;
            }
            //we can now make two new polygons by splitting the original one with the line segment
            IFeature poly1 = new Feature();
            IFeature poly2 = new Feature();

            SplitPolyInTwo(ref line, ref polygon, polyStart, polyEnd, ref poly1, ref poly2);
            if (previousSplits == false)
            {
                int shpIndex = 0;
                resultSF.Features.Insert(shpIndex, poly1);
                shpIndex = 1;
                resultSF.Features.Insert(shpIndex, poly2);
            }
            else
            {
                //this polygon underwent previous splittings, check
                //if the new results overlay the old ones before adding to resultSF

                IFeatureSet test1SF = new FeatureSet();
                IFeatureSet test2SF = new FeatureSet();

                if (ClipPolygonSFWithPolygon(ref resultSF, ref poly1, ref test1SF, false) == false)
                {
                    return false;
                }
                if (ClipPolygonSFWithPolygon(ref resultSF, ref poly2, ref test2SF, false) == false)
                {
                    return false;
                }
                if (test1SF.Features.Count > 0 || test2SF.Features.Count > 0)
                {
                    int numTestShapes = test1SF.Features.Count;
                    const int insertIndex = 0;
                    IFeature insertShape;
                    for (int j = 0; j <= numTestShapes - 1; j++)
                    {
                        insertShape = test1SF.Features[j];
                        resultSF.Features.Insert(insertIndex, insertShape);
                    }
                    numTestShapes = test2SF.Features.Count;
                    for (int j = 0; j <= numTestShapes - 1; j++)
                    {
                        insertShape = test2SF.Features[j];
                        resultSF.Features.Insert(insertIndex, insertShape);
                    }
                }
            }//end of checking against previous splits
            return true;
        }
 void cmdNew_Click(object sender, EventArgs e)
 {
     FeatureTypeDialog dlg = new FeatureTypeDialog();
     if (dlg.ShowDialog() != DialogResult.OK) return;
     FeatureSet fs = new FeatureSet(dlg.FeatureType);
     if(_geoMap.Projection != null) fs.Projection = _geoMap.Projection;
     fs.CoordinateType = dlg.CoordinateType;
     fs.IndexMode = false;
     IMapFeatureLayer layer = _geoMap.Layers.Add(fs);
     layer.EditMode = true;
     _geoMap.Layers.SelectedLayer = layer;
     layer.LegendText = _geoMap.Layers.UnusedName("New Layer");
  
 }
        /// <summary>
        /// For lines where every point lies within the polygon, this function will
        /// find if any 2pt segment crosses through the polygon. If so, it will split
        /// the polygon into mutliple parts using the intersecting line segments.
        /// </summary>
        /// <param name="line">The line whose points are all inside the polygon.</param>
        /// <param name="polygon">The polygon being checked for intersection.</param>
        /// <param name="resultSF">The file where new polygon sections should be saved to.</param>
        /// <returns>False if errors were encountered, true otherwise.</returns>
        private static bool ProcessAllInside(ref IFeature line, ref IFeature polygon, ref IFeatureSet resultSF)
        {

            int numLinePts = line.NumPoints;
            int numLineSegs = numLinePts - 1;
            int numPolyPts = polygon.NumPoints;
            int[] intersectsPerSeg = new int[numLineSegs];
            Point[][] intersectPts = new Point[numLineSegs][];
            int[][] polyIntLocs = new int[numLineSegs][]; //intersection occurs between polygon point indexed by polyIntLoc[][] and the previous point.

            //cut line into 2pt segments and put in new shapefile.
            IFeatureSet lineSegSF = new FeatureSet(FeatureTypes.Line);
            IList<Coordinate> coordi = line.Coordinates;
            Coordinate[] secCoordinate = new Coordinate[2];
            for (int i = 0; i <= numLineSegs - 1; i++)
            {
                secCoordinate[0] = coordi[i];
                secCoordinate[1] = coordi[i + 1];
                IFeature lineSegment = new Feature(FeatureTypes.Line, secCoordinate);
                lineSegSF.Features.Add(lineSegment);

                intersectPts[i] = new Point[numPolyPts];
                polyIntLocs[i] = new int[numPolyPts];
            }

            int numIntersects = CalcSiDeterm(ref lineSegSF, ref polygon, ref intersectsPerSeg, ref intersectPts, ref polyIntLocs);
            if (numIntersects == 0)//entire line is inside the polygon
            {
                //entire line is inside the polygon, no splitting occurs
            }
            else
            {
                //intersections exist! Find out where.
                List<Coordinate> intersectSegList = new List<Coordinate>();
                for (int i = 0; i <= numLineSegs - 1; i++)
                {
                    int numSegIntersects = intersectsPerSeg[i];
                    //if there are less than 4 intersects, the line will not cross the 
                    //polygon in such a way that a new polygon section can be created.
                    if (numSegIntersects <= 2)
                    {
                        //inside lines should be ignored, we only want a portion that crosses
                        //the polygon.
                        int c = i + 1;
                        while (intersectsPerSeg[c] <= 2 && c <= numLineSegs - 1)
                        {
                            c++;
                            if (c == numLineSegs)
                            {
                                break;
                            }
                        }
                        i = c - 1;
                    }
                    else
                    {
                        //there should always be an even # of intersects for a line of all inside pts
                        //find intersecting segments that will split the polygon
                        Point[] intPts = new Point[numSegIntersects];
                        Point startPt = new Point(lineSegSF.Features[i].Coordinates[0]);
                        FindAndSortValidIntersects(numSegIntersects, ref intersectPts[i], ref intPts, ref startPt, ref polyIntLocs[i]);

                        for (int j = 0; j <= numSegIntersects - 1; j++)
                        {
                            if (j == 0 || j == numSegIntersects - 1)
                            {
                                //Any segment formed from inside pt -> intersect pt
                                //or intersect pt -> inside pt will NOT cross the polygon.
                            }
                            else
                            {
                                int ptIndex = 0;
                                intersectSegList.Insert(ptIndex, intPts[j].Coordinate);
                                ptIndex = 1;
                                intersectSegList.Insert(ptIndex, intPts[j + 1].Coordinate);
                                IFeature intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);
                                int polyStartIndex = polyIntLocs[i][j] - 1;
                                int polyEndIndex = polyIntLocs[i][j + 1] - 1;
                                if (SectionPolygonWithLine(ref intersectSeg, ref polygon, polyStartIndex, polyEndIndex, ref resultSF) == false)
                                {
                                    return false;
                                }
                                intersectSeg.Coordinates.Clear();
                                j++;
                            }
                        }//end of looping through intersect pts
                    }//end of more than 2 intersects exist
                }//end of looping through 2pt line segments	
            }//end of else intersects exist	
            return true;
        }
 /// <summary>
 /// Handles the situation for exporting the layer as a new source.
 /// </summary>
 protected override void OnExportData()
 {
     ExportFeature frmExport = new ExportFeature();
     frmExport.Filename = DataSet.Filename;
     if (frmExport.ShowDialog() != DialogResult.OK) return;
     if (frmExport.FeaturesIndex == 0)
     {
         DataSet.SaveAs(frmExport.Filename, true);
     }
     else if (frmExport.FeaturesIndex == 1)
     {
         FeatureSet fs = _selection.ToFeatureSet();
         fs.SaveAs(frmExport.Filename, true);
     }
     else if (frmExport.FeaturesIndex == 2)
     {
         List<IFeature> features = DataSet.Select(MapFrame.Extents);
         FeatureSet fs = new FeatureSet(features);
         if (fs.Features.Count == 0)
         {
             fs.CopyTableSchema(DataSet);
         }
         fs.SaveAs(frmExport.Filename, true);               
     }
     AddToMapDialog dlgAddLayer = new AddToMapDialog();
     if (dlgAddLayer.ShowDialog() != DialogResult.OK) return;
     if (dlgAddLayer.AddLayer == false) return;
     IFeatureLayer newLayer = OpenFile(frmExport.Filename) as IFeatureLayer;
     IGroup parent = GetParentItem() as IGroup;
     if (parent != null)
     {
         int index = parent.IndexOf(this);
         if (newLayer != null)
         {
             parent.Insert(index + 1, newLayer);
         }
     }
 }
        /// <summary>
        /// For faster clipping of polygons with lines. Limits the finding of intersections to
        /// outside->inside or inside->outside 2pt segments. Assumes only one intersections exists
        /// per segment, that a segment of two inside points or two outside points will not intersect
        /// the polygon.
        /// </summary>
        /// <param name="polygon">The polygon that will be sectioned by the line.</param>
        /// <param name="line">The line that will clip the polygon into multiple parts.</param>
        /// <param name="resultSF">The in-memory shapefile where the polygon sections will be saved.</param>
        /// <returns>False if errors are encountered, true otherwise.</returns>
        public static bool Fast_ClipPolygonWithLine(ref IFeature polygon, ref IFeature line, ref IFeatureSet resultSF)
        {
            IFeatureSet resultFile = new FeatureSet(FeatureTypes.Polygon);
            if (polygon != null && line != null)
            {
                //make sure we are dealing with a valid shapefile type
                if (polygon.FeatureType == FeatureTypes.Polygon)
                {
                    //create the result shapefile if it does not already exist

                    if (!polygon.Overlaps(line))
                    {
                        resultSF = resultFile;
                        return false;
                    }
                    //find if all of the line is inside, outside, or part in and out of polygon
                    //line might intersect polygon mutliple times
                    int numPoints = line.NumPoints;
                    bool[] ptsInside = new bool[numPoints];

                    int numInside = 0;
                    int numOutside = 0;

                    int numParts = polygon.NumGeometries;
                    if (numParts == 0)
                    {
                        numParts = 1;
                    }

                    Coordinate[][] polyVertArray = new Coordinate[numParts][];
                    ConvertPolyToVertexArray(ref polygon, ref polyVertArray);

                    //check each point in the line to see if the entire line is either
                    //inside of the polygon or outside of it (we know it's inside polygon bounding box).
                    for (int i = 0; i <= numPoints - 1; i++)
                    {
                        Point currPt = new Point(line.Coordinates[i]);

                        if (polygon.Covers(currPt))
                        {
                            ptsInside[i] = true;
                            numInside += 1;
                        }
                        else
                        {
                            ptsInside[i] = false;
                            numOutside += 1;
                        }
                    }


                    //case: all points are inside polygon - check for possible intersections
                    if (numInside == numPoints)
                    {
                        //assume no intersections exist in fast version
                    }
                        //case: all points are outside of the polygon - check for possible intersections
                    else if (numOutside == numPoints)
                    {
                        //assume no intersections exist in fast version
                    }
                    else //case: part of line is inside and part is outside - find inside segments.
                    {
                        if (Fast_ProcessPartInAndOut(ref ptsInside, ref line, ref polygon, ref resultFile) == false)
                        {
                            resultSF = resultFile;
                            return false;
                        }
                    }
                    //resultSF result file, do not save to disk.
                    resultSF = resultFile;

                }
                else
                {
                    resultSF = resultFile;
                    return false;
                }
            }
            else //polygon or line is invalid
            {
                resultSF = resultFile;
                return false;
            }
            return true;
        }
        /// <summary>
        /// Calculates a union of any features that have a common value in the specified field.
        /// The output will only contain the specified field.  Example: Disolving a county 
        /// shapefile based on state name to produce a single polygon shaped like the state.
        /// </summary>
        /// <param name="self">The original featureSet to disolve the features of</param>
        /// <param name="fieldName">The string field name to use for the disolve operation</param>
        /// <returns>A featureset where the geometries of features with the same attribute in the specified field have been combined.</returns>
        public static IFeatureSet Dissolve(this IFeatureSet self, string fieldName)
        {
            Dictionary<object, IFeature> resultFeatures = new Dictionary<object, IFeature>();
            IFeatureSet result = new FeatureSet(self.FeatureType);
            result.DataTable.Columns.Add(fieldName, self.DataTable.Columns[fieldName].DataType);

            foreach (IFeature feature in self.Features)
            {
                object value = feature.DataRow[fieldName];
                if(resultFeatures.ContainsKey(value))
                {
                    IFeature union = resultFeatures[value].Union(feature);
                    union.DataRow = result.DataTable.NewRow();
                    union.DataRow[fieldName] = value;
                    resultFeatures[value] = union;
                }
                else
                {
                    IFeature union = feature.Copy();
                    union.DataRow = result.DataTable.NewRow();
                    union.DataRow[fieldName] = value;
                    resultFeatures.Add(value, feature);
                }
            }
           
            foreach (IFeature feature in resultFeatures.Values)
            {
                result.Features.Add(feature);
            }
            return result;
        }
        /// <summary>
        /// Given a line that contains portions both inside and outside of the polygon, this
        /// function will split the polygon based only on the segments that completely bisect
        /// the polygon. The possibility of mutliple intersections for any 2pt segment is taken
        /// into account.
        /// </summary>
        /// <param name="insidePts">A boolean array indicating if a point is inside the polygon or not.</param>
        /// <param name="line">The line that intersects the polygon.</param>
        /// <param name="polygon">The polygon that will be split by the intersecting line.</param>
        /// <param name="resultSF">The shapefile that the polygon sections will be saved to.</param>
        /// <returns>False if errors were encountered or an assumption violated, true otherwise.</returns>
        private static bool ProcessPartInAndOut(ref bool[] insidePts, ref IFeature line, ref IFeature polygon, ref IFeatureSet resultSF)
        {
            int numLinePts = line.NumPoints;
            int numLineSegs = numLinePts - 1;
            int numPolyPts = polygon.NumPoints;
            int[] intersectsPerSeg = new int[numLineSegs];
            Point[][] intersectPts = new Point[numLineSegs][];
            int[][] polyIntLocs = new int[numLineSegs][]; //intersection occurs between polygon point indexed by polyIntLoc[][] and the previous point.

            //cut line into 2pt segments and put in new shapefile.
            IFeatureSet lineSegSF = new FeatureSet(FeatureTypes.Line);
            IFeature lineSegment;
            IList<Coordinate> coordi = line.Coordinates;
            Coordinate[] secCoordinate = new Coordinate[2];
            for (int i = 0; i <= numLineSegs - 1; i++)
            {
                secCoordinate[0] = coordi[i];
                secCoordinate[1] = coordi[i + 1];
                lineSegment = new Feature(FeatureTypes.Line, secCoordinate);
                lineSegSF.Features.Add(lineSegment);
                lineSegment.Coordinates.Clear();

                intersectPts[i] = new Point[numPolyPts];
                polyIntLocs[i] = new int[numPolyPts];

            }
            //find number of intersections, intersection pts, and locations for each 2pt segment
            int numIntersects = CalcSiDeterm(ref lineSegSF, ref polygon, ref intersectsPerSeg, ref intersectPts, ref polyIntLocs);

            if (numIntersects == 0)
            {
                return false;
            }

            IFeature insideLine = new Feature();
            List<Coordinate> insideLineList;
            IFeature intersectSeg;
            List<Coordinate> intersectSegList;
            Point startIntersect = new Point();
            bool startIntExists = false;
            bool validInsideLine = false;
            int insideStart = 0;
            int startIntPolyLoc = 0;

            //loop through each 2pt segment
            for (int i = 0; i <= numLinePts - 2; i++)
            {
                insideLineList = new List<Coordinate>();
                lineSegment = lineSegSF.Features[i];
                int numSegIntersects = intersectsPerSeg[i];
                //****************** case: inside->inside **************************************//
                int ptIndex;
                if (insidePts[i] && insidePts[i + 1])
                {
                    if (numSegIntersects == 0 && i != numLinePts - 2 && i != 0)
                    {
                        //add points to an inside line segment
                        if (startIntExists)
                        {
                            ptIndex = 0;
                            insideLineList.Insert(ptIndex, startIntersect.Coordinate);
                            startIntExists = false;
                            validInsideLine = true;
                            insideStart = startIntPolyLoc;
                        }
                        if (validInsideLine)
                        {
                            ptIndex = insideLineList.Count;
                            insideLineList.Insert(ptIndex, lineSegment.Coordinates[0]);
                        }
                    }
                    else
                    {
                        //sort the intersects and their locations
                        Point[] intPts = new Point[numSegIntersects];
                        Point startPt = new Point(lineSegSF.Features[i].Coordinates[0]);
                        FindAndSortValidIntersects(numSegIntersects, ref intersectPts[i], ref intPts, ref startPt, ref polyIntLocs[i]);

                        for (int j = 0; j <= numSegIntersects - 1; j++)
                        {
                            if (j == 0)
                            {
                                if (startIntExists)
                                {
                                    //first intersect pt is an ending pt, it must be
                                    //combined with a starting intersect pt in order to section the polygon.

                                    intersectSegList = new List<Coordinate>();
                                    ptIndex = 0;
                                    intersectSegList.Insert(ptIndex, startIntersect.Coordinate);
                                    ptIndex = 1;
                                    intersectSegList.Insert(ptIndex, lineSegment.Coordinates[0]);
                                    ptIndex = 2;
                                    intersectSegList.Insert(ptIndex, intPts[0].Coordinate);
                                    intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                                    int firstPolyLoc = startIntPolyLoc;
                                    int lastPolyLoc = polyIntLocs[i][0] - 1;
                                    if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                                    {
                                        return false;
                                    }
                                    startIntExists = false; //we used it up!
                                }
                                else if (insideLine.NumPoints != 0 && validInsideLine)
                                {
                                    ptIndex = insideLineList.Count;
                                    insideLineList.Insert(ptIndex, lineSegment.Coordinates[0]);
                                    ptIndex++;
                                    insideLineList.Insert(ptIndex, intPts[0].Coordinate);
                                    insideLine = new Feature(FeatureTypes.Line, insideLineList);

                                    int firstPolyLoc = insideStart;
                                    int lastPolyLoc = polyIntLocs[i][0] - 1;
                                    if (SectionPolygonWithLine(ref insideLine, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                                    {
                                        return false;
                                    }

                                    validInsideLine = false;
                                    insideLine.Coordinates.Clear();
                                }
                            }
                            else if (j == numSegIntersects - 1 && i != numLinePts - 2)
                            {
                                //last intersect pt is a starting pt, it must be
                                //saved for later combination
                                startIntersect = intPts[j];
                                startIntPolyLoc = polyIntLocs[i][j] - 1;
                                startIntExists = true;
                            }
                            else if (j != 0 || j != numSegIntersects - 1)
                            {
                                //a full poly section is created by two intersect points

                                intersectSegList = new List<Coordinate>();
                                ptIndex = intersectSegList.Count;
                                intersectSegList.Insert(ptIndex, intPts[j].Coordinate);
                                ptIndex++;
                                intersectSegList.Insert(ptIndex, intPts[j + 1].Coordinate);
                                intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                                int firstPolyLoc = polyIntLocs[i][j] - 1;
                                int lastPolyLoc = polyIntLocs[i][j + 1] - 1;
                                if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                                {
                                    return false;
                                }
                                j++;
                            }
                        }
                    }

                }
                //********************** case: inside->outside ****************************************
                else if (insidePts[i] && insidePts[i + 1] == false)
                {
                    if (numSegIntersects == 0)
                    {
                        return false;
                    }
                    if (numSegIntersects == 1)
                    {
                        if (startIntExists)
                        {
                            intersectSegList = new List<Coordinate>();
                            ptIndex = 0;
                            intersectSegList.Insert(ptIndex, startIntersect.Coordinate);
                            ptIndex = 1;
                            intersectSegList.Insert(ptIndex, lineSegment.Coordinates[0]);
                            ptIndex = 2;
                            intersectSegList.Insert(ptIndex, intersectPts[i][0].Coordinate);
                            intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                            int firstPolyLoc = startIntPolyLoc;
                            int lastPolyLoc = polyIntLocs[i][0] - 1;
                            if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                            {
                                return false;
                            }

                            startIntExists = false; //we just used it up!
                        }
                        else if (insideLine.NumPoints != 0 && validInsideLine)
                        {
                            ptIndex = insideLineList.Count;
                            insideLineList.Insert(ptIndex, lineSegment.Coordinates[0]);
                            ptIndex++;
                            insideLineList.Insert(ptIndex, intersectPts[i][0].Coordinate);
                            insideLine = new Feature(FeatureTypes.Line, insideLineList);

                            int firstPolyLoc = insideStart;
                            int lastPolyLoc = polyIntLocs[i][0] - 1;
                            if (SectionPolygonWithLine(ref insideLine, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                            {
                                return false;
                            }

                            validInsideLine = false;
                            insideLine.Coordinates.Clear();
                        }
                    }
                    else
                    {
                        //sort the intersects and their locations
                        Point[] intPts = new Point[numSegIntersects];
                        Point startPt = new Point(lineSegSF.Features[i].Coordinates[0]);
                        FindAndSortValidIntersects(numSegIntersects, ref intersectPts[i], ref intPts, ref startPt, ref polyIntLocs[i]);
                        for (int j = 0; j <= numSegIntersects - 1; j++)
                        {
                            if (j == 0)
                            {
                                if (startIntExists)
                                {
                                    intersectSegList = new List<Coordinate>();
                                    ptIndex = 0;
                                    intersectSegList.Insert(ptIndex, startIntersect.Coordinate);
                                    ptIndex = 1;
                                    intersectSegList.Insert(ptIndex, lineSegment.Coordinates[0]);
                                    ptIndex = 2;
                                    intersectSegList.Insert(ptIndex, intPts[0].Coordinate);
                                    intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                                    int firstPolyLoc = startIntPolyLoc;
                                    int lastPolyLoc = polyIntLocs[i][0] - 1;
                                    if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                                    {
                                        return false;
                                    }

                                    startIntExists = false; //we just used it up!
                                }
                                else if (insideLine.NumPoints != 0 && validInsideLine)
                                {
                                    ptIndex = insideLineList.Count;
                                    insideLineList.Insert(ptIndex, lineSegment.Coordinates[0]);
                                    ptIndex++;
                                    insideLineList.Insert(ptIndex, intPts[0].Coordinate);
                                    insideLine = new Feature(FeatureTypes.Line, insideLineList);

                                    int firstPolyLoc = insideStart;
                                    int lastPolyLoc = polyIntLocs[i][0] - 1;
                                    if (SectionPolygonWithLine(ref insideLine, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                                    {
                                        return false;
                                    }

                                    validInsideLine = false;
                                    insideLine.Coordinates.Clear();
                                }
                            }
                            else
                            {
                                //section the polygon with the intersecting segment
                                //intersectSeg = new Feature();
                                intersectSegList = new List<Coordinate>();
                                ptIndex = 0;
                                intersectSegList.Insert(ptIndex, intPts[j].Coordinate);
                                ptIndex = 1;
                                intersectSegList.Insert(ptIndex, intPts[j + 1].Coordinate);
                                intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                                intersectSeg.Coordinates.Insert(ptIndex, intPts[j + 1].Coordinate);
                                int firstPolyLoc = polyIntLocs[i][j] - 1;
                                int lastPolyLoc = polyIntLocs[i][j + 1] - 1;
                                if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                                {
                                    return false;
                                }
                                j++;
                            }
                        }
                    }
                }
                    //********************** case: outside->inside ***************************************
                else if (insidePts[i] == false && insidePts[i + 1])
                {
                    validInsideLine = false;
                    startIntExists = false;

                    if (numSegIntersects == 0)
                    {
                        return false;
                    }
                    if (numSegIntersects == 1)
                    {
                        startIntExists = true;
                        startIntersect = intersectPts[i][0];
                        startIntPolyLoc = polyIntLocs[i][0] - 1;
                    }
                    else
                    {
                        //sort the intersects and their locations
                        Point[] intPts = new Point[numSegIntersects];
                        Point startPt = new Point(lineSegSF.Features[i].Coordinates[0]);
                        FindAndSortValidIntersects(numSegIntersects, ref intersectPts[i], ref intPts, ref startPt, ref polyIntLocs[i]);

                        //an odd number of intersects exist, at least one full poly section
                        //will be created along with one hanging intersect pt.
                        for (int j = 0; j <= numSegIntersects - 1; j++)
                        {
                            if (j == numSegIntersects - 1)
                            {
                                startIntExists = true;
                                startIntersect = intPts[j];
                                startIntPolyLoc = polyIntLocs[i][j] - 1;
                            }
                            else
                            {
                                intersectSegList = new List<Coordinate>();
                                ptIndex = 0;
                                intersectSegList.Insert(ptIndex, intPts[j].Coordinate);
                                ptIndex = 1;
                                intersectSegList.Insert(ptIndex, intPts[j + 1].Coordinate);
                                intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                                int firstPolyLoc = polyIntLocs[i][j] - 1;
                                int lastPolyLoc = polyIntLocs[i][j + 1] - 1;
                                if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                                {
                                    return false;
                                }
                                j++;
                            }
                        }
                    }
                }
                //************************ case: outside->outside ***********************************
                else if (insidePts[i] == false && insidePts[i + 1] == false)
                {
                    startIntExists = false;
                    validInsideLine = false;

                    if (numSegIntersects == 0)
                    {
                        //do nothing
                    }
                    else
                    {
                        //sort the intersects and their locations
                        Point[] intPts = new Point[numSegIntersects];
                        Point startPt = new Point(lineSegSF.Features[i].Coordinates[0]);
                        FindAndSortValidIntersects(numSegIntersects, ref intersectPts[i], ref intPts, ref startPt, ref polyIntLocs[i]);

                        //should always be an even amount of intersections, full poly section created
                        for (int j = 0; j <= numSegIntersects - 1; j++)
                        {
                            intersectSegList = new List<Coordinate>();
                            ptIndex = 0;
                            intersectSegList.Insert(ptIndex, intPts[j].Coordinate);
                            ptIndex = 1;
                            intersectSegList.Insert(ptIndex, intPts[j + 1].Coordinate);
                            intersectSeg = new Feature(FeatureTypes.Line, intersectSegList);

                            int firstPolyLoc = polyIntLocs[i][j] - 1;
                            int lastPolyLoc = polyIntLocs[i][j + 1] - 1;
                            if (SectionPolygonWithLine(ref intersectSeg, ref polygon, firstPolyLoc, lastPolyLoc, ref resultSF) == false)
                            {
                                return false;
                            }
                            j++;
                        }
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// This tests each feature of the input  
        /// </summary>
        /// <param name="self">This featureSet</param>
        /// <param name="other">The featureSet to perform intersection with</param>
        /// <param name="joinType">The attribute join type</param>
        /// <param name="progHandler">A progress handler for status messages</param>
        /// <returns>An IFeatureSet with the intersecting features, broken down based on the join Type</returns>
        public static IFeatureSet Intersection(this IFeatureSet self, IFeatureSet other, FieldJoinType joinType, IProgressHandler progHandler)
        {
          
            IFeatureSet result = null;
            ProgressMeter pm = new ProgressMeter(progHandler, "Calculating Intersection", self.Features.Count);
            if (joinType == FieldJoinType.All)
            {
                result = CombinedFields(self, other);
                // Intersection is symetric, so only consider I X J where J <= I
                int i=0;
                foreach(IFeature selfFeature in self.Features)
                {
                    List<IFeature> potentialOthers = other.Select(selfFeature.Envelope);
                    foreach (IFeature otherFeature in potentialOthers)
                    {
                        selfFeature.Intersection(otherFeature, result, joinType);
                        
                    }
                    pm.CurrentValue = i;
                    i++;
                }
                pm.Reset();
            }
            if (joinType == FieldJoinType.LocalOnly)
            {
                result = new FeatureSet();
                result.CopyTableSchema(self);
                result.FeatureType = self.FeatureType;
                IFeature union;
                pm = new ProgressMeter(progHandler, "Calculating Union", other.Features.Count);
                if(other.Features != null && other.Features.Count > 0)
                {
                    union = other.Features[0];
                    for(int i = 1; i < other.Features.Count; i++)
                    {
                        union = union.Union(other.Features[i]);
                        pm.CurrentValue = i;
                    }
                    pm.Reset();
                    pm = new ProgressMeter(progHandler, "Calculating Intersections", self.NumRows());
                    Extent otherEnvelope = new Extent(union.Envelope);
                    for (int shp = 0; shp < self.ShapeIndices.Count; shp++)
                    {
                        if (!self.ShapeIndices[shp].Extent.Intersects(otherEnvelope)) continue;
                        IFeature selfFeature = self.GetFeature(shp);
                        selfFeature.Intersection(union, result, joinType);
                        pm.CurrentValue = shp;
                    }
                    pm.Reset();
                }

                
            }
            if (joinType == FieldJoinType.ForeignOnly)
            {
                result = new FeatureSet();
                result.CopyTableSchema(other);
                IFeature union;
                if (self.Features != null && self.Features.Count > 0)
                {
                    pm = new ProgressMeter(progHandler, "Calculating Union", self.Features.Count);
                    union = self.Features[0];
                    for (int i = 1; i < self.Features.Count; i++)
                    {
                        union = union.Union(self.Features[i]);
                        pm.CurrentValue = i;
                    }
                    pm.Reset();
                    if (other.Features != null)
                    {
                        pm = new ProgressMeter(progHandler, "Calculating Intersection", other.Features.Count);
                        int j = 0;
                        foreach (IFeature otherFeature in other.Features)
                        {
                            IFeature test = otherFeature.Intersection(union, result, joinType);
                            if (test.BasicGeometry != null)
                            {
                                result.Features.Add(test);
                            }
                            pm.CurrentValue = j;
                            j++;
                        }
                    }
                    pm.Reset();
                }
                
                
            }
            return result;

        }
 /// <summary>
 /// As an example, choosing myFeatureLayer.SelectedFeatures.ToFeatureSet creates a new set.
 /// </summary>
 /// <returns>An in memory featureset that has not yet been saved to a file in any way.</returns>
 public FeatureSet ToFeatureSet()
 {
     FeatureSet fs = new FeatureSet(ToList()); // the output features will be copied.
     if (fs.Features.Count == 0)
     {
         if (_filter.FeatureList.Count > 0)
         {
             fs.CopyTableSchema(_filter.FeatureList[0].ParentFeatureSet);
         }
     }
     return fs;
 }
 private bool ImportFieldsFromDbf()
 {
     OpenFileDialog dlg = new OpenFileDialog();
     dlg.Filter = "DBase Files (*.dbf)|*.DBF";
     FeatureSet fs = new FeatureSet();
     FeatureSet fsTemp = new FeatureSet();
     fsTemp.CopyFeatures(_featureLayer.DataSet, true);
     if (dlg.ShowDialog() != DialogResult.OK)
         return false;
     string shapeFilePath2 = dlg.FileName;
     int count = shapeFilePath2.Length;
     shapeFilePath2 = shapeFilePath2.Remove(count - 4, 4);//remove the extension of the file
     shapeFilePath2 = shapeFilePath2 + ".shp";//add 
     fs.Open(shapeFilePath2);
     
     int noOfCol = fs.DataTable.Columns.Count;
     //Add all column header
     for (int i = 0; i < noOfCol; i++)
     {
         DataColumn dtcol = new DataColumn(fs.DataTable.Columns[i].ColumnName, fs.DataTable.Columns[i].DataType);
         if (fsTemp.DataTable.Columns.Contains(fs.DataTable.Columns[i].ColumnName) == false)
             fsTemp.DataTable.Columns.Add(dtcol);
     }
     dataGridView1.DataSource = fsTemp.DataTable;
     return true;
 }