/// <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, Envelope 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> /// 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 = new Feature(original.Geometry.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); }
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.Geometry.Intersects(fs.Features[index].Geometry)) { fResult = intersectSource.Union(fs.Features[index].Geometry); 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); }
/// <summary> /// Show the dialog for exporting data from a feature layer. /// </summary> /// <param name="layer">Layer whose data gets exported.</param> public void ExportData(IFeatureLayer layer) { using (var frmExport = new ExportFeature()) { frmExport.Filename = layer.DataSet.Filename; if (ShowDialog(frmExport) != DialogResult.OK) { return; } // Create a FeatureSet of features that the client wants exported // CGX // FeatureSet fs = null; IFeatureSet fs = null; // FIN CGX switch (frmExport.FeaturesIndex) { case 0: // CGX // fs = (FeatureSet)layer.DataSet; fs = layer.DataSet; // Fin CGX break; case 1: fs = layer.Selection.ToFeatureSet(); break; case 2: var features = layer.DataSet.Select(layer.MapFrame.ViewExtents); fs = new FeatureSet(features) { Projection = layer.Projection }; break; } if (fs == null) { return; } if (fs.Features.Count == 0) { fs.CopyTableSchema(layer.DataSet); fs.FeatureType = layer.DataSet.FeatureType; } fs.SaveAs(frmExport.Filename, true); if (MessageBox.Show(Owner, SymbologyFormsMessageStrings.FeatureLayerActions_LoadFeatures, SymbologyFormsMessageStrings.FeatureLayerActions_FeaturesExported, MessageBoxButtons.YesNo) == DialogResult.Yes) { LoadFeatureSetAsLayer(layer, fs, Path.GetFileNameWithoutExtension(frmExport.Filename)); } } }
/// <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 resultFeatures.CopyTableSchema(targetFeatures); // set up the data table in the new feature set for (short i = 0; i <= targetFeatures.ShapeIndices.Count - 1; i++) { var tf = targetFeatures.GetFeature(i); // get the full undifferenced feature for (short j = 0; j <= sourceFeatures.ShapeIndices.Count - 1; j++) { var sf = sourceFeatures.GetFeature(j); if (sf.Geometry.Envelope.Intersects(tf.Geometry.Envelope)) { tf = tf.Difference(sf.Geometry); // 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.Geometry).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); }
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.Geometry); //TODO jany_ why union feature if only geometry is used to create new feature? 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); }
/// <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, StringParser.Parse("${res:GIS.Common.Dialogs.SymbologyFormsMessageStrings.FeatureLayerActions_LoadFeatures}"), StringParser.Parse("${res:GIS.Common.Dialogs.SymbologyFormsMessageStrings.FeatureLayerActions_FeaturesExported}"), MessageBoxButtons.YesNo) == DialogResult.Yes) { LoadFeatureSetAsLayer(e, fs, Path.GetFileNameWithoutExtension(frmExport.Filename)); } } }
/// <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); }
private FeatureSet IntersectFeatures(IFeatureSet targetFeatures, IFeatureSet sourceFeatures) { if (targetFeatures == null || sourceFeatures == null) { return(null); } FeatureSet resultFeatures = new FeatureSet(); // the resulting featureset resultFeatures.CopyTableSchema(targetFeatures); // set up the data table in the new feature set ProgressBox p = new ProgressBox(0, 100, "Self intersection check progress"); p.ShowPregress(); p.SetProgressValue(0); p.SetProgressDescription("Overlay Intersect..."); double pi = Math.Round((double)(1.0 * 100 / targetFeatures.Features.Count), 2); for (int i = 0; i < targetFeatures.Features.Count; i++) { p.SetProgressValue(i * pi + pi); p.SetProgressDescription2(string.Format("{0} feature(s) is(are) checked, the remaining {1} feature(s) is(are) being queried", i + 1, targetFeatures.Features.Count - i - 1)); var tf = targetFeatures.GetFeature(i); // get the full undifferenced feature for (int j = 0; j < sourceFeatures.Features.Count; j++) { var sf = sourceFeatures.GetFeature(j); if (sf.Geometry.Intersects(tf.Geometry)) { tf = tf.Intersection(sf.Geometry); // clip off any pieces of SF that overlap FR } if (tf == null) { break; } } if (tf != null) { resultFeatures.AddFeature(tf.Geometry).CopyAttributes(targetFeatures.GetFeature(i)); } } p.CloseProgress(); return(resultFeatures); }
/// <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(); } for (int i = 0; i < self.Features.Count; i++) { IFeature selfFeature = self.Features[i]; List <IFeature> potentialOthers = other.Select(selfFeature.Geometry.EnvelopeInternal.ToExtent()); foreach (IFeature otherFeature in potentialOthers) { selfFeature.Intersection(otherFeature, result, joinType); } pm.CurrentValue = i; } pm.Reset(); } else if (joinType == FieldJoinType.LocalOnly) { if (!self.AttributesPopulated) { self.FillAttributes(); } result = new FeatureSet(); result.CopyTableSchema(self); result.FeatureType = self.FeatureType; if (other.Features != null && other.Features.Count > 0) { pm = new ProgressMeter(progHandler, "Calculating Union", other.Features.Count); IFeature union = other.Features[0]; for (int i = 1; i < other.Features.Count; i++) { union = union.Union(other.Features[i].Geometry); pm.CurrentValue = i; } pm.Reset(); pm = new ProgressMeter(progHandler, "Calculating Intersections", self.NumRows()); Extent otherEnvelope = union.Geometry.EnvelopeInternal.ToExtent(); 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(); } } else if (joinType == FieldJoinType.ForeignOnly) { if (!other.AttributesPopulated) { other.FillAttributes(); } result = new FeatureSet(); result.CopyTableSchema(other); result.FeatureType = other.FeatureType; if (self.Features != null && self.Features.Count > 0) { pm = new ProgressMeter(progHandler, "Calculating Union", self.Features.Count); IFeature union = self.Features[0]; for (int i = 1; i < self.Features.Count; i++) { union = union.Union(self.Features[i].Geometry); pm.CurrentValue = i; } pm.Reset(); if (other.Features != null) { pm = new ProgressMeter(progHandler, "Calculating Intersection", other.Features.Count); for (int i = 0; i < other.Features.Count; i++) { other.Features[i].Intersection(union, result, FieldJoinType.LocalOnly); pm.CurrentValue = i; } } pm.Reset(); } } return(result); }
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) { } }
public void UnionFeatureSetTest() { var file = Path.Combine(_shapefiles, @"Topology_Test.shp"); IFeatureSet fs = FeatureSet.Open(file); 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) { } }
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 void button2_Click(object sender, EventArgs e) { // Iterate through each properties of shapefiles foreach (CropProperties property in _properties) { // Test if checked or not foreach (ListViewItem item in listView1.CheckedItems) { if (item.Text.Contains(property.shp.Name)) { // Get original shapefile and reproject to WGS84 Shapefile file = property.shp; ProjectionInfo originalPrj = file.Projection; ProjectionInfo WGS84 = ProjectionInfo.FromProj4String(KnownCoordinateSystems.Geographic.World.WGS1984.ToProj4String()); file.Reproject(WGS84); // Create new shapefile & set projection FeatureSet result = new FeatureSet(FeatureType.Polygon); result.Projection = file.Projection; // Set new extent Extent extent = new Extent(); extent.SetValues(property.minCrop.Lng, property.minCrop.Lat, property.maxCrop.Lng, property.maxCrop.Lat); // Copy feature data result.CopyTableSchema(file); foreach (Feature f in file.Features) { // Test to see if coord is within extent Shape shp = f.ToShape(); IGeometry geom = shp.ToGeometry(); IList <Coordinate> coords = geom.Coordinates; int hit = 0; foreach (Coordinate coord in coords) { if (extent.Contains(coord)) { hit++; } else { continue; } } if (hit != 0) { // Iterate through coords in list Polygon poly = new Polygon(coords); result.AddFeature(poly).CopyAttributes(f); } else { continue; } } // Project pts back to original and save result.Reproject(originalPrj); if (property.path.Contains(".shp")) { result.SaveAs(property.path, true); } else { result.SaveAs(property.path + ".shp", true); } } } } this.Close(); }