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); }
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); }