Ejemplo n.º 1
0
        /// <summary>
        /// Test the intersection with a shape range.
        /// </summary>
        /// <param name="shape">The shape to do intersection calculations with.</param>
        /// <returns>True, if both intersect.</returns>
        public bool Intersects(ShapeRange shape)
        {
            // Extent check first. If the extents don't intersect, then this doesn't intersect.
            if (!Extent.Intersects(shape.Extent))
            {
                return(false);
            }

            switch (FeatureType)
            {
            case FeatureType.Polygon:
                PolygonShape.Epsilon = Epsilon;
                return(PolygonShape.Intersects(this, shape));

            case FeatureType.Line:
                LineShape.Epsilon = Epsilon;
                return(LineShape.Intersects(this, shape));

            case FeatureType.Point:
                PointShape.Epsilon = Epsilon;
                return(PointShape.Intersects(this, shape));

            default: return(false);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Test the intersection with a shape range.
        /// </summary>
        /// <param name="shape">The shape to do intersection calculations with.</param>
        /// <returns>True, if both intersect.</returns>
        public bool Intersects(ShapeRange shape)
        {
            // Extent check first. If the extents don't intersect, then this doesn't intersect.
            if (!Extent.Intersects(shape.Extent))
            {
                return(false);
            }
            Shape shape0 = new Shape(this);
            Shape shape1 = new Shape(shape);

            return(shape0.ToGeometry().Intersects(shape1.ToGeometry()));
            //switch (FeatureType)
            //{
            //    case FeatureType.Polygon:
            //        PolygonShape.Epsilon = Epsilon;
            //        return PolygonShape.Intersects(this, shape);
            //    case FeatureType.Line:
            //        LineShape.Epsilon = Epsilon;
            //        return LineShape.Intersects(this, shape);
            //    case FeatureType.Point:
            //        PointShape.Epsilon = Epsilon;
            //        return PointShape.Intersects(this, shape);
            //    default: return false;
            //}
        }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public virtual List<IFeature> Select(Extent region, out Extent affectedRegion)
        {
            var result = new List<IFeature>();
            affectedRegion = new Extent();

            if (IndexMode)
            {
                var aoi = new ShapeRange(region);
                var shapes = ShapeIndices;
                for (var shp = 0; shp < shapes.Count; shp++)
                {
                    if (!shapes[shp].Intersects(aoi))
                    {
                        continue;
                    }

                    var feature = GetFeature(shp);
                    affectedRegion.ExpandToInclude(feature.Envelope.ToExtent());
                    result.Add(feature);
                }
            }
            else
            {
                foreach (var feature in Features)
                {
                    if (!region.Intersects(feature.Envelope) ||
                       !feature.Intersects(region.ToEnvelope()))
                    {
                        continue;
                    }
                  
                    result.Add(feature);
                    affectedRegion.ExpandToInclude(feature.Envelope.ToExtent());
                }
            }

            return result;
        }
Ejemplo n.º 4
0
        /// <inheritdocs/>
        public Dictionary <int, Shape> GetShapes(ref int startIndex, int count, IEnvelope envelope)
        {
            Dictionary <int, Shape> result = new Dictionary <int, Shape>();
            ShapefileIndexFile      shx    = CacheShapeIndexFile();

            // Check to ensure the fileName is not null
            if (Filename == null)
            {
                throw new NullReferenceException(Filename);
            }

            if (File.Exists(Filename) == false)
            {
                throw new FileNotFoundException(Filename);
            }

            // Get the basic header information.
            ShapefileHeader header = new ShapefileHeader(Filename);
            Extent          ext    = new Extent(new[] { header.Xmin, header.Ymin, header.Xmax, header.Ymax });

            if (envelope != null)
            {
                if (!ext.Intersects(envelope))
                {
                    return(result);
                }
            }

            // Check to ensure that the fileName is the correct shape type
            if (header.ShapeType != ShapeType &&
                header.ShapeType != ShapeTypeM &&
                header.ShapeType != ShapeTypeZ)
            {
                throw new ArgumentException("Wrong feature type.");
            }

            FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read);

            if (fs.Length == 100)
            {
                // The shapefile is empty so we can simply return here
                fs.Close();
                return(result);
            }

            int shapesTested   = 0;
            int shapesReturned = 0;

            // Use spatial index if we have one
            if (null != _spatialIndex && null != envelope)
            {
                IList spatialQueryResults = _spatialIndex.Query(envelope);

                // Sort the results from low to high index
                var sqra = new int[spatialQueryResults.Count];
                spatialQueryResults.CopyTo(sqra, 0);
                Array.Sort(sqra);

                foreach (int shp in sqra)
                {
                    if (shp >= startIndex)
                    {
                        Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope);
                        shapesTested++;
                        if (null != myShape)
                        {
                            shapesReturned++;
                            result.Add(shp, myShape);
                            if (shapesReturned >= count)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                int numShapes = shx.Shapes.Count;
                for (int shp = startIndex; shp < numShapes; shp++)
                {
                    Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope);
                    shapesTested++;
                    if (null != myShape)
                    {
                        shapesReturned++;
                        result.Add(shp, myShape);
                        if (shapesReturned >= count)
                        {
                            break;
                        }
                    }
                }
            }
            startIndex += shapesTested;
            fs.Close();
            return(result);
        }
Ejemplo n.º 5
0
        /// <inheritdoc/>
        public virtual List<IFeature> Select(Extent region, out Extent affectedRegion)
        {
            List<IFeature> result = new List<IFeature>();
            if (IndexMode)
            {
                ShapeRange aoi = new ShapeRange(region);
                Extent affected = new Extent();
                List<ShapeRange> shapes = ShapeIndices;
                if (shapes != null)
                {
                    //ProgressMeter = new ProgressMeter(ProgressHandler, "Selecting shapes", shapes.Count);
                    for (int shp = 0; shp < shapes.Count; shp++)
                    {
                        //ProgressMeter.Next();
                        if (!shapes[shp].Intersects(aoi))
                        {
                            continue;
                        }

                        IFeature f = GetFeature(shp);
                        affected.ExpandToInclude(shapes[shp].Extent);
                        result.Add(f);
                    }
                    //ProgressMeter.Reset();
                }

                affectedRegion = affected;
                return result;
            }

            affectedRegion = new Extent();

            bool useProgress = (Features.Count > 10000);
            //ProgressMeter = new ProgressMeter(ProgressHandler, "Selecting Features", Features.Count);
            foreach (IFeature feature in Features)
            {
                //if (useProgress)
                //    ProgressMeter.Next();
                if (!region.Intersects(feature.Envelope))
                {
                    continue;
                }
                if (!feature.Intersects(region.ToEnvelope()))
                {
                    continue;
                }
                result.Add(feature);
                affectedRegion.ExpandToInclude(feature.Envelope.ToExtent());
            }
            //if (useProgress)
            //    ProgressMeter.Reset();

            return result;
        }
Ejemplo n.º 6
0
        /// <inheritdocs/>
        public Dictionary<int, Shape> GetShapes(ref int startIndex, int count, IEnvelope envelope)
        {
            Dictionary<int, Shape> result = new Dictionary<int, Shape>();
            ShapefileIndexFile shx = CacheShapeIndexFile();

            // Check to ensure the fileName is not null
            if (Filename == null)
            {
                throw new NullReferenceException(Filename);
            }

            if (File.Exists(Filename) == false)
            {
                throw new FileNotFoundException(Filename);
            }

            // Get the basic header information.
            ShapefileHeader header = new ShapefileHeader(Filename);
            Extent ext = new Extent(new[] { header.Xmin, header.Ymin, header.Xmax, header.Ymax });
            if (envelope != null)
            {
                if (!ext.Intersects(envelope)) return result;
            }

            // Check to ensure that the fileName is the correct shape type
            if (header.ShapeType != ShapeType &&
                 header.ShapeType != ShapeTypeM &&
                 header.ShapeType != ShapeTypeZ)
            {
                throw new ArgumentException("Wrong feature type.");
            }

            FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            if (fs.Length == 100)
            {
                // The shapefile is empty so we can simply return here
                fs.Close();
                return result;
            }

            int shapesTested = 0;
            int shapesReturned = 0;

            // Use spatial index if we have one
            if (null != _spatialIndex && null != envelope)
            {
                IList spatialQueryResults = _spatialIndex.Query(envelope);

                // Sort the results from low to high index
                var sqra = new int[spatialQueryResults.Count];
                spatialQueryResults.CopyTo(sqra, 0);
                Array.Sort(sqra);

                foreach (int shp in sqra)
                {
                    if (shp >= startIndex)
                    {
                        Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope);
                        shapesTested++;
                        if (null != myShape)
                        {
                            shapesReturned++;
                            result.Add(shp, myShape);
                            if (shapesReturned >= count) break;
                        }
                    }
                }
            }
            else
            {
                int numShapes = shx.Shapes.Count;
                for (int shp = startIndex; shp < numShapes; shp++)
                {
                    Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope);
                    shapesTested++;
                    if (null != myShape)
                    {
                        shapesReturned++;
                        result.Add(shp, myShape);
                        if (shapesReturned >= count) break;
                    }
                }
            }
            startIndex += shapesTested;
            fs.Close();
            return result;
        }
Ejemplo n.º 7
0
        private List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart> GetSeriesListForExtent(Extent extent, IEnumerable<string> keywords, double tileWidth, double tileHeight,
            DateTime startDate, DateTime endDate, ICollection<WebServiceNode> serviceIDs,
            BusinessObjects.Models.IProgressHandler bgWorker, Func<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart, bool> seriesFilter)
        {
            var servicesToSearch = new List<Tuple<WebServiceNode[], Extent>>();
            if (serviceIDs.Count > 0)
            {
                foreach (var webService in serviceIDs)
                {
                    if (webService.ServiceBoundingBox == null)
                    {
                        servicesToSearch.Add(new Tuple<WebServiceNode[], Extent>(new[] { webService }, extent));
                        continue;
                    }
                    const double eps = 0.05; //tolerance (0.05 deg) used for services whose bounding box is one point
                    var wsBox = webService.ServiceBoundingBox;
                    var wsExtent = new Extent(wsBox.XMin - eps, wsBox.YMin - eps, wsBox.XMax + eps, wsBox.YMax + eps);
                    if (wsExtent.Intersects(extent))
                    {
                        servicesToSearch.Add(new Tuple<WebServiceNode[], Extent>(new[] { webService }, wsExtent.Intersection(extent)));
                    }
                }
            }
            else
            {
                servicesToSearch.Add(new Tuple<WebServiceNode[], Extent>(new WebServiceNode[] { }, extent));
            }

            var servicesWithExtents = new List<Tuple<WebServiceNode[], List<Extent>>>(servicesToSearch.Count);
            int totalTilesCount = 0;
            foreach (var wsInfo in servicesToSearch)
            {
                var tiles = SearchHelper.CreateTiles(wsInfo.Item2, tileWidth, tileHeight);
                servicesWithExtents.Add(new Tuple<WebServiceNode[], List<Extent>>(wsInfo.Item1, tiles));
                totalTilesCount += tiles.Count;
            }

            var fullSeriesList = new List<List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>>();
            long  currentTileIndex = 0;
            int tilesFinished = 0;
            totalSeriesCount = 0;

            bgWorker.ReportProgress(0, "0 Series found");

            var serviceLoopOptions = new ParallelOptions
                {
                        CancellationToken = bgWorker.CancellationToken,
                        MaxDegreeOfParallelism = 2,
                };
            var tileLoopOptions = new ParallelOptions
                {
                        CancellationToken = bgWorker.CancellationToken,
                        // Note: currently HIS Central returns timeout if many requests are sent in the same time.
                        // To test set  MaxDegreeOfParallelism = -1
                        MaxDegreeOfParallelism = 4,
                };

            Parallel.ForEach(servicesWithExtents, serviceLoopOptions, wsInfo =>
            {
                bgWorker.CheckForCancel();
                var ids = wsInfo.Item1.Select(item => item.ServiceID).ToArray();
                var tiles = wsInfo.Item2;

                Parallel.ForEach(tiles, tileLoopOptions, tile =>
                {
                    var current = Interlocked.Add(ref currentTileIndex, 1);
                    bgWorker.CheckForCancel();

                    // Do the web service call
                    var tileSeriesList = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();

                    if (SearchSettings.AndSearch == true)
                    {
                        //CHANGES FOR "AND" SEARCH
                        var totalTileSeriesList = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                        var tileSeriesList2 = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                        var tileSeriesList3 = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                        var tileSeriesList4 = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();

                        SeriesComparer sc = new SeriesComparer();

                        for (int i = 0; i < keywords.Count(); i++)
                        {
                            String keyword = keywords.ElementAt(i);

                            bgWorker.CheckForCancel();
                            var series = GetSeriesCatalogForBox(tile.MinX, tile.MaxX, tile.MinY, tile.MaxY, keyword, startDate, endDate, ids, bgWorker, current, totalTilesCount);
                            totalTileSeriesList.AddRange(series);
                            if (tileSeriesList.Count() == 0)
                            {
                                if (i == 0)
                                {
                                    tileSeriesList.AddRange(series);
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {

                                tileSeriesList2.AddRange(tileSeriesList.Intersect(series, sc));
                                tileSeriesList.Clear();
                                tileSeriesList.AddRange(tileSeriesList2);
                                tileSeriesList2.Clear();
                            }
                        }

                        for (int i = 0; i < tileSeriesList.Count(); i++)
                        {
                            tileSeriesList4 = totalTileSeriesList.Where(item => (item.SiteName.Equals(tileSeriesList.ElementAt(i).SiteName))).ToList();
                            tileSeriesList3.AddRange(tileSeriesList4);
                        }

                        tileSeriesList = tileSeriesList3;
                    }
                    else
                    {
                        tileSeriesList = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                        foreach (var keyword in keywords)
                        {
                            bgWorker.CheckForCancel();
                            var series = GetSeriesCatalogForBox(tile.MinX, tile.MaxX, tile.MinY, tile.MaxY, keyword, startDate, endDate, ids, bgWorker, current, totalTilesCount);
                            tileSeriesList.AddRange(series);
                        }
                    }
                    //END CHANGES FOR "AND" SEARCH

                    bgWorker.CheckForCancel();
                    if (tileSeriesList.Count > 0)
                    {
                        var filtered = tileSeriesList.Where(seriesFilter).ToList();
                        if (filtered.Count > 0)
                        {
                            lock (_lockGetSeries)
                            {
                                totalSeriesCount += filtered.Count;
                                fullSeriesList.Add(filtered);
                            }
                        }
                    }

                    // Report progress
                    var currentFinished = Interlocked.Add(ref tilesFinished, 1);
                    var message = string.Format("{0} Series found", totalSeriesCount);
                    var percentProgress = (currentFinished * 100) / totalTilesCount;
                    bgWorker.ReportProgress(percentProgress, message);
                });
            });

            // Collect all series into result list
            var result = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>(totalSeriesCount);
            fullSeriesList.ForEach(result.AddRange);
            return result;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// For each coordinate in the other part, if it falls in the extent of this polygon, a
        /// ray crossing test is used for point in polygon testing.  If it is not in the extent,
        /// it is skipped.
        /// </summary>
        /// <param name="polygonShape">The part of the polygon to analyze polygon</param>
        /// <param name="otherPart">The other part</param>
        /// <returns>Boolean, true if any coordinate falls inside the polygon</returns>
        private static bool ContainsVertex(ShapeRange polygonShape, PartRange otherPart)
        {
            // Create an extent for faster checking in most cases
            Extent ext = polygonShape.Extent;

            foreach (Vertex point in otherPart)
            {
                // This extent check shortcut should help speed things up for large polygon parts
                if (!ext.Intersects(point))
                {
                    continue;
                }

                // Imagine a ray on the horizontal starting from point.X -> infinity.  (In practice this can be ext.XMax)
                // Count the intersections of segments with that line.  If the resulting count is odd, the point is inside.
                Segment ray          = new Segment(point.X, point.Y, ext.MaxX, point.Y);
                int[]   numCrosses   = new int[polygonShape.NumParts]; // A cross is a complete cross.  Coincident doesn't count because it is either 0 or 2 crosses.
                int     totalCrosses = 0;
                int     iPart        = 0;
                foreach (PartRange ring in polygonShape.Parts)
                {
                    foreach (Segment segment in ring.Segments)
                    {
                        if (segment.IntersectionCount(ray) != 1)
                        {
                            continue;
                        }
                        numCrosses[iPart]++;
                        totalCrosses++;
                    }
                    iPart++;
                }

                // If we didn't actually have any polygons we cant intersect with anything
                if (polygonShape.NumParts < 1)
                {
                    return(false);
                }

                // For shapes with only one part, we don't need to test part-containment.
                if (polygonShape.NumParts == 1 && totalCrosses % 2 == 1)
                {
                    return(true);
                }

                // This used to check to see if totalCrosses == 1, but now checks to see if totalCrosses is an odd number.
                // This change was made to solve the issue described in HD Issue 8593 (http://hydrodesktop.codeplex.com/workitem/8593).
                if (totalCrosses % 2 == 1)
                {
                    return(true);
                }

                totalCrosses = 0;
                for (iPart = 0; iPart < numCrosses.Length; iPart++)
                {
                    int count = numCrosses[iPart];
                    // If this part does not contain the point, don't bother trying to figure out if the part is a hole or not.
                    if (count % 2 == 0)
                    {
                        continue;
                    }

                    // If this particular part is a hole, subtract the total crosses by 1,  otherwise add one.
                    // This takes time, so we want to do this as few times as possible.
                    if (polygonShape.Parts[iPart].IsHole())
                    {
                        totalCrosses--;
                    }
                    else
                    {
                        totalCrosses++;
                    }
                }
                return(totalCrosses > 0);
            }
            return(false);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Given a geographic extent, this tests the "IsVisible", "UseDynamicVisibility",
 /// "DynamicVisibilityMode" and "DynamicVisibilityWidth"
 /// In order to determine if this layer is visible.
 /// </summary>
 /// <param name="geographicExtent">The geographic extent, where the width will be tested.</param>
 /// <returns>Boolean, true if this layer should be visible for this extent.</returns>
 public bool VisibleAtExtent(Extent geographicExtent)
 {
     return(Extent.Intersects(geographicExtent));
 }
Ejemplo n.º 10
0
        private List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart> GetSeriesListForExtent(Extent extent, IEnumerable<string> keywords, double tileWidth, double tileHeight,
            DateTime startDate, DateTime endDate, ICollection<WebServiceNode> serviceIDs,
            //BusinessObjects.Models.IProgressHandler bgWorker,
            Func<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart, bool> seriesFilter)
        {
            var servicesToSearch = new List<Tuple<WebServiceNode[], Extent>>();
            if (serviceIDs.Count > 0)
            {
                foreach (var webService in serviceIDs)
                {
                    if (webService.ServiceBoundingBox == null)
                    {
                        servicesToSearch.Add(new Tuple<WebServiceNode[], Extent>(new[] { webService }, extent));
                        continue;
                    }
                    const double eps = 0.05; //tolerance (0.05 deg) used for services whose bounding box is one point
                    var wsBox = webService.ServiceBoundingBox;
                    var wsExtent = new Extent(wsBox.XMin - eps, wsBox.YMin - eps, wsBox.XMax + eps, wsBox.YMax + eps);
                    if (wsExtent.Intersects(extent))
                    {
                        servicesToSearch.Add(new Tuple<WebServiceNode[], Extent>(new[] { webService }, wsExtent.Intersection(extent)));
                    }
                }
            }
            else
            {
                servicesToSearch.Add(new Tuple<WebServiceNode[], Extent>(new WebServiceNode[] { }, extent));
            }

            var servicesWithExtents = new List<Tuple<WebServiceNode[], List<Extent>>>(servicesToSearch.Count);
            int totalTilesCount = 0;
            foreach (var wsInfo in servicesToSearch)
            {
                var tiles = SearchHelper.CreateTiles(wsInfo.Item2, tileWidth, tileHeight);
                servicesWithExtents.Add(new Tuple<WebServiceNode[], List<Extent>>(wsInfo.Item1, tiles));
                totalTilesCount += tiles.Count;
            }

            var fullSeriesList = new List<List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>>();
            long  currentTileIndex = 0;
            int tilesFinished = 0;
            totalSeriesCount = 0;

            //bgWorker.ReportProgress(0, "0 Series found");
            CancellationTokenSource cts = new CancellationTokenSource();

            var serviceLoopOptions = new ParallelOptions
                {
                        //CancellationToken = bgWorker.CancellationToken,
            #if (DEBUG)
                        MaxDegreeOfParallelism = EnvironmentContext.LocalEnvironment() ? 1 : 2
            #else
                        MaxDegreeOfParallelism = 2
            #endif
                };
            var tileLoopOptions = new ParallelOptions
                {
                        //CancellationToken = bgWorker.CancellationToken,
                        CancellationToken = cts.Token,
                        // Note: currently HIS Central returns timeout if many requests are sent in the same time.
                        // To test set  MaxDegreeOfParallelism = -1
            #if (DEBUG)
                        MaxDegreeOfParallelism = EnvironmentContext.LocalEnvironment() ? 1 : 4
            #else
                        MaxDegreeOfParallelism = 4
            #endif
                };
            try
            {
                Parallel.ForEach(servicesWithExtents, serviceLoopOptions, wsInfo =>
                {
                    //bgWorker.CheckForCancel();
                    var ids = wsInfo.Item1.Select(item => item.ServiceID).ToArray();
                    var tiles = wsInfo.Item2;
                    try
                    {
                        Parallel.ForEach(tiles, tileLoopOptions, tile =>
                        {
                            var current = Interlocked.Add(ref currentTileIndex, 1);
                            //bgWorker.CheckForCancel();

                            // Do the web service call
                            var tileSeriesList = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();

                            if (SearchSettings.AndSearch == true)
                            {
                                //CHANGES FOR "AND" SEARCH
                                var totalTileSeriesList = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                                var tileSeriesList2 = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                                var tileSeriesList3 = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                                var tileSeriesList4 = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();

                                SeriesComparer sc = new SeriesComparer();

                                for (int i = 0; i < keywords.Count(); i++)
                                {
                                    String keyword = keywords.ElementAt(i);

                                    string sampleMedium = String.Empty;
                                    string dataType = String.Empty;
                                    string valueType = string.Empty;

                                    var series = GetSeriesCatalogForBox(tile.MinX, tile.MaxX, tile.MinY, tile.MaxY, sampleMedium, dataType, valueType, keyword, startDate, endDate, ids, current, totalTilesCount);

                                    totalTileSeriesList.AddRange(series);
                                    if (tileSeriesList.Count() == 0)
                                    {
                                        if (i == 0)
                                        {
                                            tileSeriesList.AddRange(series);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {

                                        tileSeriesList2.AddRange(tileSeriesList.Intersect(series, sc));
                                        tileSeriesList.Clear();
                                        tileSeriesList.AddRange(tileSeriesList2);
                                        tileSeriesList2.Clear();
                                    }
                                }

                                for (int i = 0; i < tileSeriesList.Count(); i++)
                                {
                                    tileSeriesList4 = totalTileSeriesList.Where(item => (item.SiteName.Equals(tileSeriesList.ElementAt(i).SiteName))).ToList();
                                    tileSeriesList3.AddRange(tileSeriesList4);
                                }

                                tileSeriesList = tileSeriesList3;
                            }
                            else
                            {
                                tileSeriesList = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>();
                                foreach (var keyword in keywords)
                                {
                                    string sampleMedium = String.Empty;
                                    string dataType = String.Empty;
                                    string valueType = string.Empty;

                                    var series = GetSeriesCatalogForBox(tile.MinX, tile.MaxX, tile.MinY, tile.MaxY, sampleMedium, dataType, valueType, keyword, startDate, endDate, ids, current, totalTilesCount);

                                    tileSeriesList.AddRange(series);
                                }
                            }
                            //END CHANGES FOR "AND" SEARCH

                            //bgWorker.CheckForCancel();
                            if (tileSeriesList.Count > 0)
                            {
                                var filtered = tileSeriesList.Where(seriesFilter).ToList();
                                if (filtered.Count > 0)
                                {
                                    lock (_lockGetSeries)
                                    {
                                        totalSeriesCount += filtered.Count;
                                        fullSeriesList.Add(filtered);
                                    }
                                }
                            }

                            // Report progress
                            var currentFinished = Interlocked.Add(ref tilesFinished, 1);
                            if (totalSeriesCount > maxAllowedTimeseriesReturn)
                            {
                                //Maximum time series exceeded - register a delegate to add an exception to the aggregate exception returned by the task cancellation processing...
                                cts.Token.Register(() => {
                                    string errorMessage = String.Format("Search returned more than {0:#,###0} timeseries and was canceled. Please limit search area and/or Keywords.", maxAllowedTimeseriesReturn);
                                    InvalidOperationException exp = new InvalidOperationException(errorMessage);
                                    throw exp;
                                });

                                cts.Cancel();
                            }
                            var message = string.Format("{0} Series found", totalSeriesCount);
                            var percentProgress = (currentFinished * 100) / totalTilesCount;
                            //bgWorker.ReportProgress(percentProgress, message);

                        });
                    }
                    catch (OperationCanceledException oex)
                    {
                        throw oex;
                    }
                });
                // Collect all series into result list
                var result = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>(totalSeriesCount);
                fullSeriesList.ForEach(result.AddRange);
                return result;
            }
            catch (OperationCanceledException oex)
            {
                throw oex;
            }
        }

        #endregion Methods
    }
}