/// <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(FeatureType.Polygon);

            result.CopyTableSchema(self);
            result.Projection = self.Projection;
            // 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);

                // Add the resulting polygon to the featureset
                result.Features.Add(buffer);

                // 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);
                }
            }
            return result;
        }
Exemple #2
0
        /// <summary>
        /// Erase features from one feature set where they are intersected by another feature set. 
        /// </summary>
        /// <param name="TargetFeatures">Features which will be erased in part or whole.</param>
        /// <param name="SourceFeatures">Features which represent areas to erase.</param>
        /// <param name="cancelProgressHandler">Optional parameter to report progress and cancel entire process if needed.</param>
        /// <returns>A point feature set with the randomly created features.</returns>
        public static FeatureSet EraseFeatures(IFeatureSet TargetFeatures, IFeatureSet SourceFeatures, ICancelProgressHandler cancelProgressHandler = null)
        {
            if (TargetFeatures == null || SourceFeatures == null)
            {
                return null;
            }
            //Erase features from one feature set where they are intersected by another feature set
            //Note: we use the ShapeIndices here rather than for each feature in featureset.features as a memory management technique.
            //The current version does not preserve any attribute info. 
            //Dan Ames 2/27/2013
            FeatureSet ResultFeatures = new FeatureSet();                   //the resulting featureset
            IFeature TF, SF;                                                //a single output feature
            ResultFeatures.CopyTableSchema(TargetFeatures);                 //set up the data table in the new feature set

            for (Int16 i = 0; i <= TargetFeatures.ShapeIndices.Count - 1; i++)
            {
                TF = TargetFeatures.GetFeature(i);                          //get the full undifferenced feature
                for (Int16 j = 0; j <= SourceFeatures.ShapeIndices.Count - 1; j++)
                {
                    SF = SourceFeatures.GetFeature(j);
                    if (SF.Envelope.Intersects(TF.Envelope))
                    {
                        TF = TF.Difference(SF);                             //clip off any pieces of SF that overlap FR
                    }
                    if (TF == null)
                    {                                                       //sometimes difference leaves nothing left of a feature
                        break;
                    }
                }
                if (TF != null)
                {
                    ResultFeatures.AddFeature(TF).CopyAttributes(TargetFeatures.GetFeature(i));  //add the fully clipped feature to the results
                }
                if (cancelProgressHandler != null)
                {
                    if (cancelProgressHandler.Cancel) { return null; }
                    int progress = Convert.ToInt32(i * 100 / TargetFeatures.ShapeIndices.Count);
                    cancelProgressHandler.Progress(String.Empty, progress, String.Empty);
                }
            }
            return ResultFeatures;
        }
 /// <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(ToFeatureList()); // the output features will be copied.
     if (fs.Features.Count == 0)
     {
         if (_filter.FeatureList.Count > 0)
         {
             fs.CopyTableSchema(_filter.FeatureList[0].ParentFeatureSet);
         }
     }
     return fs;
 }
        /// <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 symmetric, so only consider I X J where J <= I
                if (!self.AttributesPopulated) self.FillAttributes();
                if (!other.AttributesPopulated) other.FillAttributes();
                int i = 0;
                foreach (IFeature selfFeature in self.Features)
                {
                    List<IFeature> potentialOthers = other.Select(selfFeature.Envelope.ToExtent());
                    foreach (IFeature otherFeature in potentialOthers)
                    {
                        selfFeature.Intersection(otherFeature, result, joinType);
                    }
                    pm.CurrentValue = i;
                    i++;
                }
                pm.Reset();
            }
            if (joinType == FieldJoinType.LocalOnly)
            {
                if (!self.AttributesPopulated) self.FillAttributes();

                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)
            {
                if (!other.AttributesPopulated) other.FillAttributes();
                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;
        }
        private static IFeatureSet UnionIntersecting(IFeatureSet fs)
        {
            FeatureSet fsunion = new FeatureSet();

            // This is needed or else the table won't have the columns for copying attributes.
            fsunion.CopyTableSchema(fs);
            fsunion.Projection = fs.Projection;
            // Create a list of all the original shapes so if we union A->B we don't also union B->A
            List<int> freeFeatures = fs.Features.Select((t, i) => i).ToList();

            while (freeFeatures.Count > 0)
            {
                IFeature fOriginal = fs.Features[freeFeatures[0]];

                // Whether this gets unioned or not, it has been handled and should not be re-done.
                // We also don't want to waste time unioning shapes to themselves.
                freeFeatures.RemoveAt(0);

                // This is the unioned result.  Remember, we may just add the original feature if no
                // shapes present themselves for unioning.
                IFeature fResult = null;

                // This is the list of any shapes that get unioned with our shape.
                List<int> mergedList = new List<int>();
                bool shapeChanged;
                do
                {
                    shapeChanged = false; // reset this each time.
                    foreach (int index in freeFeatures)
                    {
                        if (fResult == null)
                        {
                            if (fOriginal.Intersects(fs.Features[index]))
                            {
                                // If FieldJoinType is set to all, and large numbers of shapes are combined,
                                // the attribute table will have a huge number of extra columns, since
                                // every column will be replicated for each instance.
                                fResult = fOriginal.Union(fs.Features[index], fsunion, FieldJoinType.LocalOnly);

                                // if the shape changed for an index greater than 0, then the newly unioned
                                // shape might now union with an earlier shape that we skipped before.
                                shapeChanged = true;
                            }
                        }
                        else
                        {
                            if (fResult.Intersects(fs.Features[index]))
                            {
                                // snowball unioned features.  Keep adding features to the same unioned shape.
                                fResult = fResult.Union(fs.Features[index], fsunion, FieldJoinType.LocalOnly);
                                shapeChanged = true;
                            }
                        }
                        if (shapeChanged)
                        {
                            // Don't modify the "freefeatures" list during a loop.  Keep track until later.
                            mergedList.Add(index);

                            // Less double-checking happens if we break rather than finishing the loop
                            // and then retest the whole loop because of a change early in the list.
                            break;
                        }
                    }
                    foreach (int index in mergedList)
                    {
                        // We don't want to add the same shape twice.
                        freeFeatures.Remove(index);
                    }
                } while (shapeChanged);

                // Add fResult, unless it is null, in which case add fOriginal.
                fsunion.Features.Add(fResult ?? fOriginal);

                // Union doesn't actually add to the output featureset.  The featureset is only
                // provided to the union method to handle column manipulation if necessary.
                fsunion.Features.Add(fResult);
            }
            return fsunion;
        }
 private static IFeatureSet UnionAll(IFeatureSet fs)
 {
     FeatureSet fsunion = new FeatureSet();
     fsunion.CopyTableSchema(fs);
     fsunion.Projection = fs.Projection;
     IFeature f = fs.Features[0];
     for (int i = 1; i < fs.Features.Count; i++)
     {
         f = f.Union(fs.Features[i], fsunion, FieldJoinType.LocalOnly);
     }
     fsunion.AddFeature(f);
     return fsunion;
 }
        public void UnionFeatureSetTest()
        {
            IFeatureSet fs = FeatureSet.Open(_shapefiles + @"Topology_Test.shp");
            FeatureSet fsunion = new FeatureSet();

            // This is needed or else the table won't have the columns for copying attributes.
            fsunion.CopyTableSchema(fs);

            // Create a list of all the original shapes so if we union A->B we don't also union B->A
            var freeFeatures = fs.Features.Select((t, i) => i).ToList();

            while (freeFeatures.Count > 0)
            {
                var fOriginal = fs.Features[freeFeatures[0]];

                // Whether this gets unioned or not, it has been handled and should not be re-done.
                // We also don't want to waste time unioning shapes to themselves.
                freeFeatures.RemoveAt(0);

                // This is the unioned result.  Remember, we may just add the original feature if no 
                // shapes present themselves for unioning.
                IFeature fResult = null;

                // This is the list of any shapes that get unioned with our shape.  
                List<int> mergedList = new List<int>();
                bool shapeChanged;
                do
                {
                    shapeChanged = false; // reset this each time.
                    foreach (int index in freeFeatures)
                    {
                        if (fResult == null)
                        {
                            if (fOriginal.Intersects(fs.Features[index]))
                            {
                                // If FieldJoinType is set to all, and large numbers of shapes are combined,
                                // the attribute table will have a huge number of extra columns, since 
                                // every column will be replicated for each instance.
                                fResult = fOriginal.Union(fs.Features[index], fsunion, FieldJoinType.LocalOnly);

                                // if the shape changed for an index greater than 0, then the newly unioned
                                // shape might now union with an earlier shape that we skipped before.
                                shapeChanged = true;
                            }
                        }
                        else
                        {
                            if (fResult.Intersects(fs.Features[index]))
                            {
                                // snowball unioned features.  Keep adding features to the same unioned shape.
                                fResult = fResult.Union(fs.Features[index], fsunion, FieldJoinType.LocalOnly);
                                shapeChanged = true;
                            }
                        }
                        if (shapeChanged)
                        {

                            // Don't modify the "freefeatures" list during a loop.  Keep track until later.
                            mergedList.Add(index);

                            // Less double-checking happens if we break rather than finishing the loop
                            // and then retest the whole loop because of a change early in the list.
                            break;
                        }

                    }
                    foreach (int index in mergedList)
                    {
                        // We don't want to add the same shape twice.
                        freeFeatures.Remove(index);
                    }
                } while (shapeChanged);

                // Add fResult, unless it is null, in which case add fOriginal.
                fsunion.Features.Add(fResult ?? fOriginal);

                // Union doesn't actually add to the output featureset.  The featureset is only
                // provided to the union method to handle column manipulation if necessary.
                fsunion.Features.Add(fResult);

            }

            // fsunion is in-memory until this is called.  Once this is called, the extension will
            // be parsed to determine that a shapefile is required.  The attributes and features will
            // be moved to variables in an appropriate shapefile class internally, and
            // then that class will save the features to the disk.
            fsunion.SaveAs(_shapefiles + @"Union_Test.shp", true);

            try
            {
                // cleanup
                File.Delete(_shapefiles + @"Union_Test.shp");
                File.Delete(_shapefiles + @"Union_Test.dbf");
                File.Delete(_shapefiles + @"Union_Test.shx");
            }
            catch (IOException)
            {
            }
        }
 /// <summary>
 /// Select the features in an IShapeSource
 /// </summary>
 /// <param name="sr"></param>
 /// <param name="filterExpression"></param>
 /// <param name="envelope"></param>
 /// <param name="startIndex"></param>
 /// <param name="maxCount"></param>
 /// <returns></returns>
 protected IFeatureSet Select(IShapeSource sr, string filterExpression, IEnvelope envelope, ref int startIndex, int maxCount)
 {
     var shapes = sr.GetShapes(ref startIndex, maxCount, envelope);
     AttributeTable at = GetAttributeTable(Filename);
     var result = new FeatureSet(FeatureType.Polygon);
     bool schemaDefined = false;
     foreach (var pair in shapes)
     {
         DataTable td = at.SupplyPageOfData(pair.Key, 1);
         if (td.Select(filterExpression).Length > 0)
         {
             if (!schemaDefined)
             {
                 schemaDefined = true;
                 result.CopyTableSchema(td);
             }
             var f = new Feature(pair.Value) {RecordNumber = pair.Key + 1, DataRow = td.Rows[0]};
             result.Features.Add(f);
             f.UpdateEnvelope();
         }
     }
     return result;
 }
        /// <summary>
        /// Show the dialog for exporting data from a feature layer.
        /// </summary>
        /// <param name="e"></param>
        public void ExportData(IFeatureLayer e)
        {
            using (var frmExport = new ExportFeature())
            {
                frmExport.Filename = e.DataSet.Filename;
                if (ShowDialog(frmExport) != DialogResult.OK) return;

                // Create a FeatureSet of features that the client wants exported
                FeatureSet fs = null;
                switch (frmExport.FeaturesIndex)
                {
                    case 0:
                        fs = (FeatureSet) e.DataSet;
                        break;
                    case 1:
                        fs = e.Selection.ToFeatureSet();
                        break;
                    case 2:
                        var features = e.DataSet.Select(e.MapFrame.ViewExtents);
                        fs = new FeatureSet(features) {Projection = e.Projection};
                        break;
                }

                if (fs.Features.Count == 0)
                {
                    fs.CopyTableSchema(e.DataSet);
                    fs.FeatureType = e.DataSet.FeatureType;
                }

                fs.SaveAs(frmExport.Filename, true);

                if (MessageBox.Show(Owner, "Do you want to load the shapefile?",
                                    "The layer was exported.",
                                    MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    LoadFeatureSetAsLayer(e, fs, Path.GetFileNameWithoutExtension(frmExport.Filename));
                }
            }
        }
Exemple #10
0
        private static IFeatureSet UnionIntersecting(IFeatureSet fs)
        {
            var fsunion = new FeatureSet();

            // This is needed or else the table won't have the columns for copying attributes.
            fsunion.CopyTableSchema(fs);
            fsunion.Projection = fs.Projection;
            // Create a list of all the original shapes so if we union A->B we don't also union B->A
            var freeFeatures = fs.Features.Select((t, i) => i).ToList();

            while (freeFeatures.Count > 0)
            {
                var fOriginal = fs.Features[freeFeatures[0]];

                // Whether this gets unioned or not, it has been handled and should not be re-done.
                // We also don't want to waste time unioning shapes to themselves.
                freeFeatures.RemoveAt(0);

                // This is the unioned result.  Remember, we may just add the original feature if no
                // shapes present themselves for unioning.
                IFeature fResult = null;

                // This is the list of any shapes that get unioned with our shape.
                var mergedList = new List<int>();
                bool shapeChanged;
                do
                {
                    shapeChanged = false; // reset this each time.
                    foreach (int index in freeFeatures)
                    {
                        var intersectSource = fResult ?? fOriginal;
                        if (intersectSource.Intersects(fs.Features[index]))
                        {
                            fResult = intersectSource.Union(fs.Features[index]);
                            shapeChanged = true;

                            // Don't modify the "freefeatures" list during a loop.  Keep track until later.
                            mergedList.Add(index);

                            // Less double-checking happens if we break rather than finishing the loop
                            // and then retest the whole loop because of a change early in the list.
                            break;
                        }
                    }

                    foreach (var index in mergedList)
                    {
                        // We don't want to add the same shape twice.
                        freeFeatures.Remove(index);
                    }
                } while (shapeChanged);

                // Add fResult, unless it is null, in which case add fOriginal.
                fsunion.Features.Add(fResult ?? fOriginal);
            }
            return fsunion;
        }