/// <summary> /// This uses extent checking (rather than full polygon intersection checking). It will add /// any members that are either contained by or intersect with the specified region /// depending on the SelectionMode property. The order of operation is the region /// acting on the feature, so Contains, for instance, would work with points. /// </summary> /// <param name="region"></param> /// <param name="affectedArea">The affected area of this addition</param> /// <returns>True if any item was actually added to the collection</returns> public bool AddRegion(IEnvelope region, out IEnvelope affectedArea) { bool added = false; SuspendChanges(); affectedArea = new Envelope(); Stopwatch sw = new Stopwatch(); Stopwatch total = new Stopwatch(); total.Start(); foreach (IFeature f in FeatureList) { bool doAdd = false; if (_selectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } else if (_selectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } IGeometry reg; if (region.Width == 0 && region.Height == 0) { reg = new Point(region.X, region.Y); } else if (region.Height == 0 || region.Width == 0) { Coordinate[] coords = new Coordinate[2]; coords[0] = new Coordinate(region.X, region.Y); coords[1] = new Coordinate(region.Bottom(), region.Right()); reg = new LineString(coords); } else { reg = region.ToPolygon(); } IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (_selectionMode) { case SelectionMode.Contains: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) doAdd = true; } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) doAdd = true; break; case SelectionMode.Covers: if (reg.Covers(geom)) doAdd = true; break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) doAdd = true; break; case SelectionMode.Intersects: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) doAdd = true; } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) doAdd = true; break; case SelectionMode.Touches: if (reg.Touches(geom)) doAdd = true; break; case SelectionMode.Within: if (reg.Within(geom)) doAdd = true; break; } if (doAdd) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } sw.Start(); ResumeChanges(); sw.Stop(); total.Stop(); Debug.WriteLine("Geometry Intersection Time: " + sw.ElapsedMilliseconds); Debug.WriteLine("Total Intersection Time: " + total.ElapsedMilliseconds); return added; }
/// <summary> /// This uses extent checking (rather than full polygon intersection checking). It will add /// any members that are either contained by or intersect with the specified region /// depending on the SelectionMode property. The order of operation is the region /// acting on the feature, so Contains, for instance, would work with points. /// </summary> /// <param name="region"></param> /// <param name="affectedArea">The affected area of this addition</param> /// <returns>True if any item was actually added to the collection</returns> public bool AddRegion(IEnvelope region, out IEnvelope affectedArea) { bool added = false; SuspendChanges(); affectedArea = new Envelope(); #if DEBUG var total = new Stopwatch(); total.Start(); #endif foreach (IFeature f in FeatureList) { bool doAdd = false; if (_selectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } else if (_selectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } IGeometry reg; if (region.Width == 0 && region.Height == 0) { reg = new Point(region.X, region.Y); } else if (region.Height == 0 || region.Width == 0) { Coordinate[] coords = new Coordinate[2]; coords[0] = new Coordinate(region.X, region.Y); coords[1] = new Coordinate(region.Bottom(), region.Right()); reg = new LineString(coords); } else { reg = region.ToPolygon(); } IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (_selectionMode) { case SelectionMode.Contains: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) { doAdd = true; } } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) { doAdd = true; } break; case SelectionMode.Covers: if (reg.Covers(geom)) { doAdd = true; } break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) { doAdd = true; } break; case SelectionMode.Intersects: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) { doAdd = true; } } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) { doAdd = true; } break; case SelectionMode.Touches: if (reg.Touches(geom)) { doAdd = true; } break; case SelectionMode.Within: if (reg.Within(geom)) { doAdd = true; } break; } if (doAdd) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } #if DEBUG var sw = new Stopwatch(); sw.Start(); #endif ResumeChanges(); #if DEBUG sw.Stop(); total.Stop(); Debug.WriteLine("Geometry Intersection Time: " + sw.ElapsedMilliseconds); Debug.WriteLine("Total Intersection Time: " + total.ElapsedMilliseconds); #endif return(added); }
public BoundingBox(IEnvelope e) { LowerLeft = new Point(e.Left(), e.Bottom()); UpperRight = new Point(e.Right(), e.Top()); }
/// <summary> /// Gets all data series that match the /// specified criteria and are within the geographic polygon /// </summary> /// <param name="polygons">one or multiple polygons</param> /// <param name="keywords">array of keywords. If set to null, /// results will not be filtered by keyword.</param> /// <param name="startDate">start date. If set to null, results will not be filtered by start date.</param> /// <param name="endDate">end date. If set to null, results will not be filtered by end date.</param> /// <param name="serviceIDs">array of serviceIDs provided by GetServicesInBox. /// <param name="bgWorker">The background worker (may be null) for reporting progress</param> /// <param name="e">The results of the search (convert to DataTable)</param> /// If set to null, results will not be filtered by web service.</param> /// <returns>A list of data series matching the specified criteria</returns> public void GetSeriesCatalogInPolygon(IList <IFeature> polygons, string[] keywords, DateTime startDate, DateTime endDate, int[] serviceIDs, IProgressHandler bgWorker, DoWorkEventArgs e) { double tileWidth = 1.0; //the initial tile width is set to 1 degree double tileHeight = 1.0; //the initial tile height is set to 1 degree //(1): Get the union of the polygons if (polygons.Count == 0) { throw new ArgumentException("The number of polygons must be greater than zero."); } // Check for cancel bgWorker.CheckForCancel(); if (polygons.Count > 1) { bgWorker.ReportProgress(0, "Processing Polygons"); } //get the list of series var fullSeriesList = new List <SeriesDataCart>(); foreach (IFeature polygon in polygons) { //Split the polygon area bounding box into 1x1 decimal degree tiles IEnvelope env = polygon.Envelope; Box extentBox = new Box(env.Left(), env.Right(), env.Bottom(), env.Top()); IList <Box> tiles = SearchHelper.CreateTiles(extentBox, tileWidth, tileHeight); int numTiles = tiles.Count; for (int i = 0; i < numTiles; i++) { Box tile = tiles[i]; bgWorker.CheckForCancel(); // Do the web service call IEnumerable <SeriesDataCart> tileSeriesList = GetSeriesCatalogForBox(tile.XMin, tile.XMax, tile.YMin, tile.YMax, keywords, startDate, endDate, serviceIDs); // Clip the points by polygon IEnumerable <SeriesDataCart> seriesInPolygon = SearchHelper.ClipByPolygon(tileSeriesList, polygon); fullSeriesList.AddRange(seriesInPolygon); // Report progress { string message = fullSeriesList.Count.ToString(); int percentProgress = (i * 100) / numTiles + 1; bgWorker.ReportProgress(percentProgress, message); } } } //(4) Create the Feature Set SearchResult resultFs = null; if (fullSeriesList.Count > 0) { bgWorker.ReportProgress(0, "Calculating Points"); resultFs = SearchHelper.ToFeatureSetsByDataSource(fullSeriesList); } // (5) Final Background worker updates if (e != null) { bgWorker.CheckForCancel(); // Report progress bgWorker.ReportProgress(100, "Search Finished"); e.Result = resultFs; } }
/// <inheritdocs/> public void RemoveAt(int index) { // Get shape range so we can update header smartly int startIndex = index; IFeatureSet ifs = Select(null, null, ref startIndex, 1); if (ifs.NumRows() > 0) { var shx = new ShapefileIndexFile(); shx.Open(Filename); shx.Shapes.RemoveAt(index); shx.Save(); AttributeTable dbf = GetAttributeTable(Filename); dbf.RemoveRowAt(index); if (_trackDeletedRows) { _deletedRows = dbf.DeletedRows; } // Update extent in header if feature being deleted is NOT completely contained var hdr = new ShapefileHeader(Filename); IEnvelope featureEnv = ifs.GetFeature(0).Envelope; if (featureEnv.Left() <= hdr.Xmin || featureEnv.Right() >= hdr.Xmax || featureEnv.Top() >= hdr.Ymax || featureEnv.Bottom() <= hdr.Ymin) { UpdateExtents(); } // Update the Quadtree if (null != Quadtree) { Quadtree.Remove(featureEnv, index); } } }