示例#1
0
        public IEnumerable <BoxTree <CachedRow> .TileEntry> EnumEntries(int cachedTableIndex, IBox box)
        {
            _cachedTableIndex = cachedTableIndex;
            RowBoxTree rowBoxTree = _rowBoxTrees[cachedTableIndex];

            foreach (BoxTree <CachedRow> .TileEntry entry in rowBoxTree.Search(box))
            {
                _cachedRow = entry.Value;
                yield return(entry);
            }

            _cachedRow        = null;
            _cachedTableIndex = 0;
        }
        private TestedRow GetTestedRow([NotNull] IFeature feature)
        {
            ITable table = feature.Table;

            if (table == null)
            {
                return(null);
            }

            IDictionary <BaseRow, TestedRow> testedRows;

            if (!_overlappingRows.TryGetValue(table, out testedRows))
            {
                return(null);
            }

            // TODO revise: no UniqueIdProvider passed, but rows in testedRows may use UniqueIdProvider
            var       baseRow = new CachedRow(feature);
            TestedRow testedRow;

            return(testedRows.TryGetValue(baseRow, out testedRow)
                                       ? testedRow
                                       : null);
        }
示例#3
0
        public IList <IRow> Search([NotNull] ITable table,
                                   int tableIndex,
                                   [NotNull] IQueryFilter queryFilter,
                                   [NotNull] QueryFilterHelper filterHelper,
                                   [CanBeNull] IGeometry cacheGeometry)
        {
            var       spatialFilter  = (ISpatialFilter)queryFilter;
            IGeometry filterGeometry = spatialFilter.Geometry;

            IList <IRow> result = new List <IRow>();

            // TODO explain network queries
            bool repeatCachedRows = filterHelper.ForNetwork;

            // filterHelper.PointSearchOnlyWithinTile
            if (filterHelper.ForNetwork)
            {
                var filterPoint = filterGeometry as IPoint;
                if (filterPoint != null)
                {
                    // search only if the point is within the tile box
                    // (or left/below of test run box)

                    double x;
                    double y;
                    filterPoint.QueryCoords(out x, out y);

                    Pnt  tileMin    = CurrentTileBox.Min;
                    Pnt  tileMax    = CurrentTileBox.Max;
                    IPnt testRunMin = _testRunBox.Min;

                    if ((x <= tileMin.X && x > testRunMin.X) || x > tileMax.X ||
                        (y <= tileMin.Y && y > testRunMin.Y) || y > tileMax.Y)
                    {
                        // outside of tile box, return empty list
                        return(result);
                    }
                }
            }

            List <BoxTree <CachedRow> .TileEntry> searchList = SearchList(filterGeometry,
                                                                          tableIndex);

            if (searchList == null || searchList.Count == 0)
            {
                return(result);
            }

            var cacheGeometryOverlapsLeftTile   = false;
            var cacheGeometryOverlapsBottomTile = false;

            if (!repeatCachedRows)
            {
                if (cacheGeometry != null)
                {
                    cacheGeometry.QueryEnvelope(_envelopeTemplate);
                }
                else
                {
                    filterGeometry.QueryEnvelope(_envelopeTemplate);
                }

                double xmin;
                double ymin;
                double xmax;
                double ymax;
                _envelopeTemplate.QueryCoords(out xmin, out ymin, out xmax, out ymax);

                cacheGeometryOverlapsLeftTile = xmin <CurrentTileBox.Min.X &&
                                                      xmin> _testRunBox.Min.X;

                // https://issuetracker02.eggits.net/browse/COM-85
                // observed (CtLu):
                // - filter geometry ymin = 220532.967
                // - filter geometry ymax = 220557.78500
                // - tile ymin            = 220557.78534
                // --> filter geometry is completely outside of tile boundaries!!!
                // --> causes incorrect error in QaContainsOther
                cacheGeometryOverlapsBottomTile = ymin <CurrentTileBox.Min.Y &&
                                                        ymin> _testRunBox.Min.Y;
            }

            IGeometryEngine engine = _container.GeometryEngine;

            engine.SetSourceGeometry(filterGeometry);

            IList <ContainerTest> tests = _testsPerTable[table];
            int indexTest = tests.IndexOf(filterHelper.ContainerTest);

            IList <BaseRow> ignoredRows = IgnoredRowsByTableAndTest[tableIndex][indexTest];

            foreach (BoxTree <CachedRow> .TileEntry entry in searchList)
            {
                CachedRow cachedRow = Assert.NotNull(entry.Value, "cachedRow");

                // This causes problems for QaIsCoveredByOther. However
                // IsCoveredByOther is not a network test, but still requires cached features
                // to be returned repeatedly
                if (cacheGeometryOverlapsLeftTile && !cachedRow.IsFirstOccurrenceX)
                {
                    // only if *not for network*:
                    // the filter geometry overlaps the left border of the tile, but
                    // not the left border of the test run box AND the cached row
                    // was already returned previously --> skip it
                    continue;
                }

                if (cacheGeometryOverlapsBottomTile && !cachedRow.IsFirstOccurrenceY)
                {
                    // only if *not for network*:
                    // the filter geometry overlaps the bottom border of the tile, but
                    // not the bottom border of the test run box AND the cached row
                    // was already returned previously --> skip it
                    continue;
                }

                if (ignoredRows != null && ignoredRows.Contains(entry.Value))
                {
                    continue;
                }

                IFeature targetFeature = cachedRow.Feature;

                if (targetFeature.OID < filterHelper.MinimumOID)
                {
                    continue;
                }

                engine.SetTargetGeometry(cachedRow.Geometry);

                // Remark: if most of the rows fullfill helper.Check,
                // it is better to check the geometric relation first
                var matchesConstraint = false;
                if (filterHelper.AttributeFirst)
                {
                    if (!filterHelper.MatchesConstraint(targetFeature))
                    {
                        continue;
                    }

                    matchesConstraint = true;
                }

                if (engine.EvaluateRelation(spatialFilter))
                {
                    if (matchesConstraint || filterHelper.MatchesConstraint(targetFeature))
                    {
                        result.Add(targetFeature);
                    }
                }
            }

            return(result);
        }