/// <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;
        }
示例#2
0
        /// <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);
        }
示例#3
0
 public BoundingBox(IEnvelope e)
 {
     LowerLeft  = new Point(e.Left(), e.Bottom());
     UpperRight = new Point(e.Right(), e.Top());
 }
示例#4
0
        /// <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);
                }
            }
        }